summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/unsupported/qpdf/QOutputDev.h7
-rw-r--r--noncore/unsupported/qpdf/README45
-rw-r--r--noncore/unsupported/qpdf/UTF8.h14
-rw-r--r--noncore/unsupported/qpdf/qpdf.cpp13
-rw-r--r--noncore/unsupported/qpdf/qpdf.h7
-rw-r--r--noncore/unsupported/qpdf/qpdf.pro5
-rw-r--r--noncore/unsupported/qpdf/xpdf/Annot.cc (renamed from noncore/unsupported/qpdf/xpdf/FormWidget.cc)53
-rw-r--r--noncore/unsupported/qpdf/xpdf/Annot.h (renamed from noncore/unsupported/qpdf/xpdf/FormWidget.h)40
-rw-r--r--noncore/unsupported/qpdf/xpdf/Array.cc2
-rw-r--r--noncore/unsupported/qpdf/xpdf/Array.h2
-rw-r--r--noncore/unsupported/qpdf/xpdf/BuiltinFont.h2
-rw-r--r--noncore/unsupported/qpdf/xpdf/BuiltinFontTables.cc2
-rw-r--r--noncore/unsupported/qpdf/xpdf/BuiltinFontTables.h2
-rw-r--r--noncore/unsupported/qpdf/xpdf/CMap.cc104
-rw-r--r--noncore/unsupported/qpdf/xpdf/CMap.h2
-rw-r--r--noncore/unsupported/qpdf/xpdf/Catalog.cc8
-rw-r--r--noncore/unsupported/qpdf/xpdf/Catalog.h2
-rw-r--r--noncore/unsupported/qpdf/xpdf/CharCodeToUnicode.cc160
-rw-r--r--noncore/unsupported/qpdf/xpdf/CharCodeToUnicode.h5
-rw-r--r--noncore/unsupported/qpdf/xpdf/CharTypes.h2
-rw-r--r--noncore/unsupported/qpdf/xpdf/Decrypt.cc2
-rw-r--r--noncore/unsupported/qpdf/xpdf/Decrypt.h2
-rw-r--r--noncore/unsupported/qpdf/xpdf/Dict.cc2
-rw-r--r--noncore/unsupported/qpdf/xpdf/Dict.h2
-rw-r--r--noncore/unsupported/qpdf/xpdf/DisplayFontTable.h6
-rw-r--r--noncore/unsupported/qpdf/xpdf/Error.cc2
-rw-r--r--noncore/unsupported/qpdf/xpdf/Error.h2
-rw-r--r--noncore/unsupported/qpdf/xpdf/ErrorCodes.h24
-rw-r--r--noncore/unsupported/qpdf/xpdf/FontEncodingTables.cc2
-rw-r--r--noncore/unsupported/qpdf/xpdf/FontEncodingTables.h2
-rw-r--r--noncore/unsupported/qpdf/xpdf/Function.cc13
-rw-r--r--noncore/unsupported/qpdf/xpdf/Function.h2
-rw-r--r--noncore/unsupported/qpdf/xpdf/Gfx.cc589
-rw-r--r--noncore/unsupported/qpdf/xpdf/Gfx.h20
-rw-r--r--noncore/unsupported/qpdf/xpdf/GfxFont.cc62
-rw-r--r--noncore/unsupported/qpdf/xpdf/GfxFont.h24
-rw-r--r--noncore/unsupported/qpdf/xpdf/GfxState.cc246
-rw-r--r--noncore/unsupported/qpdf/xpdf/GfxState.h39
-rw-r--r--noncore/unsupported/qpdf/xpdf/GlobalParams.cc381
-rw-r--r--noncore/unsupported/qpdf/xpdf/GlobalParams.h49
-rw-r--r--noncore/unsupported/qpdf/xpdf/Lexer.cc2
-rw-r--r--noncore/unsupported/qpdf/xpdf/Lexer.h11
-rw-r--r--noncore/unsupported/qpdf/xpdf/Link.cc34
-rw-r--r--noncore/unsupported/qpdf/xpdf/Link.h8
-rw-r--r--noncore/unsupported/qpdf/xpdf/NameToCharCode.cc2
-rw-r--r--noncore/unsupported/qpdf/xpdf/NameToCharCode.h2
-rw-r--r--noncore/unsupported/qpdf/xpdf/NameToUnicodeTable.h2
-rw-r--r--noncore/unsupported/qpdf/xpdf/Object.cc2
-rw-r--r--noncore/unsupported/qpdf/xpdf/Object.h12
-rw-r--r--noncore/unsupported/qpdf/xpdf/OutputDev.cc7
-rw-r--r--noncore/unsupported/qpdf/xpdf/OutputDev.h17
-rw-r--r--noncore/unsupported/qpdf/xpdf/PDFDoc.cc16
-rw-r--r--noncore/unsupported/qpdf/xpdf/PDFDoc.h6
-rw-r--r--noncore/unsupported/qpdf/xpdf/PSTokenizer.cc133
-rw-r--r--noncore/unsupported/qpdf/xpdf/PSTokenizer.h39
-rw-r--r--noncore/unsupported/qpdf/xpdf/Page.cc40
-rw-r--r--noncore/unsupported/qpdf/xpdf/Page.h28
-rw-r--r--noncore/unsupported/qpdf/xpdf/Parser.cc11
-rw-r--r--noncore/unsupported/qpdf/xpdf/Parser.h2
-rw-r--r--noncore/unsupported/qpdf/xpdf/Stream-CCITT.h2
-rw-r--r--noncore/unsupported/qpdf/xpdf/Stream.cc215
-rw-r--r--noncore/unsupported/qpdf/xpdf/Stream.h113
-rw-r--r--noncore/unsupported/qpdf/xpdf/TextOutputDev.cc73
-rw-r--r--noncore/unsupported/qpdf/xpdf/TextOutputDev.h22
-rw-r--r--noncore/unsupported/qpdf/xpdf/UnicodeMap.cc2
-rw-r--r--noncore/unsupported/qpdf/xpdf/UnicodeMap.h2
-rw-r--r--noncore/unsupported/qpdf/xpdf/UnicodeMapTables.h60
-rw-r--r--noncore/unsupported/qpdf/xpdf/XRef.cc80
-rw-r--r--noncore/unsupported/qpdf/xpdf/XRef.h25
69 files changed, 2201 insertions, 715 deletions
diff --git a/noncore/unsupported/qpdf/QOutputDev.h b/noncore/unsupported/qpdf/QOutputDev.h
index 2958062..f3c5a01 100644
--- a/noncore/unsupported/qpdf/QOutputDev.h
+++ b/noncore/unsupported/qpdf/QOutputDev.h
@@ -1,173 +1,180 @@
1 1
2//======================================================================== 2//========================================================================
3// 3//
4// XOutputDev.h 4// XOutputDev.h
5// 5//
6// Copyright 1996 Derek B. Noonburg 6// Copyright 1996 Derek B. Noonburg
7// 7//
8//======================================================================== 8//========================================================================
9 9
10#ifndef QOUTPUTDEV_H 10#ifndef QOUTPUTDEV_H
11#define QOUTPUTDEV_H 11#define QOUTPUTDEV_H
12 12
13#ifdef __GNUC__ 13#ifdef __GNUC__
14#pragma interface 14#pragma interface
15#endif 15#endif
16 16
17#include "aconf.h" 17#include "aconf.h"
18#include <stddef.h> 18#include <stddef.h>
19 19
20#include <qscrollview.h> 20#include <qscrollview.h>
21 21
22class Object; 22class Object;
23 23
24#include "config.h" 24#include "config.h"
25#include "CharTypes.h" 25#include "CharTypes.h"
26#include "GlobalParams.h" 26#include "GlobalParams.h"
27#include "OutputDev.h" 27#include "OutputDev.h"
28 28
29class GString; 29class GString;
30class GList; 30class GList;
31struct GfxRGB; 31struct GfxRGB;
32class GfxFont; 32class GfxFont;
33class GfxSubpath; 33class GfxSubpath;
34class TextPage; 34class TextPage;
35class XOutputFontCache; 35class XOutputFontCache;
36class Link; 36class Link;
37class Catalog; 37class Catalog;
38class DisplayFontParam; 38class DisplayFontParam;
39class UnicodeMap; 39class UnicodeMap;
40class CharCodeToUnicode; 40class CharCodeToUnicode;
41 41
42 42
43class QPainter; 43class QPainter;
44class QPixmap; 44class QPixmap;
45class QPointArray; 45class QPointArray;
46 46
47 47
48typedef fouble fp_t; 48typedef fouble fp_t;
49 49
50//------------------------------------------------------------------------ 50//------------------------------------------------------------------------
51// Constants 51// Constants
52//------------------------------------------------------------------------ 52//------------------------------------------------------------------------
53 53
54 54
55//------------------------------------------------------------------------ 55//------------------------------------------------------------------------
56// Misc types 56// Misc types
57//------------------------------------------------------------------------ 57//------------------------------------------------------------------------
58 58
59 59
60//------------------------------------------------------------------------ 60//------------------------------------------------------------------------
61// XOutputDev 61// XOutputDev
62//------------------------------------------------------------------------ 62//------------------------------------------------------------------------
63 63
64class QOutputDev : public QScrollView, public OutputDev { 64class QOutputDev : public QScrollView, public OutputDev {
65public: 65public:
66 66
67 // Constructor. 67 // Constructor.
68 QOutputDev( QWidget *parent = 0, const char *name = 0, int flags = 0 ); 68 QOutputDev( QWidget *parent = 0, const char *name = 0, int flags = 0 );
69 69
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
94 virtual void saveState(GfxState *state); 101 virtual void saveState(GfxState *state);
95 virtual void restoreState(GfxState *state); 102 virtual void restoreState(GfxState *state);
96 103
97 //----- update graphics state 104 //----- update graphics state
98 virtual void updateAll(GfxState *state); 105 virtual void updateAll(GfxState *state);
99 virtual void updateCTM(GfxState *state, fp_t m11, fp_t m12, 106 virtual void updateCTM(GfxState *state, fp_t m11, fp_t m12,
100 fp_t m21, fp_t m22, fp_t m31, fp_t m32); 107 fp_t m21, fp_t m22, fp_t m31, fp_t m32);
101 virtual void updateLineDash(GfxState *state); 108 virtual void updateLineDash(GfxState *state);
102 virtual void updateFlatness(GfxState *state); 109 virtual void updateFlatness(GfxState *state);
103 virtual void updateLineJoin(GfxState *state); 110 virtual void updateLineJoin(GfxState *state);
104 virtual void updateLineCap(GfxState *state); 111 virtual void updateLineCap(GfxState *state);
105 virtual void updateMiterLimit(GfxState *state); 112 virtual void updateMiterLimit(GfxState *state);
106 virtual void updateLineWidth(GfxState *state); 113 virtual void updateLineWidth(GfxState *state);
107 virtual void updateFillColor(GfxState *state); 114 virtual void updateFillColor(GfxState *state);
108 virtual void updateStrokeColor(GfxState *state); 115 virtual void updateStrokeColor(GfxState *state);
109 116
110 //----- update text state 117 //----- update text state
111 virtual void updateFont(GfxState *state); 118 virtual void updateFont(GfxState *state);
112 119
113 //----- path painting 120 //----- path painting
114 virtual void stroke(GfxState *state); 121 virtual void stroke(GfxState *state);
115 virtual void fill(GfxState *state); 122 virtual void fill(GfxState *state);
116 virtual void eoFill(GfxState *state); 123 virtual void eoFill(GfxState *state);
117 124
118 //----- path clipping 125 //----- path clipping
119 virtual void clip(GfxState *state); 126 virtual void clip(GfxState *state);
120 virtual void eoClip(GfxState *state); 127 virtual void eoClip(GfxState *state);
121 128
122 //----- text drawing 129 //----- text drawing
123 virtual void beginString(GfxState *state, GString *s); 130 virtual void beginString(GfxState *state, GString *s);
124 virtual void endString(GfxState *state); 131 virtual void endString(GfxState *state);
125 virtual void drawChar(GfxState *state, fp_t x, fp_t y, 132 virtual void drawChar(GfxState *state, fp_t x, fp_t y,
126 fp_t dx, fp_t dy, 133 fp_t dx, fp_t dy,
127 fp_t originX, fp_t originY, 134 fp_t originX, fp_t originY,
128 CharCode code, Unicode *u, int uLen); 135 CharCode code, Unicode *u, int uLen);
129 136
130 //----- image drawing 137 //----- image drawing
131 virtual void drawImageMask(GfxState *state, Object *ref, Stream *str, 138 virtual void drawImageMask(GfxState *state, Object *ref, Stream *str,
132 int width, int height, GBool invert, 139 int width, int height, GBool invert,
133 GBool inlineImg); 140 GBool inlineImg);
134 virtual void drawImage(GfxState *state, Object *ref, Stream *str, 141 virtual void drawImage(GfxState *state, Object *ref, Stream *str,
135 int width, int height, GfxImageColorMap *colorMap, 142 int width, int height, GfxImageColorMap *colorMap,
136 int *maskColors, GBool inlineImg); 143 int *maskColors, GBool inlineImg);
137 144
138 // Find a string. If <top> is true, starts looking at <l>,<t>; 145 // Find a string. If <top> is true, starts looking at <l>,<t>;
139 // otherwise starts looking at top of page. If <bottom> is true, 146 // otherwise starts looking at top of page. If <bottom> is true,
140 // stops looking at <l+w-1>,<t+h-1>; otherwise stops looking at bottom 147 // stops looking at <l+w-1>,<t+h-1>; otherwise stops looking at bottom
141 // of page. If found, sets the text bounding rectange and returns 148 // of page. If found, sets the text bounding rectange and returns
142 // true; otherwise returns false. 149 // true; otherwise returns false.
143 GBool findText ( Unicode *s, int len, GBool top, GBool bottom, int *xMin, int *yMin, int *xMax, int *yMax ); 150 GBool findText ( Unicode *s, int len, GBool top, GBool bottom, int *xMin, int *yMin, int *xMax, int *yMax );
144 151
145 //----- special QT access 152 //----- special QT access
146 153
147 bool findText ( const QString &str, int &l, int &t, int &w, int &h, bool top = 0, bool bottom = 0 ); 154 bool findText ( const QString &str, int &l, int &t, int &w, int &h, bool top = 0, bool bottom = 0 );
148 bool findText ( const QString &str, QRect &r, bool top = 0, bool bottom = 0 ); 155 bool findText ( const QString &str, QRect &r, bool top = 0, bool bottom = 0 );
149 156
150 // Get the text which is inside the specified rectangle. 157 // Get the text which is inside the specified rectangle.
151 QString getText ( int left, int top, int width, int height ); 158 QString getText ( int left, int top, int width, int height );
152 QString getText ( const QRect &r ); 159 QString getText ( const QRect &r );
153 160
154protected: 161protected:
155 virtual void drawContents ( QPainter *p, int, int, int, int ); 162 virtual void drawContents ( QPainter *p, int, int, int, int );
156 163
157private: 164private:
158 QPixmap *m_pixmap; // pixmap to draw into 165 QPixmap *m_pixmap; // pixmap to draw into
159 QPainter *m_painter; 166 QPainter *m_painter;
160 167
161 TextPage *m_text; // text from the current page 168 TextPage *m_text; // text from the current page
162 169
163 private: 170 private:
164 QFont matchFont ( GfxFont *, fp_t m11, fp_t m12, fp_t m21, fp_t m22 ); 171 QFont matchFont ( GfxFont *, fp_t m11, fp_t m12, fp_t m21, fp_t m22 );
165 172
166 void updateLineAttrs ( GfxState *state, GBool updateDash ); 173 void updateLineAttrs ( GfxState *state, GBool updateDash );
167 void doFill ( GfxState *state, bool winding ); 174 void doFill ( GfxState *state, bool winding );
168 void doClip ( GfxState *state, bool winding ); 175 void doClip ( GfxState *state, bool winding );
169 int convertPath ( GfxState *state, QPointArray &points, QArray<int> &lengths ); 176 int convertPath ( GfxState *state, QPointArray &points, QArray<int> &lengths );
170 int convertSubpath ( GfxState *state, GfxSubpath *subpath, QPointArray &points ); 177 int convertSubpath ( GfxState *state, GfxSubpath *subpath, QPointArray &points );
171}; 178};
172 179
173#endif 180#endif
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,89 +1,80 @@
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
41 a) the Qtopia Qt/E config has QPainter transformations disabled 48 a) the Qtopia Qt/E config has QPainter transformations disabled
42 b) the transformation is awful slow 49 b) the transformation is awful slow
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
@@ -1,24 +1,38 @@
1//======================================================================== 1//========================================================================
2// 2//
3// UTF8.h 3// UTF8.h
4// 4//
5// Copyright 2001 Derek B. Noonburg 5// Copyright 2001 Derek B. Noonburg
6// Modified for QPE by Robert Griebl 6// Modified for QPE by Robert Griebl
7// 7//
8//======================================================================== 8//========================================================================
9 9
10#include <qstring.h> 10#include <qstring.h>
11#include <string.h> 11#include <string.h>
12 12
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
@@ -1,276 +1,287 @@
1//======================================================================== 1//========================================================================
2// 2//
3// qpdf.cc 3// qpdf.cc
4// 4//
5// Copyright 2001 Robert Griebl 5// Copyright 2001 Robert Griebl
6// 6//
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
52 if (( app. argc ( ) == 3 ) && ( app. argv ( ) [1] == QCString ( "-f" ))) 58 if (( app. argc ( ) == 3 ) && ( app. argv ( ) [1] == QCString ( "-f" )))
53 dlg-> openFile ( app. argv ( ) [2] ); 59 dlg-> openFile ( app. argv ( ) [2] );
54 60
55 return app. exec ( ); 61 return app. exec ( );
56} 62}
57 63
58 64
59QPdfDlg::QPdfDlg ( ) : QMainWindow ( ) 65QPdfDlg::QPdfDlg ( ) : QMainWindow ( )
60{ 66{
61 setCaption ( tr( "QPdf" )); 67 setCaption ( tr( "QPdf" ));
62 setIcon ( Resource::loadPixmap ( "qpdf_icon" )); 68 setIcon ( Resource::loadPixmap ( "qpdf_icon" ));
63 69
64 m_busy = false; 70 m_busy = false;
65 71
66 m_doc = 0; 72 m_doc = 0;
67 m_pages = 0; 73 m_pages = 0;
68 m_zoom = 72; 74 m_zoom = 72;
69 m_currentpage = 0; 75 m_currentpage = 0;
70 76
71 m_fullscreen = false; 77 m_fullscreen = false;
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 );
97 108
98 m_pm_zoom-> insertItem ( tr( "Fit to width" ), 1 ); 109 m_pm_zoom-> insertItem ( tr( "Fit to width" ), 1 );
99 m_pm_zoom-> insertItem ( tr( "Fit to page" ), 2 ); 110 m_pm_zoom-> insertItem ( tr( "Fit to page" ), 2 );
100 m_pm_zoom-> insertSeparator ( ); 111 m_pm_zoom-> insertSeparator ( );
101 m_pm_zoom-> insertItem ( tr( "50%" ), 50 ); 112 m_pm_zoom-> insertItem ( tr( "50%" ), 50 );
102 m_pm_zoom-> insertItem ( tr( "75%" ), 75 ); 113 m_pm_zoom-> insertItem ( tr( "75%" ), 75 );
103 m_pm_zoom-> insertItem ( tr( "100%" ), 100 ); 114 m_pm_zoom-> insertItem ( tr( "100%" ), 100 );
104 m_pm_zoom-> insertItem ( tr( "125%" ), 125 ); 115 m_pm_zoom-> insertItem ( tr( "125%" ), 125 );
105 m_pm_zoom-> insertItem ( tr( "150%" ), 150 ); 116 m_pm_zoom-> insertItem ( tr( "150%" ), 150 );
106 m_pm_zoom-> insertItem ( tr( "200%" ), 200 ); 117 m_pm_zoom-> insertItem ( tr( "200%" ), 200 );
107 118
108 connect ( m_pm_zoom, SIGNAL( activated ( int )), this, SLOT( setZoom ( int ))); 119 connect ( m_pm_zoom, SIGNAL( activated ( int )), this, SLOT( setZoom ( int )));
109 120
110 m_tb_tool = new QToolBar ( this ); 121 m_tb_tool = new QToolBar ( this );
111 122
112 new QToolButton ( Resource::loadIconSet ( "fileopen" ), tr( "Open..." ), QString::null, this, SLOT( openFile ( )), m_tb_tool, "open" ); 123 new QToolButton ( Resource::loadIconSet ( "fileopen" ), tr( "Open..." ), QString::null, this, SLOT( openFile ( )), m_tb_tool, "open" );
113 m_tb_tool-> addSeparator ( ); 124 m_tb_tool-> addSeparator ( );
114 m_to_find = new QToolButton ( Resource::loadIconSet ( "find" ), tr( "Find..." ), QString::null, this, SLOT( toggleFindBar ( )), m_tb_tool, "find" ); 125 m_to_find = new QToolButton ( Resource::loadIconSet ( "find" ), tr( "Find..." ), QString::null, this, SLOT( toggleFindBar ( )), m_tb_tool, "find" );
115 m_to_find-> setToggleButton ( true ); 126 m_to_find-> setToggleButton ( true );
116 m_tb_tool-> addSeparator ( ); 127 m_tb_tool-> addSeparator ( );
117 m_to_full = new QToolButton ( Resource::loadIconSet ( "fullscreen" ), tr( "Fullscreen" ), QString::null, this, SLOT( toggleFullscreen ( )), m_tb_tool, "fullscreen" ); 128 m_to_full = new QToolButton ( Resource::loadIconSet ( "fullscreen" ), tr( "Fullscreen" ), QString::null, this, SLOT( toggleFullscreen ( )), m_tb_tool, "fullscreen" );
118 m_to_full-> setToggleButton ( true ); 129 m_to_full-> setToggleButton ( true );
119 m_tb_tool-> addSeparator ( ); 130 m_tb_tool-> addSeparator ( );
120 new QToolButton ( Resource::loadIconSet ( "fastback" ), tr( "First page" ), QString::null, this, SLOT( firstPage ( )), m_tb_tool, "first" ); 131 new QToolButton ( Resource::loadIconSet ( "fastback" ), tr( "First page" ), QString::null, this, SLOT( firstPage ( )), m_tb_tool, "first" );
121 new QToolButton ( Resource::loadIconSet ( "back" ), tr( "Previous page" ), QString::null, this, SLOT( prevPage ( )), m_tb_tool, "prev" ); 132 new QToolButton ( Resource::loadIconSet ( "back" ), tr( "Previous page" ), QString::null, this, SLOT( prevPage ( )), m_tb_tool, "prev" );
122 new QToolButton ( Resource::loadIconSet ( "down" ), tr( "Goto page..." ), QString::null, this, SLOT( gotoPageDialog ( )), m_tb_tool, "goto" ); 133 new QToolButton ( Resource::loadIconSet ( "down" ), tr( "Goto page..." ), QString::null, this, SLOT( gotoPageDialog ( )), m_tb_tool, "goto" );
123 new QToolButton ( Resource::loadIconSet ( "forward" ), tr( "Next page" ), QString::null, this, SLOT( nextPage ( )), m_tb_tool, "next" ); 134 new QToolButton ( Resource::loadIconSet ( "forward" ), tr( "Next page" ), QString::null, this, SLOT( nextPage ( )), m_tb_tool, "next" );
124 new QToolButton ( Resource::loadIconSet ( "fastforward" ), tr( "Last page" ), QString::null, this, SLOT( lastPage ( )), m_tb_tool, "last" ); 135 new QToolButton ( Resource::loadIconSet ( "fastforward" ), tr( "Last page" ), QString::null, this, SLOT( lastPage ( )), m_tb_tool, "last" );
125 136
126 m_tb_find = new QToolBar ( this ); 137 m_tb_find = new QToolBar ( this );
127 addToolBar ( m_tb_find, "Search", QMainWindow::Top, true ); 138 addToolBar ( m_tb_find, "Search", QMainWindow::Top, true );
128 m_tb_find-> setHorizontalStretchable ( true ); 139 m_tb_find-> setHorizontalStretchable ( true );
129 m_tb_find-> hide ( ); 140 m_tb_find-> hide ( );
130 141
131 m_findedit = new QLineEdit ( m_tb_find, "findedit" ); 142 m_findedit = new QLineEdit ( m_tb_find, "findedit" );
132 m_tb_find-> setStretchableWidget ( m_findedit ); 143 m_tb_find-> setStretchableWidget ( m_findedit );
133 connect ( m_findedit, SIGNAL( textChanged ( const QString & )), this, SLOT( findText ( const QString & ))); 144 connect ( m_findedit, SIGNAL( textChanged ( const QString & )), this, SLOT( findText ( const QString & )));
134 145
135 new QToolButton ( Resource::loadIconSet ( "next" ), tr( "Next" ), QString::null, this, SLOT( findText ( )), m_tb_find, "findnext" ); 146 new QToolButton ( Resource::loadIconSet ( "next" ), tr( "Next" ), QString::null, this, SLOT( findText ( )), m_tb_find, "findnext" );
136 147
137 openFile ( ); 148 openFile ( );
138} 149}
139 150
140QPdfDlg::~QPdfDlg ( ) 151QPdfDlg::~QPdfDlg ( )
141{ 152{
142 delete m_doc; 153 delete m_doc;
143} 154}
144 155
145// vv Fullscreen handling (for broken QT-lib) [David Hedbor, www.eongames.com] 156// vv Fullscreen handling (for broken QT-lib) [David Hedbor, www.eongames.com]
146 157
147void QPdfDlg::resizeEvent ( QResizeEvent * ) 158void QPdfDlg::resizeEvent ( QResizeEvent * )
148{ 159{
149 if ( m_fullscreen && ( size ( ) != qApp-> desktop ( )-> size ( ))) 160 if ( m_fullscreen && ( size ( ) != qApp-> desktop ( )-> size ( )))
150 setFullscreen ( true ); 161 setFullscreen ( true );
151} 162}
152 163
153void QPdfDlg::focusInEvent ( QFocusEvent * ) 164void QPdfDlg::focusInEvent ( QFocusEvent * )
154{ 165{
155 if ( m_fullscreen ) 166 if ( m_fullscreen )
156 setFullscreen ( true ); 167 setFullscreen ( true );
157} 168}
158 169
159void QPdfDlg::toggleFullscreen ( ) 170void QPdfDlg::toggleFullscreen ( )
160{ 171{
161 if ( m_to_full-> isOn ( ) == m_fullscreen ) 172 if ( m_to_full-> isOn ( ) == m_fullscreen )
162 m_to_full-> setOn ( !m_fullscreen ); 173 m_to_full-> setOn ( !m_fullscreen );
163 174
164 m_fullscreen = !m_fullscreen; 175 m_fullscreen = !m_fullscreen;
165 setFullscreen ( m_fullscreen ); 176 setFullscreen ( m_fullscreen );
166} 177}
167 178
168void QPdfDlg::setFullscreen ( bool b ) 179void QPdfDlg::setFullscreen ( bool b )
169{ 180{
170 static QSize normalsize; 181 static QSize normalsize;
171 182
172 if ( b ) { 183 if ( b ) {
173 if ( !normalsize. isValid ( )) 184 if ( !normalsize. isValid ( ))
174 normalsize = size ( ); 185 normalsize = size ( );
175 186
176 setFixedSize ( qApp-> desktop ( )-> size ( )); 187 setFixedSize ( qApp-> desktop ( )-> size ( ));
177 showNormal ( ); 188 showNormal ( );
178 reparent ( 0, WStyle_Customize | WStyle_NoBorder, QPoint ( 0, 0 )); 189 reparent ( 0, WStyle_Customize | WStyle_NoBorder, QPoint ( 0, 0 ));
179 showFullScreen ( ); 190 showFullScreen ( );
180 } 191 }
181 else { 192 else {
182 showNormal ( ); 193 showNormal ( );
183 reparent ( 0, 0, QPoint ( 0, 0 )); 194 reparent ( 0, 0, QPoint ( 0, 0 ));
184 resize ( normalsize ); 195 resize ( normalsize );
185 showMaximized ( ); 196 showMaximized ( );
186 normalsize = QSize ( ); 197 normalsize = QSize ( );
187 } 198 }
188} 199}
189 200
190// ^^ Fullscreen handling (for broken QT-lib) 201// ^^ Fullscreen handling (for broken QT-lib)
191 202
192void QPdfDlg::setBusy ( bool b ) 203void QPdfDlg::setBusy ( bool b )
193{ 204{
194 if ( b != m_busy ) { 205 if ( b != m_busy ) {
195 m_busy = b; 206 m_busy = b;
196 207
197 m_outdev-> setBusy ( m_busy ); 208 m_outdev-> setBusy ( m_busy );
198 setEnabled ( !m_busy ); 209 setEnabled ( !m_busy );
199 } 210 }
200} 211}
201 212
202bool QPdfDlg::busy ( ) const 213bool QPdfDlg::busy ( ) const
203{ 214{
204 return m_busy; 215 return m_busy;
205} 216}
206 217
207 218
208void QPdfDlg::updateCaption ( ) 219void QPdfDlg::updateCaption ( )
209{ 220{
210 QString cap = ""; 221 QString cap = "";
211 222
212 if ( !m_currentdoc. isEmpty ( )) 223 if ( !m_currentdoc. isEmpty ( ))
213 cap = QString ( "%1 - " ). arg ( m_currentdoc ); 224 cap = QString ( "%1 - " ). arg ( m_currentdoc );
214 cap += "QPdf"; 225 cap += "QPdf";
215 226
216 setCaption ( cap ); 227 setCaption ( cap );
217} 228}
218 229
219 230
220void QPdfDlg::setZoom ( int id ) 231void QPdfDlg::setZoom ( int id )
221{ 232{
222 int dpi = 0; 233 int dpi = 0;
223 234
224 switch ( id ) { 235 switch ( id ) {
225 case 1: 236 case 1:
226 if ( m_doc && m_doc-> isOk ( )) 237 if ( m_doc && m_doc-> isOk ( ))
227 dpi = m_outdev-> visibleWidth ( ) * 72 / m_doc-> getPageWidth ( m_currentpage ); 238 dpi = m_outdev-> visibleWidth ( ) * 72 / m_doc-> getPageWidth ( m_currentpage );
228 break; 239 break;
229 240
230 case 2: 241 case 2:
231 if ( m_doc && m_doc-> isOk ( )) 242 if ( m_doc && m_doc-> isOk ( ))
232 dpi = QMIN( m_outdev-> visibleWidth ( ) * 72 / m_doc-> getPageWidth ( m_currentpage ), \ 243 dpi = QMIN( m_outdev-> visibleWidth ( ) * 72 / m_doc-> getPageWidth ( m_currentpage ), \
233 m_outdev-> visibleHeight ( ) * 72 / m_doc-> getPageHeight ( m_currentpage )); 244 m_outdev-> visibleHeight ( ) * 72 / m_doc-> getPageHeight ( m_currentpage ));
234 break; 245 break;
235 246
236 default: 247 default:
237 dpi = id * 72 / 100; 248 dpi = id * 72 / 100;
238 break; 249 break;
239 } 250 }
240 251
241 if ( dpi < 18 ) 252 if ( dpi < 18 )
242 dpi = 18; 253 dpi = 18;
243 if ( dpi > 216 ) 254 if ( dpi > 216 )
244 dpi = 216; 255 dpi = 216;
245 256
246 for ( uint i = 0; i < m_pm_zoom-> count ( ); i++ ) { 257 for ( uint i = 0; i < m_pm_zoom-> count ( ); i++ ) {
247 int xid = m_pm_zoom-> idAt ( i ); 258 int xid = m_pm_zoom-> idAt ( i );
248 m_pm_zoom-> setItemChecked ( xid, xid == id ); 259 m_pm_zoom-> setItemChecked ( xid, xid == id );
249 } 260 }
250 261
251 if ( dpi != m_zoom ) { 262 if ( dpi != m_zoom ) {
252 m_zoom = dpi; 263 m_zoom = dpi;
253 264
254 renderPage ( ); 265 renderPage ( );
255 } 266 }
256} 267}
257 268
258 269
259void QPdfDlg::gotoPageDialog ( ) 270void QPdfDlg::gotoPageDialog ( )
260{ 271{
261 QDialog *d = new QDialog ( this, "gotodlg", true ); 272 QDialog *d = new QDialog ( this, "gotodlg", true );
262 d-> setCaption ( tr( "Goto page" )); 273 d-> setCaption ( tr( "Goto page" ));
263 274
264 QBoxLayout *lay = new QVBoxLayout ( d, 4, 4 ); 275 QBoxLayout *lay = new QVBoxLayout ( d, 4, 4 );
265 276
266 QLabel *l = new QLabel ( tr( "Select from 1 .. %1:" ). arg ( m_pages ), d ); 277 QLabel *l = new QLabel ( tr( "Select from 1 .. %1:" ). arg ( m_pages ), d );
267 lay-> addWidget ( l ); 278 lay-> addWidget ( l );
268 279
269 QSpinBox *spin = new QSpinBox ( 1, m_pages, 1, d ); 280 QSpinBox *spin = new QSpinBox ( 1, m_pages, 1, d );
270 spin-> setValue ( m_currentpage ); 281 spin-> setValue ( m_currentpage );
271 spin-> setWrapping ( true ); 282 spin-> setWrapping ( true );
272 spin-> setButtonSymbols ( QSpinBox::PlusMinus ); 283 spin-> setButtonSymbols ( QSpinBox::PlusMinus );
273 lay-> addWidget ( spin ); 284 lay-> addWidget ( spin );
274 285
275 if ( d-> exec ( ) == QDialog::Accepted ) { 286 if ( d-> exec ( ) == QDialog::Accepted ) {
276 gotoPage ( spin-> value ( )); 287 gotoPage ( spin-> value ( ));
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,94 +1,101 @@
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:
26 void firstPage ( ); 28 void firstPage ( );
27 void prevPage ( ); 29 void prevPage ( );
28 void nextPage ( ); 30 void nextPage ( );
29 void lastPage ( ); 31 void lastPage ( );
30 32
31 void gotoPage ( int n ); 33 void gotoPage ( int n );
32 34
33 void setZoom ( int z ); 35 void setZoom ( int z );
34 36
35 void gotoPageDialog ( ); 37 void gotoPageDialog ( );
36 38
37 void toggleFullscreen ( ); 39 void toggleFullscreen ( );
38 void toggleFindBar ( ); 40 void toggleFindBar ( );
39 41
40 void findText ( const QString & ); 42 void findText ( const QString & );
41 void findText ( ); 43 void findText ( );
42 44
43 void openFile ( ); 45 void openFile ( );
44 void openFile ( const QString & ); 46 void openFile ( const QString & );
45 void openFile ( const DocLnk & ); 47 void openFile ( const DocLnk & );
46 48
47 void setDocument ( const QString & ); 49 void setDocument ( const QString & );
48 50
49private slots: 51private slots:
50 void delayedInit ( ); 52 void delayedInit ( );
51 void closeFileSelector ( ); 53 void closeFileSelector ( );
52 54
53 void updateCaption ( ); 55 void updateCaption ( );
54 56
55 void copyToClipboard ( const QRect & ); 57 void copyToClipboard ( const QRect & );
56 58
57protected: 59protected:
58 void setFullscreen ( bool b = true ); 60 void setFullscreen ( bool b = true );
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
84 int m_currentpage; 91 int m_currentpage;
85 int m_pages; 92 int m_pages;
86 int m_zoom; 93 int m_zoom;
87 94
88 PDFDoc *m_doc; 95 PDFDoc *m_doc;
89 96
90 QString m_currentdoc; 97 QString m_currentdoc;
91}; 98};
92 99
93 100
94#endif 101#endif
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
@@ -1,60 +1,61 @@
1TEMPLATE = app 1TEMPLATE = app
2 2
3CONFIG *= qt embedded release warn_off 3CONFIG *= 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
42 43
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,139 +1,138 @@
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;
36 } 36 }
37 obj2.free(); 37 obj2.free();
38 } 38 }
39 obj1.free(); 39 obj1.free();
40 } else { 40 } else {
41 if (apObj.dictLookupNF("N", &obj1)->isRef()) { 41 if (apObj.dictLookupNF("N", &obj1)->isRef()) {
42 obj1.copy(&appearance); 42 obj1.copy(&appearance);
43 ok = gTrue; 43 ok = gTrue;
44 } 44 }
45 obj1.free(); 45 obj1.free();
46 } 46 }
47 asObj.free(); 47 asObj.free();
48 } 48 }
49 apObj.free(); 49 apObj.free();
50 50
51 if (dict->lookup("Rect", &obj1)->isArray() && 51 if (dict->lookup("Rect", &obj1)->isArray() &&
52 obj1.arrayGetLength() == 4) { 52 obj1.arrayGetLength() == 4) {
53 //~ should check object types here 53 //~ should check object types here
54 obj1.arrayGet(0, &obj2); 54 obj1.arrayGet(0, &obj2);
55 xMin = obj2.getNum(); 55 xMin = obj2.getNum();
56 obj2.free(); 56 obj2.free();
57 obj1.arrayGet(1, &obj2); 57 obj1.arrayGet(1, &obj2);
58 yMin = obj2.getNum(); 58 yMin = obj2.getNum();
59 obj2.free(); 59 obj2.free();
60 obj1.arrayGet(2, &obj2); 60 obj1.arrayGet(2, &obj2);
61 xMax = obj2.getNum(); 61 xMax = obj2.getNum();
62 obj2.free(); 62 obj2.free();
63 obj1.arrayGet(3, &obj2); 63 obj1.arrayGet(3, &obj2);
64 yMax = obj2.getNum(); 64 yMax = obj2.getNum();
65 obj2.free(); 65 obj2.free();
66 if (xMin > xMax) { 66 if (xMin > xMax) {
67 t = xMin; xMin = xMax; xMax = t; 67 t = xMin; xMin = xMax; xMax = t;
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,53 +1,53 @@
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"
18 18
19//------------------------------------------------------------------------ 19//------------------------------------------------------------------------
20// Array 20// Array
21//------------------------------------------------------------------------ 21//------------------------------------------------------------------------
22 22
23Array::Array(XRef *xrefA) { 23Array::Array(XRef *xrefA) {
24 xref = xrefA; 24 xref = xrefA;
25 elems = NULL; 25 elems = NULL;
26 size = length = 0; 26 size = length = 0;
27 ref = 1; 27 ref = 1;
28} 28}
29 29
30Array::~Array() { 30Array::~Array() {
31 int i; 31 int i;
32 32
33 for (i = 0; i < length; ++i) 33 for (i = 0; i < length; ++i)
34 elems[i].free(); 34 elems[i].free();
35 gfree(elems); 35 gfree(elems);
36} 36}
37 37
38void Array::add(Object *elem) { 38void Array::add(Object *elem) {
39 if (length + 1 > size) { 39 if (length + 1 > size) {
40 size += 8; 40 size += 8;
41 elems = (Object *)grealloc(elems, size * sizeof(Object)); 41 elems = (Object *)grealloc(elems, size * sizeof(Object));
42 } 42 }
43 elems[length] = *elem; 43 elems[length] = *elem;
44 ++length; 44 ++length;
45} 45}
46 46
47Object *Array::get(int i, Object *obj) { 47Object *Array::get(int i, Object *obj) {
48 return elems[i].fetch(xref, obj); 48 return elems[i].fetch(xref, obj);
49} 49}
50 50
51Object *Array::getNF(int i, Object *obj) { 51Object *Array::getNF(int i, Object *obj) {
52 return elems[i].copy(obj); 52 return elems[i].copy(obj);
53} 53}
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,56 +1,56 @@
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
18class XRef; 18class XRef;
19 19
20//------------------------------------------------------------------------ 20//------------------------------------------------------------------------
21// Array 21// Array
22//------------------------------------------------------------------------ 22//------------------------------------------------------------------------
23 23
24class Array { 24class Array {
25public: 25public:
26 26
27 // Constructor. 27 // Constructor.
28 Array(XRef *xrefA); 28 Array(XRef *xrefA);
29 29
30 // Destructor. 30 // Destructor.
31 ~Array(); 31 ~Array();
32 32
33 // Reference counting. 33 // Reference counting.
34 int incRef() { return ++ref; } 34 int incRef() { return ++ref; }
35 int decRef() { return --ref; } 35 int decRef() { return --ref; }
36 36
37 // Get number of elements. 37 // Get number of elements.
38 int getLength() { return length; } 38 int getLength() { return length; }
39 39
40 // Add an element. 40 // Add an element.
41 void add(Object *elem); 41 void add(Object *elem);
42 42
43 // Accessors. 43 // Accessors.
44 Object *get(int i, Object *obj); 44 Object *get(int i, Object *obj);
45 Object *getNF(int i, Object *obj); 45 Object *getNF(int i, Object *obj);
46 46
47private: 47private:
48 48
49 XRef *xref; // the xref table for this PDF file 49 XRef *xref; // the xref table for this PDF file
50 Object *elems; // array of elements 50 Object *elems; // array of elements
51 int size; // size of <elems> array 51 int size; // size of <elems> array
52 int length; // number of elements in array 52 int length; // number of elements in array
53 int ref; // reference count 53 int ref; // reference count
54}; 54};
55 55
56#endif 56#endif
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,55 +1,55 @@
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
18struct BuiltinFont; 18struct BuiltinFont;
19class BuiltinFontWidths; 19class BuiltinFontWidths;
20 20
21//------------------------------------------------------------------------ 21//------------------------------------------------------------------------
22 22
23struct BuiltinFont { 23struct BuiltinFont {
24 char *name; 24 char *name;
25 char **defaultBaseEnc; 25 char **defaultBaseEnc;
26 short ascent; 26 short ascent;
27 short descent; 27 short descent;
28 short bbox[4]; 28 short bbox[4];
29 BuiltinFontWidths *widths; 29 BuiltinFontWidths *widths;
30}; 30};
31 31
32//------------------------------------------------------------------------ 32//------------------------------------------------------------------------
33 33
34struct BuiltinFontWidth { 34struct BuiltinFontWidth {
35 char *name; 35 char *name;
36 Gushort width; 36 Gushort width;
37 BuiltinFontWidth *next; 37 BuiltinFontWidth *next;
38}; 38};
39 39
40class BuiltinFontWidths { 40class BuiltinFontWidths {
41public: 41public:
42 42
43 BuiltinFontWidths(BuiltinFontWidth *widths, int sizeA); 43 BuiltinFontWidths(BuiltinFontWidth *widths, int sizeA);
44 ~BuiltinFontWidths(); 44 ~BuiltinFontWidths();
45 GBool getWidth(char *name, Gushort *width); 45 GBool getWidth(char *name, Gushort *width);
46 46
47private: 47private:
48 48
49 int hash(char *name); 49 int hash(char *name);
50 50
51 BuiltinFontWidth **tab; 51 BuiltinFontWidth **tab;
52 int size; 52 int size;
53}; 53};
54 54
55#endif 55#endif
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,197 +1,197 @@
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 },
18 { "plusminus", 600, NULL }, 18 { "plusminus", 600, NULL },
19 { "arrowup", 600, NULL }, 19 { "arrowup", 600, NULL },
20 { "circumflex", 600, NULL }, 20 { "circumflex", 600, NULL },
21 { "dotaccent", 600, NULL }, 21 { "dotaccent", 600, NULL },
22 { "LL", 600, NULL }, 22 { "LL", 600, NULL },
23 { "asciitilde", 600, NULL }, 23 { "asciitilde", 600, NULL },
24 { "colon", 600, NULL }, 24 { "colon", 600, NULL },
25 { "onehalf", 600, NULL }, 25 { "onehalf", 600, NULL },
26 { "dollar", 600, NULL }, 26 { "dollar", 600, NULL },
27 { "ntilde", 600, NULL }, 27 { "ntilde", 600, NULL },
28 { "left", 600, NULL }, 28 { "left", 600, NULL },
29 { "minus", 600, NULL }, 29 { "minus", 600, NULL },
30 { "yen", 600, NULL }, 30 { "yen", 600, NULL },
31 { "space", 600, NULL }, 31 { "space", 600, NULL },
32 { "questiondown", 600, NULL }, 32 { "questiondown", 600, NULL },
33 { "emdash", 600, NULL }, 33 { "emdash", 600, NULL },
34 { "Agrave", 600, NULL }, 34 { "Agrave", 600, NULL },
35 { "three", 600, NULL }, 35 { "three", 600, NULL },
36 { "numbersign", 600, NULL }, 36 { "numbersign", 600, NULL },
37 { "A", 600, NULL }, 37 { "A", 600, NULL },
38 { "B", 600, NULL }, 38 { "B", 600, NULL },
39 { "C", 600, NULL }, 39 { "C", 600, NULL },
40 { "D", 600, NULL }, 40 { "D", 600, NULL },
41 { "E", 600, NULL }, 41 { "E", 600, NULL },
42 { "onequarter", 600, NULL }, 42 { "onequarter", 600, NULL },
43 { "F", 600, NULL }, 43 { "F", 600, NULL },
44 { "G", 600, NULL }, 44 { "G", 600, NULL },
45 { "H", 600, NULL }, 45 { "H", 600, NULL },
46 { "I", 600, NULL }, 46 { "I", 600, NULL },
47 { "J", 600, NULL }, 47 { "J", 600, NULL },
48 { "K", 600, NULL }, 48 { "K", 600, NULL },
49 { "L", 600, NULL }, 49 { "L", 600, NULL },
50 { "backslash", 600, NULL }, 50 { "backslash", 600, NULL },
51 { "periodcentered", 600, NULL }, 51 { "periodcentered", 600, NULL },
52 { "M", 600, NULL }, 52 { "M", 600, NULL },
53 { "N", 600, NULL }, 53 { "N", 600, NULL },
54 { "O", 600, NULL }, 54 { "O", 600, NULL },
55 { "P", 600, NULL }, 55 { "P", 600, NULL },
56 { "Q", 600, NULL }, 56 { "Q", 600, NULL },
57 { "R", 600, NULL }, 57 { "R", 600, NULL },
58 { "Aacute", 600, NULL }, 58 { "Aacute", 600, NULL },
59 { "caron", 600, NULL }, 59 { "caron", 600, NULL },
60 { "S", 600, NULL }, 60 { "S", 600, NULL },
61 { "T", 600, NULL }, 61 { "T", 600, NULL },
62 { "U", 600, NULL }, 62 { "U", 600, NULL },
63 { "agrave", 600, NULL }, 63 { "agrave", 600, NULL },
64 { "V", 600, NULL }, 64 { "V", 600, NULL },
65 { "tab", 600, NULL }, 65 { "tab", 600, NULL },
66 { "W", 600, NULL }, 66 { "W", 600, NULL },
67 { "ll", 600, NULL }, 67 { "ll", 600, NULL },
68 { "equal", 600, NULL }, 68 { "equal", 600, NULL },
69 { "question", 600, NULL }, 69 { "question", 600, NULL },
70 { "X", 600, NULL }, 70 { "X", 600, NULL },
71 { "Y", 600, NULL }, 71 { "Y", 600, NULL },
72 { "Z", 600, NULL }, 72 { "Z", 600, NULL },
73 { "four", 600, NULL }, 73 { "four", 600, NULL },
74 { "a", 600, NULL }, 74 { "a", 600, NULL },
75 { "b", 600, NULL }, 75 { "b", 600, NULL },
76 { "c", 600, NULL }, 76 { "c", 600, NULL },
77 { "d", 600, NULL }, 77 { "d", 600, NULL },
78 { "e", 600, NULL }, 78 { "e", 600, NULL },
79 { "f", 600, NULL }, 79 { "f", 600, NULL },
80 { "g", 600, NULL }, 80 { "g", 600, NULL },
81 { "bullet", 600, NULL }, 81 { "bullet", 600, NULL },
82 { "h", 600, NULL }, 82 { "h", 600, NULL },
83 { "i", 600, NULL }, 83 { "i", 600, NULL },
84 { "Oslash", 600, NULL }, 84 { "Oslash", 600, NULL },
85 { "dagger", 600, NULL }, 85 { "dagger", 600, NULL },
86 { "j", 600, NULL }, 86 { "j", 600, NULL },
87 { "k", 600, NULL }, 87 { "k", 600, NULL },
88 { "l", 600, NULL }, 88 { "l", 600, NULL },
89 { "m", 600, NULL }, 89 { "m", 600, NULL },
90 { "n", 600, NULL }, 90 { "n", 600, NULL },
91 { "o", 600, NULL }, 91 { "o", 600, NULL },
92 { "ordfeminine", 600, NULL }, 92 { "ordfeminine", 600, NULL },
93 { "ring", 600, NULL }, 93 { "ring", 600, NULL },
94 { "p", 600, NULL }, 94 { "p", 600, NULL },
95 { "q", 600, NULL }, 95 { "q", 600, NULL },
96 { "r", 600, NULL }, 96 { "r", 600, NULL },
97 { "twosuperior", 600, NULL }, 97 { "twosuperior", 600, NULL },
98 { "largebullet", 600, NULL }, 98 { "largebullet", 600, NULL },
99 { "aacute", 600, NULL }, 99 { "aacute", 600, NULL },
100 { "s", 600, NULL }, 100 { "s", 600, NULL },
101 { "OE", 600, NULL }, 101 { "OE", 600, NULL },
102 { "t", 600, NULL }, 102 { "t", 600, NULL },
103 { "divide", 600, NULL }, 103 { "divide", 600, NULL },
104 { "u", 600, NULL }, 104 { "u", 600, NULL },
105 { "v", 600, NULL }, 105 { "v", 600, NULL },
106 { "w", 600, NULL }, 106 { "w", 600, NULL },
107 { "x", 600, NULL }, 107 { "x", 600, NULL },
108 { "y", 600, NULL }, 108 { "y", 600, NULL },
109 { "z", 600, NULL }, 109 { "z", 600, NULL },
110 { "hungarumlaut", 600, NULL }, 110 { "hungarumlaut", 600, NULL },
111 { "quotedbl", 600, NULL }, 111 { "quotedbl", 600, NULL },
112 { "mu", 600, NULL }, 112 { "mu", 600, NULL },
113 { "Scaron", 600, NULL }, 113 { "Scaron", 600, NULL },
114 { "Lslash", 600, NULL }, 114 { "Lslash", 600, NULL },
115 { "semicolon", 600, NULL }, 115 { "semicolon", 600, NULL },
116 { "oslash", 600, NULL }, 116 { "oslash", 600, NULL },
117 { "parenright", 600, NULL }, 117 { "parenright", 600, NULL },
118 { "Ecircumflex", 600, NULL }, 118 { "Ecircumflex", 600, NULL },
119 { "trademark", 600, NULL }, 119 { "trademark", 600, NULL },
120 { "daggerdbl", 600, NULL }, 120 { "daggerdbl", 600, NULL },
121 { "macron", 600, NULL }, 121 { "macron", 600, NULL },
122 { "Otilde", 600, NULL }, 122 { "Otilde", 600, NULL },
123 { "ellipsis", 600, NULL }, 123 { "ellipsis", 600, NULL },
124 { "scaron", 600, NULL }, 124 { "scaron", 600, NULL },
125 { "AE", 600, NULL }, 125 { "AE", 600, NULL },
126 { "Ucircumflex", 600, NULL }, 126 { "Ucircumflex", 600, NULL },
127 { "lslash", 600, NULL }, 127 { "lslash", 600, NULL },
128 { "lira", 600, NULL }, 128 { "lira", 600, NULL },
129 { "quotedblleft", 600, NULL }, 129 { "quotedblleft", 600, NULL },
130 { "hyphen", 600, NULL }, 130 { "hyphen", 600, NULL },
131 { "guilsinglright", 600, NULL }, 131 { "guilsinglright", 600, NULL },
132 { "quotesingle", 600, NULL }, 132 { "quotesingle", 600, NULL },
133 { "eight", 600, NULL }, 133 { "eight", 600, NULL },
134 { "exclamdown", 600, NULL }, 134 { "exclamdown", 600, NULL },
135 { "endash", 600, NULL }, 135 { "endash", 600, NULL },
136 { "oe", 600, NULL }, 136 { "oe", 600, NULL },
137 { "ecircumflex", 600, NULL }, 137 { "ecircumflex", 600, NULL },
138 { "copyright", 600, NULL }, 138 { "copyright", 600, NULL },
139 { "Adieresis", 600, NULL }, 139 { "Adieresis", 600, NULL },
140 { "Egrave", 600, NULL }, 140 { "Egrave", 600, NULL },
141 { "slash", 600, NULL }, 141 { "slash", 600, NULL },
142 { "Edieresis", 600, NULL }, 142 { "Edieresis", 600, NULL },
143 { "otilde", 600, NULL }, 143 { "otilde", 600, NULL },
144 { "Idieresis", 600, NULL }, 144 { "Idieresis", 600, NULL },
145 { "parenleft", 600, NULL }, 145 { "parenleft", 600, NULL },
146 { "one", 600, NULL }, 146 { "one", 600, NULL },
147 { "ucircumflex", 600, NULL }, 147 { "ucircumflex", 600, NULL },
148 { "Odieresis", 600, NULL }, 148 { "Odieresis", 600, NULL },
149 { "bracketleft", 600, NULL }, 149 { "bracketleft", 600, NULL },
150 { "Ugrave", 600, NULL }, 150 { "Ugrave", 600, NULL },
151 { "quoteright", 600, NULL }, 151 { "quoteright", 600, NULL },
152 { "Udieresis", 600, NULL }, 152 { "Udieresis", 600, NULL },
153 { "perthousand", 600, NULL }, 153 { "perthousand", 600, NULL },
154 { "Ydieresis", 600, NULL }, 154 { "Ydieresis", 600, NULL },
155 { "Eacute", 600, NULL }, 155 { "Eacute", 600, NULL },
156 { "adieresis", 600, NULL }, 156 { "adieresis", 600, NULL },
157 { "egrave", 600, NULL }, 157 { "egrave", 600, NULL },
158 { "edieresis", 600, NULL }, 158 { "edieresis", 600, NULL },
159 { "idieresis", 600, NULL }, 159 { "idieresis", 600, NULL },
160 { "Eth", 600, NULL }, 160 { "Eth", 600, NULL },
161 { "ae", 600, NULL }, 161 { "ae", 600, NULL },
162 { "asterisk", 600, NULL }, 162 { "asterisk", 600, NULL },
163 { "odieresis", 600, NULL }, 163 { "odieresis", 600, NULL },
164 { "Uacute", 600, NULL }, 164 { "Uacute", 600, NULL },
165 { "ugrave", 600, NULL }, 165 { "ugrave", 600, NULL },
166 { "five", 600, NULL }, 166 { "five", 600, NULL },
167 { "nine", 600, NULL }, 167 { "nine", 600, NULL },
168 { "udieresis", 600, NULL }, 168 { "udieresis", 600, NULL },
169 { "Zcaron", 600, NULL }, 169 { "Zcaron", 600, NULL },
170 { "threequarters", 600, NULL }, 170 { "threequarters", 600, NULL },
171 { "guillemotright", 600, NULL }, 171 { "guillemotright", 600, NULL },
172 { "ydieresis", 600, NULL }, 172 { "ydieresis", 600, NULL },
173 { "Ccedilla", 600, NULL }, 173 { "Ccedilla", 600, NULL },
174 { "tilde", 600, NULL }, 174 { "tilde", 600, NULL },
175 { "at", 600, NULL }, 175 { "at", 600, NULL },
176 { "eacute", 600, NULL }, 176 { "eacute", 600, NULL },
177 { "Gcaron", 600, NULL }, 177 { "Gcaron", 600, NULL },
178 { "underscore", 600, NULL }, 178 { "underscore", 600, NULL },
179 { "zero", 600, NULL }, 179 { "zero", 600, NULL },
180 { "multiply", 600, NULL }, 180 { "multiply", 600, NULL },
181 { "Scedilla", 600, NULL }, 181 { "Scedilla", 600, NULL },
182 { "eth", 600, NULL }, 182 { "eth", 600, NULL },
183 { "Ograve", 600, NULL }, 183 { "Ograve", 600, NULL },
184 { "uacute", 600, NULL }, 184 { "uacute", 600, NULL },
185 { "braceleft", 600, NULL }, 185 { "braceleft", 600, NULL },
186 { "Thorn", 600, NULL }, 186 { "Thorn", 600, NULL },
187 { "zcaron", 600, NULL }, 187 { "zcaron", 600, NULL },
188 { "ccedilla", 600, NULL }, 188 { "ccedilla", 600, NULL },
189 { "gcaron", 600, NULL }, 189 { "gcaron", 600, NULL },
190 { "Oacute", 600, NULL }, 190 { "Oacute", 600, NULL },
191 { "Ocircumflex", 600, NULL }, 191 { "Ocircumflex", 600, NULL },
192 { "scedilla", 600, NULL }, 192 { "scedilla", 600, NULL },
193 { "ogonek", 600, NULL }, 193 { "ogonek", 600, NULL },
194 { "arrowdown", 600, NULL }, 194 { "arrowdown", 600, NULL },
195 { "ograve", 600, NULL }, 195 { "ograve", 600, NULL },
196 { "thorn", 600, NULL }, 196 { "thorn", 600, NULL },
197 { "degree", 600, NULL }, 197 { "degree", 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,23 +1,23 @@
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];
18extern BuiltinFont *builtinFontSubst[nBuiltinFontSubsts]; 18extern BuiltinFont *builtinFontSubst[nBuiltinFontSubsts];
19 19
20extern void initBuiltinFontTables(); 20extern void initBuiltinFontTables();
21extern void freeBuiltinFontTables(); 21extern void freeBuiltinFontTables();
22 22
23#endif 23#endif
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,299 +1,319 @@
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;
120 vector = (CMapVectorEntry *)gmalloc(256 * sizeof(CMapVectorEntry)); 140 vector = (CMapVectorEntry *)gmalloc(256 * sizeof(CMapVectorEntry));
121 for (i = 0; i < 256; ++i) { 141 for (i = 0; i < 256; ++i) {
122 vector[i].isVector = gFalse; 142 vector[i].isVector = gFalse;
123 vector[i].cid = 0; 143 vector[i].cid = 0;
124 } 144 }
125 refCnt = 1; 145 refCnt = 1;
126} 146}
127 147
128CMap::CMap(GString *collectionA, GString *cMapNameA, int wModeA) { 148CMap::CMap(GString *collectionA, GString *cMapNameA, int wModeA) {
129 collection = collectionA; 149 collection = collectionA;
130 cMapName = cMapNameA; 150 cMapName = cMapNameA;
131 wMode = wModeA; 151 wMode = wModeA;
132 vector = NULL; 152 vector = NULL;
133 refCnt = 1; 153 refCnt = 1;
134} 154}
135 155
136void CMap::useCMap(CMapCache *cache, char *useName) { 156void CMap::useCMap(CMapCache *cache, char *useName) {
137 GString *useNameStr; 157 GString *useNameStr;
138 CMap *subCMap; 158 CMap *subCMap;
139 159
140 useNameStr = new GString(useName); 160 useNameStr = new GString(useName);
141 subCMap = cache->getCMap(collection, useNameStr); 161 subCMap = cache->getCMap(collection, useNameStr);
142 delete useNameStr; 162 delete useNameStr;
143 if (!subCMap) { 163 if (!subCMap) {
144 return; 164 return;
145 } 165 }
146 copyVector(vector, subCMap->vector); 166 copyVector(vector, subCMap->vector);
147 subCMap->decRefCnt(); 167 subCMap->decRefCnt();
148} 168}
149 169
150void CMap::copyVector(CMapVectorEntry *dest, CMapVectorEntry *src) { 170void CMap::copyVector(CMapVectorEntry *dest, CMapVectorEntry *src) {
151 int i, j; 171 int i, j;
152 172
153 for (i = 0; i < 256; ++i) { 173 for (i = 0; i < 256; ++i) {
154 if (src[i].isVector) { 174 if (src[i].isVector) {
155 if (!dest[i].isVector) { 175 if (!dest[i].isVector) {
156 dest[i].isVector = gTrue; 176 dest[i].isVector = gTrue;
157 dest[i].vector = 177 dest[i].vector =
158 (CMapVectorEntry *)gmalloc(256 * sizeof(CMapVectorEntry)); 178 (CMapVectorEntry *)gmalloc(256 * sizeof(CMapVectorEntry));
159 for (j = 0; j < 256; ++j) { 179 for (j = 0; j < 256; ++j) {
160 dest[i].vector[j].isVector = gFalse; 180 dest[i].vector[j].isVector = gFalse;
161 dest[i].vector[j].cid = 0; 181 dest[i].vector[j].cid = 0;
162 } 182 }
163 } 183 }
164 copyVector(dest[i].vector, src[i].vector); 184 copyVector(dest[i].vector, src[i].vector);
165 } else { 185 } else {
166 if (dest[i].isVector) { 186 if (dest[i].isVector) {
167 error(-1, "Collision in usecmap"); 187 error(-1, "Collision in usecmap");
168 } else { 188 } else {
169 dest[i].cid = src[i].cid; 189 dest[i].cid = src[i].cid;
170 } 190 }
171 } 191 }
172 } 192 }
173} 193}
174 194
175void CMap::addCodeSpace(CMapVectorEntry *vec, Guint start, Guint end, 195void CMap::addCodeSpace(CMapVectorEntry *vec, Guint start, Guint end,
176 Guint nBytes) { 196 Guint nBytes) {
177 Guint start2, end2; 197 Guint start2, end2;
178 int startByte, endByte, i, j; 198 int startByte, endByte, i, j;
179 199
180 if (nBytes > 1) { 200 if (nBytes > 1) {
181 startByte = (start >> (8 * (nBytes - 1))) & 0xff; 201 startByte = (start >> (8 * (nBytes - 1))) & 0xff;
182 endByte = (end >> (8 * (nBytes - 1))) & 0xff; 202 endByte = (end >> (8 * (nBytes - 1))) & 0xff;
183 start2 = start & ((1 << (8 * (nBytes - 1))) - 1); 203 start2 = start & ((1 << (8 * (nBytes - 1))) - 1);
184 end2 = end & ((1 << (8 * (nBytes - 1))) - 1); 204 end2 = end & ((1 << (8 * (nBytes - 1))) - 1);
185 for (i = startByte; i <= endByte; ++i) { 205 for (i = startByte; i <= endByte; ++i) {
186 if (!vec[i].isVector) { 206 if (!vec[i].isVector) {
187 vec[i].isVector = gTrue; 207 vec[i].isVector = gTrue;
188 vec[i].vector = 208 vec[i].vector =
189 (CMapVectorEntry *)gmalloc(256 * sizeof(CMapVectorEntry)); 209 (CMapVectorEntry *)gmalloc(256 * sizeof(CMapVectorEntry));
190 for (j = 0; j < 256; ++j) { 210 for (j = 0; j < 256; ++j) {
191 vec[i].vector[j].isVector = gFalse; 211 vec[i].vector[j].isVector = gFalse;
192 vec[i].vector[j].cid = 0; 212 vec[i].vector[j].cid = 0;
193 } 213 }
194 } 214 }
195 addCodeSpace(vec[i].vector, start2, end2, nBytes - 1); 215 addCodeSpace(vec[i].vector, start2, end2, nBytes - 1);
196 } 216 }
197 } 217 }
198} 218}
199 219
200void CMap::addCIDs(Guint start, Guint end, Guint nBytes, CID firstCID) { 220void CMap::addCIDs(Guint start, Guint end, Guint nBytes, CID firstCID) {
201 CMapVectorEntry *vec; 221 CMapVectorEntry *vec;
202 CID cid; 222 CID cid;
203 int byte; 223 int byte;
204 Guint i; 224 Guint i;
205 225
206 vec = vector; 226 vec = vector;
207 for (i = nBytes - 1; i >= 1; --i) { 227 for (i = nBytes - 1; i >= 1; --i) {
208 byte = (start >> (8 * i)) & 0xff; 228 byte = (start >> (8 * i)) & 0xff;
209 if (!vec[byte].isVector) { 229 if (!vec[byte].isVector) {
210 error(-1, "Invalid CID (%*x - %*x) in CMap", 230 error(-1, "Invalid CID (%*x - %*x) in CMap",
211 2*nBytes, start, 2*nBytes, end); 231 2*nBytes, start, 2*nBytes, end);
212 return; 232 return;
213 } 233 }
214 vec = vec[byte].vector; 234 vec = vec[byte].vector;
215 } 235 }
216 cid = firstCID; 236 cid = firstCID;
217 for (byte = (int)(start & 0xff); byte <= (int)(end & 0xff); ++byte) { 237 for (byte = (int)(start & 0xff); byte <= (int)(end & 0xff); ++byte) {
218 if (vec[byte].isVector) { 238 if (vec[byte].isVector) {
219 error(-1, "Invalid CID (%*x - %*x) in CMap", 239 error(-1, "Invalid CID (%*x - %*x) in CMap",
220 2*nBytes, start, 2*nBytes, end); 240 2*nBytes, start, 2*nBytes, end);
221 } else { 241 } else {
222 vec[byte].cid = cid; 242 vec[byte].cid = cid;
223 } 243 }
224 ++cid; 244 ++cid;
225 } 245 }
226} 246}
227 247
228CMap::~CMap() { 248CMap::~CMap() {
229 delete collection; 249 delete collection;
230 delete cMapName; 250 delete cMapName;
231 if (vector) { 251 if (vector) {
232 freeCMapVector(vector); 252 freeCMapVector(vector);
233 } 253 }
234} 254}
235 255
236void CMap::freeCMapVector(CMapVectorEntry *vec) { 256void CMap::freeCMapVector(CMapVectorEntry *vec) {
237 int i; 257 int i;
238 258
239 for (i = 0; i < 256; ++i) { 259 for (i = 0; i < 256; ++i) {
240 if (vec[i].isVector) { 260 if (vec[i].isVector) {
241 freeCMapVector(vec[i].vector); 261 freeCMapVector(vec[i].vector);
242 } 262 }
243 } 263 }
244 gfree(vec); 264 gfree(vec);
245} 265}
246 266
247void CMap::incRefCnt() { 267void CMap::incRefCnt() {
248 ++refCnt; 268 ++refCnt;
249} 269}
250 270
251void CMap::decRefCnt() { 271void CMap::decRefCnt() {
252 if (--refCnt == 0) { 272 if (--refCnt == 0) {
253 delete this; 273 delete this;
254 } 274 }
255} 275}
256 276
257GBool CMap::match(GString *collectionA, GString *cMapNameA) { 277GBool CMap::match(GString *collectionA, GString *cMapNameA) {
258 return !collection->cmp(collectionA) && !cMapName->cmp(cMapNameA); 278 return !collection->cmp(collectionA) && !cMapName->cmp(cMapNameA);
259} 279}
260 280
261CID CMap::getCID(char *s, int len, int *nUsed) { 281CID CMap::getCID(char *s, int len, int *nUsed) {
262 CMapVectorEntry *vec; 282 CMapVectorEntry *vec;
263 int n, i; 283 int n, i;
264 284
265 if (!(vec = vector)) { 285 if (!(vec = vector)) {
266 // identity CMap 286 // identity CMap
267 *nUsed = 2; 287 *nUsed = 2;
268 if (len < 2) { 288 if (len < 2) {
269 return 0; 289 return 0;
270 } 290 }
271 return ((s[0] & 0xff) << 8) + (s[1] & 0xff); 291 return ((s[0] & 0xff) << 8) + (s[1] & 0xff);
272 } 292 }
273 n = 0; 293 n = 0;
274 while (1) { 294 while (1) {
275 if (n >= len) { 295 if (n >= len) {
276 *nUsed = n; 296 *nUsed = n;
277 return 0; 297 return 0;
278 } 298 }
279 i = s[n++] & 0xff; 299 i = s[n++] & 0xff;
280 if (!vec[i].isVector) { 300 if (!vec[i].isVector) {
281 *nUsed = n; 301 *nUsed = n;
282 return vec[i].cid; 302 return vec[i].cid;
283 } 303 }
284 vec = vec[i].vector; 304 vec = vec[i].vector;
285 } 305 }
286} 306}
287 307
288//------------------------------------------------------------------------ 308//------------------------------------------------------------------------
289 309
290CMapCache::CMapCache() { 310CMapCache::CMapCache() {
291 int i; 311 int i;
292 312
293 for (i = 0; i < cMapCacheSize; ++i) { 313 for (i = 0; i < cMapCacheSize; ++i) {
294 cache[i] = NULL; 314 cache[i] = NULL;
295 } 315 }
296} 316}
297 317
298CMapCache::~CMapCache() { 318CMapCache::~CMapCache() {
299 int i; 319 int i;
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,93 +1,93 @@
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"
18 18
19class GString; 19class GString;
20struct CMapVectorEntry; 20struct CMapVectorEntry;
21class CMapCache; 21class CMapCache;
22 22
23//------------------------------------------------------------------------ 23//------------------------------------------------------------------------
24 24
25class CMap { 25class CMap {
26public: 26public:
27 27
28 // Create the CMap specified by <collection> and <cMapName>. Sets 28 // Create the CMap specified by <collection> and <cMapName>. Sets
29 // the initial reference count to 1. Returns NULL on failure. 29 // the initial reference count to 1. Returns NULL on failure.
30 static CMap *parse(CMapCache *cache, GString *collectionA, 30 static CMap *parse(CMapCache *cache, GString *collectionA,
31 GString *cMapNameA); 31 GString *cMapNameA);
32 32
33 ~CMap(); 33 ~CMap();
34 34
35 void incRefCnt(); 35 void incRefCnt();
36 void decRefCnt(); 36 void decRefCnt();
37 37
38 // Return collection name (<registry>-<ordering>). 38 // Return collection name (<registry>-<ordering>).
39 GString *getCollection() { return collection; } 39 GString *getCollection() { return collection; }
40 40
41 // Return true if this CMap matches the specified <collectionA>, and 41 // Return true if this CMap matches the specified <collectionA>, and
42 // <cMapNameA>. 42 // <cMapNameA>.
43 GBool match(GString *collectionA, GString *cMapNameA); 43 GBool match(GString *collectionA, GString *cMapNameA);
44 44
45 // Return the CID corresponding to the character code starting at 45 // Return the CID corresponding to the character code starting at
46 // <s>, which contains <len> bytes. Sets *<nUsed> to the number of 46 // <s>, which contains <len> bytes. Sets *<nUsed> to the number of
47 // bytes used by the char code. 47 // bytes used by the char code.
48 CID getCID(char *s, int len, int *nUsed); 48 CID getCID(char *s, int len, int *nUsed);
49 49
50 // Return the writing mode (0=horizontal, 1=vertical). 50 // Return the writing mode (0=horizontal, 1=vertical).
51 int getWMode() { return wMode; } 51 int getWMode() { return wMode; }
52 52
53private: 53private:
54 54
55 CMap(GString *collectionA, GString *cMapNameA); 55 CMap(GString *collectionA, GString *cMapNameA);
56 CMap(GString *collectionA, GString *cMapNameA, int wModeA); 56 CMap(GString *collectionA, GString *cMapNameA, int wModeA);
57 void useCMap(CMapCache *cache, char *useName); 57 void useCMap(CMapCache *cache, char *useName);
58 void copyVector(CMapVectorEntry *dest, CMapVectorEntry *src); 58 void copyVector(CMapVectorEntry *dest, CMapVectorEntry *src);
59 void addCodeSpace(CMapVectorEntry *vec, Guint start, Guint end, 59 void addCodeSpace(CMapVectorEntry *vec, Guint start, Guint end,
60 Guint nBytes); 60 Guint nBytes);
61 void addCIDs(Guint start, Guint end, Guint nBytes, CID firstCID); 61 void addCIDs(Guint start, Guint end, Guint nBytes, CID firstCID);
62 void freeCMapVector(CMapVectorEntry *vec); 62 void freeCMapVector(CMapVectorEntry *vec);
63 63
64 GString *collection; 64 GString *collection;
65 GString *cMapName; 65 GString *cMapName;
66 int wMode; // writing mode (0=horizontal, 1=vertical) 66 int wMode; // writing mode (0=horizontal, 1=vertical)
67 CMapVectorEntry *vector;// vector for first byte (NULL for 67 CMapVectorEntry *vector;// vector for first byte (NULL for
68 // identity CMap) 68 // identity CMap)
69 int refCnt; 69 int refCnt;
70}; 70};
71 71
72//------------------------------------------------------------------------ 72//------------------------------------------------------------------------
73 73
74#define cMapCacheSize 4 74#define cMapCacheSize 4
75 75
76class CMapCache { 76class CMapCache {
77public: 77public:
78 78
79 CMapCache(); 79 CMapCache();
80 ~CMapCache(); 80 ~CMapCache();
81 81
82 // Get the <cMapName> CMap for the specified character collection. 82 // Get the <cMapName> CMap for the specified character collection.
83 // Increments its reference count; there will be one reference for 83 // Increments its reference count; there will be one reference for
84 // the cache plus one for the caller of this function. Returns NULL 84 // the cache plus one for the caller of this function. Returns NULL
85 // on failure. 85 // on failure.
86 CMap *getCMap(GString *collection, GString *cMapName); 86 CMap *getCMap(GString *collection, GString *cMapName);
87 87
88private: 88private:
89 89
90 CMap *cache[cMapCacheSize]; 90 CMap *cache[cMapCacheSize];
91}; 91};
92 92
93#endif 93#endif
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,341 +1,341 @@
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"
18#include "Array.h" 18#include "Array.h"
19#include "Dict.h" 19#include "Dict.h"
20#include "Page.h" 20#include "Page.h"
21#include "Error.h" 21#include "Error.h"
22#include "Link.h" 22#include "Link.h"
23#include "Catalog.h" 23#include "Catalog.h"
24 24
25//------------------------------------------------------------------------ 25//------------------------------------------------------------------------
26// Catalog 26// Catalog
27//------------------------------------------------------------------------ 27//------------------------------------------------------------------------
28 28
29Catalog::Catalog(XRef *xrefA, GBool printCommands) { 29Catalog::Catalog(XRef *xrefA, GBool printCommands) {
30 Object catDict, pagesDict; 30 Object catDict, pagesDict;
31 Object obj, obj2; 31 Object obj, obj2;
32 int numPages0; 32 int numPages0;
33 int i; 33 int i;
34 34
35 ok = gTrue; 35 ok = gTrue;
36 xref = xrefA; 36 xref = xrefA;
37 pages = NULL; 37 pages = NULL;
38 pageRefs = NULL; 38 pageRefs = NULL;
39 numPages = pagesSize = 0; 39 numPages = pagesSize = 0;
40 baseURI = NULL; 40 baseURI = NULL;
41 41
42 xref->getCatalog(&catDict); 42 xref->getCatalog(&catDict);
43 if (!catDict.isDict()) { 43 if (!catDict.isDict()) {
44 error(-1, "Catalog object is wrong type (%s)", catDict.getTypeName()); 44 error(-1, "Catalog object is wrong type (%s)", catDict.getTypeName());
45 goto err1; 45 goto err1;
46 } 46 }
47 47
48 // read page tree 48 // read page tree
49 catDict.dictLookup("Pages", &pagesDict); 49 catDict.dictLookup("Pages", &pagesDict);
50 // This should really be isDict("Pages"), but I've seen at least one 50 // This should really be isDict("Pages"), but I've seen at least one
51 // PDF file where the /Type entry is missing. 51 // PDF file where the /Type entry is missing.
52 if (!pagesDict.isDict()) { 52 if (!pagesDict.isDict()) {
53 error(-1, "Top-level pages object is wrong type (%s)", 53 error(-1, "Top-level pages object is wrong type (%s)",
54 pagesDict.getTypeName()); 54 pagesDict.getTypeName());
55 goto err2; 55 goto err2;
56 } 56 }
57 pagesDict.dictLookup("Count", &obj); 57 pagesDict.dictLookup("Count", &obj);
58 if (!obj.isInt()) { 58 if (!obj.isInt()) {
59 error(-1, "Page count in top-level pages object is wrong type (%s)", 59 error(-1, "Page count in top-level pages object is wrong type (%s)",
60 obj.getTypeName()); 60 obj.getTypeName());
61 goto err3; 61 goto err3;
62 } 62 }
63 pagesSize = numPages0 = obj.getInt(); 63 pagesSize = numPages0 = obj.getInt();
64 obj.free(); 64 obj.free();
65 pages = (Page **)gmalloc(pagesSize * sizeof(Page *)); 65 pages = (Page **)gmalloc(pagesSize * sizeof(Page *));
66 pageRefs = (Ref *)gmalloc(pagesSize * sizeof(Ref)); 66 pageRefs = (Ref *)gmalloc(pagesSize * sizeof(Ref));
67 for (i = 0; i < pagesSize; ++i) { 67 for (i = 0; i < pagesSize; ++i) {
68 pages[i] = NULL; 68 pages[i] = NULL;
69 pageRefs[i].num = -1; 69 pageRefs[i].num = -1;
70 pageRefs[i].gen = -1; 70 pageRefs[i].gen = -1;
71 } 71 }
72 numPages = readPageTree(pagesDict.getDict(), NULL, 0, printCommands); 72 numPages = readPageTree(pagesDict.getDict(), NULL, 0, printCommands);
73 if (numPages != numPages0) { 73 if (numPages != numPages0) {
74 error(-1, "Page count in top-level pages object is incorrect"); 74 error(-1, "Page count in top-level pages object is incorrect");
75 } 75 }
76 pagesDict.free(); 76 pagesDict.free();
77 77
78 // read named destination dictionary 78 // read named destination dictionary
79 catDict.dictLookup("Dests", &dests); 79 catDict.dictLookup("Dests", &dests);
80 80
81 // read root of named destination tree 81 // read root of named destination tree
82 if (catDict.dictLookup("Names", &obj)->isDict()) 82 if (catDict.dictLookup("Names", &obj)->isDict())
83 obj.dictLookup("Dests", &nameTree); 83 obj.dictLookup("Dests", &nameTree);
84 else 84 else
85 nameTree.initNull(); 85 nameTree.initNull();
86 obj.free(); 86 obj.free();
87 87
88 // read base URI 88 // read base URI
89 if (catDict.dictLookup("URI", &obj)->isDict()) { 89 if (catDict.dictLookup("URI", &obj)->isDict()) {
90 if (obj.dictLookup("Base", &obj2)->isString()) { 90 if (obj.dictLookup("Base", &obj2)->isString()) {
91 baseURI = obj2.getString()->copy(); 91 baseURI = obj2.getString()->copy();
92 } 92 }
93 obj2.free(); 93 obj2.free();
94 } 94 }
95 obj.free(); 95 obj.free();
96 96
97 // get the metadata stream 97 // get the metadata stream
98 catDict.dictLookup("Metadata", &metadata); 98 catDict.dictLookup("Metadata", &metadata);
99 99
100 // get the structure tree root 100 // get the structure tree root
101 catDict.dictLookup("StructTreeRoot", &structTreeRoot); 101 catDict.dictLookup("StructTreeRoot", &structTreeRoot);
102 102
103 catDict.free(); 103 catDict.free();
104 return; 104 return;
105 105
106 err3: 106 err3:
107 obj.free(); 107 obj.free();
108 err2: 108 err2:
109 pagesDict.free(); 109 pagesDict.free();
110 err1: 110 err1:
111 catDict.free(); 111 catDict.free();
112 dests.initNull(); 112 dests.initNull();
113 nameTree.initNull(); 113 nameTree.initNull();
114 ok = gFalse; 114 ok = gFalse;
115} 115}
116 116
117Catalog::~Catalog() { 117Catalog::~Catalog() {
118 int i; 118 int i;
119 119
120 if (pages) { 120 if (pages) {
121 for (i = 0; i < pagesSize; ++i) { 121 for (i = 0; i < pagesSize; ++i) {
122 if (pages[i]) { 122 if (pages[i]) {
123 delete pages[i]; 123 delete pages[i];
124 } 124 }
125 } 125 }
126 gfree(pages); 126 gfree(pages);
127 gfree(pageRefs); 127 gfree(pageRefs);
128 } 128 }
129 dests.free(); 129 dests.free();
130 nameTree.free(); 130 nameTree.free();
131 if (baseURI) { 131 if (baseURI) {
132 delete baseURI; 132 delete baseURI;
133 } 133 }
134 metadata.free(); 134 metadata.free();
135 structTreeRoot.free(); 135 structTreeRoot.free();
136} 136}
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
162int Catalog::readPageTree(Dict *pagesDict, PageAttrs *attrs, int start, 162int Catalog::readPageTree(Dict *pagesDict, PageAttrs *attrs, int start,
163 GBool printCommands) { 163 GBool printCommands) {
164 Object kids; 164 Object kids;
165 Object kid; 165 Object kid;
166 Object kidRef; 166 Object kidRef;
167 PageAttrs *attrs1, *attrs2; 167 PageAttrs *attrs1, *attrs2;
168 Page *page; 168 Page *page;
169 int i, j; 169 int i, j;
170 170
171 attrs1 = new PageAttrs(attrs, pagesDict); 171 attrs1 = new PageAttrs(attrs, pagesDict);
172 pagesDict->lookup("Kids", &kids); 172 pagesDict->lookup("Kids", &kids);
173 if (!kids.isArray()) { 173 if (!kids.isArray()) {
174 error(-1, "Kids object (page %d) is wrong type (%s)", 174 error(-1, "Kids object (page %d) is wrong type (%s)",
175 start+1, kids.getTypeName()); 175 start+1, kids.getTypeName());
176 goto err1; 176 goto err1;
177 } 177 }
178 for (i = 0; i < kids.arrayGetLength(); ++i) { 178 for (i = 0; i < kids.arrayGetLength(); ++i) {
179 kids.arrayGet(i, &kid); 179 kids.arrayGet(i, &kid);
180 if (kid.isDict("Page")) { 180 if (kid.isDict("Page")) {
181 attrs2 = new PageAttrs(attrs1, kid.getDict()); 181 attrs2 = new PageAttrs(attrs1, kid.getDict());
182 page = new Page(xref, start+1, kid.getDict(), attrs2, printCommands); 182 page = new Page(xref, start+1, kid.getDict(), attrs2, printCommands);
183 if (!page->isOk()) { 183 if (!page->isOk()) {
184 ++start; 184 ++start;
185 goto err3; 185 goto err3;
186 } 186 }
187 if (start >= pagesSize) { 187 if (start >= pagesSize) {
188 pagesSize += 32; 188 pagesSize += 32;
189 pages = (Page **)grealloc(pages, pagesSize * sizeof(Page *)); 189 pages = (Page **)grealloc(pages, pagesSize * sizeof(Page *));
190 pageRefs = (Ref *)grealloc(pageRefs, pagesSize * sizeof(Ref)); 190 pageRefs = (Ref *)grealloc(pageRefs, pagesSize * sizeof(Ref));
191 for (j = pagesSize - 32; j < pagesSize; ++j) { 191 for (j = pagesSize - 32; j < pagesSize; ++j) {
192 pages[j] = NULL; 192 pages[j] = NULL;
193 pageRefs[j].num = -1; 193 pageRefs[j].num = -1;
194 pageRefs[j].gen = -1; 194 pageRefs[j].gen = -1;
195 } 195 }
196 } 196 }
197 pages[start] = page; 197 pages[start] = page;
198 kids.arrayGetNF(i, &kidRef); 198 kids.arrayGetNF(i, &kidRef);
199 if (kidRef.isRef()) { 199 if (kidRef.isRef()) {
200 pageRefs[start].num = kidRef.getRefNum(); 200 pageRefs[start].num = kidRef.getRefNum();
201 pageRefs[start].gen = kidRef.getRefGen(); 201 pageRefs[start].gen = kidRef.getRefGen();
202 } 202 }
203 kidRef.free(); 203 kidRef.free();
204 ++start; 204 ++start;
205 // This should really be isDict("Pages"), but I've seen at least one 205 // This should really be isDict("Pages"), but I've seen at least one
206 // PDF file where the /Type entry is missing. 206 // PDF file where the /Type entry is missing.
207 } else if (kid.isDict()) { 207 } else if (kid.isDict()) {
208 if ((start = readPageTree(kid.getDict(), attrs1, start, printCommands)) 208 if ((start = readPageTree(kid.getDict(), attrs1, start, printCommands))
209 < 0) 209 < 0)
210 goto err2; 210 goto err2;
211 } else { 211 } else {
212 error(-1, "Kid object (page %d) is wrong type (%s)", 212 error(-1, "Kid object (page %d) is wrong type (%s)",
213 start+1, kid.getTypeName()); 213 start+1, kid.getTypeName());
214 goto err2; 214 goto err2;
215 } 215 }
216 kid.free(); 216 kid.free();
217 } 217 }
218 delete attrs1; 218 delete attrs1;
219 kids.free(); 219 kids.free();
220 return start; 220 return start;
221 221
222 err3: 222 err3:
223 delete page; 223 delete page;
224 err2: 224 err2:
225 kid.free(); 225 kid.free();
226 err1: 226 err1:
227 kids.free(); 227 kids.free();
228 delete attrs1; 228 delete attrs1;
229 ok = gFalse; 229 ok = gFalse;
230 return -1; 230 return -1;
231} 231}
232 232
233int Catalog::findPage(int num, int gen) { 233int Catalog::findPage(int num, int gen) {
234 int i; 234 int i;
235 235
236 for (i = 0; i < numPages; ++i) { 236 for (i = 0; i < numPages; ++i) {
237 if (pageRefs[i].num == num && pageRefs[i].gen == gen) 237 if (pageRefs[i].num == num && pageRefs[i].gen == gen)
238 return i + 1; 238 return i + 1;
239 } 239 }
240 return 0; 240 return 0;
241} 241}
242 242
243LinkDest *Catalog::findDest(GString *name) { 243LinkDest *Catalog::findDest(GString *name) {
244 LinkDest *dest; 244 LinkDest *dest;
245 Object obj1, obj2; 245 Object obj1, obj2;
246 GBool found; 246 GBool found;
247 247
248 // try named destination dictionary then name tree 248 // try named destination dictionary then name tree
249 found = gFalse; 249 found = gFalse;
250 if (dests.isDict()) { 250 if (dests.isDict()) {
251 if (!dests.dictLookup(name->getCString(), &obj1)->isNull()) 251 if (!dests.dictLookup(name->getCString(), &obj1)->isNull())
252 found = gTrue; 252 found = gTrue;
253 else 253 else
254 obj1.free(); 254 obj1.free();
255 } 255 }
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) {
284 Object names, name1; 284 Object names, name1;
285 Object kids, kid, limits, low, high; 285 Object kids, kid, limits, low, high;
286 GBool done, found; 286 GBool done, found;
287 int cmp, i; 287 int cmp, i;
288 288
289 // leaf node 289 // leaf node
290 if (tree->dictLookup("Names", &names)->isArray()) { 290 if (tree->dictLookup("Names", &names)->isArray()) {
291 done = found = gFalse; 291 done = found = gFalse;
292 for (i = 0; !done && i < names.arrayGetLength(); i += 2) { 292 for (i = 0; !done && i < names.arrayGetLength(); i += 2) {
293 if (names.arrayGet(i, &name1)->isString()) { 293 if (names.arrayGet(i, &name1)->isString()) {
294 cmp = name->cmp(name1.getString()); 294 cmp = name->cmp(name1.getString());
295 if (cmp == 0) { 295 if (cmp == 0) {
296 names.arrayGet(i+1, obj); 296 names.arrayGet(i+1, obj);
297 found = gTrue; 297 found = gTrue;
298 done = gTrue; 298 done = gTrue;
299 } else if (cmp < 0) { 299 } else if (cmp < 0) {
300 done = gTrue; 300 done = gTrue;
301 } 301 }
302 name1.free(); 302 name1.free();
303 } 303 }
304 } 304 }
305 names.free(); 305 names.free();
306 if (!found) 306 if (!found)
307 obj->initNull(); 307 obj->initNull();
308 return obj; 308 return obj;
309 } 309 }
310 names.free(); 310 names.free();
311 311
312 // root or intermediate node 312 // root or intermediate node
313 done = gFalse; 313 done = gFalse;
314 if (tree->dictLookup("Kids", &kids)->isArray()) { 314 if (tree->dictLookup("Kids", &kids)->isArray()) {
315 for (i = 0; !done && i < kids.arrayGetLength(); ++i) { 315 for (i = 0; !done && i < kids.arrayGetLength(); ++i) {
316 if (kids.arrayGet(i, &kid)->isDict()) { 316 if (kids.arrayGet(i, &kid)->isDict()) {
317 if (kid.dictLookup("Limits", &limits)->isArray()) { 317 if (kid.dictLookup("Limits", &limits)->isArray()) {
318 if (limits.arrayGet(0, &low)->isString() && 318 if (limits.arrayGet(0, &low)->isString() &&
319 name->cmp(low.getString()) >= 0) { 319 name->cmp(low.getString()) >= 0) {
320 if (limits.arrayGet(1, &high)->isString() && 320 if (limits.arrayGet(1, &high)->isString() &&
321 name->cmp(high.getString()) <= 0) { 321 name->cmp(high.getString()) <= 0) {
322 findDestInTree(&kid, name, obj); 322 findDestInTree(&kid, name, obj);
323 done = gTrue; 323 done = gTrue;
324 } 324 }
325 high.free(); 325 high.free();
326 } 326 }
327 low.free(); 327 low.free();
328 } 328 }
329 limits.free(); 329 limits.free();
330 } 330 }
331 kid.free(); 331 kid.free();
332 } 332 }
333 } 333 }
334 kids.free(); 334 kids.free();
335 335
336 // name was outside of ranges of all kids 336 // name was outside of ranges of all kids
337 if (!done) 337 if (!done)
338 obj->initNull(); 338 obj->initNull();
339 339
340 return obj; 340 return obj;
341} 341}
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,85 +1,85 @@
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;
18class Page; 18class Page;
19class PageAttrs; 19class PageAttrs;
20struct Ref; 20struct Ref;
21class LinkDest; 21class LinkDest;
22 22
23//------------------------------------------------------------------------ 23//------------------------------------------------------------------------
24// Catalog 24// Catalog
25//------------------------------------------------------------------------ 25//------------------------------------------------------------------------
26 26
27class Catalog { 27class Catalog {
28public: 28public:
29 29
30 // Constructor. 30 // Constructor.
31 Catalog(XRef *xrefA, GBool printCommands = gFalse); 31 Catalog(XRef *xrefA, GBool printCommands = gFalse);
32 32
33 // Destructor. 33 // Destructor.
34 ~Catalog(); 34 ~Catalog();
35 35
36 // Is catalog valid? 36 // Is catalog valid?
37 GBool isOk() { return ok; } 37 GBool isOk() { return ok; }
38 38
39 // Get number of pages. 39 // Get number of pages.
40 int getNumPages() { return numPages; } 40 int getNumPages() { return numPages; }
41 41
42 // Get a page. 42 // Get a page.
43 Page *getPage(int i) { return pages[i-1]; } 43 Page *getPage(int i) { return pages[i-1]; }
44 44
45 // Get the reference for a page object. 45 // Get the reference for a page object.
46 Ref *getPageRef(int i) { return &pageRefs[i-1]; } 46 Ref *getPageRef(int i) { return &pageRefs[i-1]; }
47 47
48 // Return base URI, or NULL if none. 48 // Return base URI, or NULL if none.
49 GString *getBaseURI() { return baseURI; } 49 GString *getBaseURI() { return baseURI; }
50 50
51 // Return the contents of the metadata stream, or NULL if there is 51 // Return the contents of the metadata stream, or NULL if there is
52 // no metadata. 52 // no metadata.
53 GString *readMetadata(); 53 GString *readMetadata();
54 54
55 // Return the structure tree root object. 55 // Return the structure tree root object.
56 Object *getStructTreeRoot() { return &structTreeRoot; } 56 Object *getStructTreeRoot() { return &structTreeRoot; }
57 57
58 // Find a page, given its object ID. Returns page number, or 0 if 58 // Find a page, given its object ID. Returns page number, or 0 if
59 // not found. 59 // not found.
60 int findPage(int num, int gen); 60 int findPage(int num, int gen);
61 61
62 // Find a named destination. Returns the link destination, or 62 // Find a named destination. Returns the link destination, or
63 // NULL if <name> is not a destination. 63 // NULL if <name> is not a destination.
64 LinkDest *findDest(GString *name); 64 LinkDest *findDest(GString *name);
65 65
66private: 66private:
67 67
68 XRef *xref; // the xref table for this PDF file 68 XRef *xref; // the xref table for this PDF file
69 Page **pages; // array of pages 69 Page **pages; // array of pages
70 Ref *pageRefs; // object ID for each page 70 Ref *pageRefs; // object ID for each page
71 int numPages; // number of pages 71 int numPages; // number of pages
72 int pagesSize; // size of pages array 72 int pagesSize; // size of pages array
73 Object dests; // named destination dictionary 73 Object dests; // named destination dictionary
74 Object nameTree; // name tree 74 Object nameTree; // name tree
75 GString *baseURI; // base URI for URI-type links 75 GString *baseURI; // base URI for URI-type links
76 Object metadata; // metadata stream 76 Object metadata; // metadata stream
77 Object structTreeRoot;// structure tree root dictionary 77 Object structTreeRoot;// structure tree root dictionary
78 GBool ok; // true if catalog is valid 78 GBool ok; // true if catalog is valid
79 79
80 int readPageTree(Dict *pages, PageAttrs *attrs, int start, 80 int readPageTree(Dict *pages, PageAttrs *attrs, int start,
81 GBool printCommands); 81 GBool printCommands);
82 Object *findDestInTree(Object *tree, GString *name, Object *obj); 82 Object *findDestInTree(Object *tree, GString *name, Object *obj);
83}; 83};
84 84
85#endif 85#endif
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,394 +1,390 @@
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;
47 } 68 }
48 69
49 size = 32768; 70 size = 32768;
50 mapA = (Unicode *)gmalloc(size * sizeof(Unicode)); 71 mapA = (Unicode *)gmalloc(size * sizeof(Unicode));
51 mapLenA = 0; 72 mapLenA = 0;
52 73
53 while (getLine(buf, sizeof(buf), f)) { 74 while (getLine(buf, sizeof(buf), f)) {
54 if (mapLenA == size) { 75 if (mapLenA == size) {
55 size *= 2; 76 size *= 2;
56 mapA = (Unicode *)grealloc(mapA, size * sizeof(Unicode)); 77 mapA = (Unicode *)grealloc(mapA, size * sizeof(Unicode));
57 } 78 }
58 if (sscanf(buf, "%x", &u) == 1) { 79 if (sscanf(buf, "%x", &u) == 1) {
59 mapA[mapLenA] = u; 80 mapA[mapLenA] = u;
60 } else { 81 } else {
61 error(-1, "Bad line (%d) in cidToUnicode file for the '%s' collection", 82 error(-1, "Bad line (%d) in cidToUnicode file for the '%s' collection",
62 (int)(mapLenA + 1), collectionA->getCString()); 83 (int)(mapLenA + 1), collectionA->getCString());
63 mapA[mapLenA] = 0; 84 mapA[mapLenA] = 0;
64 } 85 }
65 ++mapLenA; 86 ++mapLenA;
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;
277 sMapLen = sMapSize = 0; 273 sMapLen = sMapSize = 0;
278 refCnt = 1; 274 refCnt = 1;
279} 275}
280 276
281CharCodeToUnicode::CharCodeToUnicode(GString *collectionA, Unicode *mapA, 277CharCodeToUnicode::CharCodeToUnicode(GString *collectionA, Unicode *mapA,
282 CharCode mapLenA, GBool copyMap, 278 CharCode mapLenA, GBool copyMap,
283 CharCodeToUnicodeString *sMapA, 279 CharCodeToUnicodeString *sMapA,
284 int sMapLenA) { 280 int sMapLenA) {
285 collection = collectionA; 281 collection = collectionA;
286 mapLen = mapLenA; 282 mapLen = mapLenA;
287 if (copyMap) { 283 if (copyMap) {
288 map = (Unicode *)gmalloc(mapLen * sizeof(Unicode)); 284 map = (Unicode *)gmalloc(mapLen * sizeof(Unicode));
289 memcpy(map, mapA, mapLen * sizeof(Unicode)); 285 memcpy(map, mapA, mapLen * sizeof(Unicode));
290 } else { 286 } else {
291 map = mapA; 287 map = mapA;
292 } 288 }
293 sMap = sMapA; 289 sMap = sMapA;
294 sMapLen = sMapSize = sMapLenA; 290 sMapLen = sMapSize = sMapLenA;
295 refCnt = 1; 291 refCnt = 1;
296} 292}
297 293
298CharCodeToUnicode::~CharCodeToUnicode() { 294CharCodeToUnicode::~CharCodeToUnicode() {
299 if (collection) { 295 if (collection) {
300 delete collection; 296 delete collection;
301 } 297 }
302 gfree(map); 298 gfree(map);
303 if (sMap) { 299 if (sMap) {
304 gfree(sMap); 300 gfree(sMap);
305 } 301 }
306} 302}
307 303
308void CharCodeToUnicode::incRefCnt() { 304void CharCodeToUnicode::incRefCnt() {
309 ++refCnt; 305 ++refCnt;
310} 306}
311 307
312void CharCodeToUnicode::decRefCnt() { 308void CharCodeToUnicode::decRefCnt() {
313 if (--refCnt == 0) { 309 if (--refCnt == 0) {
314 delete this; 310 delete this;
315 } 311 }
316} 312}
317 313
318GBool CharCodeToUnicode::match(GString *collectionA) { 314GBool CharCodeToUnicode::match(GString *collectionA) {
319 return collection && !collection->cmp(collectionA); 315 return collection && !collection->cmp(collectionA);
320} 316}
321 317
322int CharCodeToUnicode::mapToUnicode(CharCode c, Unicode *u, int size) { 318int CharCodeToUnicode::mapToUnicode(CharCode c, Unicode *u, int size) {
323 int i, j; 319 int i, j;
324 320
325 if (c >= mapLen) { 321 if (c >= mapLen) {
326 return 0; 322 return 0;
327 } 323 }
328 if (map[c]) { 324 if (map[c]) {
329 u[0] = map[c]; 325 u[0] = map[c];
330 return 1; 326 return 1;
331 } 327 }
332 for (i = 0; i < sMapLen; ++i) { 328 for (i = 0; i < sMapLen; ++i) {
333 if (sMap[i].c == c) { 329 if (sMap[i].c == c) {
334 for (j = 0; j < sMap[i].len && j < size; ++j) { 330 for (j = 0; j < sMap[i].len && j < size; ++j) {
335 u[j] = sMap[i].u[j]; 331 u[j] = sMap[i].u[j];
336 } 332 }
337 return j; 333 return j;
338 } 334 }
339 } 335 }
340 return 0; 336 return 0;
341} 337}
342 338
343//------------------------------------------------------------------------ 339//------------------------------------------------------------------------
344 340
345CIDToUnicodeCache::CIDToUnicodeCache() { 341CIDToUnicodeCache::CIDToUnicodeCache() {
346 int i; 342 int i;
347 343
348 for (i = 0; i < cidToUnicodeCacheSize; ++i) { 344 for (i = 0; i < cidToUnicodeCacheSize; ++i) {
349 cache[i] = NULL; 345 cache[i] = NULL;
350 } 346 }
351} 347}
352 348
353CIDToUnicodeCache::~CIDToUnicodeCache() { 349CIDToUnicodeCache::~CIDToUnicodeCache() {
354 int i; 350 int i;
355 351
356 for (i = 0; i < cidToUnicodeCacheSize; ++i) { 352 for (i = 0; i < cidToUnicodeCacheSize; ++i) {
357 if (cache[i]) { 353 if (cache[i]) {
358 cache[i]->decRefCnt(); 354 cache[i]->decRefCnt();
359 } 355 }
360 } 356 }
361} 357}
362 358
363CharCodeToUnicode *CIDToUnicodeCache::getCIDToUnicode(GString *collection) { 359CharCodeToUnicode *CIDToUnicodeCache::getCIDToUnicode(GString *collection) {
364 CharCodeToUnicode *ctu; 360 CharCodeToUnicode *ctu;
365 int i, j; 361 int i, j;
366 362
367 if (cache[0] && cache[0]->match(collection)) { 363 if (cache[0] && cache[0]->match(collection)) {
368 cache[0]->incRefCnt(); 364 cache[0]->incRefCnt();
369 return cache[0]; 365 return cache[0];
370 } 366 }
371 for (i = 1; i < cidToUnicodeCacheSize; ++i) { 367 for (i = 1; i < cidToUnicodeCacheSize; ++i) {
372 if (cache[i] && cache[i]->match(collection)) { 368 if (cache[i] && cache[i]->match(collection)) {
373 ctu = cache[i]; 369 ctu = cache[i];
374 for (j = i; j >= 1; --j) { 370 for (j = i; j >= 1; --j) {
375 cache[j] = cache[j - 1]; 371 cache[j] = cache[j - 1];
376 } 372 }
377 cache[0] = ctu; 373 cache[0] = ctu;
378 ctu->incRefCnt(); 374 ctu->incRefCnt();
379 return ctu; 375 return ctu;
380 } 376 }
381 } 377 }
382 if ((ctu = CharCodeToUnicode::parseCIDToUnicode(collection))) { 378 if ((ctu = CharCodeToUnicode::parseCIDToUnicode(collection))) {
383 if (cache[cidToUnicodeCacheSize - 1]) { 379 if (cache[cidToUnicodeCacheSize - 1]) {
384 cache[cidToUnicodeCacheSize - 1]->decRefCnt(); 380 cache[cidToUnicodeCacheSize - 1]->decRefCnt();
385 } 381 }
386 for (j = cidToUnicodeCacheSize - 1; j >= 1; --j) { 382 for (j = cidToUnicodeCacheSize - 1; j >= 1; --j) {
387 cache[j] = cache[j - 1]; 383 cache[j] = cache[j - 1];
388 } 384 }
389 cache[0] = ctu; 385 cache[0] = ctu;
390 ctu->incRefCnt(); 386 ctu->incRefCnt();
391 return ctu; 387 return ctu;
392 } 388 }
393 return NULL; 389 return NULL;
394} 390}
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,89 +1,88 @@
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
20struct CharCodeToUnicodeString; 20struct CharCodeToUnicodeString;
21 21
22//------------------------------------------------------------------------ 22//------------------------------------------------------------------------
23 23
24class CharCodeToUnicode { 24class CharCodeToUnicode {
25public: 25public:
26 26
27 // Create the CID-to-Unicode mapping specified by <collection>. 27 // Create the CID-to-Unicode mapping specified by <collection>.
28 // This reads a .cidToUnicode file from disk. Sets the initial 28 // This reads a .cidToUnicode file from disk. Sets the initial
29 // reference count to 1. Returns NULL on failure. 29 // reference count to 1. Returns NULL on failure.
30 static CharCodeToUnicode *parseCIDToUnicode(GString *collectionA); 30 static CharCodeToUnicode *parseCIDToUnicode(GString *collectionA);
31 31
32 // Create the CharCode-to-Unicode mapping for an 8-bit font. 32 // Create the CharCode-to-Unicode mapping for an 8-bit font.
33 // <toUnicode> is an array of 256 Unicode indexes. Sets the initial 33 // <toUnicode> is an array of 256 Unicode indexes. Sets the initial
34 // reference count to 1. 34 // reference count to 1.
35 static CharCodeToUnicode *make8BitToUnicode(Unicode *toUnicode); 35 static CharCodeToUnicode *make8BitToUnicode(Unicode *toUnicode);
36 36
37 // Parse a ToUnicode CMap for an 8- or 16-bit font. 37 // Parse a ToUnicode CMap for an 8- or 16-bit font.
38 static CharCodeToUnicode *parseCMap(GString *buf, int nBits); 38 static CharCodeToUnicode *parseCMap(GString *buf, int nBits);
39 39
40 ~CharCodeToUnicode(); 40 ~CharCodeToUnicode();
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};
67 66
68//------------------------------------------------------------------------ 67//------------------------------------------------------------------------
69 68
70#define cidToUnicodeCacheSize 4 69#define cidToUnicodeCacheSize 4
71 70
72class CIDToUnicodeCache { 71class CIDToUnicodeCache {
73public: 72public:
74 73
75 CIDToUnicodeCache(); 74 CIDToUnicodeCache();
76 ~CIDToUnicodeCache(); 75 ~CIDToUnicodeCache();
77 76
78 // Get the CharCodeToUnicode object for <collection>. Increments 77 // Get the CharCodeToUnicode object for <collection>. Increments
79 // its reference count; there will be one reference for the cache 78 // its reference count; there will be one reference for the cache
80 // plus one for the caller of this function. Returns NULL on 79 // plus one for the caller of this function. Returns NULL on
81 // failure. 80 // failure.
82 CharCodeToUnicode *getCIDToUnicode(GString *collection); 81 CharCodeToUnicode *getCIDToUnicode(GString *collection);
83 82
84private: 83private:
85 84
86 CharCodeToUnicode *cache[cidToUnicodeCacheSize]; 85 CharCodeToUnicode *cache[cidToUnicodeCacheSize];
87}; 86};
88 87
89#endif 88#endif
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,24 +1,24 @@
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
18// This is large enough to hold any of the following: 18// This is large enough to hold any of the following:
19// - 8-bit char code 19// - 8-bit char code
20// - 16-bit CID 20// - 16-bit CID
21// - Unicode 21// - Unicode
22typedef unsigned int CharCode; 22typedef unsigned int CharCode;
23 23
24#endif 24#endif
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,197 +1,197 @@
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);
18static Guchar rc4DecryptByte(Guchar *state, Guchar *x, Guchar *y, Guchar c); 18static Guchar rc4DecryptByte(Guchar *state, Guchar *x, Guchar *y, Guchar c);
19static void md5(Guchar *msg, int msgLen, Guchar *digest); 19static void md5(Guchar *msg, int msgLen, Guchar *digest);
20 20
21static Guchar passwordPad[32] = { 21static Guchar passwordPad[32] = {
22 0x28, 0xbf, 0x4e, 0x5e, 0x4e, 0x75, 0x8a, 0x41, 22 0x28, 0xbf, 0x4e, 0x5e, 0x4e, 0x75, 0x8a, 0x41,
23 0x64, 0x00, 0x4e, 0x56, 0xff, 0xfa, 0x01, 0x08, 23 0x64, 0x00, 0x4e, 0x56, 0xff, 0xfa, 0x01, 0x08,
24 0x2e, 0x2e, 0x00, 0xb6, 0xd0, 0x68, 0x3e, 0x80, 24 0x2e, 0x2e, 0x00, 0xb6, 0xd0, 0x68, 0x3e, 0x80,
25 0x2f, 0x0c, 0xa9, 0xfe, 0x64, 0x53, 0x69, 0x7a 25 0x2f, 0x0c, 0xa9, 0xfe, 0x64, 0x53, 0x69, 0x7a
26}; 26};
27 27
28//------------------------------------------------------------------------ 28//------------------------------------------------------------------------
29// Decrypt 29// Decrypt
30//------------------------------------------------------------------------ 30//------------------------------------------------------------------------
31 31
32Decrypt::Decrypt(Guchar *fileKey, int keyLength, int objNum, int objGen) { 32Decrypt::Decrypt(Guchar *fileKey, int keyLength, int objNum, int objGen) {
33 int i; 33 int i;
34 34
35 // construct object key 35 // construct object key
36 for (i = 0; i < keyLength; ++i) { 36 for (i = 0; i < keyLength; ++i) {
37 objKey[i] = fileKey[i]; 37 objKey[i] = fileKey[i];
38 } 38 }
39 objKey[keyLength] = objNum & 0xff; 39 objKey[keyLength] = objNum & 0xff;
40 objKey[keyLength + 1] = (objNum >> 8) & 0xff; 40 objKey[keyLength + 1] = (objNum >> 8) & 0xff;
41 objKey[keyLength + 2] = (objNum >> 16) & 0xff; 41 objKey[keyLength + 2] = (objNum >> 16) & 0xff;
42 objKey[keyLength + 3] = objGen & 0xff; 42 objKey[keyLength + 3] = objGen & 0xff;
43 objKey[keyLength + 4] = (objGen >> 8) & 0xff; 43 objKey[keyLength + 4] = (objGen >> 8) & 0xff;
44 md5(objKey, keyLength + 5, objKey); 44 md5(objKey, keyLength + 5, objKey);
45 45
46 // set up for decryption 46 // set up for decryption
47 x = y = 0; 47 x = y = 0;
48 if ((objKeyLength = keyLength + 5) > 16) { 48 if ((objKeyLength = keyLength + 5) > 16) {
49 objKeyLength = 16; 49 objKeyLength = 16;
50 } 50 }
51 rc4InitKey(objKey, objKeyLength, state); 51 rc4InitKey(objKey, objKeyLength, state);
52} 52}
53 53
54void Decrypt::reset() { 54void Decrypt::reset() {
55 x = y = 0; 55 x = y = 0;
56 rc4InitKey(objKey, objKeyLength, state); 56 rc4InitKey(objKey, objKeyLength, state);
57} 57}
58 58
59Guchar Decrypt::decryptByte(Guchar c) { 59Guchar Decrypt::decryptByte(Guchar c) {
60 return rc4DecryptByte(state, &x, &y, c); 60 return rc4DecryptByte(state, &x, &y, c);
61} 61}
62 62
63GBool Decrypt::makeFileKey(int encVersion, int encRevision, int keyLength, 63GBool Decrypt::makeFileKey(int encVersion, int encRevision, int keyLength,
64 GString *ownerKey, GString *userKey, 64 GString *ownerKey, GString *userKey,
65 int permissions, GString *fileID, 65 int permissions, GString *fileID,
66 GString *ownerPassword, GString *userPassword, 66 GString *ownerPassword, GString *userPassword,
67 Guchar *fileKey, GBool *ownerPasswordOk) { 67 Guchar *fileKey, GBool *ownerPasswordOk) {
68 Guchar test[32]; 68 Guchar test[32];
69 GString *userPassword2; 69 GString *userPassword2;
70 Guchar fState[256]; 70 Guchar fState[256];
71 Guchar fx, fy; 71 Guchar fx, fy;
72 int len, i; 72 int len, i;
73 73
74 // try using the supplied owner password to generate the user password 74 // try using the supplied owner password to generate the user password
75 if (ownerPassword) { 75 if (ownerPassword) {
76 len = ownerPassword->getLength(); 76 len = ownerPassword->getLength();
77 if (len < 32) { 77 if (len < 32) {
78 memcpy(test, ownerPassword->getCString(), len); 78 memcpy(test, ownerPassword->getCString(), len);
79 memcpy(test + len, passwordPad, 32 - len); 79 memcpy(test + len, passwordPad, 32 - len);
80 } else { 80 } else {
81 memcpy(test, ownerPassword->getCString(), 32); 81 memcpy(test, ownerPassword->getCString(), 32);
82 } 82 }
83 } else { 83 } else {
84 memcpy(test, passwordPad, 32); 84 memcpy(test, passwordPad, 32);
85 } 85 }
86 md5(test, 32, test); 86 md5(test, 32, test);
87 if (encRevision == 3) { 87 if (encRevision == 3) {
88 for (i = 0; i < 50; ++i) { 88 for (i = 0; i < 50; ++i) {
89 md5(test, 16, test); 89 md5(test, 16, test);
90 } 90 }
91 } 91 }
92 rc4InitKey(test, keyLength, fState); 92 rc4InitKey(test, keyLength, fState);
93 fx = fy = 0; 93 fx = fy = 0;
94 for (i = 0; i < 32; ++i) { 94 for (i = 0; i < 32; ++i) {
95 test[i] = rc4DecryptByte(fState, &fx, &fy, ownerKey->getChar(i)); 95 test[i] = rc4DecryptByte(fState, &fx, &fy, ownerKey->getChar(i));
96 } 96 }
97 userPassword2 = new GString((char *)test, 32); 97 userPassword2 = new GString((char *)test, 32);
98 if (makeFileKey2(encVersion, encRevision, keyLength, ownerKey, userKey, 98 if (makeFileKey2(encVersion, encRevision, keyLength, ownerKey, userKey,
99 permissions, fileID, userPassword2, fileKey)) { 99 permissions, fileID, userPassword2, fileKey)) {
100 *ownerPasswordOk = gTrue; 100 *ownerPasswordOk = gTrue;
101 delete userPassword2; 101 delete userPassword2;
102 return gTrue; 102 return gTrue;
103 } 103 }
104 *ownerPasswordOk = gFalse; 104 *ownerPasswordOk = gFalse;
105 delete userPassword2; 105 delete userPassword2;
106 106
107 // try using the supplied user password 107 // try using the supplied user password
108 return makeFileKey2(encVersion, encRevision, keyLength, ownerKey, userKey, 108 return makeFileKey2(encVersion, encRevision, keyLength, ownerKey, userKey,
109 permissions, fileID, userPassword, fileKey); 109 permissions, fileID, userPassword, fileKey);
110} 110}
111 111
112GBool Decrypt::makeFileKey2(int encVersion, int encRevision, int keyLength, 112GBool Decrypt::makeFileKey2(int encVersion, int encRevision, int keyLength,
113 GString *ownerKey, GString *userKey, 113 GString *ownerKey, GString *userKey,
114 int permissions, GString *fileID, 114 int permissions, GString *fileID,
115 GString *userPassword, Guchar *fileKey) { 115 GString *userPassword, Guchar *fileKey) {
116 Guchar *buf; 116 Guchar *buf;
117 Guchar test[32]; 117 Guchar test[32];
118 Guchar fState[256]; 118 Guchar fState[256];
119 Guchar tmpKey[16]; 119 Guchar tmpKey[16];
120 Guchar fx, fy; 120 Guchar fx, fy;
121 int len, i, j; 121 int len, i, j;
122 GBool ok; 122 GBool ok;
123 123
124 // generate file key 124 // generate file key
125 buf = (Guchar *)gmalloc(68 + fileID->getLength()); 125 buf = (Guchar *)gmalloc(68 + fileID->getLength());
126 if (userPassword) { 126 if (userPassword) {
127 len = userPassword->getLength(); 127 len = userPassword->getLength();
128 if (len < 32) { 128 if (len < 32) {
129 memcpy(buf, userPassword->getCString(), len); 129 memcpy(buf, userPassword->getCString(), len);
130 memcpy(buf + len, passwordPad, 32 - len); 130 memcpy(buf + len, passwordPad, 32 - len);
131 } else { 131 } else {
132 memcpy(buf, userPassword->getCString(), 32); 132 memcpy(buf, userPassword->getCString(), 32);
133 } 133 }
134 } else { 134 } else {
135 memcpy(buf, passwordPad, 32); 135 memcpy(buf, passwordPad, 32);
136 } 136 }
137 memcpy(buf + 32, ownerKey->getCString(), 32); 137 memcpy(buf + 32, ownerKey->getCString(), 32);
138 buf[64] = permissions & 0xff; 138 buf[64] = permissions & 0xff;
139 buf[65] = (permissions >> 8) & 0xff; 139 buf[65] = (permissions >> 8) & 0xff;
140 buf[66] = (permissions >> 16) & 0xff; 140 buf[66] = (permissions >> 16) & 0xff;
141 buf[67] = (permissions >> 24) & 0xff; 141 buf[67] = (permissions >> 24) & 0xff;
142 memcpy(buf + 68, fileID->getCString(), fileID->getLength()); 142 memcpy(buf + 68, fileID->getCString(), fileID->getLength());
143 md5(buf, 68 + fileID->getLength(), fileKey); 143 md5(buf, 68 + fileID->getLength(), fileKey);
144 if (encRevision == 3) { 144 if (encRevision == 3) {
145 for (i = 0; i < 50; ++i) { 145 for (i = 0; i < 50; ++i) {
146 md5(fileKey, 16, fileKey); 146 md5(fileKey, 16, fileKey);
147 } 147 }
148 } 148 }
149 149
150 // test user password 150 // test user password
151 if (encRevision == 2) { 151 if (encRevision == 2) {
152 rc4InitKey(fileKey, keyLength, fState); 152 rc4InitKey(fileKey, keyLength, fState);
153 fx = fy = 0; 153 fx = fy = 0;
154 for (i = 0; i < 32; ++i) { 154 for (i = 0; i < 32; ++i) {
155 test[i] = rc4DecryptByte(fState, &fx, &fy, userKey->getChar(i)); 155 test[i] = rc4DecryptByte(fState, &fx, &fy, userKey->getChar(i));
156 } 156 }
157 ok = memcmp(test, passwordPad, 32) == 0; 157 ok = memcmp(test, passwordPad, 32) == 0;
158 } else if (encRevision == 3) { 158 } else if (encRevision == 3) {
159 memcpy(test, userKey->getCString(), 32); 159 memcpy(test, userKey->getCString(), 32);
160 for (i = 19; i >= 0; --i) { 160 for (i = 19; i >= 0; --i) {
161 for (j = 0; j < keyLength; ++j) { 161 for (j = 0; j < keyLength; ++j) {
162 tmpKey[j] = fileKey[j] ^ i; 162 tmpKey[j] = fileKey[j] ^ i;
163 } 163 }
164 rc4InitKey(tmpKey, keyLength, fState); 164 rc4InitKey(tmpKey, keyLength, fState);
165 fx = fy = 0; 165 fx = fy = 0;
166 for (j = 0; j < 32; ++j) { 166 for (j = 0; j < 32; ++j) {
167 test[j] = rc4DecryptByte(fState, &fx, &fy, test[j]); 167 test[j] = rc4DecryptByte(fState, &fx, &fy, test[j]);
168 } 168 }
169 } 169 }
170 memcpy(buf, passwordPad, 32); 170 memcpy(buf, passwordPad, 32);
171 memcpy(buf + 32, fileID->getCString(), fileID->getLength()); 171 memcpy(buf + 32, fileID->getCString(), fileID->getLength());
172 md5(buf, 32 + fileID->getLength(), buf); 172 md5(buf, 32 + fileID->getLength(), buf);
173 ok = memcmp(test, buf, 16) == 0; 173 ok = memcmp(test, buf, 16) == 0;
174 } else { 174 } else {
175 ok = gFalse; 175 ok = gFalse;
176 } 176 }
177 177
178 gfree(buf); 178 gfree(buf);
179 return ok; 179 return ok;
180} 180}
181 181
182//------------------------------------------------------------------------ 182//------------------------------------------------------------------------
183// RC4-compatible decryption 183// RC4-compatible decryption
184//------------------------------------------------------------------------ 184//------------------------------------------------------------------------
185 185
186static void rc4InitKey(Guchar *key, int keyLen, Guchar *state) { 186static void rc4InitKey(Guchar *key, int keyLen, Guchar *state) {
187 Guchar index1, index2; 187 Guchar index1, index2;
188 Guchar t; 188 Guchar t;
189 int i; 189 int i;
190 190
191 for (i = 0; i < 256; ++i) 191 for (i = 0; i < 256; ++i)
192 state[i] = i; 192 state[i] = i;
193 index1 = index2 = 0; 193 index1 = index2 = 0;
194 for (i = 0; i < 256; ++i) { 194 for (i = 0; i < 256; ++i) {
195 index2 = (key[index1] + state[i] + index2) % 256; 195 index2 = (key[index1] + state[i] + index2) % 256;
196 t = state[i]; 196 t = state[i];
197 state[i] = state[index2]; 197 state[i] = state[index2];
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,59 +1,59 @@
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"
18 18
19//------------------------------------------------------------------------ 19//------------------------------------------------------------------------
20// Decrypt 20// Decrypt
21//------------------------------------------------------------------------ 21//------------------------------------------------------------------------
22 22
23class Decrypt { 23class Decrypt {
24public: 24public:
25 25
26 // Initialize the decryptor object. 26 // Initialize the decryptor object.
27 Decrypt(Guchar *fileKey, int keyLength, int objNum, int objGen); 27 Decrypt(Guchar *fileKey, int keyLength, int objNum, int objGen);
28 28
29 // Reset decryption. 29 // Reset decryption.
30 void reset(); 30 void reset();
31 31
32 // Decrypt one byte. 32 // Decrypt one byte.
33 Guchar decryptByte(Guchar c); 33 Guchar decryptByte(Guchar c);
34 34
35 // Generate a file key. The <fileKey> buffer must have space for at 35 // Generate a file key. The <fileKey> buffer must have space for at
36 // least 16 bytes. Checks <ownerPassword> and then <userPassword> 36 // least 16 bytes. Checks <ownerPassword> and then <userPassword>
37 // and returns true if either is correct. Sets <ownerPasswordOk> if 37 // and returns true if either is correct. Sets <ownerPasswordOk> if
38 // the owner password was correct. Either or both of the passwords 38 // the owner password was correct. Either or both of the passwords
39 // may be NULL, which is treated as an empty string. 39 // may be NULL, which is treated as an empty string.
40 static GBool makeFileKey(int encVersion, int encRevision, int keyLength, 40 static GBool makeFileKey(int encVersion, int encRevision, int keyLength,
41 GString *ownerKey, GString *userKey, 41 GString *ownerKey, GString *userKey,
42 int permissions, GString *fileID, 42 int permissions, GString *fileID,
43 GString *ownerPassword, GString *userPassword, 43 GString *ownerPassword, GString *userPassword,
44 Guchar *fileKey, GBool *ownerPasswordOk); 44 Guchar *fileKey, GBool *ownerPasswordOk);
45 45
46private: 46private:
47 47
48 static GBool makeFileKey2(int encVersion, int encRevision, int keyLength, 48 static GBool makeFileKey2(int encVersion, int encRevision, int keyLength,
49 GString *ownerKey, GString *userKey, 49 GString *ownerKey, GString *userKey,
50 int permissions, GString *fileID, 50 int permissions, GString *fileID,
51 GString *userPassword, Guchar *fileKey); 51 GString *userPassword, Guchar *fileKey);
52 52
53 int objKeyLength; 53 int objKeyLength;
54 Guchar objKey[21]; 54 Guchar objKey[21];
55 Guchar state[256]; 55 Guchar state[256];
56 Guchar x, y; 56 Guchar x, y;
57}; 57};
58 58
59#endif 59#endif
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,90 +1,90 @@
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"
18#include "XRef.h" 18#include "XRef.h"
19#include "Dict.h" 19#include "Dict.h"
20 20
21//------------------------------------------------------------------------ 21//------------------------------------------------------------------------
22// Dict 22// Dict
23//------------------------------------------------------------------------ 23//------------------------------------------------------------------------
24 24
25Dict::Dict(XRef *xrefA) { 25Dict::Dict(XRef *xrefA) {
26 xref = xrefA; 26 xref = xrefA;
27 entries = NULL; 27 entries = NULL;
28 size = length = 0; 28 size = length = 0;
29 ref = 1; 29 ref = 1;
30} 30}
31 31
32Dict::~Dict() { 32Dict::~Dict() {
33 int i; 33 int i;
34 34
35 for (i = 0; i < length; ++i) { 35 for (i = 0; i < length; ++i) {
36 gfree(entries[i].key); 36 gfree(entries[i].key);
37 entries[i].val.free(); 37 entries[i].val.free();
38 } 38 }
39 gfree(entries); 39 gfree(entries);
40} 40}
41 41
42void Dict::add(char *key, Object *val) { 42void Dict::add(char *key, Object *val) {
43 if (length + 1 > size) { 43 if (length + 1 > size) {
44 size += 8; 44 size += 8;
45 entries = (DictEntry *)grealloc(entries, size * sizeof(DictEntry)); 45 entries = (DictEntry *)grealloc(entries, size * sizeof(DictEntry));
46 } 46 }
47 entries[length].key = key; 47 entries[length].key = key;
48 entries[length].val = *val; 48 entries[length].val = *val;
49 ++length; 49 ++length;
50} 50}
51 51
52inline DictEntry *Dict::find(char *key) { 52inline DictEntry *Dict::find(char *key) {
53 int i; 53 int i;
54 54
55 for (i = 0; i < length; ++i) { 55 for (i = 0; i < length; ++i) {
56 if (!strcmp(key, entries[i].key)) 56 if (!strcmp(key, entries[i].key))
57 return &entries[i]; 57 return &entries[i];
58 } 58 }
59 return NULL; 59 return NULL;
60} 60}
61 61
62GBool Dict::is(char *type) { 62GBool Dict::is(char *type) {
63 DictEntry *e; 63 DictEntry *e;
64 64
65 return (e = find("Type")) && e->val.isName(type); 65 return (e = find("Type")) && e->val.isName(type);
66} 66}
67 67
68Object *Dict::lookup(char *key, Object *obj) { 68Object *Dict::lookup(char *key, Object *obj) {
69 DictEntry *e; 69 DictEntry *e;
70 70
71 return (e = find(key)) ? e->val.fetch(xref, obj) : obj->initNull(); 71 return (e = find(key)) ? e->val.fetch(xref, obj) : obj->initNull();
72} 72}
73 73
74Object *Dict::lookupNF(char *key, Object *obj) { 74Object *Dict::lookupNF(char *key, Object *obj) {
75 DictEntry *e; 75 DictEntry *e;
76 76
77 return (e = find(key)) ? e->val.copy(obj) : obj->initNull(); 77 return (e = find(key)) ? e->val.copy(obj) : obj->initNull();
78} 78}
79 79
80char *Dict::getKey(int i) { 80char *Dict::getKey(int i) {
81 return entries[i].key; 81 return entries[i].key;
82} 82}
83 83
84Object *Dict::getVal(int i, Object *obj) { 84Object *Dict::getVal(int i, Object *obj) {
85 return entries[i].val.fetch(xref, obj); 85 return entries[i].val.fetch(xref, obj);
86} 86}
87 87
88Object *Dict::getValNF(int i, Object *obj) { 88Object *Dict::getValNF(int i, Object *obj) {
89 return entries[i].val.copy(obj); 89 return entries[i].val.copy(obj);
90} 90}
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,75 +1,75 @@
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
18//------------------------------------------------------------------------ 18//------------------------------------------------------------------------
19// Dict 19// Dict
20//------------------------------------------------------------------------ 20//------------------------------------------------------------------------
21 21
22struct DictEntry { 22struct DictEntry {
23 char *key; 23 char *key;
24 Object val; 24 Object val;
25}; 25};
26 26
27class Dict { 27class Dict {
28public: 28public:
29 29
30 // Constructor. 30 // Constructor.
31 Dict(XRef *xrefA); 31 Dict(XRef *xrefA);
32 32
33 // Destructor. 33 // Destructor.
34 ~Dict(); 34 ~Dict();
35 35
36 // Reference counting. 36 // Reference counting.
37 int incRef() { return ++ref; } 37 int incRef() { return ++ref; }
38 int decRef() { return --ref; } 38 int decRef() { return --ref; }
39 39
40 // Get number of entries. 40 // Get number of entries.
41 int getLength() { return length; } 41 int getLength() { return length; }
42 42
43 // Add an entry. NB: does not copy key. 43 // Add an entry. NB: does not copy key.
44 void add(char *key, Object *val); 44 void add(char *key, Object *val);
45 45
46 // Check if dictionary is of specified type. 46 // Check if dictionary is of specified type.
47 GBool is(char *type); 47 GBool is(char *type);
48 48
49 // Look up an entry and return the value. Returns a null object 49 // Look up an entry and return the value. Returns a null object
50 // if <key> is not in the dictionary. 50 // if <key> is not in the dictionary.
51 Object *lookup(char *key, Object *obj); 51 Object *lookup(char *key, Object *obj);
52 Object *lookupNF(char *key, Object *obj); 52 Object *lookupNF(char *key, Object *obj);
53 53
54 // Iterative accessors. 54 // Iterative accessors.
55 char *getKey(int i); 55 char *getKey(int i);
56 Object *getVal(int i, Object *obj); 56 Object *getVal(int i, Object *obj);
57 Object *getValNF(int i, Object *obj); 57 Object *getValNF(int i, Object *obj);
58 58
59 // Set the xref pointer. This is only used in one special case: the 59 // Set the xref pointer. This is only used in one special case: the
60 // trailer dictionary, which is read before the xref table is 60 // trailer dictionary, which is read before the xref table is
61 // parsed. 61 // parsed.
62 void setXRef(XRef *xrefA) { xref = xrefA; } 62 void setXRef(XRef *xrefA) { xref = xrefA; }
63 63
64private: 64private:
65 65
66 XRef *xref; // the xref table for this PDF file 66 XRef *xref; // the xref table for this PDF file
67 DictEntry *entries; // array of entries 67 DictEntry *entries; // array of entries
68 int size; // size of <entries> array 68 int size; // size of <entries> array
69 int length; // number of entries in dictionary 69 int length; // number of entries in dictionary
70 int ref; // reference count 70 int ref; // reference count
71 71
72 DictEntry *find(char *key); 72 DictEntry *find(char *key);
73}; 73};
74 74
75#endif 75#endif
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,37 +1,37 @@
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"
18#include "Error.h" 18#include "Error.h"
19 19
20void CDECL error(int pos, char *msg, ...) { 20void CDECL error(int pos, char *msg, ...) {
21 va_list args; 21 va_list args;
22 22
23 // NB: this can be called before the globalParams object is created 23 // NB: this can be called before the globalParams object is created
24 if (globalParams && globalParams->getErrQuiet()) { 24 if (globalParams && globalParams->getErrQuiet()) {
25 return; 25 return;
26 } 26 }
27 if (pos >= 0) { 27 if (pos >= 0) {
28 fprintf(stderr, "Error (%d): ", pos); 28 fprintf(stderr, "Error (%d): ", pos);
29 } else { 29 } else {
30 fprintf(stderr, "Error: "); 30 fprintf(stderr, "Error: ");
31 } 31 }
32 va_start(args, msg); 32 va_start(args, msg);
33 vfprintf(stderr, msg, args); 33 vfprintf(stderr, msg, args);
34 va_end(args); 34 va_end(args);
35 fprintf(stderr, "\n"); 35 fprintf(stderr, "\n");
36 fflush(stderr); 36 fflush(stderr);
37} 37}
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,21 +1,21 @@
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"
18 18
19extern void CDECL error(int pos, char *msg, ...); 19extern void CDECL error(int pos, char *msg, ...);
20 20
21#endif 21#endif
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,197 +1,197 @@
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,
18 NULL, 18 NULL,
19 NULL, 19 NULL,
20 NULL, 20 NULL,
21 NULL, 21 NULL,
22 NULL, 22 NULL,
23 NULL, 23 NULL,
24 NULL, 24 NULL,
25 NULL, 25 NULL,
26 NULL, 26 NULL,
27 NULL, 27 NULL,
28 NULL, 28 NULL,
29 NULL, 29 NULL,
30 NULL, 30 NULL,
31 NULL, 31 NULL,
32 NULL, 32 NULL,
33 NULL, 33 NULL,
34 NULL, 34 NULL,
35 NULL, 35 NULL,
36 NULL, 36 NULL,
37 NULL, 37 NULL,
38 NULL, 38 NULL,
39 NULL, 39 NULL,
40 NULL, 40 NULL,
41 NULL, 41 NULL,
42 NULL, 42 NULL,
43 NULL, 43 NULL,
44 NULL, 44 NULL,
45 NULL, 45 NULL,
46 "space", 46 "space",
47 "exclam", 47 "exclam",
48 "quotedbl", 48 "quotedbl",
49 "numbersign", 49 "numbersign",
50 "dollar", 50 "dollar",
51 "percent", 51 "percent",
52 "ampersand", 52 "ampersand",
53 "quotesingle", 53 "quotesingle",
54 "parenleft", 54 "parenleft",
55 "parenright", 55 "parenright",
56 "asterisk", 56 "asterisk",
57 "plus", 57 "plus",
58 "comma", 58 "comma",
59 "hyphen", 59 "hyphen",
60 "period", 60 "period",
61 "slash", 61 "slash",
62 "zero", 62 "zero",
63 "one", 63 "one",
64 "two", 64 "two",
65 "three", 65 "three",
66 "four", 66 "four",
67 "five", 67 "five",
68 "six", 68 "six",
69 "seven", 69 "seven",
70 "eight", 70 "eight",
71 "nine", 71 "nine",
72 "colon", 72 "colon",
73 "semicolon", 73 "semicolon",
74 "less", 74 "less",
75 "equal", 75 "equal",
76 "greater", 76 "greater",
77 "question", 77 "question",
78 "at", 78 "at",
79 "A", 79 "A",
80 "B", 80 "B",
81 "C", 81 "C",
82 "D", 82 "D",
83 "E", 83 "E",
84 "F", 84 "F",
85 "G", 85 "G",
86 "H", 86 "H",
87 "I", 87 "I",
88 "J", 88 "J",
89 "K", 89 "K",
90 "L", 90 "L",
91 "M", 91 "M",
92 "N", 92 "N",
93 "O", 93 "O",
94 "P", 94 "P",
95 "Q", 95 "Q",
96 "R", 96 "R",
97 "S", 97 "S",
98 "T", 98 "T",
99 "U", 99 "U",
100 "V", 100 "V",
101 "W", 101 "W",
102 "X", 102 "X",
103 "Y", 103 "Y",
104 "Z", 104 "Z",
105 "bracketleft", 105 "bracketleft",
106 "backslash", 106 "backslash",
107 "bracketright", 107 "bracketright",
108 "asciicircum", 108 "asciicircum",
109 "underscore", 109 "underscore",
110 "grave", 110 "grave",
111 "a", 111 "a",
112 "b", 112 "b",
113 "c", 113 "c",
114 "d", 114 "d",
115 "e", 115 "e",
116 "f", 116 "f",
117 "g", 117 "g",
118 "h", 118 "h",
119 "i", 119 "i",
120 "j", 120 "j",
121 "k", 121 "k",
122 "l", 122 "l",
123 "m", 123 "m",
124 "n", 124 "n",
125 "o", 125 "o",
126 "p", 126 "p",
127 "q", 127 "q",
128 "r", 128 "r",
129 "s", 129 "s",
130 "t", 130 "t",
131 "u", 131 "u",
132 "v", 132 "v",
133 "w", 133 "w",
134 "x", 134 "x",
135 "y", 135 "y",
136 "z", 136 "z",
137 "braceleft", 137 "braceleft",
138 "bar", 138 "bar",
139 "braceright", 139 "braceright",
140 "asciitilde", 140 "asciitilde",
141 NULL, 141 NULL,
142 "Adieresis", 142 "Adieresis",
143 "Aring", 143 "Aring",
144 "Ccedilla", 144 "Ccedilla",
145 "Eacute", 145 "Eacute",
146 "Ntilde", 146 "Ntilde",
147 "Odieresis", 147 "Odieresis",
148 "Udieresis", 148 "Udieresis",
149 "aacute", 149 "aacute",
150 "agrave", 150 "agrave",
151 "acircumflex", 151 "acircumflex",
152 "adieresis", 152 "adieresis",
153 "atilde", 153 "atilde",
154 "aring", 154 "aring",
155 "ccedilla", 155 "ccedilla",
156 "eacute", 156 "eacute",
157 "egrave", 157 "egrave",
158 "ecircumflex", 158 "ecircumflex",
159 "edieresis", 159 "edieresis",
160 "iacute", 160 "iacute",
161 "igrave", 161 "igrave",
162 "icircumflex", 162 "icircumflex",
163 "idieresis", 163 "idieresis",
164 "ntilde", 164 "ntilde",
165 "oacute", 165 "oacute",
166 "ograve", 166 "ograve",
167 "ocircumflex", 167 "ocircumflex",
168 "odieresis", 168 "odieresis",
169 "otilde", 169 "otilde",
170 "uacute", 170 "uacute",
171 "ugrave", 171 "ugrave",
172 "ucircumflex", 172 "ucircumflex",
173 "udieresis", 173 "udieresis",
174 "dagger", 174 "dagger",
175 "degree", 175 "degree",
176 "cent", 176 "cent",
177 "sterling", 177 "sterling",
178 "section", 178 "section",
179 "bullet", 179 "bullet",
180 "paragraph", 180 "paragraph",
181 "germandbls", 181 "germandbls",
182 "registered", 182 "registered",
183 "copyright", 183 "copyright",
184 "trademark", 184 "trademark",
185 "acute", 185 "acute",
186 "dieresis", 186 "dieresis",
187 NULL, 187 NULL,
188 "AE", 188 "AE",
189 "Oslash", 189 "Oslash",
190 NULL, 190 NULL,
191 "plusminus", 191 "plusminus",
192 NULL, 192 NULL,
193 NULL, 193 NULL,
194 "yen", 194 "yen",
195 "mu", 195 "mu",
196 NULL, 196 NULL,
197 NULL, 197 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,20 +1,20 @@
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[];
18extern char *zapfDingbatsEncoding[]; 18extern char *zapfDingbatsEncoding[];
19 19
20#endif 20#endif
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,197 +1,197 @@
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>
18#include "gmem.h" 18#include "gmem.h"
19#include "Object.h" 19#include "Object.h"
20#include "Dict.h" 20#include "Dict.h"
21#include "Stream.h" 21#include "Stream.h"
22#include "Error.h" 22#include "Error.h"
23#include "Function.h" 23#include "Function.h"
24 24
25//------------------------------------------------------------------------ 25//------------------------------------------------------------------------
26// Function 26// Function
27//------------------------------------------------------------------------ 27//------------------------------------------------------------------------
28 28
29Function::Function() { 29Function::Function() {
30} 30}
31 31
32Function::~Function() { 32Function::~Function() {
33} 33}
34 34
35Function *Function::parse(Object *funcObj) { 35Function *Function::parse(Object *funcObj) {
36 Function *func; 36 Function *func;
37 Dict *dict; 37 Dict *dict;
38 int funcType; 38 int funcType;
39 Object obj1; 39 Object obj1;
40 40
41 if (funcObj->isStream()) { 41 if (funcObj->isStream()) {
42 dict = funcObj->streamGetDict(); 42 dict = funcObj->streamGetDict();
43 } else if (funcObj->isDict()) { 43 } else if (funcObj->isDict()) {
44 dict = funcObj->getDict(); 44 dict = funcObj->getDict();
45 } else if (funcObj->isName("Identity")) { 45 } else if (funcObj->isName("Identity")) {
46 return new IdentityFunction(); 46 return new IdentityFunction();
47 } else { 47 } else {
48 error(-1, "Expected function dictionary or stream"); 48 error(-1, "Expected function dictionary or stream");
49 return NULL; 49 return NULL;
50 } 50 }
51 51
52 if (!dict->lookup("FunctionType", &obj1)->isInt()) { 52 if (!dict->lookup("FunctionType", &obj1)->isInt()) {
53 error(-1, "Function type is missing or wrong type"); 53 error(-1, "Function type is missing or wrong type");
54 obj1.free(); 54 obj1.free();
55 return NULL; 55 return NULL;
56 } 56 }
57 funcType = obj1.getInt(); 57 funcType = obj1.getInt();
58 obj1.free(); 58 obj1.free();
59 59
60 if (funcType == 0) { 60 if (funcType == 0) {
61 func = new SampledFunction(funcObj, dict); 61 func = new SampledFunction(funcObj, dict);
62 } else if (funcType == 2) { 62 } else if (funcType == 2) {
63 func = new ExponentialFunction(funcObj, dict); 63 func = new ExponentialFunction(funcObj, dict);
64 } else if (funcType == 3) { 64 } else if (funcType == 3) {
65 func = new StitchingFunction(funcObj, dict); 65 func = new StitchingFunction(funcObj, dict);
66 } else if (funcType == 4) { 66 } else if (funcType == 4) {
67 func = new PostScriptFunction(funcObj, dict); 67 func = new PostScriptFunction(funcObj, dict);
68 } else { 68 } else {
69 error(-1, "Unimplemented function type (%d)", funcType); 69 error(-1, "Unimplemented function type (%d)", funcType);
70 return NULL; 70 return NULL;
71 } 71 }
72 if (!func->isOk()) { 72 if (!func->isOk()) {
73 delete func; 73 delete func;
74 return NULL; 74 return NULL;
75 } 75 }
76 76
77 return func; 77 return func;
78} 78}
79 79
80GBool Function::init(Dict *dict) { 80GBool Function::init(Dict *dict) {
81 Object obj1, obj2; 81 Object obj1, obj2;
82 int i; 82 int i;
83 83
84 //----- Domain 84 //----- Domain
85 if (!dict->lookup("Domain", &obj1)->isArray()) { 85 if (!dict->lookup("Domain", &obj1)->isArray()) {
86 error(-1, "Function is missing domain"); 86 error(-1, "Function is missing domain");
87 goto err2; 87 goto err2;
88 } 88 }
89 m = obj1.arrayGetLength() / 2; 89 m = obj1.arrayGetLength() / 2;
90 if (m > funcMaxInputs) { 90 if (m > funcMaxInputs) {
91 error(-1, "Functions with more than %d inputs are unsupported", 91 error(-1, "Functions with more than %d inputs are unsupported",
92 funcMaxInputs); 92 funcMaxInputs);
93 goto err2; 93 goto err2;
94 } 94 }
95 for (i = 0; i < m; ++i) { 95 for (i = 0; i < m; ++i) {
96 obj1.arrayGet(2*i, &obj2); 96 obj1.arrayGet(2*i, &obj2);
97 if (!obj2.isNum()) { 97 if (!obj2.isNum()) {
98 error(-1, "Illegal value in function domain array"); 98 error(-1, "Illegal value in function domain array");
99 goto err1; 99 goto err1;
100 } 100 }
101 domain[i][0] = obj2.getNum(); 101 domain[i][0] = obj2.getNum();
102 obj2.free(); 102 obj2.free();
103 obj1.arrayGet(2*i+1, &obj2); 103 obj1.arrayGet(2*i+1, &obj2);
104 if (!obj2.isNum()) { 104 if (!obj2.isNum()) {
105 error(-1, "Illegal value in function domain array"); 105 error(-1, "Illegal value in function domain array");
106 goto err1; 106 goto err1;
107 } 107 }
108 domain[i][1] = obj2.getNum(); 108 domain[i][1] = obj2.getNum();
109 obj2.free(); 109 obj2.free();
110 } 110 }
111 obj1.free(); 111 obj1.free();
112 112
113 //----- Range 113 //----- Range
114 hasRange = gFalse; 114 hasRange = gFalse;
115 n = 0; 115 n = 0;
116 if (dict->lookup("Range", &obj1)->isArray()) { 116 if (dict->lookup("Range", &obj1)->isArray()) {
117 hasRange = gTrue; 117 hasRange = gTrue;
118 n = obj1.arrayGetLength() / 2; 118 n = obj1.arrayGetLength() / 2;
119 if (n > funcMaxOutputs) { 119 if (n > funcMaxOutputs) {
120 error(-1, "Functions with more than %d outputs are unsupported", 120 error(-1, "Functions with more than %d outputs are unsupported",
121 funcMaxOutputs); 121 funcMaxOutputs);
122 goto err2; 122 goto err2;
123 } 123 }
124 for (i = 0; i < n; ++i) { 124 for (i = 0; i < n; ++i) {
125 obj1.arrayGet(2*i, &obj2); 125 obj1.arrayGet(2*i, &obj2);
126 if (!obj2.isNum()) { 126 if (!obj2.isNum()) {
127 error(-1, "Illegal value in function range array"); 127 error(-1, "Illegal value in function range array");
128 goto err1; 128 goto err1;
129 } 129 }
130 range[i][0] = obj2.getNum(); 130 range[i][0] = obj2.getNum();
131 obj2.free(); 131 obj2.free();
132 obj1.arrayGet(2*i+1, &obj2); 132 obj1.arrayGet(2*i+1, &obj2);
133 if (!obj2.isNum()) { 133 if (!obj2.isNum()) {
134 error(-1, "Illegal value in function range array"); 134 error(-1, "Illegal value in function range array");
135 goto err1; 135 goto err1;
136 } 136 }
137 range[i][1] = obj2.getNum(); 137 range[i][1] = obj2.getNum();
138 obj2.free(); 138 obj2.free();
139 } 139 }
140 } 140 }
141 obj1.free(); 141 obj1.free();
142 142
143 return gTrue; 143 return gTrue;
144 144
145 err1: 145 err1:
146 obj2.free(); 146 obj2.free();
147 err2: 147 err2:
148 obj1.free(); 148 obj1.free();
149 return gFalse; 149 return gFalse;
150} 150}
151 151
152//------------------------------------------------------------------------ 152//------------------------------------------------------------------------
153// IdentityFunction 153// IdentityFunction
154//------------------------------------------------------------------------ 154//------------------------------------------------------------------------
155 155
156IdentityFunction::IdentityFunction() { 156IdentityFunction::IdentityFunction() {
157 int i; 157 int i;
158 158
159 // fill these in with arbitrary values just in case they get used 159 // fill these in with arbitrary values just in case they get used
160 // somewhere 160 // somewhere
161 m = funcMaxInputs; 161 m = funcMaxInputs;
162 n = funcMaxOutputs; 162 n = funcMaxOutputs;
163 for (i = 0; i < funcMaxInputs; ++i) { 163 for (i = 0; i < funcMaxInputs; ++i) {
164 domain[i][0] = 0; 164 domain[i][0] = 0;
165 domain[i][1] = 1; 165 domain[i][1] = 1;
166 } 166 }
167 hasRange = gFalse; 167 hasRange = gFalse;
168} 168}
169 169
170IdentityFunction::~IdentityFunction() { 170IdentityFunction::~IdentityFunction() {
171} 171}
172 172
173void IdentityFunction::transform(fouble *in, fouble *out) { 173void IdentityFunction::transform(fouble *in, fouble *out) {
174 int i; 174 int i;
175 175
176 for (i = 0; i < funcMaxOutputs; ++i) { 176 for (i = 0; i < funcMaxOutputs; ++i) {
177 out[i] = in[i]; 177 out[i] = in[i];
178 } 178 }
179} 179}
180 180
181//------------------------------------------------------------------------ 181//------------------------------------------------------------------------
182// SampledFunction 182// SampledFunction
183//------------------------------------------------------------------------ 183//------------------------------------------------------------------------
184 184
185SampledFunction::SampledFunction(Object *funcObj, Dict *dict) { 185SampledFunction::SampledFunction(Object *funcObj, Dict *dict) {
186 Stream *str; 186 Stream *str;
187 int nSamples, sampleBits; 187 int nSamples, sampleBits;
188 fouble sampleMul; 188 fouble sampleMul;
189 Object obj1, obj2; 189 Object obj1, obj2;
190 Guint buf, bitMask; 190 Guint buf, bitMask;
191 int bits; 191 int bits;
192 int s; 192 int s;
193 int i; 193 int i;
194 194
195 samples = NULL; 195 samples = NULL;
196 ok = gFalse; 196 ok = gFalse;
197 197
@@ -226,449 +226,458 @@ SampledFunction::SampledFunction(Object *funcObj, Dict *dict) {
226 sampleSize[i] = obj2.getInt(); 226 sampleSize[i] = obj2.getInt();
227 obj2.free(); 227 obj2.free();
228 } 228 }
229 obj1.free(); 229 obj1.free();
230 230
231 //----- BitsPerSample 231 //----- BitsPerSample
232 if (!dict->lookup("BitsPerSample", &obj1)->isInt()) { 232 if (!dict->lookup("BitsPerSample", &obj1)->isInt()) {
233 error(-1, "Function has missing or invalid BitsPerSample"); 233 error(-1, "Function has missing or invalid BitsPerSample");
234 goto err2; 234 goto err2;
235 } 235 }
236 sampleBits = obj1.getInt(); 236 sampleBits = obj1.getInt();
237 sampleMul = 1.0 / (fouble)((1 << sampleBits) - 1); 237 sampleMul = 1.0 / (fouble)((1 << sampleBits) - 1);
238 obj1.free(); 238 obj1.free();
239 239
240 //----- Encode 240 //----- Encode
241 if (dict->lookup("Encode", &obj1)->isArray() && 241 if (dict->lookup("Encode", &obj1)->isArray() &&
242 obj1.arrayGetLength() == 2*m) { 242 obj1.arrayGetLength() == 2*m) {
243 for (i = 0; i < m; ++i) { 243 for (i = 0; i < m; ++i) {
244 obj1.arrayGet(2*i, &obj2); 244 obj1.arrayGet(2*i, &obj2);
245 if (!obj2.isNum()) { 245 if (!obj2.isNum()) {
246 error(-1, "Illegal value in function encode array"); 246 error(-1, "Illegal value in function encode array");
247 goto err3; 247 goto err3;
248 } 248 }
249 encode[i][0] = obj2.getNum(); 249 encode[i][0] = obj2.getNum();
250 obj2.free(); 250 obj2.free();
251 obj1.arrayGet(2*i+1, &obj2); 251 obj1.arrayGet(2*i+1, &obj2);
252 if (!obj2.isNum()) { 252 if (!obj2.isNum()) {
253 error(-1, "Illegal value in function encode array"); 253 error(-1, "Illegal value in function encode array");
254 goto err3; 254 goto err3;
255 } 255 }
256 encode[i][1] = obj2.getNum(); 256 encode[i][1] = obj2.getNum();
257 obj2.free(); 257 obj2.free();
258 } 258 }
259 } else { 259 } else {
260 for (i = 0; i < m; ++i) { 260 for (i = 0; i < m; ++i) {
261 encode[i][0] = 0; 261 encode[i][0] = 0;
262 encode[i][1] = sampleSize[i] - 1; 262 encode[i][1] = sampleSize[i] - 1;
263 } 263 }
264 } 264 }
265 obj1.free(); 265 obj1.free();
266 266
267 //----- Decode 267 //----- Decode
268 if (dict->lookup("Decode", &obj1)->isArray() && 268 if (dict->lookup("Decode", &obj1)->isArray() &&
269 obj1.arrayGetLength() == 2*n) { 269 obj1.arrayGetLength() == 2*n) {
270 for (i = 0; i < n; ++i) { 270 for (i = 0; i < n; ++i) {
271 obj1.arrayGet(2*i, &obj2); 271 obj1.arrayGet(2*i, &obj2);
272 if (!obj2.isNum()) { 272 if (!obj2.isNum()) {
273 error(-1, "Illegal value in function decode array"); 273 error(-1, "Illegal value in function decode array");
274 goto err3; 274 goto err3;
275 } 275 }
276 decode[i][0] = obj2.getNum(); 276 decode[i][0] = obj2.getNum();
277 obj2.free(); 277 obj2.free();
278 obj1.arrayGet(2*i+1, &obj2); 278 obj1.arrayGet(2*i+1, &obj2);
279 if (!obj2.isNum()) { 279 if (!obj2.isNum()) {
280 error(-1, "Illegal value in function decode array"); 280 error(-1, "Illegal value in function decode array");
281 goto err3; 281 goto err3;
282 } 282 }
283 decode[i][1] = obj2.getNum(); 283 decode[i][1] = obj2.getNum();
284 obj2.free(); 284 obj2.free();
285 } 285 }
286 } else { 286 } else {
287 for (i = 0; i < n; ++i) { 287 for (i = 0; i < n; ++i) {
288 decode[i][0] = range[i][0]; 288 decode[i][0] = range[i][0];
289 decode[i][1] = range[i][1]; 289 decode[i][1] = range[i][1];
290 } 290 }
291 } 291 }
292 obj1.free(); 292 obj1.free();
293 293
294 //----- samples 294 //----- samples
295 nSamples = n; 295 nSamples = n;
296 for (i = 0; i < m; ++i) 296 for (i = 0; i < m; ++i)
297 nSamples *= sampleSize[i]; 297 nSamples *= sampleSize[i];
298 samples = (fouble *)gmalloc(nSamples * sizeof(fouble)); 298 samples = (fouble *)gmalloc(nSamples * sizeof(fouble));
299 buf = 0; 299 buf = 0;
300 bits = 0; 300 bits = 0;
301 bitMask = (1 << sampleBits) - 1; 301 bitMask = (1 << sampleBits) - 1;
302 str->reset(); 302 str->reset();
303 for (i = 0; i < nSamples; ++i) { 303 for (i = 0; i < nSamples; ++i) {
304 if (sampleBits == 8) { 304 if (sampleBits == 8) {
305 s = str->getChar(); 305 s = str->getChar();
306 } else if (sampleBits == 16) { 306 } else if (sampleBits == 16) {
307 s = str->getChar(); 307 s = str->getChar();
308 s = (s << 8) + str->getChar(); 308 s = (s << 8) + str->getChar();
309 } else if (sampleBits == 32) { 309 } else if (sampleBits == 32) {
310 s = str->getChar(); 310 s = str->getChar();
311 s = (s << 8) + str->getChar(); 311 s = (s << 8) + str->getChar();
312 s = (s << 8) + str->getChar(); 312 s = (s << 8) + str->getChar();
313 s = (s << 8) + str->getChar(); 313 s = (s << 8) + str->getChar();
314 } else { 314 } else {
315 while (bits < sampleBits) { 315 while (bits < sampleBits) {
316 buf = (buf << 8) | (str->getChar() & 0xff); 316 buf = (buf << 8) | (str->getChar() & 0xff);
317 bits += 8; 317 bits += 8;
318 } 318 }
319 s = (buf >> (bits - sampleBits)) & bitMask; 319 s = (buf >> (bits - sampleBits)) & bitMask;
320 bits -= sampleBits; 320 bits -= sampleBits;
321 } 321 }
322 samples[i] = (fouble)s * sampleMul; 322 samples[i] = (fouble)s * sampleMul;
323 } 323 }
324 str->close(); 324 str->close();
325 325
326 ok = gTrue; 326 ok = gTrue;
327 return; 327 return;
328 328
329 err3: 329 err3:
330 obj2.free(); 330 obj2.free();
331 err2: 331 err2:
332 obj1.free(); 332 obj1.free();
333 err1: 333 err1:
334 return; 334 return;
335} 335}
336 336
337SampledFunction::~SampledFunction() { 337SampledFunction::~SampledFunction() {
338 if (samples) { 338 if (samples) {
339 gfree(samples); 339 gfree(samples);
340 } 340 }
341} 341}
342 342
343SampledFunction::SampledFunction(SampledFunction *func) { 343SampledFunction::SampledFunction(SampledFunction *func) {
344 int nSamples, i; 344 int nSamples, i;
345 345
346 memcpy(this, func, sizeof(SampledFunction)); 346 memcpy(this, func, sizeof(SampledFunction));
347 347
348 nSamples = n; 348 nSamples = n;
349 for (i = 0; i < m; ++i) { 349 for (i = 0; i < m; ++i) {
350 nSamples *= sampleSize[i]; 350 nSamples *= sampleSize[i];
351 } 351 }
352 samples = (fouble *)gmalloc(nSamples * sizeof(fouble)); 352 samples = (fouble *)gmalloc(nSamples * sizeof(fouble));
353 memcpy(samples, func->samples, nSamples * sizeof(fouble)); 353 memcpy(samples, func->samples, nSamples * sizeof(fouble));
354} 354}
355 355
356void SampledFunction::transform(fouble *in, fouble *out) { 356void SampledFunction::transform(fouble *in, fouble *out) {
357 fouble x; 357 fouble x;
358 int e[2][funcMaxInputs]; 358 int e[2][funcMaxInputs];
359 fouble efrac[funcMaxInputs]; 359 fouble efrac[funcMaxInputs];
360 fouble s0[1 << funcMaxInputs], s1[1 << funcMaxInputs]; 360 fouble s0[1 << funcMaxInputs], s1[1 << funcMaxInputs];
361 int i, j, k, idx; 361 int i, j, k, idx;
362 362
363 // map input values into sample array 363 // map input values into sample array
364 for (i = 0; i < m; ++i) { 364 for (i = 0; i < m; ++i) {
365 x = ((in[i] - domain[i][0]) / (domain[i][1] - domain[i][0])) * 365 x = ((in[i] - domain[i][0]) / (domain[i][1] - domain[i][0])) *
366 (encode[i][1] - encode[i][0]) + encode[i][0]; 366 (encode[i][1] - encode[i][0]) + encode[i][0];
367 if (x < 0) { 367 if (x < 0) {
368 x = 0; 368 x = 0;
369 } else if (x > sampleSize[i] - 1) { 369 } else if (x > sampleSize[i] - 1) {
370 x = sampleSize[i] - 1; 370 x = sampleSize[i] - 1;
371 } 371 }
372 e[0][i] = (int)floor(x); 372 e[0][i] = (int)floor(x);
373 e[1][i] = (int)ceil(x); 373 e[1][i] = (int)ceil(x);
374 efrac[i] = x - e[0][i]; 374 efrac[i] = x - e[0][i];
375 } 375 }
376 376
377 // for each output, do m-linear interpolation 377 // for each output, do m-linear interpolation
378 for (i = 0; i < n; ++i) { 378 for (i = 0; i < n; ++i) {
379 379
380 // pull 2^m values out of the sample array 380 // pull 2^m values out of the sample array
381 for (j = 0; j < (1<<m); ++j) { 381 for (j = 0; j < (1<<m); ++j) {
382 idx = e[j & 1][m - 1]; 382 idx = e[j & 1][m - 1];
383 for (k = m - 2; k >= 0; --k) { 383 for (k = m - 2; k >= 0; --k) {
384 idx = idx * sampleSize[k] + e[(j >> k) & 1][k]; 384 idx = idx * sampleSize[k] + e[(j >> k) & 1][k];
385 } 385 }
386 idx = idx * n + i; 386 idx = idx * n + i;
387 s0[j] = samples[idx]; 387 s0[j] = samples[idx];
388 } 388 }
389 389
390 // do m sets of interpolations 390 // do m sets of interpolations
391 for (j = 0; j < m; ++j) { 391 for (j = 0; j < m; ++j) {
392 for (k = 0; k < (1 << (m - j)); k += 2) { 392 for (k = 0; k < (1 << (m - j)); k += 2) {
393 s1[k >> 1] = (1 - efrac[j]) * s0[k] + efrac[j] * s0[k+1]; 393 s1[k >> 1] = (1 - efrac[j]) * s0[k] + efrac[j] * s0[k+1];
394 } 394 }
395 memcpy(s0, s1, (1 << (m - j - 1)) * sizeof(fouble)); 395 memcpy(s0, s1, (1 << (m - j - 1)) * sizeof(fouble));
396 } 396 }
397 397
398 // map output value to range 398 // map output value to range
399 out[i] = s0[0] * (decode[i][1] - decode[i][0]) + decode[i][0]; 399 out[i] = s0[0] * (decode[i][1] - decode[i][0]) + decode[i][0];
400 if (out[i] < range[i][0]) { 400 if (out[i] < range[i][0]) {
401 out[i] = range[i][0]; 401 out[i] = range[i][0];
402 } else if (out[i] > range[i][1]) { 402 } else if (out[i] > range[i][1]) {
403 out[i] = range[i][1]; 403 out[i] = range[i][1];
404 } 404 }
405 } 405 }
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() {
495} 504}
496 505
497ExponentialFunction::ExponentialFunction(ExponentialFunction *func) { 506ExponentialFunction::ExponentialFunction(ExponentialFunction *func) {
498 memcpy(this, func, sizeof(ExponentialFunction)); 507 memcpy(this, func, sizeof(ExponentialFunction));
499} 508}
500 509
501void ExponentialFunction::transform(fouble *in, fouble *out) { 510void ExponentialFunction::transform(fouble *in, fouble *out) {
502 fouble x; 511 fouble x;
503 int i; 512 int i;
504 513
505 if (in[0] < domain[0][0]) { 514 if (in[0] < domain[0][0]) {
506 x = domain[0][0]; 515 x = domain[0][0];
507 } else if (in[0] > domain[0][1]) { 516 } else if (in[0] > domain[0][1]) {
508 x = domain[0][1]; 517 x = domain[0][1];
509 } else { 518 } else {
510 x = in[0]; 519 x = in[0];
511 } 520 }
512 for (i = 0; i < n; ++i) { 521 for (i = 0; i < n; ++i) {
513 out[i] = c0[i] + pow(x, e) * (c1[i] - c0[i]); 522 out[i] = c0[i] + pow(x, e) * (c1[i] - c0[i]);
514 if (hasRange) { 523 if (hasRange) {
515 if (out[i] < range[i][0]) { 524 if (out[i] < range[i][0]) {
516 out[i] = range[i][0]; 525 out[i] = range[i][0];
517 } else if (out[i] > range[i][1]) { 526 } else if (out[i] > range[i][1]) {
518 out[i] = range[i][1]; 527 out[i] = range[i][1];
519 } 528 }
520 } 529 }
521 } 530 }
522 return; 531 return;
523} 532}
524 533
525//------------------------------------------------------------------------ 534//------------------------------------------------------------------------
526// StitchingFunction 535// StitchingFunction
527//------------------------------------------------------------------------ 536//------------------------------------------------------------------------
528 537
529StitchingFunction::StitchingFunction(Object *funcObj, Dict *dict) { 538StitchingFunction::StitchingFunction(Object *funcObj, Dict *dict) {
530 Object obj1, obj2; 539 Object obj1, obj2;
531 int i; 540 int i;
532 541
533 ok = gFalse; 542 ok = gFalse;
534 funcs = NULL; 543 funcs = NULL;
535 bounds = NULL; 544 bounds = NULL;
536 encode = NULL; 545 encode = NULL;
537 546
538 //----- initialize the generic stuff 547 //----- initialize the generic stuff
539 if (!init(dict)) { 548 if (!init(dict)) {
540 goto err1; 549 goto err1;
541 } 550 }
542 if (m != 1) { 551 if (m != 1) {
543 error(-1, "Stitching function with more than one input"); 552 error(-1, "Stitching function with more than one input");
544 goto err1; 553 goto err1;
545 } 554 }
546 555
547 //----- Functions 556 //----- Functions
548 if (!dict->lookup("Functions", &obj1)->isArray()) { 557 if (!dict->lookup("Functions", &obj1)->isArray()) {
549 error(-1, "Missing 'Functions' entry in stitching function"); 558 error(-1, "Missing 'Functions' entry in stitching function");
550 goto err1; 559 goto err1;
551 } 560 }
552 k = obj1.arrayGetLength(); 561 k = obj1.arrayGetLength();
553 funcs = (Function **)gmalloc(k * sizeof(Function *)); 562 funcs = (Function **)gmalloc(k * sizeof(Function *));
554 bounds = (fouble *)gmalloc((k + 1) * sizeof(fouble)); 563 bounds = (fouble *)gmalloc((k + 1) * sizeof(fouble));
555 encode = (fouble *)gmalloc(2 * k * sizeof(fouble)); 564 encode = (fouble *)gmalloc(2 * k * sizeof(fouble));
556 for (i = 0; i < k; ++i) { 565 for (i = 0; i < k; ++i) {
557 funcs[i] = NULL; 566 funcs[i] = NULL;
558 } 567 }
559 for (i = 0; i < k; ++i) { 568 for (i = 0; i < k; ++i) {
560 if (!(funcs[i] = Function::parse(obj1.arrayGet(i, &obj2)))) { 569 if (!(funcs[i] = Function::parse(obj1.arrayGet(i, &obj2)))) {
561 goto err2; 570 goto err2;
562 } 571 }
563 if (i > 0 && (funcs[i]->getInputSize() != 1 || 572 if (i > 0 && (funcs[i]->getInputSize() != 1 ||
564 funcs[i]->getOutputSize() != funcs[0]->getOutputSize())) { 573 funcs[i]->getOutputSize() != funcs[0]->getOutputSize())) {
565 error(-1, "Incompatible subfunctions in stitching function"); 574 error(-1, "Incompatible subfunctions in stitching function");
566 goto err2; 575 goto err2;
567 } 576 }
568 obj2.free(); 577 obj2.free();
569 } 578 }
570 obj1.free(); 579 obj1.free();
571 580
572 //----- Bounds 581 //----- Bounds
573 if (!dict->lookup("Bounds", &obj1)->isArray() || 582 if (!dict->lookup("Bounds", &obj1)->isArray() ||
574 obj1.arrayGetLength() != k - 1) { 583 obj1.arrayGetLength() != k - 1) {
575 error(-1, "Missing or invalid 'Bounds' entry in stitching function"); 584 error(-1, "Missing or invalid 'Bounds' entry in stitching function");
576 goto err1; 585 goto err1;
577 } 586 }
578 bounds[0] = domain[0][0]; 587 bounds[0] = domain[0][0];
579 for (i = 1; i < k; ++i) { 588 for (i = 1; i < k; ++i) {
580 if (!obj1.arrayGet(i - 1, &obj2)->isNum()) { 589 if (!obj1.arrayGet(i - 1, &obj2)->isNum()) {
581 error(-1, "Invalid type in 'Bounds' array in stitching function"); 590 error(-1, "Invalid type in 'Bounds' array in stitching function");
582 goto err2; 591 goto err2;
583 } 592 }
584 bounds[i] = obj2.getNum(); 593 bounds[i] = obj2.getNum();
585 obj2.free(); 594 obj2.free();
586 } 595 }
587 bounds[k] = domain[0][1]; 596 bounds[k] = domain[0][1];
588 obj1.free(); 597 obj1.free();
589 598
590 //----- Encode 599 //----- Encode
591 if (!dict->lookup("Encode", &obj1)->isArray() || 600 if (!dict->lookup("Encode", &obj1)->isArray() ||
592 obj1.arrayGetLength() != 2 * k) { 601 obj1.arrayGetLength() != 2 * k) {
593 error(-1, "Missing or invalid 'Encode' entry in stitching function"); 602 error(-1, "Missing or invalid 'Encode' entry in stitching function");
594 goto err1; 603 goto err1;
595 } 604 }
596 for (i = 0; i < 2 * k; ++i) { 605 for (i = 0; i < 2 * k; ++i) {
597 if (!obj1.arrayGet(i, &obj2)->isNum()) { 606 if (!obj1.arrayGet(i, &obj2)->isNum()) {
598 error(-1, "Invalid type in 'Encode' array in stitching function"); 607 error(-1, "Invalid type in 'Encode' array in stitching function");
599 goto err2; 608 goto err2;
600 } 609 }
601 encode[i] = obj2.getNum(); 610 encode[i] = obj2.getNum();
602 obj2.free(); 611 obj2.free();
603 } 612 }
604 obj1.free(); 613 obj1.free();
605 614
606 ok = gTrue; 615 ok = gTrue;
607 return; 616 return;
608 617
609 err2: 618 err2:
610 obj2.free(); 619 obj2.free();
611 err1: 620 err1:
612 obj1.free(); 621 obj1.free();
613} 622}
614 623
615StitchingFunction::StitchingFunction(StitchingFunction *func) { 624StitchingFunction::StitchingFunction(StitchingFunction *func) {
616 k = func->k; 625 k = func->k;
617 funcs = (Function **)gmalloc(k * sizeof(Function *)); 626 funcs = (Function **)gmalloc(k * sizeof(Function *));
618 memcpy(funcs, func->funcs, k * sizeof(Function *)); 627 memcpy(funcs, func->funcs, k * sizeof(Function *));
619 bounds = (fouble *)gmalloc((k + 1) * sizeof(fouble)); 628 bounds = (fouble *)gmalloc((k + 1) * sizeof(fouble));
620 memcpy(bounds, func->bounds, (k + 1) * sizeof(fouble)); 629 memcpy(bounds, func->bounds, (k + 1) * sizeof(fouble));
621 encode = (fouble *)gmalloc(2 * k * sizeof(fouble)); 630 encode = (fouble *)gmalloc(2 * k * sizeof(fouble));
622 memcpy(encode, func->encode, 2 * k * sizeof(fouble)); 631 memcpy(encode, func->encode, 2 * k * sizeof(fouble));
623 ok = gTrue; 632 ok = gTrue;
624} 633}
625 634
626StitchingFunction::~StitchingFunction() { 635StitchingFunction::~StitchingFunction() {
627 int i; 636 int i;
628 637
629 for (i = 0; i < k; ++i) { 638 for (i = 0; i < k; ++i) {
630 if (funcs[i]) { 639 if (funcs[i]) {
631 delete funcs[i]; 640 delete funcs[i];
632 } 641 }
633 } 642 }
634 gfree(funcs); 643 gfree(funcs);
635 gfree(bounds); 644 gfree(bounds);
636 gfree(encode); 645 gfree(encode);
637} 646}
638 647
639void StitchingFunction::transform(fouble *in, fouble *out) { 648void StitchingFunction::transform(fouble *in, fouble *out) {
640 fouble x; 649 fouble x;
641 int i; 650 int i;
642 651
643 if (in[0] < domain[0][0]) { 652 if (in[0] < domain[0][0]) {
644 x = domain[0][0]; 653 x = domain[0][0];
645 } else if (in[0] > domain[0][1]) { 654 } else if (in[0] > domain[0][1]) {
646 x = domain[0][1]; 655 x = domain[0][1];
647 } else { 656 } else {
648 x = in[0]; 657 x = in[0];
649 } 658 }
650 for (i = 0; i < k - 1; ++i) { 659 for (i = 0; i < k - 1; ++i) {
651 if (x < bounds[i+1]) { 660 if (x < bounds[i+1]) {
652 break; 661 break;
653 } 662 }
654 } 663 }
655 x = encode[2*i] + ((x - bounds[i]) / (bounds[i+1] - bounds[i])) * 664 x = encode[2*i] + ((x - bounds[i]) / (bounds[i+1] - bounds[i])) *
656 (encode[2*i+1] - encode[2*i]); 665 (encode[2*i+1] - encode[2*i]);
657 funcs[i]->transform(&x, out); 666 funcs[i]->transform(&x, out);
658} 667}
659 668
660//------------------------------------------------------------------------ 669//------------------------------------------------------------------------
661// PostScriptFunction 670// PostScriptFunction
662//------------------------------------------------------------------------ 671//------------------------------------------------------------------------
663 672
664enum PSOp { 673enum PSOp {
665 psOpAbs, 674 psOpAbs,
666 psOpAdd, 675 psOpAdd,
667 psOpAnd, 676 psOpAnd,
668 psOpAtan, 677 psOpAtan,
669 psOpBitshift, 678 psOpBitshift,
670 psOpCeiling, 679 psOpCeiling,
671 psOpCopy, 680 psOpCopy,
672 psOpCos, 681 psOpCos,
673 psOpCvi, 682 psOpCvi,
674 psOpCvr, 683 psOpCvr,
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,181 +1,181 @@
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"
18 18
19class Dict; 19class Dict;
20class Stream; 20class Stream;
21struct PSObject; 21struct PSObject;
22class PSStack; 22class PSStack;
23 23
24//------------------------------------------------------------------------ 24//------------------------------------------------------------------------
25// Function 25// Function
26//------------------------------------------------------------------------ 26//------------------------------------------------------------------------
27 27
28#define funcMaxInputs 8 28#define funcMaxInputs 8
29#define funcMaxOutputs 8 29#define funcMaxOutputs 8
30 30
31class Function { 31class Function {
32public: 32public:
33 33
34 Function(); 34 Function();
35 35
36 virtual ~Function(); 36 virtual ~Function();
37 37
38 // Construct a function. Returns NULL if unsuccessful. 38 // Construct a function. Returns NULL if unsuccessful.
39 static Function *parse(Object *funcObj); 39 static Function *parse(Object *funcObj);
40 40
41 // Initialize the entries common to all function types. 41 // Initialize the entries common to all function types.
42 GBool init(Dict *dict); 42 GBool init(Dict *dict);
43 43
44 virtual Function *copy() = 0; 44 virtual Function *copy() = 0;
45 45
46 // Return size of input and output tuples. 46 // Return size of input and output tuples.
47 int getInputSize() { return m; } 47 int getInputSize() { return m; }
48 int getOutputSize() { return n; } 48 int getOutputSize() { return n; }
49 49
50 // Transform an input tuple into an output tuple. 50 // Transform an input tuple into an output tuple.
51 virtual void transform(fouble *in, fouble *out) = 0; 51 virtual void transform(fouble *in, fouble *out) = 0;
52 52
53 virtual GBool isOk() = 0; 53 virtual GBool isOk() = 0;
54 54
55protected: 55protected:
56 56
57 int m, n; // size of input and output tuples 57 int m, n; // size of input and output tuples
58 fouble // min and max values for function domain 58 fouble // min and max values for function domain
59 domain[funcMaxInputs][2]; 59 domain[funcMaxInputs][2];
60 fouble // min and max values for function range 60 fouble // min and max values for function range
61 range[funcMaxOutputs][2]; 61 range[funcMaxOutputs][2];
62 GBool hasRange; // set if range is defined 62 GBool hasRange; // set if range is defined
63}; 63};
64 64
65//------------------------------------------------------------------------ 65//------------------------------------------------------------------------
66// IdentityFunction 66// IdentityFunction
67//------------------------------------------------------------------------ 67//------------------------------------------------------------------------
68 68
69class IdentityFunction: public Function { 69class IdentityFunction: public Function {
70public: 70public:
71 71
72 IdentityFunction(); 72 IdentityFunction();
73 virtual ~IdentityFunction(); 73 virtual ~IdentityFunction();
74 virtual Function *copy() { return new IdentityFunction(); } 74 virtual Function *copy() { return new IdentityFunction(); }
75 virtual void transform(fouble *in, fouble *out); 75 virtual void transform(fouble *in, fouble *out);
76 virtual GBool isOk() { return gTrue; } 76 virtual GBool isOk() { return gTrue; }
77 77
78private: 78private:
79}; 79};
80 80
81//------------------------------------------------------------------------ 81//------------------------------------------------------------------------
82// SampledFunction 82// SampledFunction
83//------------------------------------------------------------------------ 83//------------------------------------------------------------------------
84 84
85class SampledFunction: public Function { 85class SampledFunction: public Function {
86public: 86public:
87 87
88 SampledFunction(Object *funcObj, Dict *dict); 88 SampledFunction(Object *funcObj, Dict *dict);
89 virtual ~SampledFunction(); 89 virtual ~SampledFunction();
90 virtual Function *copy() { return new SampledFunction(this); } 90 virtual Function *copy() { return new SampledFunction(this); }
91 virtual void transform(fouble *in, fouble *out); 91 virtual void transform(fouble *in, fouble *out);
92 virtual GBool isOk() { return ok; } 92 virtual GBool isOk() { return ok; }
93 93
94private: 94private:
95 95
96 SampledFunction(SampledFunction *func); 96 SampledFunction(SampledFunction *func);
97 97
98 int // number of samples for each domain element 98 int // number of samples for each domain element
99 sampleSize[funcMaxInputs]; 99 sampleSize[funcMaxInputs];
100 fouble // min and max values for domain encoder 100 fouble // min and max values for domain encoder
101 encode[funcMaxInputs][2]; 101 encode[funcMaxInputs][2];
102 fouble // min and max values for range decoder 102 fouble // min and max values for range decoder
103 decode[funcMaxOutputs][2]; 103 decode[funcMaxOutputs][2];
104 fouble *samples; // the samples 104 fouble *samples; // the samples
105 GBool ok; 105 GBool ok;
106}; 106};
107 107
108//------------------------------------------------------------------------ 108//------------------------------------------------------------------------
109// ExponentialFunction 109// ExponentialFunction
110//------------------------------------------------------------------------ 110//------------------------------------------------------------------------
111 111
112class ExponentialFunction: public Function { 112class ExponentialFunction: public Function {
113public: 113public:
114 114
115 ExponentialFunction(Object *funcObj, Dict *dict); 115 ExponentialFunction(Object *funcObj, Dict *dict);
116 virtual ~ExponentialFunction(); 116 virtual ~ExponentialFunction();
117 virtual Function *copy() { return new ExponentialFunction(this); } 117 virtual Function *copy() { return new ExponentialFunction(this); }
118 virtual void transform(fouble *in, fouble *out); 118 virtual void transform(fouble *in, fouble *out);
119 virtual GBool isOk() { return ok; } 119 virtual GBool isOk() { return ok; }
120 120
121private: 121private:
122 122
123 ExponentialFunction(ExponentialFunction *func); 123 ExponentialFunction(ExponentialFunction *func);
124 124
125 fouble c0[funcMaxOutputs]; 125 fouble c0[funcMaxOutputs];
126 fouble c1[funcMaxOutputs]; 126 fouble c1[funcMaxOutputs];
127 fouble e; 127 fouble e;
128 GBool ok; 128 GBool ok;
129}; 129};
130 130
131//------------------------------------------------------------------------ 131//------------------------------------------------------------------------
132// StitchingFunction 132// StitchingFunction
133//------------------------------------------------------------------------ 133//------------------------------------------------------------------------
134 134
135class StitchingFunction: public Function { 135class StitchingFunction: public Function {
136public: 136public:
137 137
138 StitchingFunction(Object *funcObj, Dict *dict); 138 StitchingFunction(Object *funcObj, Dict *dict);
139 virtual ~StitchingFunction(); 139 virtual ~StitchingFunction();
140 virtual Function *copy() { return new StitchingFunction(this); } 140 virtual Function *copy() { return new StitchingFunction(this); }
141 virtual void transform(fouble *in, fouble *out); 141 virtual void transform(fouble *in, fouble *out);
142 virtual GBool isOk() { return ok; } 142 virtual GBool isOk() { return ok; }
143 143
144private: 144private:
145 145
146 StitchingFunction(StitchingFunction *func); 146 StitchingFunction(StitchingFunction *func);
147 147
148 int k; 148 int k;
149 Function **funcs; 149 Function **funcs;
150 fouble *bounds; 150 fouble *bounds;
151 fouble *encode; 151 fouble *encode;
152 GBool ok; 152 GBool ok;
153}; 153};
154 154
155//------------------------------------------------------------------------ 155//------------------------------------------------------------------------
156// PostScriptFunction 156// PostScriptFunction
157//------------------------------------------------------------------------ 157//------------------------------------------------------------------------
158 158
159class PostScriptFunction: public Function { 159class PostScriptFunction: public Function {
160public: 160public:
161 161
162 PostScriptFunction(Object *funcObj, Dict *dict); 162 PostScriptFunction(Object *funcObj, Dict *dict);
163 virtual ~PostScriptFunction(); 163 virtual ~PostScriptFunction();
164 virtual Function *copy() { return new PostScriptFunction(this); } 164 virtual Function *copy() { return new PostScriptFunction(this); }
165 virtual void transform(fouble *in, fouble *out); 165 virtual void transform(fouble *in, fouble *out);
166 virtual GBool isOk() { return ok; } 166 virtual GBool isOk() { return ok; }
167 167
168private: 168private:
169 169
170 PostScriptFunction(PostScriptFunction *func); 170 PostScriptFunction(PostScriptFunction *func);
171 GBool parseCode(Stream *str, int *codePtr); 171 GBool parseCode(Stream *str, int *codePtr);
172 GString *getToken(Stream *str); 172 GString *getToken(Stream *str);
173 void resizeCode(int newSize); 173 void resizeCode(int newSize);
174 void exec(PSStack *stack, int codePtr); 174 void exec(PSStack *stack, int codePtr);
175 175
176 PSObject *code; 176 PSObject *code;
177 int codeSize; 177 int codeSize;
178 GBool ok; 178 GBool ok;
179}; 179};
180 180
181#endif 181#endif
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,714 +1,759 @@
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>
18#include "gmem.h" 18#include "gmem.h"
19#include "CharTypes.h" 19#include "CharTypes.h"
20#include "Object.h" 20#include "Object.h"
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},
55 &Gfx::opEOFillStroke}, 66 &Gfx::opEOFillStroke},
56 {"BDC", 2, {tchkName, tchkProps}, 67 {"BDC", 2, {tchkName, tchkProps},
57 &Gfx::opBeginMarkedContent}, 68 &Gfx::opBeginMarkedContent},
58 {"BI", 0, {tchkNone}, 69 {"BI", 0, {tchkNone},
59 &Gfx::opBeginImage}, 70 &Gfx::opBeginImage},
60 {"BMC", 1, {tchkName}, 71 {"BMC", 1, {tchkName},
61 &Gfx::opBeginMarkedContent}, 72 &Gfx::opBeginMarkedContent},
62 {"BT", 0, {tchkNone}, 73 {"BT", 0, {tchkNone},
63 &Gfx::opBeginText}, 74 &Gfx::opBeginText},
64 {"BX", 0, {tchkNone}, 75 {"BX", 0, {tchkNone},
65 &Gfx::opBeginIgnoreUndef}, 76 &Gfx::opBeginIgnoreUndef},
66 {"CS", 1, {tchkName}, 77 {"CS", 1, {tchkName},
67 &Gfx::opSetStrokeColorSpace}, 78 &Gfx::opSetStrokeColorSpace},
68 {"DP", 2, {tchkName, tchkProps}, 79 {"DP", 2, {tchkName, tchkProps},
69 &Gfx::opMarkPoint}, 80 &Gfx::opMarkPoint},
70 {"Do", 1, {tchkName}, 81 {"Do", 1, {tchkName},
71 &Gfx::opXObject}, 82 &Gfx::opXObject},
72 {"EI", 0, {tchkNone}, 83 {"EI", 0, {tchkNone},
73 &Gfx::opEndImage}, 84 &Gfx::opEndImage},
74 {"EMC", 0, {tchkNone}, 85 {"EMC", 0, {tchkNone},
75 &Gfx::opEndMarkedContent}, 86 &Gfx::opEndMarkedContent},
76 {"ET", 0, {tchkNone}, 87 {"ET", 0, {tchkNone},
77 &Gfx::opEndText}, 88 &Gfx::opEndText},
78 {"EX", 0, {tchkNone}, 89 {"EX", 0, {tchkNone},
79 &Gfx::opEndIgnoreUndef}, 90 &Gfx::opEndIgnoreUndef},
80 {"F", 0, {tchkNone}, 91 {"F", 0, {tchkNone},
81 &Gfx::opFill}, 92 &Gfx::opFill},
82 {"G", 1, {tchkNum}, 93 {"G", 1, {tchkNum},
83 &Gfx::opSetStrokeGray}, 94 &Gfx::opSetStrokeGray},
84 {"ID", 0, {tchkNone}, 95 {"ID", 0, {tchkNone},
85 &Gfx::opImageData}, 96 &Gfx::opImageData},
86 {"J", 1, {tchkInt}, 97 {"J", 1, {tchkInt},
87 &Gfx::opSetLineCap}, 98 &Gfx::opSetLineCap},
88 {"K", 4, {tchkNum, tchkNum, tchkNum, tchkNum}, 99 {"K", 4, {tchkNum, tchkNum, tchkNum, tchkNum},
89 &Gfx::opSetStrokeCMYKColor}, 100 &Gfx::opSetStrokeCMYKColor},
90 {"M", 1, {tchkNum}, 101 {"M", 1, {tchkNum},
91 &Gfx::opSetMiterLimit}, 102 &Gfx::opSetMiterLimit},
92 {"MP", 1, {tchkName}, 103 {"MP", 1, {tchkName},
93 &Gfx::opMarkPoint}, 104 &Gfx::opMarkPoint},
94 {"Q", 0, {tchkNone}, 105 {"Q", 0, {tchkNone},
95 &Gfx::opRestore}, 106 &Gfx::opRestore},
96 {"RG", 3, {tchkNum, tchkNum, tchkNum}, 107 {"RG", 3, {tchkNum, tchkNum, tchkNum},
97 &Gfx::opSetStrokeRGBColor}, 108 &Gfx::opSetStrokeRGBColor},
98 {"S", 0, {tchkNone}, 109 {"S", 0, {tchkNone},
99 &Gfx::opStroke}, 110 &Gfx::opStroke},
100 {"SC", -4, {tchkNum, tchkNum, tchkNum, tchkNum}, 111 {"SC", -4, {tchkNum, tchkNum, tchkNum, tchkNum},
101 &Gfx::opSetStrokeColor}, 112 &Gfx::opSetStrokeColor},
102 {"SCN", -5, {tchkSCN, tchkSCN, tchkSCN, tchkSCN, 113 {"SCN", -5, {tchkSCN, tchkSCN, tchkSCN, tchkSCN,
103 tchkSCN}, 114 tchkSCN},
104 &Gfx::opSetStrokeColorN}, 115 &Gfx::opSetStrokeColorN},
105 {"T*", 0, {tchkNone}, 116 {"T*", 0, {tchkNone},
106 &Gfx::opTextNextLine}, 117 &Gfx::opTextNextLine},
107 {"TD", 2, {tchkNum, tchkNum}, 118 {"TD", 2, {tchkNum, tchkNum},
108 &Gfx::opTextMoveSet}, 119 &Gfx::opTextMoveSet},
109 {"TJ", 1, {tchkArray}, 120 {"TJ", 1, {tchkArray},
110 &Gfx::opShowSpaceText}, 121 &Gfx::opShowSpaceText},
111 {"TL", 1, {tchkNum}, 122 {"TL", 1, {tchkNum},
112 &Gfx::opSetTextLeading}, 123 &Gfx::opSetTextLeading},
113 {"Tc", 1, {tchkNum}, 124 {"Tc", 1, {tchkNum},
114 &Gfx::opSetCharSpacing}, 125 &Gfx::opSetCharSpacing},
115 {"Td", 2, {tchkNum, tchkNum}, 126 {"Td", 2, {tchkNum, tchkNum},
116 &Gfx::opTextMove}, 127 &Gfx::opTextMove},
117 {"Tf", 2, {tchkName, tchkNum}, 128 {"Tf", 2, {tchkName, tchkNum},
118 &Gfx::opSetFont}, 129 &Gfx::opSetFont},
119 {"Tj", 1, {tchkString}, 130 {"Tj", 1, {tchkString},
120 &Gfx::opShowText}, 131 &Gfx::opShowText},
121 {"Tm", 6, {tchkNum, tchkNum, tchkNum, tchkNum, 132 {"Tm", 6, {tchkNum, tchkNum, tchkNum, tchkNum,
122 tchkNum, tchkNum}, 133 tchkNum, tchkNum},
123 &Gfx::opSetTextMatrix}, 134 &Gfx::opSetTextMatrix},
124 {"Tr", 1, {tchkInt}, 135 {"Tr", 1, {tchkInt},
125 &Gfx::opSetTextRender}, 136 &Gfx::opSetTextRender},
126 {"Ts", 1, {tchkNum}, 137 {"Ts", 1, {tchkNum},
127 &Gfx::opSetTextRise}, 138 &Gfx::opSetTextRise},
128 {"Tw", 1, {tchkNum}, 139 {"Tw", 1, {tchkNum},
129 &Gfx::opSetWordSpacing}, 140 &Gfx::opSetWordSpacing},
130 {"Tz", 1, {tchkNum}, 141 {"Tz", 1, {tchkNum},
131 &Gfx::opSetHorizScaling}, 142 &Gfx::opSetHorizScaling},
132 {"W", 0, {tchkNone}, 143 {"W", 0, {tchkNone},
133 &Gfx::opClip}, 144 &Gfx::opClip},
134 {"W*", 0, {tchkNone}, 145 {"W*", 0, {tchkNone},
135 &Gfx::opEOClip}, 146 &Gfx::opEOClip},
136 {"b", 0, {tchkNone}, 147 {"b", 0, {tchkNone},
137 &Gfx::opCloseFillStroke}, 148 &Gfx::opCloseFillStroke},
138 {"b*", 0, {tchkNone}, 149 {"b*", 0, {tchkNone},
139 &Gfx::opCloseEOFillStroke}, 150 &Gfx::opCloseEOFillStroke},
140 {"c", 6, {tchkNum, tchkNum, tchkNum, tchkNum, 151 {"c", 6, {tchkNum, tchkNum, tchkNum, tchkNum,
141 tchkNum, tchkNum}, 152 tchkNum, tchkNum},
142 &Gfx::opCurveTo}, 153 &Gfx::opCurveTo},
143 {"cm", 6, {tchkNum, tchkNum, tchkNum, tchkNum, 154 {"cm", 6, {tchkNum, tchkNum, tchkNum, tchkNum,
144 tchkNum, tchkNum}, 155 tchkNum, tchkNum},
145 &Gfx::opConcat}, 156 &Gfx::opConcat},
146 {"cs", 1, {tchkName}, 157 {"cs", 1, {tchkName},
147 &Gfx::opSetFillColorSpace}, 158 &Gfx::opSetFillColorSpace},
148 {"d", 2, {tchkArray, tchkNum}, 159 {"d", 2, {tchkArray, tchkNum},
149 &Gfx::opSetDash}, 160 &Gfx::opSetDash},
150 {"d0", 2, {tchkNum, tchkNum}, 161 {"d0", 2, {tchkNum, tchkNum},
151 &Gfx::opSetCharWidth}, 162 &Gfx::opSetCharWidth},
152 {"d1", 6, {tchkNum, tchkNum, tchkNum, tchkNum, 163 {"d1", 6, {tchkNum, tchkNum, tchkNum, tchkNum,
153 tchkNum, tchkNum}, 164 tchkNum, tchkNum},
154 &Gfx::opSetCacheDevice}, 165 &Gfx::opSetCacheDevice},
155 {"f", 0, {tchkNone}, 166 {"f", 0, {tchkNone},
156 &Gfx::opFill}, 167 &Gfx::opFill},
157 {"f*", 0, {tchkNone}, 168 {"f*", 0, {tchkNone},
158 &Gfx::opEOFill}, 169 &Gfx::opEOFill},
159 {"g", 1, {tchkNum}, 170 {"g", 1, {tchkNum},
160 &Gfx::opSetFillGray}, 171 &Gfx::opSetFillGray},
161 {"gs", 1, {tchkName}, 172 {"gs", 1, {tchkName},
162 &Gfx::opSetExtGState}, 173 &Gfx::opSetExtGState},
163 {"h", 0, {tchkNone}, 174 {"h", 0, {tchkNone},
164 &Gfx::opClosePath}, 175 &Gfx::opClosePath},
165 {"i", 1, {tchkNum}, 176 {"i", 1, {tchkNum},
166 &Gfx::opSetFlat}, 177 &Gfx::opSetFlat},
167 {"j", 1, {tchkInt}, 178 {"j", 1, {tchkInt},
168 &Gfx::opSetLineJoin}, 179 &Gfx::opSetLineJoin},
169 {"k", 4, {tchkNum, tchkNum, tchkNum, tchkNum}, 180 {"k", 4, {tchkNum, tchkNum, tchkNum, tchkNum},
170 &Gfx::opSetFillCMYKColor}, 181 &Gfx::opSetFillCMYKColor},
171 {"l", 2, {tchkNum, tchkNum}, 182 {"l", 2, {tchkNum, tchkNum},
172 &Gfx::opLineTo}, 183 &Gfx::opLineTo},
173 {"m", 2, {tchkNum, tchkNum}, 184 {"m", 2, {tchkNum, tchkNum},
174 &Gfx::opMoveTo}, 185 &Gfx::opMoveTo},
175 {"n", 0, {tchkNone}, 186 {"n", 0, {tchkNone},
176 &Gfx::opEndPath}, 187 &Gfx::opEndPath},
177 {"q", 0, {tchkNone}, 188 {"q", 0, {tchkNone},
178 &Gfx::opSave}, 189 &Gfx::opSave},
179 {"re", 4, {tchkNum, tchkNum, tchkNum, tchkNum}, 190 {"re", 4, {tchkNum, tchkNum, tchkNum, tchkNum},
180 &Gfx::opRectangle}, 191 &Gfx::opRectangle},
181 {"rg", 3, {tchkNum, tchkNum, tchkNum}, 192 {"rg", 3, {tchkNum, tchkNum, tchkNum},
182 &Gfx::opSetFillRGBColor}, 193 &Gfx::opSetFillRGBColor},
183 {"ri", 1, {tchkName}, 194 {"ri", 1, {tchkName},
184 &Gfx::opSetRenderingIntent}, 195 &Gfx::opSetRenderingIntent},
185 {"s", 0, {tchkNone}, 196 {"s", 0, {tchkNone},
186 &Gfx::opCloseStroke}, 197 &Gfx::opCloseStroke},
187 {"sc", -4, {tchkNum, tchkNum, tchkNum, tchkNum}, 198 {"sc", -4, {tchkNum, tchkNum, tchkNum, tchkNum},
188 &Gfx::opSetFillColor}, 199 &Gfx::opSetFillColor},
189 {"scn", -5, {tchkSCN, tchkSCN, tchkSCN, tchkSCN, 200 {"scn", -5, {tchkSCN, tchkSCN, tchkSCN, tchkSCN,
190 tchkSCN}, 201 tchkSCN},
191 &Gfx::opSetFillColorN}, 202 &Gfx::opSetFillColorN},
192 {"sh", 1, {tchkName}, 203 {"sh", 1, {tchkName},
193 &Gfx::opShFill}, 204 &Gfx::opShFill},
194 {"v", 4, {tchkNum, tchkNum, tchkNum, tchkNum}, 205 {"v", 4, {tchkNum, tchkNum, tchkNum, tchkNum},
195 &Gfx::opCurveTo1}, 206 &Gfx::opCurveTo1},
196 {"w", 1, {tchkNum}, 207 {"w", 1, {tchkNum},
197 &Gfx::opSetLineWidth}, 208 &Gfx::opSetLineWidth},
198 {"y", 4, {tchkNum, tchkNum, tchkNum, tchkNum}, 209 {"y", 4, {tchkNum, tchkNum, tchkNum, tchkNum},
199 &Gfx::opCurveTo2}, 210 &Gfx::opCurveTo2},
200}; 211};
201 212
202#define numOps (sizeof(opTab) / sizeof(Operator)) 213#define numOps (sizeof(opTab) / sizeof(Operator))
203 214
204//------------------------------------------------------------------------ 215//------------------------------------------------------------------------
205// GfxResources 216// GfxResources
206//------------------------------------------------------------------------ 217//------------------------------------------------------------------------
207 218
208GfxResources::GfxResources(XRef *xref, Dict *resDict, GfxResources *nextA) { 219GfxResources::GfxResources(XRef *xref, Dict *resDict, GfxResources *nextA) {
209 Object obj1; 220 Object obj1;
210 221
211 if (resDict) { 222 if (resDict) {
212 223
213 // build font dictionary 224 // build font dictionary
214 fonts = NULL; 225 fonts = NULL;
215 resDict->lookup("Font", &obj1); 226 resDict->lookup("Font", &obj1);
216 if (obj1.isDict()) { 227 if (obj1.isDict()) {
217 fonts = new GfxFontDict(xref, obj1.getDict()); 228 fonts = new GfxFontDict(xref, obj1.getDict());
218 } 229 }
219 obj1.free(); 230 obj1.free();
220 231
221 // get XObject dictionary 232 // get XObject dictionary
222 resDict->lookup("XObject", &xObjDict); 233 resDict->lookup("XObject", &xObjDict);
223 234
224 // get color space dictionary 235 // get color space dictionary
225 resDict->lookup("ColorSpace", &colorSpaceDict); 236 resDict->lookup("ColorSpace", &colorSpaceDict);
226 237
227 // get pattern dictionary 238 // get pattern dictionary
228 resDict->lookup("Pattern", &patternDict); 239 resDict->lookup("Pattern", &patternDict);
229 240
230 // get shading dictionary 241 // get shading dictionary
231 resDict->lookup("Shading", &shadingDict); 242 resDict->lookup("Shading", &shadingDict);
232 243
233 // get graphics state parameter dictionary 244 // get graphics state parameter dictionary
234 resDict->lookup("ExtGState", &gStateDict); 245 resDict->lookup("ExtGState", &gStateDict);
235 246
236 } else { 247 } else {
237 fonts = NULL; 248 fonts = NULL;
238 xObjDict.initNull(); 249 xObjDict.initNull();
239 colorSpaceDict.initNull(); 250 colorSpaceDict.initNull();
240 patternDict.initNull(); 251 patternDict.initNull();
241 gStateDict.initNull(); 252 gStateDict.initNull();
242 } 253 }
243 254
244 next = nextA; 255 next = nextA;
245} 256}
246 257
247GfxResources::~GfxResources() { 258GfxResources::~GfxResources() {
248 if (fonts) { 259 if (fonts) {
249 delete fonts; 260 delete fonts;
250 } 261 }
251 xObjDict.free(); 262 xObjDict.free();
252 colorSpaceDict.free(); 263 colorSpaceDict.free();
253 patternDict.free(); 264 patternDict.free();
254 shadingDict.free(); 265 shadingDict.free();
255 gStateDict.free(); 266 gStateDict.free();
256} 267}
257 268
258GfxFont *GfxResources::lookupFont(char *name) { 269GfxFont *GfxResources::lookupFont(char *name) {
259 GfxFont *font; 270 GfxFont *font;
260 GfxResources *resPtr; 271 GfxResources *resPtr;
261 272
262 for (resPtr = this; resPtr; resPtr = resPtr->next) { 273 for (resPtr = this; resPtr; resPtr = resPtr->next) {
263 if (resPtr->fonts) { 274 if (resPtr->fonts) {
264 if ((font = resPtr->fonts->lookup(name))) 275 if ((font = resPtr->fonts->lookup(name)))
265 return font; 276 return font;
266 } 277 }
267 } 278 }
268 error(-1, "Unknown font tag '%s'", name); 279 error(-1, "Unknown font tag '%s'", name);
269 return NULL; 280 return NULL;
270} 281}
271 282
272GBool GfxResources::lookupXObject(char *name, Object *obj) { 283GBool GfxResources::lookupXObject(char *name, Object *obj) {
273 GfxResources *resPtr; 284 GfxResources *resPtr;
274 285
275 for (resPtr = this; resPtr; resPtr = resPtr->next) { 286 for (resPtr = this; resPtr; resPtr = resPtr->next) {
276 if (resPtr->xObjDict.isDict()) { 287 if (resPtr->xObjDict.isDict()) {
277 if (!resPtr->xObjDict.dictLookup(name, obj)->isNull()) 288 if (!resPtr->xObjDict.dictLookup(name, obj)->isNull())
278 return gTrue; 289 return gTrue;
279 obj->free(); 290 obj->free();
280 } 291 }
281 } 292 }
282 error(-1, "XObject '%s' is unknown", name); 293 error(-1, "XObject '%s' is unknown", name);
283 return gFalse; 294 return gFalse;
284} 295}
285 296
286GBool GfxResources::lookupXObjectNF(char *name, Object *obj) { 297GBool GfxResources::lookupXObjectNF(char *name, Object *obj) {
287 GfxResources *resPtr; 298 GfxResources *resPtr;
288 299
289 for (resPtr = this; resPtr; resPtr = resPtr->next) { 300 for (resPtr = this; resPtr; resPtr = resPtr->next) {
290 if (resPtr->xObjDict.isDict()) { 301 if (resPtr->xObjDict.isDict()) {
291 if (!resPtr->xObjDict.dictLookupNF(name, obj)->isNull()) 302 if (!resPtr->xObjDict.dictLookupNF(name, obj)->isNull())
292 return gTrue; 303 return gTrue;
293 obj->free(); 304 obj->free();
294 } 305 }
295 } 306 }
296 error(-1, "XObject '%s' is unknown", name); 307 error(-1, "XObject '%s' is unknown", name);
297 return gFalse; 308 return gFalse;
298} 309}
299 310
300void GfxResources::lookupColorSpace(char *name, Object *obj) { 311void GfxResources::lookupColorSpace(char *name, Object *obj) {
301 GfxResources *resPtr; 312 GfxResources *resPtr;
302 313
303 for (resPtr = this; resPtr; resPtr = resPtr->next) { 314 for (resPtr = this; resPtr; resPtr = resPtr->next) {
304 if (resPtr->colorSpaceDict.isDict()) { 315 if (resPtr->colorSpaceDict.isDict()) {
305 if (!resPtr->colorSpaceDict.dictLookup(name, obj)->isNull()) { 316 if (!resPtr->colorSpaceDict.dictLookup(name, obj)->isNull()) {
306 return; 317 return;
307 } 318 }
308 obj->free(); 319 obj->free();
309 } 320 }
310 } 321 }
311 obj->initNull(); 322 obj->initNull();
312} 323}
313 324
314GfxPattern *GfxResources::lookupPattern(char *name) { 325GfxPattern *GfxResources::lookupPattern(char *name) {
315 GfxResources *resPtr; 326 GfxResources *resPtr;
316 GfxPattern *pattern; 327 GfxPattern *pattern;
317 Object obj; 328 Object obj;
318 329
319 for (resPtr = this; resPtr; resPtr = resPtr->next) { 330 for (resPtr = this; resPtr; resPtr = resPtr->next) {
320 if (resPtr->patternDict.isDict()) { 331 if (resPtr->patternDict.isDict()) {
321 if (!resPtr->patternDict.dictLookup(name, &obj)->isNull()) { 332 if (!resPtr->patternDict.dictLookup(name, &obj)->isNull()) {
322 pattern = GfxPattern::parse(&obj); 333 pattern = GfxPattern::parse(&obj);
323 obj.free(); 334 obj.free();
324 return pattern; 335 return pattern;
325 } 336 }
326 obj.free(); 337 obj.free();
327 } 338 }
328 } 339 }
329 error(-1, "Unknown pattern '%s'", name); 340 error(-1, "Unknown pattern '%s'", name);
330 return NULL; 341 return NULL;
331} 342}
332 343
333GfxShading *GfxResources::lookupShading(char *name) { 344GfxShading *GfxResources::lookupShading(char *name) {
334 GfxResources *resPtr; 345 GfxResources *resPtr;
335 GfxShading *shading; 346 GfxShading *shading;
336 Object obj; 347 Object obj;
337 348
338 for (resPtr = this; resPtr; resPtr = resPtr->next) { 349 for (resPtr = this; resPtr; resPtr = resPtr->next) {
339 if (resPtr->shadingDict.isDict()) { 350 if (resPtr->shadingDict.isDict()) {
340 if (!resPtr->shadingDict.dictLookup(name, &obj)->isNull()) { 351 if (!resPtr->shadingDict.dictLookup(name, &obj)->isNull()) {
341 shading = GfxShading::parse(&obj); 352 shading = GfxShading::parse(&obj);
342 obj.free(); 353 obj.free();
343 return shading; 354 return shading;
344 } 355 }
345 obj.free(); 356 obj.free();
346 } 357 }
347 } 358 }
348 error(-1, "Unknown shading '%s'", name); 359 error(-1, "Unknown shading '%s'", name);
349 return NULL; 360 return NULL;
350} 361}
351 362
352GBool GfxResources::lookupGState(char *name, Object *obj) { 363GBool GfxResources::lookupGState(char *name, Object *obj) {
353 GfxResources *resPtr; 364 GfxResources *resPtr;
354 365
355 for (resPtr = this; resPtr; resPtr = resPtr->next) { 366 for (resPtr = this; resPtr; resPtr = resPtr->next) {
356 if (resPtr->gStateDict.isDict()) { 367 if (resPtr->gStateDict.isDict()) {
357 if (!resPtr->gStateDict.dictLookup(name, obj)->isNull()) { 368 if (!resPtr->gStateDict.dictLookup(name, obj)->isNull()) {
358 return gTrue; 369 return gTrue;
359 } 370 }
360 obj->free(); 371 obj->free();
361 } 372 }
362 } 373 }
363 error(-1, "ExtGState '%s' is unknown", name); 374 error(-1, "ExtGState '%s' is unknown", name);
364 return gFalse; 375 return gFalse;
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);
389 out->setDefaultCTM(state->getCTM()); 401 out->setDefaultCTM(state->getCTM());
390 out->updateAll(state); 402 out->updateAll(state);
391 for (i = 0; i < 6; ++i) { 403 for (i = 0; i < 6; ++i) {
392 baseMatrix[i] = state->getCTM()[i]; 404 baseMatrix[i] = state->getCTM()[i];
393 } 405 }
394 406
395 // set crop box 407 // set crop box
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();
435 return; 480 return;
436 } 481 }
437 obj2.free(); 482 obj2.free();
438 } 483 }
439 } else if (!obj->isStream()) { 484 } else if (!obj->isStream()) {
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);
494 printf("\n"); 539 printf("\n");
495 fflush(stdout); 540 fflush(stdout);
496 } 541 }
497 obj.free(); 542 obj.free();
498 } 543 }
499 544
500 // grab the next object 545 // grab the next object
501 parser->getObj(&obj); 546 parser->getObj(&obj);
502 } 547 }
503 obj.free(); 548 obj.free();
504 549
505 // args at end with no command 550 // args at end with no command
506 if (numArgs > 0) { 551 if (numArgs > 0) {
507 error(getPos(), "Leftover args in content stream"); 552 error(getPos(), "Leftover args in content stream");
508 if (printCommands) { 553 if (printCommands) {
509 printf("%d leftovers:", numArgs); 554 printf("%d leftovers:", numArgs);
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))) {
535 if (ignoreUndef == 0) 580 if (ignoreUndef == 0)
536 error(getPos(), "Unknown operator '%s'", name); 581 error(getPos(), "Unknown operator '%s'", name);
537 return; 582 return;
538 } 583 }
539 584
540 // type check args 585 // type check args
541 if (op->numArgs >= 0) { 586 if (op->numArgs >= 0) {
542 if (numArgs != op->numArgs) { 587 if (numArgs != op->numArgs) {
543 error(getPos(), "Wrong number (%d) of args to '%s' operator", 588 error(getPos(), "Wrong number (%d) of args to '%s' operator",
544 numArgs, name); 589 numArgs, name);
545 return; 590 return;
546 } 591 }
547 } else { 592 } else {
548 if (numArgs > -op->numArgs) { 593 if (numArgs > -op->numArgs) {
549 error(getPos(), "Too many (%d) args to '%s' operator", 594 error(getPos(), "Too many (%d) args to '%s' operator",
550 numArgs, name); 595 numArgs, name);
551 return; 596 return;
552 } 597 }
553 } 598 }
554 for (i = 0; i < numArgs; ++i) { 599 for (i = 0; i < numArgs; ++i) {
555 if (!checkArg(&args[i], op->tchk[i])) { 600 if (!checkArg(&args[i], op->tchk[i])) {
556 error(getPos(), "Arg #%d to '%s' operator is wrong type (%s)", 601 error(getPos(), "Arg #%d to '%s' operator is wrong type (%s)",
557 i, name, args[i].getTypeName()); 602 i, name, args[i].getTypeName());
558 return; 603 return;
559 } 604 }
560 } 605 }
561 606
562 // do it 607 // do it
563 (this->*op->func)(args, numArgs); 608 (this->*op->func)(args, numArgs);
564} 609}
565 610
566Operator *Gfx::findOp(char *name) { 611Operator *Gfx::findOp(char *name) {
567 int a, b, m, cmp; 612 int a, b, m, cmp;
568 613
569 a = -1; 614 a = -1;
570 b = numOps; 615 b = numOps;
571 // invariant: opTab[a] < name < opTab[b] 616 // invariant: opTab[a] < name < opTab[b]
572 while (b - a > 1) { 617 while (b - a > 1) {
573 m = (a + b) / 2; 618 m = (a + b) / 2;
574 cmp = strcmp(opTab[m].name, name); 619 cmp = strcmp(opTab[m].name, name);
575 if (cmp < 0) 620 if (cmp < 0)
576 a = m; 621 a = m;
577 else if (cmp > 0) 622 else if (cmp > 0)
578 b = m; 623 b = m;
579 else 624 else
580 a = b = m; 625 a = b = m;
581 } 626 }
582 if (cmp != 0) 627 if (cmp != 0)
583 return NULL; 628 return NULL;
584 return &opTab[a]; 629 return &opTab[a];
585} 630}
586 631
587GBool Gfx::checkArg(Object *arg, TchkType type) { 632GBool Gfx::checkArg(Object *arg, TchkType type) {
588 switch (type) { 633 switch (type) {
589 case tchkBool: return arg->isBool(); 634 case tchkBool: return arg->isBool();
590 case tchkInt: return arg->isInt(); 635 case tchkInt: return arg->isInt();
591 case tchkNum: return arg->isNum(); 636 case tchkNum: return arg->isNum();
592 case tchkString: return arg->isString(); 637 case tchkString: return arg->isString();
593 case tchkName: return arg->isName(); 638 case tchkName: return arg->isName();
594 case tchkArray: return arg->isArray(); 639 case tchkArray: return arg->isArray();
595 case tchkProps: return arg->isDict() || arg->isName(); 640 case tchkProps: return arg->isDict() || arg->isName();
596 case tchkSCN: return arg->isNum() || arg->isName(); 641 case tchkSCN: return arg->isNum() || arg->isName();
597 case tchkNone: return gFalse; 642 case tchkNone: return gFalse;
598 } 643 }
599 return gFalse; 644 return gFalse;
600} 645}
601 646
602int Gfx::getPos() { 647int Gfx::getPos() {
603 return parser ? parser->getPos() : -1; 648 return parser ? parser->getPos() : -1;
604} 649}
605 650
606//------------------------------------------------------------------------ 651//------------------------------------------------------------------------
607// graphics state operators 652// graphics state operators
608//------------------------------------------------------------------------ 653//------------------------------------------------------------------------
609 654
610void Gfx::opSave(Object args[], int numArgs) { 655void Gfx::opSave(Object args[], int numArgs) {
611 out->saveState(state); 656 out->saveState(state);
612 state = state->save(); 657 state = state->save();
613} 658}
614 659
615void Gfx::opRestore(Object args[], int numArgs) { 660void Gfx::opRestore(Object args[], int numArgs) {
616 state = state->restore(); 661 state = state->restore();
617 out->restoreState(state); 662 out->restoreState(state);
618} 663}
619 664
620void Gfx::opConcat(Object args[], int numArgs) { 665void Gfx::opConcat(Object args[], int numArgs) {
621 state->concatCTM(args[0].getNum(), args[1].getNum(), 666 state->concatCTM(args[0].getNum(), args[1].getNum(),
622 args[2].getNum(), args[3].getNum(), 667 args[2].getNum(), args[3].getNum(),
623 args[4].getNum(), args[5].getNum()); 668 args[4].getNum(), args[5].getNum());
624 out->updateCTM(state, args[0].getNum(), args[1].getNum(), 669 out->updateCTM(state, args[0].getNum(), args[1].getNum(),
625 args[2].getNum(), args[3].getNum(), 670 args[2].getNum(), args[3].getNum(),
626 args[4].getNum(), args[5].getNum()); 671 args[4].getNum(), args[5].getNum());
627 fontChanged = gTrue; 672 fontChanged = gTrue;
628} 673}
629 674
630void Gfx::opSetDash(Object args[], int numArgs) { 675void Gfx::opSetDash(Object args[], int numArgs) {
631 Array *a; 676 Array *a;
632 int length; 677 int length;
633 Object obj; 678 Object obj;
634 fouble *dash; 679 fouble *dash;
635 int i; 680 int i;
636 681
637 a = args[0].getArray(); 682 a = args[0].getArray();
638 length = a->getLength(); 683 length = a->getLength();
639 if (length == 0) { 684 if (length == 0) {
640 dash = NULL; 685 dash = NULL;
641 } else { 686 } else {
642 dash = (fouble *)gmalloc(length * sizeof(fouble)); 687 dash = (fouble *)gmalloc(length * sizeof(fouble));
643 for (i = 0; i < length; ++i) { 688 for (i = 0; i < length; ++i) {
644 dash[i] = a->get(i, &obj)->getNum(); 689 dash[i] = a->get(i, &obj)->getNum();
645 obj.free(); 690 obj.free();
646 } 691 }
647 } 692 }
648 state->setLineDash(dash, length, args[1].getNum()); 693 state->setLineDash(dash, length, args[1].getNum());
649 out->updateLineDash(state); 694 out->updateLineDash(state);
650} 695}
651 696
652void Gfx::opSetFlat(Object args[], int numArgs) { 697void Gfx::opSetFlat(Object args[], int numArgs) {
653 state->setFlatness((int)args[0].getNum()); 698 state->setFlatness((int)args[0].getNum());
654 out->updateFlatness(state); 699 out->updateFlatness(state);
655} 700}
656 701
657void Gfx::opSetLineJoin(Object args[], int numArgs) { 702void Gfx::opSetLineJoin(Object args[], int numArgs) {
658 state->setLineJoin(args[0].getInt()); 703 state->setLineJoin(args[0].getInt());
659 out->updateLineJoin(state); 704 out->updateLineJoin(state);
660} 705}
661 706
662void Gfx::opSetLineCap(Object args[], int numArgs) { 707void Gfx::opSetLineCap(Object args[], int numArgs) {
663 state->setLineCap(args[0].getInt()); 708 state->setLineCap(args[0].getInt());
664 out->updateLineCap(state); 709 out->updateLineCap(state);
665} 710}
666 711
667void Gfx::opSetMiterLimit(Object args[], int numArgs) { 712void Gfx::opSetMiterLimit(Object args[], int numArgs) {
668 state->setMiterLimit(args[0].getNum()); 713 state->setMiterLimit(args[0].getNum());
669 out->updateMiterLimit(state); 714 out->updateMiterLimit(state);
670} 715}
671 716
672void Gfx::opSetLineWidth(Object args[], int numArgs) { 717void Gfx::opSetLineWidth(Object args[], int numArgs) {
673 state->setLineWidth(args[0].getNum()); 718 state->setLineWidth(args[0].getNum());
674 out->updateLineWidth(state); 719 out->updateLineWidth(state);
675} 720}
676 721
677void Gfx::opSetExtGState(Object args[], int numArgs) { 722void Gfx::opSetExtGState(Object args[], int numArgs) {
678 Object obj1, obj2; 723 Object obj1, obj2;
679 724
680 if (!res->lookupGState(args[0].getName(), &obj1)) { 725 if (!res->lookupGState(args[0].getName(), &obj1)) {
681 return; 726 return;
682 } 727 }
683 if (!obj1.isDict()) { 728 if (!obj1.isDict()) {
684 error(getPos(), "ExtGState '%s' is wrong type", args[0].getName()); 729 error(getPos(), "ExtGState '%s' is wrong type", args[0].getName());
685 obj1.free(); 730 obj1.free();
686 return; 731 return;
687 } 732 }
688 if (obj1.dictLookup("ca", &obj2)->isNum()) { 733 if (obj1.dictLookup("ca", &obj2)->isNum()) {
689 state->setFillOpacity(obj2.getNum()); 734 state->setFillOpacity(obj2.getNum());
690 out->updateFillOpacity(state); 735 out->updateFillOpacity(state);
691 } 736 }
692 obj2.free(); 737 obj2.free();
693 if (obj1.dictLookup("CA", &obj2)->isNum()) { 738 if (obj1.dictLookup("CA", &obj2)->isNum()) {
694 state->setStrokeOpacity(obj2.getNum()); 739 state->setStrokeOpacity(obj2.getNum());
695 out->updateStrokeOpacity(state); 740 out->updateStrokeOpacity(state);
696 } 741 }
697 obj2.free(); 742 obj2.free();
698 obj1.free(); 743 obj1.free();
699} 744}
700 745
701void Gfx::opSetRenderingIntent(Object args[], int numArgs) { 746void Gfx::opSetRenderingIntent(Object args[], int numArgs) {
702} 747}
703 748
704//------------------------------------------------------------------------ 749//------------------------------------------------------------------------
705// color operators 750// color operators
706//------------------------------------------------------------------------ 751//------------------------------------------------------------------------
707 752
708void Gfx::opSetFillGray(Object args[], int numArgs) { 753void Gfx::opSetFillGray(Object args[], int numArgs) {
709 GfxColor color; 754 GfxColor color;
710 755
711 state->setFillPattern(NULL); 756 state->setFillPattern(NULL);
712 state->setFillColorSpace(new GfxDeviceGrayColorSpace()); 757 state->setFillColorSpace(new GfxDeviceGrayColorSpace());
713 color.c[0] = args[0].getNum(); 758 color.c[0] = args[0].getNum();
714 state->setFillColor(&color); 759 state->setFillColor(&color);
@@ -949,1513 +994,1767 @@ void Gfx::opCurveTo(Object args[], int numArgs) {
949 state->curveTo(x1, y1, x2, y2, x3, y3); 994 state->curveTo(x1, y1, x2, y2, x3, y3);
950} 995}
951 996
952void Gfx::opCurveTo1(Object args[], int numArgs) { 997void Gfx::opCurveTo1(Object args[], int numArgs) {
953 fouble x1, y1, x2, y2, x3, y3; 998 fouble x1, y1, x2, y2, x3, y3;
954 999
955 if (!state->isCurPt()) { 1000 if (!state->isCurPt()) {
956 error(getPos(), "No current point in curveto1"); 1001 error(getPos(), "No current point in curveto1");
957 return; 1002 return;
958 } 1003 }
959 x1 = state->getCurX(); 1004 x1 = state->getCurX();
960 y1 = state->getCurY(); 1005 y1 = state->getCurY();
961 x2 = args[0].getNum(); 1006 x2 = args[0].getNum();
962 y2 = args[1].getNum(); 1007 y2 = args[1].getNum();
963 x3 = args[2].getNum(); 1008 x3 = args[2].getNum();
964 y3 = args[3].getNum(); 1009 y3 = args[3].getNum();
965 state->curveTo(x1, y1, x2, y2, x3, y3); 1010 state->curveTo(x1, y1, x2, y2, x3, y3);
966} 1011}
967 1012
968void Gfx::opCurveTo2(Object args[], int numArgs) { 1013void Gfx::opCurveTo2(Object args[], int numArgs) {
969 fouble x1, y1, x2, y2, x3, y3; 1014 fouble x1, y1, x2, y2, x3, y3;
970 1015
971 if (!state->isCurPt()) { 1016 if (!state->isCurPt()) {
972 error(getPos(), "No current point in curveto2"); 1017 error(getPos(), "No current point in curveto2");
973 return; 1018 return;
974 } 1019 }
975 x1 = args[0].getNum(); 1020 x1 = args[0].getNum();
976 y1 = args[1].getNum(); 1021 y1 = args[1].getNum();
977 x2 = args[2].getNum(); 1022 x2 = args[2].getNum();
978 y2 = args[3].getNum(); 1023 y2 = args[3].getNum();
979 x3 = x2; 1024 x3 = x2;
980 y3 = y2; 1025 y3 = y2;
981 state->curveTo(x1, y1, x2, y2, x3, y3); 1026 state->curveTo(x1, y1, x2, y2, x3, y3);
982} 1027}
983 1028
984void Gfx::opRectangle(Object args[], int numArgs) { 1029void Gfx::opRectangle(Object args[], int numArgs) {
985 fouble x, y, w, h; 1030 fouble x, y, w, h;
986 1031
987 x = args[0].getNum(); 1032 x = args[0].getNum();
988 y = args[1].getNum(); 1033 y = args[1].getNum();
989 w = args[2].getNum(); 1034 w = args[2].getNum();
990 h = args[3].getNum(); 1035 h = args[3].getNum();
991 state->moveTo(x, y); 1036 state->moveTo(x, y);
992 state->lineTo(x + w, y); 1037 state->lineTo(x + w, y);
993 state->lineTo(x + w, y + h); 1038 state->lineTo(x + w, y + h);
994 state->lineTo(x, y + h); 1039 state->lineTo(x, y + h);
995 state->closePath(); 1040 state->closePath();
996} 1041}
997 1042
998void Gfx::opClosePath(Object args[], int numArgs) { 1043void Gfx::opClosePath(Object args[], int numArgs) {
999 if (!state->isCurPt()) { 1044 if (!state->isCurPt()) {
1000 error(getPos(), "No current point in closepath"); 1045 error(getPos(), "No current point in closepath");
1001 return; 1046 return;
1002 } 1047 }
1003 state->closePath(); 1048 state->closePath();
1004} 1049}
1005 1050
1006//------------------------------------------------------------------------ 1051//------------------------------------------------------------------------
1007// path painting operators 1052// path painting operators
1008//------------------------------------------------------------------------ 1053//------------------------------------------------------------------------
1009 1054
1010void Gfx::opEndPath(Object args[], int numArgs) { 1055void Gfx::opEndPath(Object args[], int numArgs) {
1011 doEndPath(); 1056 doEndPath();
1012} 1057}
1013 1058
1014void Gfx::opStroke(Object args[], int numArgs) { 1059void Gfx::opStroke(Object args[], int numArgs) {
1015 if (!state->isCurPt()) { 1060 if (!state->isCurPt()) {
1016 //error(getPos(), "No path in stroke"); 1061 //error(getPos(), "No path in stroke");
1017 return; 1062 return;
1018 } 1063 }
1019 if (state->isPath()) 1064 if (state->isPath())
1020 out->stroke(state); 1065 out->stroke(state);
1021 doEndPath(); 1066 doEndPath();
1022} 1067}
1023 1068
1024void Gfx::opCloseStroke(Object args[], int numArgs) { 1069void Gfx::opCloseStroke(Object args[], int numArgs) {
1025 if (!state->isCurPt()) { 1070 if (!state->isCurPt()) {
1026 //error(getPos(), "No path in closepath/stroke"); 1071 //error(getPos(), "No path in closepath/stroke");
1027 return; 1072 return;
1028 } 1073 }
1029 if (state->isPath()) { 1074 if (state->isPath()) {
1030 state->closePath(); 1075 state->closePath();
1031 out->stroke(state); 1076 out->stroke(state);
1032 } 1077 }
1033 doEndPath(); 1078 doEndPath();
1034} 1079}
1035 1080
1036void Gfx::opFill(Object args[], int numArgs) { 1081void Gfx::opFill(Object args[], int numArgs) {
1037 if (!state->isCurPt()) { 1082 if (!state->isCurPt()) {
1038 //error(getPos(), "No path in fill"); 1083 //error(getPos(), "No path in fill");
1039 return; 1084 return;
1040 } 1085 }
1041 if (state->isPath()) { 1086 if (state->isPath()) {
1042 if (state->getFillColorSpace()->getMode() == csPattern) { 1087 if (state->getFillColorSpace()->getMode() == csPattern) {
1043 doPatternFill(gFalse); 1088 doPatternFill(gFalse);
1044 } else { 1089 } else {
1045 out->fill(state); 1090 out->fill(state);
1046 } 1091 }
1047 } 1092 }
1048 doEndPath(); 1093 doEndPath();
1049} 1094}
1050 1095
1051void Gfx::opEOFill(Object args[], int numArgs) { 1096void Gfx::opEOFill(Object args[], int numArgs) {
1052 if (!state->isCurPt()) { 1097 if (!state->isCurPt()) {
1053 //error(getPos(), "No path in eofill"); 1098 //error(getPos(), "No path in eofill");
1054 return; 1099 return;
1055 } 1100 }
1056 if (state->isPath()) { 1101 if (state->isPath()) {
1057 if (state->getFillColorSpace()->getMode() == csPattern) { 1102 if (state->getFillColorSpace()->getMode() == csPattern) {
1058 doPatternFill(gTrue); 1103 doPatternFill(gTrue);
1059 } else { 1104 } else {
1060 out->eoFill(state); 1105 out->eoFill(state);
1061 } 1106 }
1062 } 1107 }
1063 doEndPath(); 1108 doEndPath();
1064} 1109}
1065 1110
1066void Gfx::opFillStroke(Object args[], int numArgs) { 1111void Gfx::opFillStroke(Object args[], int numArgs) {
1067 if (!state->isCurPt()) { 1112 if (!state->isCurPt()) {
1068 //error(getPos(), "No path in fill/stroke"); 1113 //error(getPos(), "No path in fill/stroke");
1069 return; 1114 return;
1070 } 1115 }
1071 if (state->isPath()) { 1116 if (state->isPath()) {
1072 if (state->getFillColorSpace()->getMode() == csPattern) { 1117 if (state->getFillColorSpace()->getMode() == csPattern) {
1073 doPatternFill(gFalse); 1118 doPatternFill(gFalse);
1074 } else { 1119 } else {
1075 out->fill(state); 1120 out->fill(state);
1076 } 1121 }
1077 out->stroke(state); 1122 out->stroke(state);
1078 } 1123 }
1079 doEndPath(); 1124 doEndPath();
1080} 1125}
1081 1126
1082void Gfx::opCloseFillStroke(Object args[], int numArgs) { 1127void Gfx::opCloseFillStroke(Object args[], int numArgs) {
1083 if (!state->isCurPt()) { 1128 if (!state->isCurPt()) {
1084 //error(getPos(), "No path in closepath/fill/stroke"); 1129 //error(getPos(), "No path in closepath/fill/stroke");
1085 return; 1130 return;
1086 } 1131 }
1087 if (state->isPath()) { 1132 if (state->isPath()) {
1088 state->closePath(); 1133 state->closePath();
1089 if (state->getFillColorSpace()->getMode() == csPattern) { 1134 if (state->getFillColorSpace()->getMode() == csPattern) {
1090 doPatternFill(gFalse); 1135 doPatternFill(gFalse);
1091 } else { 1136 } else {
1092 out->fill(state); 1137 out->fill(state);
1093 } 1138 }
1094 out->stroke(state); 1139 out->stroke(state);
1095 } 1140 }
1096 doEndPath(); 1141 doEndPath();
1097} 1142}
1098 1143
1099void Gfx::opEOFillStroke(Object args[], int numArgs) { 1144void Gfx::opEOFillStroke(Object args[], int numArgs) {
1100 if (!state->isCurPt()) { 1145 if (!state->isCurPt()) {
1101 //error(getPos(), "No path in eofill/stroke"); 1146 //error(getPos(), "No path in eofill/stroke");
1102 return; 1147 return;
1103 } 1148 }
1104 if (state->isPath()) { 1149 if (state->isPath()) {
1105 if (state->getFillColorSpace()->getMode() == csPattern) { 1150 if (state->getFillColorSpace()->getMode() == csPattern) {
1106 doPatternFill(gTrue); 1151 doPatternFill(gTrue);
1107 } else { 1152 } else {
1108 out->eoFill(state); 1153 out->eoFill(state);
1109 } 1154 }
1110 out->stroke(state); 1155 out->stroke(state);
1111 } 1156 }
1112 doEndPath(); 1157 doEndPath();
1113} 1158}
1114 1159
1115void Gfx::opCloseEOFillStroke(Object args[], int numArgs) { 1160void Gfx::opCloseEOFillStroke(Object args[], int numArgs) {
1116 if (!state->isCurPt()) { 1161 if (!state->isCurPt()) {
1117 //error(getPos(), "No path in closepath/eofill/stroke"); 1162 //error(getPos(), "No path in closepath/eofill/stroke");
1118 return; 1163 return;
1119 } 1164 }
1120 if (state->isPath()) { 1165 if (state->isPath()) {
1121 state->closePath(); 1166 state->closePath();
1122 if (state->getFillColorSpace()->getMode() == csPattern) { 1167 if (state->getFillColorSpace()->getMode() == csPattern) {
1123 doPatternFill(gTrue); 1168 doPatternFill(gTrue);
1124 } else { 1169 } else {
1125 out->eoFill(state); 1170 out->eoFill(state);
1126 } 1171 }
1127 out->stroke(state); 1172 out->stroke(state);
1128 } 1173 }
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
1154 patCS = (GfxPatternColorSpace *)state->getFillColorSpace(); 1199 patCS = (GfxPatternColorSpace *)state->getFillColorSpace();
1155 1200
1156 // get pattern 1201 // get pattern
1157 if (!(pattern = state->getFillPattern())) { 1202 if (!(pattern = state->getFillPattern())) {
1158 return; 1203 return;
1159 } 1204 }
1160 if (pattern->getType() != 1) { 1205 if (pattern->getType() != 1) {
1161 return; 1206 return;
1162 } 1207 }
1163 tPat = (GfxTilingPattern *)pattern; 1208 tPat = (GfxTilingPattern *)pattern;
1164 1209
1165 // construct a (pattern space) -> (current space) transform matrix 1210 // construct a (pattern space) -> (current space) transform matrix
1166 ctm = state->getCTM(); 1211 ctm = state->getCTM();
1167 btm = baseMatrix; 1212 btm = baseMatrix;
1168 ptm = tPat->getMatrix(); 1213 ptm = tPat->getMatrix();
1169 // iCTM = invert CTM 1214 // iCTM = invert CTM
1170 det = 1 / (ctm[0] * ctm[3] - ctm[1] * ctm[2]); 1215 det = 1 / (ctm[0] * ctm[3] - ctm[1] * ctm[2]);
1171 ictm[0] = ctm[3] * det; 1216 ictm[0] = ctm[3] * det;
1172 ictm[1] = -ctm[1] * det; 1217 ictm[1] = -ctm[1] * det;
1173 ictm[2] = -ctm[2] * det; 1218 ictm[2] = -ctm[2] * det;
1174 ictm[3] = ctm[0] * det; 1219 ictm[3] = ctm[0] * det;
1175 ictm[4] = (ctm[2] * ctm[5] - ctm[3] * ctm[4]) * det; 1220 ictm[4] = (ctm[2] * ctm[5] - ctm[3] * ctm[4]) * det;
1176 ictm[5] = (ctm[1] * ctm[4] - ctm[0] * ctm[5]) * det; 1221 ictm[5] = (ctm[1] * ctm[4] - ctm[0] * ctm[5]) * det;
1177 // m1 = PTM * BTM = PTM * base transform matrix 1222 // m1 = PTM * BTM = PTM * base transform matrix
1178 m1[0] = ptm[0] * btm[0] + ptm[1] * btm[2]; 1223 m1[0] = ptm[0] * btm[0] + ptm[1] * btm[2];
1179 m1[1] = ptm[0] * btm[1] + ptm[1] * btm[3]; 1224 m1[1] = ptm[0] * btm[1] + ptm[1] * btm[3];
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();
1213 1249
1214 // set underlying color space (for uncolored tiling patterns) 1250 // set underlying color space (for uncolored tiling patterns)
1215 if (tPat->getPaintType() == 2 && (cs = patCS->getUnder())) { 1251 if (tPat->getPaintType() == 2 && (cs = patCS->getUnder())) {
1216 state->setFillColorSpace(cs->copy()); 1252 state->setFillColorSpace(cs->copy());
1217 } else { 1253 } else {
1218 state->setFillColorSpace(new GfxDeviceGrayColorSpace()); 1254 state->setFillColorSpace(new GfxDeviceGrayColorSpace());
1219 } 1255 }
1220 state->setFillPattern(NULL); 1256 state->setFillPattern(NULL);
1221 out->updateFillColor(state); 1257 out->updateFillColor(state);
1222 1258
1223 // clip to current path 1259 // clip to current path
1224 state->clip(); 1260 state->clip();
1225 if (eoFill) { 1261 if (eoFill) {
1226 out->eoClip(state); 1262 out->eoClip(state);
1227 } else { 1263 } else {
1228 out->clip(state); 1264 out->clip(state);
1229 } 1265 }
1230 state->clearPath(); 1266 state->clearPath();
1231 1267
1232 // transform clip region bbox to pattern space 1268 // transform clip region bbox to pattern space
1233 state->getClipBBox(&cxMin, &cyMin, &cxMax, &cyMax); 1269 state->getClipBBox(&cxMin, &cyMin, &cxMax, &cyMax);
1234 xMin = xMax = cxMin * imb[0] + cyMin * imb[2] + imb[4]; 1270 xMin = xMax = cxMin * imb[0] + cyMin * imb[2] + imb[4];
1235 yMin = yMax = cxMin * imb[1] + cyMin * imb[3] + imb[5]; 1271 yMin = yMax = cxMin * imb[1] + cyMin * imb[3] + imb[5];
1236 x1 = cxMin * imb[0] + cyMax * imb[2] + imb[4]; 1272 x1 = cxMin * imb[0] + cyMax * imb[2] + imb[4];
1237 y1 = cxMin * imb[1] + cyMax * imb[3] + imb[5]; 1273 y1 = cxMin * imb[1] + cyMax * imb[3] + imb[5];
1238 if (x1 < xMin) { 1274 if (x1 < xMin) {
1239 xMin = x1; 1275 xMin = x1;
1240 } else if (x1 > xMax) { 1276 } else if (x1 > xMax) {
1241 xMax = x1; 1277 xMax = x1;
1242 } 1278 }
1243 if (y1 < yMin) { 1279 if (y1 < yMin) {
1244 yMin = y1; 1280 yMin = y1;
1245 } else if (y1 > yMax) { 1281 } else if (y1 > yMax) {
1246 yMax = y1; 1282 yMax = y1;
1247 } 1283 }
1248 x1 = cxMax * imb[0] + cyMin * imb[2] + imb[4]; 1284 x1 = cxMax * imb[0] + cyMin * imb[2] + imb[4];
1249 y1 = cxMax * imb[1] + cyMin * imb[3] + imb[5]; 1285 y1 = cxMax * imb[1] + cyMin * imb[3] + imb[5];
1250 if (x1 < xMin) { 1286 if (x1 < xMin) {
1251 xMin = x1; 1287 xMin = x1;
1252 } else if (x1 > xMax) { 1288 } else if (x1 > xMax) {
1253 xMax = x1; 1289 xMax = x1;
1254 } 1290 }
1255 if (y1 < yMin) { 1291 if (y1 < yMin) {
1256 yMin = y1; 1292 yMin = y1;
1257 } else if (y1 > yMax) { 1293 } else if (y1 > yMax) {
1258 yMax = y1; 1294 yMax = y1;
1259 } 1295 }
1260 x1 = cxMax * imb[0] + cyMax * imb[2] + imb[4]; 1296 x1 = cxMax * imb[0] + cyMax * imb[2] + imb[4];
1261 y1 = cxMax * imb[1] + cyMax * imb[3] + imb[5]; 1297 y1 = cxMax * imb[1] + cyMax * imb[3] + imb[5];
1262 if (x1 < xMin) { 1298 if (x1 < xMin) {
1263 xMin = x1; 1299 xMin = x1;
1264 } else if (x1 > xMax) { 1300 } else if (x1 > xMax) {
1265 xMax = x1; 1301 xMax = x1;
1266 } 1302 }
1267 if (y1 < yMin) { 1303 if (y1 < yMin) {
1268 yMin = y1; 1304 yMin = y1;
1269 } else if (y1 > yMax) { 1305 } else if (y1 > yMax) {
1270 yMax = y1; 1306 yMax = y1;
1271 } 1307 }
1272 1308
1273 // draw the pattern 1309 // draw the pattern
1274 //~ this should treat negative steps differently -- start at right/top 1310 //~ this should treat negative steps differently -- start at right/top
1275 //~ edge instead of left/bottom (?) 1311 //~ edge instead of left/bottom (?)
1276 xstep = fabs(tPat->getXStep()); 1312 xstep = fabs(tPat->getXStep());
1277 ystep = fabs(tPat->getYStep()); 1313 ystep = fabs(tPat->getYStep());
1278 xi0 = (int)floor(xMin / xstep); 1314 xi0 = (int)floor(xMin / xstep);
1279 xi1 = (int)ceil(xMax / xstep); 1315 xi1 = (int)ceil(xMax / xstep);
1280 yi0 = (int)floor(yMin / ystep); 1316 yi0 = (int)floor(yMin / ystep);
1281 yi1 = (int)ceil(yMax / ystep); 1317 yi1 = (int)ceil(yMax / ystep);
1282 for (i = 0; i < 4; ++i) { 1318 for (i = 0; i < 4; ++i) {
1283 m1[i] = m[i]; 1319 m1[i] = m[i];
1284 } 1320 }
1285 for (yi = yi0; yi < yi1; ++yi) { 1321 for (yi = yi0; yi < yi1; ++yi) {
1286 for (xi = xi0; xi < xi1; ++xi) { 1322 for (xi = xi0; xi < xi1; ++xi) {
1287 x = xi * xstep; 1323 x = xi * xstep;
1288 y = yi * ystep; 1324 y = yi * ystep;
1289 m1[4] = x * m[0] + y * m[2] + m[4]; 1325 m1[4] = x * m[0] + y * m[2] + m[4];
1290 m1[5] = x * m[1] + y * m[3] + m[5]; 1326 m1[5] = x * m[1] + y * m[3] + m[5];
1291 doForm1(tPat->getContentStream(), tPat->getResDict(), 1327 doForm1(tPat->getContentStream(), tPat->getResDict(),
1292 m1, tPat->getBBox()); 1328 m1, tPat->getBBox());
1293 } 1329 }
1294 } 1330 }
1295 1331
1296 // restore graphics state 1332 // restore graphics state
1297 state = state->restore(); 1333 state = state->restore();
1298 out->restoreState(state); 1334 out->restoreState(state);
1299} 1335}
1300 1336
1301void Gfx::opShFill(Object args[], int numArgs) { 1337void Gfx::opShFill(Object args[], int numArgs) {
1302 GfxShading *shading; 1338 GfxShading *shading;
1303 fouble xMin, yMin, xMax, yMax; 1339 fouble xMin, yMin, xMax, yMax;
1304 1340
1305 if (!(shading = res->lookupShading(args[0].getName()))) { 1341 if (!(shading = res->lookupShading(args[0].getName()))) {
1306 return; 1342 return;
1307 } 1343 }
1308 1344
1309 // save current graphics state 1345 // save current graphics state
1310 out->saveState(state); 1346 out->saveState(state);
1311 state = state->save(); 1347 state = state->save();
1312 1348
1313 // clip to bbox 1349 // clip to bbox
1314 if (shading->getHasBBox()) { 1350 if (shading->getHasBBox()) {
1315 shading->getBBox(&xMin, &yMin, &xMax, &yMax); 1351 shading->getBBox(&xMin, &yMin, &xMax, &yMax);
1316 state->moveTo(xMin, yMin); 1352 state->moveTo(xMin, yMin);
1317 state->lineTo(xMax, yMin); 1353 state->lineTo(xMax, yMin);
1318 state->lineTo(xMax, yMax); 1354 state->lineTo(xMax, yMax);
1319 state->lineTo(xMin, yMax); 1355 state->lineTo(xMin, yMax);
1320 state->closePath(); 1356 state->closePath();
1321 state->clip(); 1357 state->clip();
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) {
1420 tMax = t; 1410 tMax = t;
1421 } 1411 }
1422 t = ((xMax - x0) * dx + (yMin - y0) * dy) * mul; 1412 t = ((xMax - x0) * dx + (yMin - y0) * dy) * mul;
1423 if (t < tMin) { 1413 if (t < tMin) {
1424 tMin = t; 1414 tMin = t;
1425 } else if (t > tMax) { 1415 } else if (t > tMax) {
1426 tMax = t; 1416 tMax = t;
1427 } 1417 }
1428 t = ((xMax - x0) * dx + (yMax - y0) * dy) * mul; 1418 t = ((xMax - x0) * dx + (yMax - y0) * dy) * mul;
1429 if (t < tMin) { 1419 if (t < tMin) {
1430 tMin = t; 1420 tMin = t;
1431 } else if (t > tMax) { 1421 } else if (t > tMax) {
1432 tMax = t; 1422 tMax = t;
1433 } 1423 }
1434 if (tMin < 0 && !shading->getExtend0()) { 1424 if (tMin < 0 && !shading->getExtend0()) {
1435 tMin = 0; 1425 tMin = 0;
1436 } 1426 }
1437 if (tMax > 1 && !shading->getExtend1()) { 1427 if (tMax > 1 && !shading->getExtend1()) {
1438 tMax = 1; 1428 tMax = 1;
1439 } 1429 }
1440 1430
1441 // get the function domain 1431 // get the function domain
1442 t0 = shading->getDomain0(); 1432 t0 = shading->getDomain0();
1443 t1 = shading->getDomain1(); 1433 t1 = shading->getDomain1();
1444 1434
1445 // Traverse the t axis and do the shading. 1435 // Traverse the t axis and do the shading.
1446 // 1436 //
1447 // For each point (tx, ty) on the t axis, consider a line through 1437 // For each point (tx, ty) on the t axis, consider a line through
1448 // that point perpendicular to the t axis: 1438 // that point perpendicular to the t axis:
1449 // 1439 //
1450 // x(s) = tx + s * -dy --> s = (x - tx) / -dy 1440 // x(s) = tx + s * -dy --> s = (x - tx) / -dy
1451 // y(s) = ty + s * dx --> s = (y - ty) / dx 1441 // y(s) = ty + s * dx --> s = (y - ty) / dx
1452 // 1442 //
1453 // Then look at the intersection of this line with the bounding box 1443 // Then look at the intersection of this line with the bounding box
1454 // (xMin, yMin, xMax, yMax). In the general case, there are four 1444 // (xMin, yMin, xMax, yMax). In the general case, there are four
1455 // intersection points: 1445 // intersection points:
1456 // 1446 //
1457 // s0 = (xMin - tx) / -dy 1447 // s0 = (xMin - tx) / -dy
1458 // s1 = (xMax - tx) / -dy 1448 // s1 = (xMax - tx) / -dy
1459 // s2 = (yMin - ty) / dx 1449 // s2 = (yMin - ty) / dx
1460 // s3 = (yMax - ty) / dx 1450 // s3 = (yMax - ty) / dx
1461 // 1451 //
1462 // and we want the middle two s values. 1452 // and we want the middle two s values.
1463 // 1453 //
1464 // In the case where dx = 0, take s0 and s1; in the case where dy = 1454 // In the case where dx = 0, take s0 and s1; in the case where dy =
1465 // 0, take s2 and s3. 1455 // 0, take s2 and s3.
1466 // 1456 //
1467 // Each filled polygon is bounded by two of these line segments 1457 // Each filled polygon is bounded by two of these line segments
1468 // perpdendicular to the t axis. 1458 // perpdendicular to the t axis.
1469 // 1459 //
1470 // The t axis is bisected into smaller regions until the color 1460 // The t axis is bisected into smaller regions until the color
1471 // difference across a region is small enough, and then the region 1461 // difference across a region is small enough, and then the region
1472 // is painted with a single color. 1462 // is painted with a single color.
1473 1463
1474 // set up 1464 // set up
1475 nComps = shading->getColorSpace()->getNComps(); 1465 nComps = shading->getColorSpace()->getNComps();
1476 ta[0] = tMin; 1466 ta[0] = tMin;
1477 ta[axialMaxSplits] = tMax; 1467 ta[axialMaxSplits] = tMax;
1478 next[0] = axialMaxSplits; 1468 next[0] = axialMaxSplits;
1479 1469
1480 // compute the color at t = tMin 1470 // compute the color at t = tMin
1481 if (tMin < 0) { 1471 if (tMin < 0) {
1482 tt = t0; 1472 tt = t0;
1483 } else if (tMin > 1) { 1473 } else if (tMin > 1) {
1484 tt = t1; 1474 tt = t1;
1485 } else { 1475 } else {
1486 tt = t0 + (t1 - t0) * tMin; 1476 tt = t0 + (t1 - t0) * tMin;
1487 } 1477 }
1488 shading->getColor(tt, &color0); 1478 shading->getColor(tt, &color0);
1489 1479
1490 // compute the coordinates of the point on the t axis at t = tMin; 1480 // compute the coordinates of the point on the t axis at t = tMin;
1491 // then compute the intersection of the perpendicular line with the 1481 // then compute the intersection of the perpendicular line with the
1492 // bounding box 1482 // bounding box
1493 tx = x0 + tMin * dx; 1483 tx = x0 + tMin * dx;
1494 ty = y0 + tMin * dy; 1484 ty = y0 + tMin * dy;
1495 if (dx == 0 && dy == 0) { 1485 if (dx == 0 && dy == 0) {
1496 sMin = sMax = 0; 1486 sMin = sMax = 0;
1497 } if (dx == 0) { 1487 } if (dx == 0) {
1498 sMin = (xMin - tx) / -dy; 1488 sMin = (xMin - tx) / -dy;
1499 sMax = (xMax - tx) / -dy; 1489 sMax = (xMax - tx) / -dy;
1500 if (sMin > sMax) { tmp = sMin; sMin = sMax; sMax = tmp; } 1490 if (sMin > sMax) { tmp = sMin; sMin = sMax; sMax = tmp; }
1501 } else if (dy == 0) { 1491 } else if (dy == 0) {
1502 sMin = (yMin - ty) / dx; 1492 sMin = (yMin - ty) / dx;
1503 sMax = (yMax - ty) / dx; 1493 sMax = (yMax - ty) / dx;
1504 if (sMin > sMax) { tmp = sMin; sMin = sMax; sMax = tmp; } 1494 if (sMin > sMax) { tmp = sMin; sMin = sMax; sMax = tmp; }
1505 } else { 1495 } else {
1506 s[0] = (yMin - ty) / dx; 1496 s[0] = (yMin - ty) / dx;
1507 s[1] = (yMax - ty) / dx; 1497 s[1] = (yMax - ty) / dx;
1508 s[2] = (xMin - tx) / -dy; 1498 s[2] = (xMin - tx) / -dy;
1509 s[3] = (xMax - tx) / -dy; 1499 s[3] = (xMax - tx) / -dy;
1510 for (j = 0; j < 3; ++j) { 1500 for (j = 0; j < 3; ++j) {
1511 kk = j; 1501 kk = j;
1512 for (k = j + 1; k < 4; ++k) { 1502 for (k = j + 1; k < 4; ++k) {
1513 if (s[k] < s[kk]) { 1503 if (s[k] < s[kk]) {
1514 kk = k; 1504 kk = k;
1515 } 1505 }
1516 } 1506 }
1517 tmp = s[j]; s[j] = s[kk]; s[kk] = tmp; 1507 tmp = s[j]; s[j] = s[kk]; s[kk] = tmp;
1518 } 1508 }
1519 sMin = s[1]; 1509 sMin = s[1];
1520 sMax = s[2]; 1510 sMax = s[2];
1521 } 1511 }
1522 ux0 = tx - sMin * dy; 1512 ux0 = tx - sMin * dy;
1523 uy0 = ty + sMin * dx; 1513 uy0 = ty + sMin * dx;
1524 vx0 = tx - sMax * dy; 1514 vx0 = tx - sMax * dy;
1525 vy0 = ty + sMax * dx; 1515 vy0 = ty + sMax * dx;
1526 1516
1527 i = 0; 1517 i = 0;
1528 while (i < axialMaxSplits) { 1518 while (i < axialMaxSplits) {
1529 1519
1530 // bisect until color difference is small enough or we hit the 1520 // bisect until color difference is small enough or we hit the
1531 // bisection limit 1521 // bisection limit
1532 j = next[i]; 1522 j = next[i];
1533 while (j > i + 1) { 1523 while (j > i + 1) {
1534 if (ta[j] < 0) { 1524 if (ta[j] < 0) {
1535 tt = t0; 1525 tt = t0;
1536 } else if (ta[j] > 1) { 1526 } else if (ta[j] > 1) {
1537 tt = t1; 1527 tt = t1;
1538 } else { 1528 } else {
1539 tt = t0 + (t1 - t0) * ta[j]; 1529 tt = t0 + (t1 - t0) * ta[j];
1540 } 1530 }
1541 shading->getColor(tt, &color1); 1531 shading->getColor(tt, &color1);
1542 for (k = 0; k < nComps; ++k) { 1532 for (k = 0; k < nComps; ++k) {
1543 if (fabs(color1.c[k] - color0.c[k]) > axialColorDelta) { 1533 if (fabs(color1.c[k] - color0.c[k]) > axialColorDelta) {
1544 break; 1534 break;
1545 } 1535 }
1546 } 1536 }
1547 if (k == nComps) { 1537 if (k == nComps) {
1548 break; 1538 break;
1549 } 1539 }
1550 k = (i + j) / 2; 1540 k = (i + j) / 2;
1551 ta[k] = 0.5 * (ta[i] + ta[j]); 1541 ta[k] = 0.5 * (ta[i] + ta[j]);
1552 next[i] = k; 1542 next[i] = k;
1553 next[k] = j; 1543 next[k] = j;
1554 j = k; 1544 j = k;
1555 } 1545 }
1556 1546
1557 // use the average of the colors of the two sides of the region 1547 // use the average of the colors of the two sides of the region
1558 for (k = 0; k < nComps; ++k) { 1548 for (k = 0; k < nComps; ++k) {
1559 color0.c[k] = 0.5 * (color0.c[k] + color1.c[k]); 1549 color0.c[k] = 0.5 * (color0.c[k] + color1.c[k]);
1560 } 1550 }
1561 1551
1562 // compute the coordinates of the point on the t axis; then 1552 // compute the coordinates of the point on the t axis; then
1563 // compute the intersection of the perpendicular line with the 1553 // compute the intersection of the perpendicular line with the
1564 // bounding box 1554 // bounding box
1565 tx = x0 + ta[j] * dx; 1555 tx = x0 + ta[j] * dx;
1566 ty = y0 + ta[j] * dy; 1556 ty = y0 + ta[j] * dy;
1567 if (dx == 0 && dy == 0) { 1557 if (dx == 0 && dy == 0) {
1568 sMin = sMax = 0; 1558 sMin = sMax = 0;
1569 } if (dx == 0) { 1559 } if (dx == 0) {
1570 sMin = (xMin - tx) / -dy; 1560 sMin = (xMin - tx) / -dy;
1571 sMax = (xMax - tx) / -dy; 1561 sMax = (xMax - tx) / -dy;
1572 if (sMin > sMax) { tmp = sMin; sMin = sMax; sMax = tmp; } 1562 if (sMin > sMax) { tmp = sMin; sMin = sMax; sMax = tmp; }
1573 } else if (dy == 0) { 1563 } else if (dy == 0) {
1574 sMin = (yMin - ty) / dx; 1564 sMin = (yMin - ty) / dx;
1575 sMax = (yMax - ty) / dx; 1565 sMax = (yMax - ty) / dx;
1576 if (sMin > sMax) { tmp = sMin; sMin = sMax; sMax = tmp; } 1566 if (sMin > sMax) { tmp = sMin; sMin = sMax; sMax = tmp; }
1577 } else { 1567 } else {
1578 s[0] = (yMin - ty) / dx; 1568 s[0] = (yMin - ty) / dx;
1579 s[1] = (yMax - ty) / dx; 1569 s[1] = (yMax - ty) / dx;
1580 s[2] = (xMin - tx) / -dy; 1570 s[2] = (xMin - tx) / -dy;
1581 s[3] = (xMax - tx) / -dy; 1571 s[3] = (xMax - tx) / -dy;
1582 for (j = 0; j < 3; ++j) { 1572 for (j = 0; j < 3; ++j) {
1583 kk = j; 1573 kk = j;
1584 for (k = j + 1; k < 4; ++k) { 1574 for (k = j + 1; k < 4; ++k) {
1585 if (s[k] < s[kk]) { 1575 if (s[k] < s[kk]) {
1586 kk = k; 1576 kk = k;
1587 } 1577 }
1588 } 1578 }
1589 tmp = s[j]; s[j] = s[kk]; s[kk] = tmp; 1579 tmp = s[j]; s[j] = s[kk]; s[kk] = tmp;
1590 } 1580 }
1591 sMin = s[1]; 1581 sMin = s[1];
1592 sMax = s[2]; 1582 sMax = s[2];
1593 } 1583 }
1594 ux1 = tx - sMin * dy; 1584 ux1 = tx - sMin * dy;
1595 uy1 = ty + sMin * dx; 1585 uy1 = ty + sMin * dx;
1596 vx1 = tx - sMax * dy; 1586 vx1 = tx - sMax * dy;
1597 vy1 = ty + sMax * dx; 1587 vy1 = ty + sMax * dx;
1598 1588
1599 // set the color 1589 // set the color
1600 state->setFillColor(&color0); 1590 state->setFillColor(&color0);
1601 out->updateFillColor(state); 1591 out->updateFillColor(state);
1602 1592
1603 // fill the region 1593 // fill the region
1604 state->moveTo(ux0, uy0); 1594 state->moveTo(ux0, uy0);
1605 state->lineTo(vx0, vy0); 1595 state->lineTo(vx0, vy0);
1606 state->lineTo(vx1, vy1); 1596 state->lineTo(vx1, vy1);
1607 state->lineTo(ux1, uy1); 1597 state->lineTo(ux1, uy1);
1608 state->closePath(); 1598 state->closePath();
1609 out->fill(state); 1599 out->fill(state);
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}
1634 1820
1635//------------------------------------------------------------------------ 1821//------------------------------------------------------------------------
1636// path clipping operators 1822// path clipping operators
1637//------------------------------------------------------------------------ 1823//------------------------------------------------------------------------
1638 1824
1639void Gfx::opClip(Object args[], int numArgs) { 1825void Gfx::opClip(Object args[], int numArgs) {
1640 clip = clipNormal; 1826 clip = clipNormal;
1641} 1827}
1642 1828
1643void Gfx::opEOClip(Object args[], int numArgs) { 1829void Gfx::opEOClip(Object args[], int numArgs) {
1644 clip = clipEO; 1830 clip = clipEO;
1645} 1831}
1646 1832
1647//------------------------------------------------------------------------ 1833//------------------------------------------------------------------------
1648// text object operators 1834// text object operators
1649//------------------------------------------------------------------------ 1835//------------------------------------------------------------------------
1650 1836
1651void Gfx::opBeginText(Object args[], int numArgs) { 1837void Gfx::opBeginText(Object args[], int numArgs) {
1652 state->setTextMat(1, 0, 0, 1, 0, 0); 1838 state->setTextMat(1, 0, 0, 1, 0, 0);
1653 state->textMoveTo(0, 0); 1839 state->textMoveTo(0, 0);
1654 out->updateTextMat(state); 1840 out->updateTextMat(state);
1655 out->updateTextPos(state); 1841 out->updateTextPos(state);
1656 fontChanged = gTrue; 1842 fontChanged = gTrue;
1657} 1843}
1658 1844
1659void Gfx::opEndText(Object args[], int numArgs) { 1845void Gfx::opEndText(Object args[], int numArgs) {
1660} 1846}
1661 1847
1662//------------------------------------------------------------------------ 1848//------------------------------------------------------------------------
1663// text state operators 1849// text state operators
1664//------------------------------------------------------------------------ 1850//------------------------------------------------------------------------
1665 1851
1666void Gfx::opSetCharSpacing(Object args[], int numArgs) { 1852void Gfx::opSetCharSpacing(Object args[], int numArgs) {
1667 state->setCharSpace(args[0].getNum()); 1853 state->setCharSpace(args[0].getNum());
1668 out->updateCharSpace(state); 1854 out->updateCharSpace(state);
1669} 1855}
1670 1856
1671void Gfx::opSetFont(Object args[], int numArgs) { 1857void Gfx::opSetFont(Object args[], int numArgs) {
1672 GfxFont *font; 1858 GfxFont *font;
1673 1859
1674 if (!(font = res->lookupFont(args[0].getName()))) { 1860 if (!(font = res->lookupFont(args[0].getName()))) {
1675 return; 1861 return;
1676 } 1862 }
1677 if (printCommands) { 1863 if (printCommands) {
1678 printf(" font: tag=%s name='%s' %g\n", 1864 printf(" font: tag=%s name='%s' %g\n",
1679 font->getTag()->getCString(), 1865 font->getTag()->getCString(),
1680 font->getName() ? font->getName()->getCString() : "???", 1866 font->getName() ? font->getName()->getCString() : "???",
1681 args[1].getNum()); 1867 args[1].getNum());
1682 fflush(stdout); 1868 fflush(stdout);
1683 } 1869 }
1684 state->setFont(font, args[1].getNum()); 1870 state->setFont(font, args[1].getNum());
1685 fontChanged = gTrue; 1871 fontChanged = gTrue;
1686} 1872}
1687 1873
1688void Gfx::opSetTextLeading(Object args[], int numArgs) { 1874void Gfx::opSetTextLeading(Object args[], int numArgs) {
1689 state->setLeading(args[0].getNum()); 1875 state->setLeading(args[0].getNum());
1690} 1876}
1691 1877
1692void Gfx::opSetTextRender(Object args[], int numArgs) { 1878void Gfx::opSetTextRender(Object args[], int numArgs) {
1693 state->setRender(args[0].getInt()); 1879 state->setRender(args[0].getInt());
1694 out->updateRender(state); 1880 out->updateRender(state);
1695} 1881}
1696 1882
1697void Gfx::opSetTextRise(Object args[], int numArgs) { 1883void Gfx::opSetTextRise(Object args[], int numArgs) {
1698 state->setRise(args[0].getNum()); 1884 state->setRise(args[0].getNum());
1699 out->updateRise(state); 1885 out->updateRise(state);
1700} 1886}
1701 1887
1702void Gfx::opSetWordSpacing(Object args[], int numArgs) { 1888void Gfx::opSetWordSpacing(Object args[], int numArgs) {
1703 state->setWordSpace(args[0].getNum()); 1889 state->setWordSpace(args[0].getNum());
1704 out->updateWordSpace(state); 1890 out->updateWordSpace(state);
1705} 1891}
1706 1892
1707void Gfx::opSetHorizScaling(Object args[], int numArgs) { 1893void Gfx::opSetHorizScaling(Object args[], int numArgs) {
1708 state->setHorizScaling(args[0].getNum()); 1894 state->setHorizScaling(args[0].getNum());
1709 out->updateHorizScaling(state); 1895 out->updateHorizScaling(state);
1710 fontChanged = gTrue; 1896 fontChanged = gTrue;
1711} 1897}
1712 1898
1713//------------------------------------------------------------------------ 1899//------------------------------------------------------------------------
1714// text positioning operators 1900// text positioning operators
1715//------------------------------------------------------------------------ 1901//------------------------------------------------------------------------
1716 1902
1717void Gfx::opTextMove(Object args[], int numArgs) { 1903void Gfx::opTextMove(Object args[], int numArgs) {
1718 fouble tx, ty; 1904 fouble tx, ty;
1719 1905
1720 tx = state->getLineX() + args[0].getNum(); 1906 tx = state->getLineX() + args[0].getNum();
1721 ty = state->getLineY() + args[1].getNum(); 1907 ty = state->getLineY() + args[1].getNum();
1722 state->textMoveTo(tx, ty); 1908 state->textMoveTo(tx, ty);
1723 out->updateTextPos(state); 1909 out->updateTextPos(state);
1724} 1910}
1725 1911
1726void Gfx::opTextMoveSet(Object args[], int numArgs) { 1912void Gfx::opTextMoveSet(Object args[], int numArgs) {
1727 fouble tx, ty; 1913 fouble tx, ty;
1728 1914
1729 tx = state->getLineX() + args[0].getNum(); 1915 tx = state->getLineX() + args[0].getNum();
1730 ty = args[1].getNum(); 1916 ty = args[1].getNum();
1731 state->setLeading(-ty); 1917 state->setLeading(-ty);
1732 ty += state->getLineY(); 1918 ty += state->getLineY();
1733 state->textMoveTo(tx, ty); 1919 state->textMoveTo(tx, ty);
1734 out->updateTextPos(state); 1920 out->updateTextPos(state);
1735} 1921}
1736 1922
1737void Gfx::opSetTextMatrix(Object args[], int numArgs) { 1923void Gfx::opSetTextMatrix(Object args[], int numArgs) {
1738 state->setTextMat(args[0].getNum(), args[1].getNum(), 1924 state->setTextMat(args[0].getNum(), args[1].getNum(),
1739 args[2].getNum(), args[3].getNum(), 1925 args[2].getNum(), args[3].getNum(),
1740 args[4].getNum(), args[5].getNum()); 1926 args[4].getNum(), args[5].getNum());
1741 state->textMoveTo(0, 0); 1927 state->textMoveTo(0, 0);
1742 out->updateTextMat(state); 1928 out->updateTextMat(state);
1743 out->updateTextPos(state); 1929 out->updateTextPos(state);
1744 fontChanged = gTrue; 1930 fontChanged = gTrue;
1745} 1931}
1746 1932
1747void Gfx::opTextNextLine(Object args[], int numArgs) { 1933void Gfx::opTextNextLine(Object args[], int numArgs) {
1748 fouble tx, ty; 1934 fouble tx, ty;
1749 1935
1750 tx = state->getLineX(); 1936 tx = state->getLineX();
1751 ty = state->getLineY() - state->getLeading(); 1937 ty = state->getLineY() - state->getLeading();
1752 state->textMoveTo(tx, ty); 1938 state->textMoveTo(tx, ty);
1753 out->updateTextPos(state); 1939 out->updateTextPos(state);
1754} 1940}
1755 1941
1756//------------------------------------------------------------------------ 1942//------------------------------------------------------------------------
1757// text string operators 1943// text string operators
1758//------------------------------------------------------------------------ 1944//------------------------------------------------------------------------
1759 1945
1760void Gfx::opShowText(Object args[], int numArgs) { 1946void Gfx::opShowText(Object args[], int numArgs) {
1761 if (!state->getFont()) { 1947 if (!state->getFont()) {
1762 error(getPos(), "No font in show"); 1948 error(getPos(), "No font in show");
1763 return; 1949 return;
1764 } 1950 }
1765 doShowText(args[0].getString()); 1951 doShowText(args[0].getString());
1766} 1952}
1767 1953
1768void Gfx::opMoveShowText(Object args[], int numArgs) { 1954void Gfx::opMoveShowText(Object args[], int numArgs) {
1769 fouble tx, ty; 1955 fouble tx, ty;
1770 1956
1771 if (!state->getFont()) { 1957 if (!state->getFont()) {
1772 error(getPos(), "No font in move/show"); 1958 error(getPos(), "No font in move/show");
1773 return; 1959 return;
1774 } 1960 }
1775 tx = state->getLineX(); 1961 tx = state->getLineX();
1776 ty = state->getLineY() - state->getLeading(); 1962 ty = state->getLineY() - state->getLeading();
1777 state->textMoveTo(tx, ty); 1963 state->textMoveTo(tx, ty);
1778 out->updateTextPos(state); 1964 out->updateTextPos(state);
1779 doShowText(args[0].getString()); 1965 doShowText(args[0].getString());
1780} 1966}
1781 1967
1782void Gfx::opMoveSetShowText(Object args[], int numArgs) { 1968void Gfx::opMoveSetShowText(Object args[], int numArgs) {
1783 fouble tx, ty; 1969 fouble tx, ty;
1784 1970
1785 if (!state->getFont()) { 1971 if (!state->getFont()) {
1786 error(getPos(), "No font in move/set/show"); 1972 error(getPos(), "No font in move/set/show");
1787 return; 1973 return;
1788 } 1974 }
1789 state->setWordSpace(args[0].getNum()); 1975 state->setWordSpace(args[0].getNum());
1790 state->setCharSpace(args[1].getNum()); 1976 state->setCharSpace(args[1].getNum());
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 }
1983#if OPI_SUPPORT 2206#if OPI_SUPPORT
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
2008 obj1.free(); 2235 obj1.free();
2009} 2236}
2010 2237
2011void Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) { 2238void Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {
2012 Dict *dict; 2239 Dict *dict;
2013 int width, height; 2240 int width, height;
2014 int bits; 2241 int bits;
2015 GBool mask; 2242 GBool mask;
2016 GBool invert; 2243 GBool invert;
2017 GfxColorSpace *colorSpace; 2244 GfxColorSpace *colorSpace;
2018 GfxImageColorMap *colorMap; 2245 GfxImageColorMap *colorMap;
2019 Object maskObj; 2246 Object maskObj;
2020 GBool haveMask; 2247 GBool haveMask;
2021 int maskColors[2*gfxColorMaxComps]; 2248 int maskColors[2*gfxColorMaxComps];
2022 Object obj1, obj2; 2249 Object obj1, obj2;
2023 int i; 2250 int i;
2024 2251
2025 // get stream dict 2252 // get stream dict
2026 dict = str->getDict(); 2253 dict = str->getDict();
2027 2254
2028 // get size 2255 // get size
2029 dict->lookup("Width", &obj1); 2256 dict->lookup("Width", &obj1);
2030 if (obj1.isNull()) { 2257 if (obj1.isNull()) {
2031 obj1.free(); 2258 obj1.free();
2032 dict->lookup("W", &obj1); 2259 dict->lookup("W", &obj1);
2033 } 2260 }
2034 if (!obj1.isInt()) 2261 if (!obj1.isInt())
2035 goto err2; 2262 goto err2;
2036 width = obj1.getInt(); 2263 width = obj1.getInt();
2037 obj1.free(); 2264 obj1.free();
2038 dict->lookup("Height", &obj1); 2265 dict->lookup("Height", &obj1);
2039 if (obj1.isNull()) { 2266 if (obj1.isNull()) {
2040 obj1.free(); 2267 obj1.free();
2041 dict->lookup("H", &obj1); 2268 dict->lookup("H", &obj1);
2042 } 2269 }
2043 if (!obj1.isInt()) 2270 if (!obj1.isInt())
2044 goto err2; 2271 goto err2;
2045 height = obj1.getInt(); 2272 height = obj1.getInt();
2046 obj1.free(); 2273 obj1.free();
2047 2274
2048 // image or mask? 2275 // image or mask?
2049 dict->lookup("ImageMask", &obj1); 2276 dict->lookup("ImageMask", &obj1);
2050 if (obj1.isNull()) { 2277 if (obj1.isNull()) {
2051 obj1.free(); 2278 obj1.free();
2052 dict->lookup("IM", &obj1); 2279 dict->lookup("IM", &obj1);
2053 } 2280 }
2054 mask = gFalse; 2281 mask = gFalse;
2055 if (obj1.isBool()) 2282 if (obj1.isBool())
2056 mask = obj1.getBool(); 2283 mask = obj1.getBool();
2057 else if (!obj1.isNull()) 2284 else if (!obj1.isNull())
2058 goto err2; 2285 goto err2;
2059 obj1.free(); 2286 obj1.free();
2060 2287
2061 // bit depth 2288 // bit depth
2062 dict->lookup("BitsPerComponent", &obj1); 2289 dict->lookup("BitsPerComponent", &obj1);
2063 if (obj1.isNull()) { 2290 if (obj1.isNull()) {
2064 obj1.free(); 2291 obj1.free();
2065 dict->lookup("BPC", &obj1); 2292 dict->lookup("BPC", &obj1);
2066 } 2293 }
2067 if (!obj1.isInt()) 2294 if (!obj1.isInt())
2068 goto err2; 2295 goto err2;
2069 bits = obj1.getInt(); 2296 bits = obj1.getInt();
2070 obj1.free(); 2297 obj1.free();
2071 2298
2072 // display a mask 2299 // display a mask
2073 if (mask) { 2300 if (mask) {
2074 2301
2075 // check for inverted mask 2302 // check for inverted mask
2076 if (bits != 1) 2303 if (bits != 1)
2077 goto err1; 2304 goto err1;
2078 invert = gFalse; 2305 invert = gFalse;
2079 dict->lookup("Decode", &obj1); 2306 dict->lookup("Decode", &obj1);
2080 if (obj1.isNull()) { 2307 if (obj1.isNull()) {
2081 obj1.free(); 2308 obj1.free();
2082 dict->lookup("D", &obj1); 2309 dict->lookup("D", &obj1);
2083 } 2310 }
2084 if (obj1.isArray()) { 2311 if (obj1.isArray()) {
2085 obj1.arrayGet(0, &obj2); 2312 obj1.arrayGet(0, &obj2);
2086 if (obj2.isInt() && obj2.getInt() == 1) 2313 if (obj2.isInt() && obj2.getInt() == 1)
2087 invert = gTrue; 2314 invert = gTrue;
2088 obj2.free(); 2315 obj2.free();
2089 } else if (!obj1.isNull()) { 2316 } else if (!obj1.isNull()) {
2090 goto err2; 2317 goto err2;
2091 } 2318 }
2092 obj1.free(); 2319 obj1.free();
2093 2320
2094 // draw it 2321 // draw it
2095 out->drawImageMask(state, ref, str, width, height, invert, inlineImg); 2322 out->drawImageMask(state, ref, str, width, height, invert, inlineImg);
2096 2323
2097 } else { 2324 } else {
2098 2325
2099 // get color space and color map 2326 // get color space and color map
2100 dict->lookup("ColorSpace", &obj1); 2327 dict->lookup("ColorSpace", &obj1);
2101 if (obj1.isNull()) { 2328 if (obj1.isNull()) {
2102 obj1.free(); 2329 obj1.free();
2103 dict->lookup("CS", &obj1); 2330 dict->lookup("CS", &obj1);
2104 } 2331 }
2105 if (obj1.isName()) { 2332 if (obj1.isName()) {
2106 res->lookupColorSpace(obj1.getName(), &obj2); 2333 res->lookupColorSpace(obj1.getName(), &obj2);
2107 if (!obj2.isNull()) { 2334 if (!obj2.isNull()) {
2108 obj1.free(); 2335 obj1.free();
2109 obj1 = obj2; 2336 obj1 = obj2;
2110 } else { 2337 } else {
2111 obj2.free(); 2338 obj2.free();
2112 } 2339 }
2113 } 2340 }
2114 colorSpace = GfxColorSpace::parse(&obj1); 2341 colorSpace = GfxColorSpace::parse(&obj1);
2115 obj1.free(); 2342 obj1.free();
2116 if (!colorSpace) { 2343 if (!colorSpace) {
2117 goto err1; 2344 goto err1;
2118 } 2345 }
2119 dict->lookup("Decode", &obj1); 2346 dict->lookup("Decode", &obj1);
2120 if (obj1.isNull()) { 2347 if (obj1.isNull()) {
2121 obj1.free(); 2348 obj1.free();
2122 dict->lookup("D", &obj1); 2349 dict->lookup("D", &obj1);
2123 } 2350 }
2124 colorMap = new GfxImageColorMap(bits, &obj1, colorSpace); 2351 colorMap = new GfxImageColorMap(bits, &obj1, colorSpace);
2125 obj1.free(); 2352 obj1.free();
2126 if (!colorMap->isOk()) { 2353 if (!colorMap->isOk()) {
2127 delete colorMap; 2354 delete colorMap;
2128 goto err1; 2355 goto err1;
2129 } 2356 }
2130 2357
2131 // get the mask 2358 // get the mask
2132 haveMask = gFalse; 2359 haveMask = gFalse;
2133 dict->lookup("Mask", &maskObj); 2360 dict->lookup("Mask", &maskObj);
2134 if (maskObj.isArray()) { 2361 if (maskObj.isArray()) {
2135 for (i = 0; i < maskObj.arrayGetLength(); ++i) { 2362 for (i = 0; i < maskObj.arrayGetLength(); ++i) {
2136 maskObj.arrayGet(i, &obj1); 2363 maskObj.arrayGet(i, &obj1);
2137 maskColors[i] = obj1.getInt(); 2364 maskColors[i] = obj1.getInt();
2138 obj1.free(); 2365 obj1.free();
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];
2163 Object resObj; 2395 Object resObj;
2164 Dict *resDict; 2396 Dict *resDict;
2165 Object obj1; 2397 Object obj1;
2166 int i; 2398 int i;
2167 2399
2168 // get stream dict 2400 // get stream dict
2169 dict = str->streamGetDict(); 2401 dict = str->streamGetDict();
2170 2402
2171 // check form type 2403 // check form type
2172 dict->lookup("FormType", &obj1); 2404 dict->lookup("FormType", &obj1);
2173 if (!(obj1.isInt() && obj1.getInt() == 1)) { 2405 if (!(obj1.isInt() && obj1.getInt() == 1)) {
2174 error(getPos(), "Unknown form type"); 2406 error(getPos(), "Unknown form type");
2175 } 2407 }
2176 obj1.free(); 2408 obj1.free();
2177 2409
2178 // get bounding box 2410 // get bounding box
2179 dict->lookup("BBox", &bboxObj); 2411 dict->lookup("BBox", &bboxObj);
2180 if (!bboxObj.isArray()) { 2412 if (!bboxObj.isArray()) {
2181 matrixObj.free(); 2413 matrixObj.free();
2182 bboxObj.free(); 2414 bboxObj.free();
2183 error(getPos(), "Bad form bounding box"); 2415 error(getPos(), "Bad form bounding box");
2184 return; 2416 return;
2185 } 2417 }
2186 for (i = 0; i < 4; ++i) { 2418 for (i = 0; i < 4; ++i) {
2187 bboxObj.arrayGet(i, &obj1); 2419 bboxObj.arrayGet(i, &obj1);
2188 bbox[i] = obj1.getNum(); 2420 bbox[i] = obj1.getNum();
2189 obj1.free(); 2421 obj1.free();
2190 } 2422 }
2191 bboxObj.free(); 2423 bboxObj.free();
2192 2424
2193 // get matrix 2425 // get matrix
2194 dict->lookup("Matrix", &matrixObj); 2426 dict->lookup("Matrix", &matrixObj);
2195 if (matrixObj.isArray()) { 2427 if (matrixObj.isArray()) {
2196 for (i = 0; i < 6; ++i) { 2428 for (i = 0; i < 6; ++i) {
2197 matrixObj.arrayGet(i, &obj1); 2429 matrixObj.arrayGet(i, &obj1);
2198 m[i] = obj1.getNum(); 2430 m[i] = obj1.getNum();
2199 obj1.free(); 2431 obj1.free();
2200 } 2432 }
2201 } else { 2433 } else {
2202 m[0] = 1; m[1] = 0; 2434 m[0] = 1; m[1] = 0;
2203 m[2] = 0; m[3] = 1; 2435 m[2] = 0; m[3] = 1;
2204 m[4] = 0; m[5] = 0; 2436 m[4] = 0; m[5] = 0;
2205 } 2437 }
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],
2301 matrix[3], matrix[4], matrix[5]); 2583 matrix[3], matrix[4], matrix[5]);
2302 2584
2303 // set new base matrix 2585 // set new base matrix
2304 for (i = 0; i < 6; ++i) { 2586 for (i = 0; i < 6; ++i) {
2305 oldBaseMatrix[i] = baseMatrix[i]; 2587 oldBaseMatrix[i] = baseMatrix[i];
2306 baseMatrix[i] = state->getCTM()[i]; 2588 baseMatrix[i] = state->getCTM()[i];
2307 } 2589 }
2308 2590
2309 // set form bounding box 2591 // set form bounding box
2310 state->moveTo(bbox[0], bbox[1]); 2592 state->moveTo(bbox[0], bbox[1]);
2311 state->lineTo(bbox[2], bbox[1]); 2593 state->lineTo(bbox[2], bbox[1]);
2312 state->lineTo(bbox[2], bbox[3]); 2594 state->lineTo(bbox[2], bbox[3]);
2313 state->lineTo(bbox[0], bbox[3]); 2595 state->lineTo(bbox[0], bbox[3]);
2314 state->closePath(); 2596 state->closePath();
2315 state->clip(); 2597 state->clip();
2316 out->clip(state); 2598 out->clip(state);
2317 state->clearPath(); 2599 state->clearPath();
2318 2600
2319 // draw the form 2601 // draw the form
2320 display(str, gFalse); 2602 display(str, gFalse);
2321 2603
2322 // restore base matrix 2604 // restore base matrix
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();
2352 2644
2353 // display the image 2645 // display the image
2354 if (str) { 2646 if (str) {
2355 doImage(NULL, str, gTrue); 2647 doImage(NULL, str, gTrue);
2356 2648
2357 // skip 'EI' tag 2649 // skip 'EI' tag
2358 c1 = str->getBaseStream()->getChar(); 2650 c1 = str->getBaseStream()->getChar();
2359 c2 = str->getBaseStream()->getChar(); 2651 c2 = str->getBaseStream()->getChar();
2360 while (!(c1 == 'E' && c2 == 'I') && c2 != EOF) { 2652 while (!(c1 == 'E' && c2 == 'I') && c2 != EOF) {
2361 c1 = c2; 2653 c1 = c2;
2362 c2 = str->getBaseStream()->getChar(); 2654 c2 = str->getBaseStream()->getChar();
2363 } 2655 }
2364 delete str; 2656 delete str;
2365 } 2657 }
2366} 2658}
2367 2659
2368Stream *Gfx::buildImageStream() { 2660Stream *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)
2433 --ignoreUndef; 2732 --ignoreUndef;
2434} 2733}
2435 2734
2436//------------------------------------------------------------------------ 2735//------------------------------------------------------------------------
2437// marked content operators 2736// marked content operators
2438//------------------------------------------------------------------------ 2737//------------------------------------------------------------------------
2439 2738
2440void Gfx::opBeginMarkedContent(Object args[], int numArgs) { 2739void Gfx::opBeginMarkedContent(Object args[], int numArgs) {
2441 if (printCommands) { 2740 if (printCommands) {
2442 printf(" marked content: %s ", args[0].getName()); 2741 printf(" marked content: %s ", args[0].getName());
2443 if (numArgs == 2) 2742 if (numArgs == 2)
2444 args[2].print(stdout); 2743 args[2].print(stdout);
2445 printf("\n"); 2744 printf("\n");
2446 fflush(stdout); 2745 fflush(stdout);
2447 } 2746 }
2448} 2747}
2449 2748
2450void Gfx::opEndMarkedContent(Object args[], int numArgs) { 2749void Gfx::opEndMarkedContent(Object args[], int numArgs) {
2451} 2750}
2452 2751
2453void Gfx::opMarkPoint(Object args[], int numArgs) { 2752void Gfx::opMarkPoint(Object args[], int numArgs) {
2454 if (printCommands) { 2753 if (printCommands) {
2455 printf(" mark point: %s ", args[0].getName()); 2754 printf(" mark point: %s ", args[0].getName());
2456 if (numArgs == 2) 2755 if (numArgs == 2)
2457 args[2].print(stdout); 2756 args[2].print(stdout);
2458 printf("\n"); 2757 printf("\n");
2459 fflush(stdout); 2758 fflush(stdout);
2460 } 2759 }
2461} 2760}
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,240 +1,252 @@
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
42}; 43};
43 44
44enum TchkType { 45enum TchkType {
45 tchkBool, // boolean 46 tchkBool, // boolean
46 tchkInt, // integer 47 tchkInt, // integer
47 tchkNum, // number (integer or real) 48 tchkNum, // number (integer or real)
48 tchkString, // string 49 tchkString, // string
49 tchkName, // name 50 tchkName, // name
50 tchkArray, // array 51 tchkArray, // array
51 tchkProps, // properties (dictionary or name) 52 tchkProps, // properties (dictionary or name)
52 tchkSCN, // scn/SCN args (number of name) 53 tchkSCN, // scn/SCN args (number of name)
53 tchkNone // used to avoid empty initializer lists 54 tchkNone // used to avoid empty initializer lists
54}; 55};
55 56
56#define maxArgs 8 57#define maxArgs 8
57 58
58struct Operator { 59struct Operator {
59 char name[4]; 60 char name[4];
60 int numArgs; 61 int numArgs;
61 TchkType tchk[maxArgs]; 62 TchkType tchk[maxArgs];
62 void (Gfx::*func)(Object args[], int numArgs); 63 void (Gfx::*func)(Object args[], int numArgs);
63}; 64};
64 65
65class GfxResources { 66class GfxResources {
66public: 67public:
67 68
68 GfxResources(XRef *xref, Dict *resDict, GfxResources *nextA); 69 GfxResources(XRef *xref, Dict *resDict, GfxResources *nextA);
69 ~GfxResources(); 70 ~GfxResources();
70 71
71 GfxFont *lookupFont(char *name); 72 GfxFont *lookupFont(char *name);
72 GBool lookupXObject(char *name, Object *obj); 73 GBool lookupXObject(char *name, Object *obj);
73 GBool lookupXObjectNF(char *name, Object *obj); 74 GBool lookupXObjectNF(char *name, Object *obj);
74 void lookupColorSpace(char *name, Object *obj); 75 void lookupColorSpace(char *name, Object *obj);
75 GfxPattern *lookupPattern(char *name); 76 GfxPattern *lookupPattern(char *name);
76 GfxShading *lookupShading(char *name); 77 GfxShading *lookupShading(char *name);
77 GBool lookupGState(char *name, Object *obj); 78 GBool lookupGState(char *name, Object *obj);
78 79
79 GfxResources *getNext() { return next; } 80 GfxResources *getNext() { return next; }
80 81
81private: 82private:
82 83
83 GfxFontDict *fonts; 84 GfxFontDict *fonts;
84 Object xObjDict; 85 Object xObjDict;
85 Object colorSpaceDict; 86 Object colorSpaceDict;
86 Object patternDict; 87 Object patternDict;
87 Object shadingDict; 88 Object shadingDict;
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
127 void go(GBool topLevel); 138 void go(GBool topLevel);
128 void execOp(Object *cmd, Object args[], int numArgs); 139 void execOp(Object *cmd, Object args[], int numArgs);
129 Operator *findOp(char *name); 140 Operator *findOp(char *name);
130 GBool checkArg(Object *arg, TchkType type); 141 GBool checkArg(Object *arg, TchkType type);
131 int getPos(); 142 int getPos();
132 143
133 // graphics state operators 144 // graphics state operators
134 void opSave(Object args[], int numArgs); 145 void opSave(Object args[], int numArgs);
135 void opRestore(Object args[], int numArgs); 146 void opRestore(Object args[], int numArgs);
136 void opConcat(Object args[], int numArgs); 147 void opConcat(Object args[], int numArgs);
137 void opSetDash(Object args[], int numArgs); 148 void opSetDash(Object args[], int numArgs);
138 void opSetFlat(Object args[], int numArgs); 149 void opSetFlat(Object args[], int numArgs);
139 void opSetLineJoin(Object args[], int numArgs); 150 void opSetLineJoin(Object args[], int numArgs);
140 void opSetLineCap(Object args[], int numArgs); 151 void opSetLineCap(Object args[], int numArgs);
141 void opSetMiterLimit(Object args[], int numArgs); 152 void opSetMiterLimit(Object args[], int numArgs);
142 void opSetLineWidth(Object args[], int numArgs); 153 void opSetLineWidth(Object args[], int numArgs);
143 void opSetExtGState(Object args[], int numArgs); 154 void opSetExtGState(Object args[], int numArgs);
144 void opSetRenderingIntent(Object args[], int numArgs); 155 void opSetRenderingIntent(Object args[], int numArgs);
145 156
146 // color operators 157 // color operators
147 void opSetFillGray(Object args[], int numArgs); 158 void opSetFillGray(Object args[], int numArgs);
148 void opSetStrokeGray(Object args[], int numArgs); 159 void opSetStrokeGray(Object args[], int numArgs);
149 void opSetFillCMYKColor(Object args[], int numArgs); 160 void opSetFillCMYKColor(Object args[], int numArgs);
150 void opSetStrokeCMYKColor(Object args[], int numArgs); 161 void opSetStrokeCMYKColor(Object args[], int numArgs);
151 void opSetFillRGBColor(Object args[], int numArgs); 162 void opSetFillRGBColor(Object args[], int numArgs);
152 void opSetStrokeRGBColor(Object args[], int numArgs); 163 void opSetStrokeRGBColor(Object args[], int numArgs);
153 void opSetFillColorSpace(Object args[], int numArgs); 164 void opSetFillColorSpace(Object args[], int numArgs);
154 void opSetStrokeColorSpace(Object args[], int numArgs); 165 void opSetStrokeColorSpace(Object args[], int numArgs);
155 void opSetFillColor(Object args[], int numArgs); 166 void opSetFillColor(Object args[], int numArgs);
156 void opSetStrokeColor(Object args[], int numArgs); 167 void opSetStrokeColor(Object args[], int numArgs);
157 void opSetFillColorN(Object args[], int numArgs); 168 void opSetFillColorN(Object args[], int numArgs);
158 void opSetStrokeColorN(Object args[], int numArgs); 169 void opSetStrokeColorN(Object args[], int numArgs);
159 170
160 // path segment operators 171 // path segment operators
161 void opMoveTo(Object args[], int numArgs); 172 void opMoveTo(Object args[], int numArgs);
162 void opLineTo(Object args[], int numArgs); 173 void opLineTo(Object args[], int numArgs);
163 void opCurveTo(Object args[], int numArgs); 174 void opCurveTo(Object args[], int numArgs);
164 void opCurveTo1(Object args[], int numArgs); 175 void opCurveTo1(Object args[], int numArgs);
165 void opCurveTo2(Object args[], int numArgs); 176 void opCurveTo2(Object args[], int numArgs);
166 void opRectangle(Object args[], int numArgs); 177 void opRectangle(Object args[], int numArgs);
167 void opClosePath(Object args[], int numArgs); 178 void opClosePath(Object args[], int numArgs);
168 179
169 // path painting operators 180 // path painting operators
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);
194 void opSetFont(Object args[], int numArgs); 206 void opSetFont(Object args[], int numArgs);
195 void opSetTextLeading(Object args[], int numArgs); 207 void opSetTextLeading(Object args[], int numArgs);
196 void opSetTextRender(Object args[], int numArgs); 208 void opSetTextRender(Object args[], int numArgs);
197 void opSetTextRise(Object args[], int numArgs); 209 void opSetTextRise(Object args[], int numArgs);
198 void opSetWordSpacing(Object args[], int numArgs); 210 void opSetWordSpacing(Object args[], int numArgs);
199 void opSetHorizScaling(Object args[], int numArgs); 211 void opSetHorizScaling(Object args[], int numArgs);
200 212
201 // text positioning operators 213 // text positioning operators
202 void opTextMove(Object args[], int numArgs); 214 void opTextMove(Object args[], int numArgs);
203 void opTextMoveSet(Object args[], int numArgs); 215 void opTextMoveSet(Object args[], int numArgs);
204 void opSetTextMatrix(Object args[], int numArgs); 216 void opSetTextMatrix(Object args[], int numArgs);
205 void opTextNextLine(Object args[], int numArgs); 217 void opTextNextLine(Object args[], int numArgs);
206 218
207 // text string operators 219 // text string operators
208 void opShowText(Object args[], int numArgs); 220 void opShowText(Object args[], int numArgs);
209 void opMoveShowText(Object args[], int numArgs); 221 void opMoveShowText(Object args[], int numArgs);
210 void opMoveSetShowText(Object args[], int numArgs); 222 void opMoveSetShowText(Object args[], int numArgs);
211 void opShowSpaceText(Object args[], int numArgs); 223 void opShowSpaceText(Object args[], int numArgs);
212 void doShowText(GString *s); 224 void doShowText(GString *s);
213 225
214 // XObject operators 226 // XObject operators
215 void opXObject(Object args[], int numArgs); 227 void opXObject(Object args[], int numArgs);
216 void doImage(Object *ref, Stream *str, GBool inlineImg); 228 void doImage(Object *ref, Stream *str, GBool inlineImg);
217 void doForm(Object *str); 229 void doForm(Object *str);
218 void doForm1(Object *str, Dict *resDict, fouble *matrix, fouble *bbox); 230 void doForm1(Object *str, Dict *resDict, fouble *matrix, fouble *bbox);
219 231
220 // in-line image operators 232 // in-line image operators
221 void opBeginImage(Object args[], int numArgs); 233 void opBeginImage(Object args[], int numArgs);
222 Stream *buildImageStream(); 234 Stream *buildImageStream();
223 void opImageData(Object args[], int numArgs); 235 void opImageData(Object args[], int numArgs);
224 void opEndImage(Object args[], int numArgs); 236 void opEndImage(Object args[], int numArgs);
225 237
226 // type 3 font operators 238 // type 3 font operators
227 void opSetCharWidth(Object args[], int numArgs); 239 void opSetCharWidth(Object args[], int numArgs);
228 void opSetCacheDevice(Object args[], int numArgs); 240 void opSetCacheDevice(Object args[], int numArgs);
229 241
230 // compatibility operators 242 // compatibility operators
231 void opBeginIgnoreUndef(Object args[], int numArgs); 243 void opBeginIgnoreUndef(Object args[], int numArgs);
232 void opEndIgnoreUndef(Object args[], int numArgs); 244 void opEndIgnoreUndef(Object args[], int numArgs);
233 245
234 // marked content operators 246 // marked content operators
235 void opBeginMarkedContent(Object args[], int numArgs); 247 void opBeginMarkedContent(Object args[], int numArgs);
236 void opEndMarkedContent(Object args[], int numArgs); 248 void opEndMarkedContent(Object args[], int numArgs);
237 void opMarkPoint(Object args[], int numArgs); 249 void opMarkPoint(Object args[], int numArgs);
238}; 250};
239 251
240#endif 252#endif
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,197 +1,197 @@
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>
18#include "gmem.h" 18#include "gmem.h"
19#include "Error.h" 19#include "Error.h"
20#include "Object.h" 20#include "Object.h"
21#include "Dict.h" 21#include "Dict.h"
22#include "GlobalParams.h" 22#include "GlobalParams.h"
23#include "CMap.h" 23#include "CMap.h"
24#include "CharCodeToUnicode.h" 24#include "CharCodeToUnicode.h"
25#include "FontEncodingTables.h" 25#include "FontEncodingTables.h"
26#include "BuiltinFontTables.h" 26#include "BuiltinFontTables.h"
27#include "FontFile.h" 27#include "FontFile.h"
28#include "GfxFont.h" 28#include "GfxFont.h"
29 29
30//------------------------------------------------------------------------ 30//------------------------------------------------------------------------
31 31
32struct StdFontMapEntry { 32struct StdFontMapEntry {
33 char *altName; 33 char *altName;
34 char *properName; 34 char *properName;
35}; 35};
36 36
37static StdFontMapEntry stdFontMap[] = { 37static StdFontMapEntry stdFontMap[] = {
38 { "Arial", "Helvetica" }, 38 { "Arial", "Helvetica" },
39 { "Arial,Bold", "Helvetica-Bold" }, 39 { "Arial,Bold", "Helvetica-Bold" },
40 { "Arial,BoldItalic", "Helvetica-BoldOblique" }, 40 { "Arial,BoldItalic", "Helvetica-BoldOblique" },
41 { "Arial,Italic", "Helvetica-Oblique" }, 41 { "Arial,Italic", "Helvetica-Oblique" },
42 { "Arial-Bold", "Helvetica-Bold" }, 42 { "Arial-Bold", "Helvetica-Bold" },
43 { "Arial-BoldItalic", "Helvetica-BoldOblique" }, 43 { "Arial-BoldItalic", "Helvetica-BoldOblique" },
44 { "Arial-BoldItalicMT", "Helvetica-BoldOblique" }, 44 { "Arial-BoldItalicMT", "Helvetica-BoldOblique" },
45 { "Arial-BoldMT", "Helvetica-Bold" }, 45 { "Arial-BoldMT", "Helvetica-Bold" },
46 { "Arial-Italic", "Helvetica-Oblique" }, 46 { "Arial-Italic", "Helvetica-Oblique" },
47 { "Arial-ItalicMT", "Helvetica-Oblique" }, 47 { "Arial-ItalicMT", "Helvetica-Oblique" },
48 { "ArialMT", "Helvetica" }, 48 { "ArialMT", "Helvetica" },
49 { "Courier,Bold", "Courier-Bold" }, 49 { "Courier,Bold", "Courier-Bold" },
50 { "Courier,Italic", "Courier-Oblique" }, 50 { "Courier,Italic", "Courier-Oblique" },
51 { "Courier,BoldItalic", "Courier-BoldOblique" }, 51 { "Courier,BoldItalic", "Courier-BoldOblique" },
52 { "CourierNew", "Courier" }, 52 { "CourierNew", "Courier" },
53 { "CourierNew,Bold", "Courier-Bold" }, 53 { "CourierNew,Bold", "Courier-Bold" },
54 { "CourierNew,BoldItalic", "Courier-BoldOblique" }, 54 { "CourierNew,BoldItalic", "Courier-BoldOblique" },
55 { "CourierNew,Italic", "Courier-Oblique" }, 55 { "CourierNew,Italic", "Courier-Oblique" },
56 { "CourierNew-Bold", "Courier-Bold" }, 56 { "CourierNew-Bold", "Courier-Bold" },
57 { "CourierNew-BoldItalic", "Courier-BoldOblique" }, 57 { "CourierNew-BoldItalic", "Courier-BoldOblique" },
58 { "CourierNew-Italic", "Courier-Oblique" }, 58 { "CourierNew-Italic", "Courier-Oblique" },
59 { "CourierNewPS-BoldItalicMT", "Courier-BoldOblique" }, 59 { "CourierNewPS-BoldItalicMT", "Courier-BoldOblique" },
60 { "CourierNewPS-BoldMT", "Courier-Bold" }, 60 { "CourierNewPS-BoldMT", "Courier-Bold" },
61 { "CourierNewPS-ItalicMT", "Courier-Oblique" }, 61 { "CourierNewPS-ItalicMT", "Courier-Oblique" },
62 { "CourierNewPSMT", "Courier" }, 62 { "CourierNewPSMT", "Courier" },
63 { "Helvetica,Bold", "Helvetica-Bold" }, 63 { "Helvetica,Bold", "Helvetica-Bold" },
64 { "Helvetica,BoldItalic", "Helvetica-BoldOblique" }, 64 { "Helvetica,BoldItalic", "Helvetica-BoldOblique" },
65 { "Helvetica,Italic", "Helvetica-Oblique" }, 65 { "Helvetica,Italic", "Helvetica-Oblique" },
66 { "Helvetica-BoldItalic", "Helvetica-BoldOblique" }, 66 { "Helvetica-BoldItalic", "Helvetica-BoldOblique" },
67 { "Helvetica-Italic", "Helvetica-Oblique" }, 67 { "Helvetica-Italic", "Helvetica-Oblique" },
68 { "TimesNewRoman", "Times-Roman" }, 68 { "TimesNewRoman", "Times-Roman" },
69 { "TimesNewRoman,Bold", "Times-Bold" }, 69 { "TimesNewRoman,Bold", "Times-Bold" },
70 { "TimesNewRoman,BoldItalic", "Times-BoldItalic" }, 70 { "TimesNewRoman,BoldItalic", "Times-BoldItalic" },
71 { "TimesNewRoman,Italic", "Times-Italic" }, 71 { "TimesNewRoman,Italic", "Times-Italic" },
72 { "TimesNewRoman-Bold", "Times-Bold" }, 72 { "TimesNewRoman-Bold", "Times-Bold" },
73 { "TimesNewRoman-BoldItalic", "Times-BoldItalic" }, 73 { "TimesNewRoman-BoldItalic", "Times-BoldItalic" },
74 { "TimesNewRoman-Italic", "Times-Italic" }, 74 { "TimesNewRoman-Italic", "Times-Italic" },
75 { "TimesNewRomanPS", "Times-Roman" }, 75 { "TimesNewRomanPS", "Times-Roman" },
76 { "TimesNewRomanPS-Bold", "Times-Bold" }, 76 { "TimesNewRomanPS-Bold", "Times-Bold" },
77 { "TimesNewRomanPS-BoldItalic", "Times-BoldItalic" }, 77 { "TimesNewRomanPS-BoldItalic", "Times-BoldItalic" },
78 { "TimesNewRomanPS-BoldItalicMT", "Times-BoldItalic" }, 78 { "TimesNewRomanPS-BoldItalicMT", "Times-BoldItalic" },
79 { "TimesNewRomanPS-BoldMT", "Times-Bold" }, 79 { "TimesNewRomanPS-BoldMT", "Times-Bold" },
80 { "TimesNewRomanPS-Italic", "Times-Italic" }, 80 { "TimesNewRomanPS-Italic", "Times-Italic" },
81 { "TimesNewRomanPS-ItalicMT", "Times-Italic" }, 81 { "TimesNewRomanPS-ItalicMT", "Times-Italic" },
82 { "TimesNewRomanPSMT", "Times-Roman" } 82 { "TimesNewRomanPSMT", "Times-Roman" }
83}; 83};
84 84
85//------------------------------------------------------------------------ 85//------------------------------------------------------------------------
86// GfxFont 86// GfxFont
87//------------------------------------------------------------------------ 87//------------------------------------------------------------------------
88 88
89GfxFont *GfxFont::makeFont(XRef *xref, char *tagA, Ref idA, Dict *fontDict) { 89GfxFont *GfxFont::makeFont(XRef *xref, char *tagA, Ref idA, Dict *fontDict) {
90 GString *nameA; 90 GString *nameA;
91 GfxFont *font; 91 GfxFont *font;
92 Object obj1; 92 Object obj1;
93 93
94 // get base font name 94 // get base font name
95 nameA = NULL; 95 nameA = NULL;
96 fontDict->lookup("BaseFont", &obj1); 96 fontDict->lookup("BaseFont", &obj1);
97 if (obj1.isName()) { 97 if (obj1.isName()) {
98 nameA = new GString(obj1.getName()); 98 nameA = new GString(obj1.getName());
99 } 99 }
100 obj1.free(); 100 obj1.free();
101 101
102 // get font type 102 // get font type
103 font = NULL; 103 font = NULL;
104 fontDict->lookup("Subtype", &obj1); 104 fontDict->lookup("Subtype", &obj1);
105 if (obj1.isName("Type1") || obj1.isName("MMType1")) { 105 if (obj1.isName("Type1") || obj1.isName("MMType1")) {
106 font = new Gfx8BitFont(xref, tagA, idA, nameA, fontType1, fontDict); 106 font = new Gfx8BitFont(xref, tagA, idA, nameA, fontType1, fontDict);
107 } else if (obj1.isName("Type1C")) { 107 } else if (obj1.isName("Type1C")) {
108 font = new Gfx8BitFont(xref, tagA, idA, nameA, fontType1C, fontDict); 108 font = new Gfx8BitFont(xref, tagA, idA, nameA, fontType1C, fontDict);
109 } else if (obj1.isName("Type3")) { 109 } else if (obj1.isName("Type3")) {
110 font = new Gfx8BitFont(xref, tagA, idA, nameA, fontType3, fontDict); 110 font = new Gfx8BitFont(xref, tagA, idA, nameA, fontType3, fontDict);
111 } else if (obj1.isName("TrueType")) { 111 } else if (obj1.isName("TrueType")) {
112 font = new Gfx8BitFont(xref, tagA, idA, nameA, fontTrueType, fontDict); 112 font = new Gfx8BitFont(xref, tagA, idA, nameA, fontTrueType, fontDict);
113 } else if (obj1.isName("Type0")) { 113 } else if (obj1.isName("Type0")) {
114 font = new GfxCIDFont(xref, tagA, idA, nameA, fontDict); 114 font = new GfxCIDFont(xref, tagA, idA, nameA, fontDict);
115 } else { 115 } else {
116 error(-1, "Unknown font type: '%s'", 116 error(-1, "Unknown font type: '%s'",
117 obj1.isName() ? obj1.getName() : "???"); 117 obj1.isName() ? obj1.getName() : "???");
118 font = new Gfx8BitFont(xref, tagA, idA, nameA, fontUnknownType, fontDict); 118 font = new Gfx8BitFont(xref, tagA, idA, nameA, fontUnknownType, fontDict);
119 } 119 }
120 obj1.free(); 120 obj1.free();
121 121
122 return font; 122 return font;
123} 123}
124 124
125GfxFont::GfxFont(char *tagA, Ref idA, GString *nameA) { 125GfxFont::GfxFont(char *tagA, Ref idA, GString *nameA) {
126 ok = gFalse; 126 ok = gFalse;
127 tag = new GString(tagA); 127 tag = new GString(tagA);
128 id = idA; 128 id = idA;
129 name = nameA; 129 name = nameA;
130 embFontName = NULL; 130 embFontName = NULL;
131 extFontFile = NULL; 131 extFontFile = NULL;
132} 132}
133 133
134GfxFont::~GfxFont() { 134GfxFont::~GfxFont() {
135 delete tag; 135 delete tag;
136 if (name) { 136 if (name) {
137 delete name; 137 delete name;
138 } 138 }
139 if (embFontName) { 139 if (embFontName) {
140 delete embFontName; 140 delete embFontName;
141 } 141 }
142 if (extFontFile) { 142 if (extFontFile) {
143 delete extFontFile; 143 delete extFontFile;
144 } 144 }
145} 145}
146 146
147void GfxFont::readFontDescriptor(XRef *xref, Dict *fontDict) { 147void GfxFont::readFontDescriptor(XRef *xref, Dict *fontDict) {
148 Object obj1, obj2, obj3, obj4; 148 Object obj1, obj2, obj3, obj4;
149 fouble t; 149 fouble t;
150 int i; 150 int i;
151 151
152 // assume Times-Roman by default (for substitution purposes) 152 // assume Times-Roman by default (for substitution purposes)
153 flags = fontSerif; 153 flags = fontSerif;
154 154
155 embFontID.num = -1; 155 embFontID.num = -1;
156 embFontID.gen = -1; 156 embFontID.gen = -1;
157 missingWidth = 0; 157 missingWidth = 0;
158 158
159 if (fontDict->lookup("FontDescriptor", &obj1)->isDict()) { 159 if (fontDict->lookup("FontDescriptor", &obj1)->isDict()) {
160 160
161 // get flags 161 // get flags
162 if (obj1.dictLookup("Flags", &obj2)->isInt()) { 162 if (obj1.dictLookup("Flags", &obj2)->isInt()) {
163 flags = obj2.getInt(); 163 flags = obj2.getInt();
164 } 164 }
165 obj2.free(); 165 obj2.free();
166 166
167 // get name 167 // get name
168 obj1.dictLookup("FontName", &obj2); 168 obj1.dictLookup("FontName", &obj2);
169 if (obj2.isName()) { 169 if (obj2.isName()) {
170 embFontName = new GString(obj2.getName()); 170 embFontName = new GString(obj2.getName());
171 } 171 }
172 obj2.free(); 172 obj2.free();
173 173
174 // look for embedded font file 174 // look for embedded font file
175 if (obj1.dictLookupNF("FontFile", &obj2)->isRef()) { 175 if (obj1.dictLookupNF("FontFile", &obj2)->isRef()) {
176 if (type == fontType1) { 176 if (type == fontType1) {
177 embFontID = obj2.getRef(); 177 embFontID = obj2.getRef();
178 } else { 178 } else {
179 error(-1, "Mismatch between font type and embedded font file"); 179 error(-1, "Mismatch between font type and embedded font file");
180 } 180 }
181 } 181 }
182 obj2.free(); 182 obj2.free();
183 if (embFontID.num == -1 && 183 if (embFontID.num == -1 &&
184 obj1.dictLookupNF("FontFile2", &obj2)->isRef()) { 184 obj1.dictLookupNF("FontFile2", &obj2)->isRef()) {
185 if (type == fontTrueType || type == fontCIDType2) { 185 if (type == fontTrueType || type == fontCIDType2) {
186 embFontID = obj2.getRef(); 186 embFontID = obj2.getRef();
187 } else { 187 } else {
188 error(-1, "Mismatch between font type and embedded font file"); 188 error(-1, "Mismatch between font type and embedded font file");
189 } 189 }
190 } 190 }
191 obj2.free(); 191 obj2.free();
192 if (embFontID.num == -1 && 192 if (embFontID.num == -1 &&
193 obj1.dictLookupNF("FontFile3", &obj2)->isRef()) { 193 obj1.dictLookupNF("FontFile3", &obj2)->isRef()) {
194 if (obj2.fetch(xref, &obj3)->isStream()) { 194 if (obj2.fetch(xref, &obj3)->isStream()) {
195 obj3.streamGetDict()->lookup("Subtype", &obj4); 195 obj3.streamGetDict()->lookup("Subtype", &obj4);
196 if (obj4.isName("Type1")) { 196 if (obj4.isName("Type1")) {
197 if (type == fontType1) { 197 if (type == fontType1) {
@@ -265,710 +265,746 @@ void GfxFont::readFontDescriptor(XRef *xref, Dict *fontDict) {
265 fontBBox[i] = 0.001 * obj3.getNum(); 265 fontBBox[i] = 0.001 * obj3.getNum();
266 } 266 }
267 obj3.free(); 267 obj3.free();
268 } 268 }
269 } 269 }
270 obj2.free(); 270 obj2.free();
271 271
272 } 272 }
273 obj1.free(); 273 obj1.free();
274} 274}
275 275
276CharCodeToUnicode *GfxFont::readToUnicodeCMap(Dict *fontDict, int nBits) { 276CharCodeToUnicode *GfxFont::readToUnicodeCMap(Dict *fontDict, int nBits) {
277 CharCodeToUnicode *ctu; 277 CharCodeToUnicode *ctu;
278 GString *buf; 278 GString *buf;
279 Object obj1; 279 Object obj1;
280 int c; 280 int c;
281 281
282 if (!fontDict->lookup("ToUnicode", &obj1)->isStream()) { 282 if (!fontDict->lookup("ToUnicode", &obj1)->isStream()) {
283 obj1.free(); 283 obj1.free();
284 return NULL; 284 return NULL;
285 } 285 }
286 buf = new GString(); 286 buf = new GString();
287 obj1.streamReset(); 287 obj1.streamReset();
288 while ((c = obj1.streamGetChar()) != EOF) { 288 while ((c = obj1.streamGetChar()) != EOF) {
289 buf->append(c); 289 buf->append(c);
290 } 290 }
291 obj1.streamClose(); 291 obj1.streamClose();
292 obj1.free(); 292 obj1.free();
293 ctu = CharCodeToUnicode::parseCMap(buf, nBits); 293 ctu = CharCodeToUnicode::parseCMap(buf, nBits);
294 delete buf; 294 delete buf;
295 return ctu; 295 return ctu;
296} 296}
297 297
298void GfxFont::findExtFontFile() { 298void GfxFont::findExtFontFile() {
299 if (name) { 299 if (name) {
300 if (type == fontType1) { 300 if (type == fontType1) {
301 extFontFile = globalParams->findFontFile(name, ".pfa", ".pfb"); 301 extFontFile = globalParams->findFontFile(name, ".pfa", ".pfb");
302 } else if (type == fontTrueType) { 302 } else if (type == fontTrueType) {
303 extFontFile = globalParams->findFontFile(name, ".ttf", NULL); 303 extFontFile = globalParams->findFontFile(name, ".ttf", NULL);
304 } 304 }
305 } 305 }
306} 306}
307 307
308char *GfxFont::readExtFontFile(int *len) { 308char *GfxFont::readExtFontFile(int *len) {
309 FILE *f; 309 FILE *f;
310 char *buf; 310 char *buf;
311 311
312 if (!(f = fopen(extFontFile->getCString(), "rb"))) { 312 if (!(f = fopen(extFontFile->getCString(), "rb"))) {
313 error(-1, "External font file '%s' vanished", extFontFile->getCString()); 313 error(-1, "External font file '%s' vanished", extFontFile->getCString());
314 return NULL; 314 return NULL;
315 } 315 }
316 fseek(f, 0, SEEK_END); 316 fseek(f, 0, SEEK_END);
317 *len = (int)ftell(f); 317 *len = (int)ftell(f);
318 fseek(f, 0, SEEK_SET); 318 fseek(f, 0, SEEK_SET);
319 buf = (char *)gmalloc(*len); 319 buf = (char *)gmalloc(*len);
320 if ((int)fread(buf, 1, *len, f) != *len) { 320 if ((int)fread(buf, 1, *len, f) != *len) {
321 error(-1, "Error reading external font file '%s'", extFontFile); 321 error(-1, "Error reading external font file '%s'", extFontFile);
322 } 322 }
323 fclose(f); 323 fclose(f);
324 return buf; 324 return buf;
325} 325}
326 326
327char *GfxFont::readEmbFontFile(XRef *xref, int *len) { 327char *GfxFont::readEmbFontFile(XRef *xref, int *len) {
328 char *buf; 328 char *buf;
329 Object obj1, obj2; 329 Object obj1, obj2;
330 Stream *str; 330 Stream *str;
331 int c; 331 int c;
332 int size, i; 332 int size, i;
333 333
334 obj1.initRef(embFontID.num, embFontID.gen); 334 obj1.initRef(embFontID.num, embFontID.gen);
335 obj1.fetch(xref, &obj2); 335 obj1.fetch(xref, &obj2);
336 if (!obj2.isStream()) { 336 if (!obj2.isStream()) {
337 error(-1, "Embedded font file is not a stream"); 337 error(-1, "Embedded font file is not a stream");
338 obj2.free(); 338 obj2.free();
339 obj1.free(); 339 obj1.free();
340 embFontID.num = -1; 340 embFontID.num = -1;
341 return NULL; 341 return NULL;
342 } 342 }
343 str = obj2.getStream(); 343 str = obj2.getStream();
344 344
345 buf = NULL; 345 buf = NULL;
346 i = size = 0; 346 i = size = 0;
347 str->reset(); 347 str->reset();
348 while ((c = str->getChar()) != EOF) { 348 while ((c = str->getChar()) != EOF) {
349 if (i == size) { 349 if (i == size) {
350 size += 4096; 350 size += 4096;
351 buf = (char *)grealloc(buf, size); 351 buf = (char *)grealloc(buf, size);
352 } 352 }
353 buf[i++] = c; 353 buf[i++] = c;
354 } 354 }
355 *len = i; 355 *len = i;
356 str->close(); 356 str->close();
357 357
358 obj2.free(); 358 obj2.free();
359 obj1.free(); 359 obj1.free();
360 360
361 return buf; 361 return buf;
362} 362}
363 363
364//------------------------------------------------------------------------ 364//------------------------------------------------------------------------
365// Gfx8BitFont 365// Gfx8BitFont
366//------------------------------------------------------------------------ 366//------------------------------------------------------------------------
367 367
368Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA, 368Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
369 GfxFontType typeA, Dict *fontDict): 369 GfxFontType typeA, Dict *fontDict):
370 GfxFont(tagA, idA, nameA) 370 GfxFont(tagA, idA, nameA)
371{ 371{
372 BuiltinFont *builtinFont; 372 BuiltinFont *builtinFont;
373 char **baseEnc; 373 char **baseEnc;
374 GBool baseEncFromFontFile; 374 GBool baseEncFromFontFile;
375 char *buf; 375 char *buf;
376 int len; 376 int len;
377 FontFile *fontFile; 377 FontFile *fontFile;
378 int code, code2; 378 int code, code2;
379 char *charName; 379 char *charName;
380 GBool missing, hex; 380 GBool missing, hex;
381 Unicode toUnicode[256]; 381 Unicode toUnicode[256];
382 fouble mul; 382 fouble mul;
383 int firstChar, lastChar; 383 int firstChar, lastChar;
384 Gushort w; 384 Gushort w;
385 Object obj1, obj2, obj3; 385 Object obj1, obj2, obj3;
386 int n, i, a, b, m; 386 int n, i, a, b, m;
387 387
388 type = typeA; 388 type = typeA;
389 ctu = NULL; 389 ctu = NULL;
390 390
391 // Acrobat 4.0 and earlier substituted Base14-compatible fonts 391 // Acrobat 4.0 and earlier substituted Base14-compatible fonts
392 // without providing Widths and a FontDescriptor, so we munge the 392 // without providing Widths and a FontDescriptor, so we munge the
393 // names into the proper Base14 names. (This table is from 393 // names into the proper Base14 names. (This table is from
394 // implementation note 44 in the PDF 1.4 spec.) 394 // implementation note 44 in the PDF 1.4 spec.)
395 if (name) { 395 if (name) {
396 a = 0; 396 a = 0;
397 b = sizeof(stdFontMap) / sizeof(StdFontMapEntry); 397 b = sizeof(stdFontMap) / sizeof(StdFontMapEntry);
398 // invariant: stdFontMap[a].altName <= name < stdFontMap[b].altName 398 // invariant: stdFontMap[a].altName <= name < stdFontMap[b].altName
399 while (b - a > 1) { 399 while (b - a > 1) {
400 m = (a + b) / 2; 400 m = (a + b) / 2;
401 if (name->cmp(stdFontMap[m].altName) >= 0) { 401 if (name->cmp(stdFontMap[m].altName) >= 0) {
402 a = m; 402 a = m;
403 } else { 403 } else {
404 b = m; 404 b = m;
405 } 405 }
406 } 406 }
407 if (!name->cmp(stdFontMap[a].altName)) { 407 if (!name->cmp(stdFontMap[a].altName)) {
408 delete name; 408 delete name;
409 name = new GString(stdFontMap[a].properName); 409 name = new GString(stdFontMap[a].properName);
410 } 410 }
411 } 411 }
412 412
413 // is it a built-in font? 413 // is it a built-in font?
414 builtinFont = NULL; 414 builtinFont = NULL;
415 if (name) { 415 if (name) {
416 for (i = 0; i < nBuiltinFonts; ++i) { 416 for (i = 0; i < nBuiltinFonts; ++i) {
417 if (!name->cmp(builtinFonts[i].name)) { 417 if (!name->cmp(builtinFonts[i].name)) {
418 builtinFont = &builtinFonts[i]; 418 builtinFont = &builtinFonts[i];
419 break; 419 break;
420 } 420 }
421 } 421 }
422 } 422 }
423 423
424 // default ascent/descent values 424 // default ascent/descent values
425 if (builtinFont) { 425 if (builtinFont) {
426 ascent = 0.001 * builtinFont->ascent; 426 ascent = 0.001 * builtinFont->ascent;
427 descent = 0.001 * builtinFont->descent; 427 descent = 0.001 * builtinFont->descent;
428 fontBBox[0] = 0.001 * builtinFont->bbox[0]; 428 fontBBox[0] = 0.001 * builtinFont->bbox[0];
429 fontBBox[1] = 0.001 * builtinFont->bbox[1]; 429 fontBBox[1] = 0.001 * builtinFont->bbox[1];
430 fontBBox[2] = 0.001 * builtinFont->bbox[2]; 430 fontBBox[2] = 0.001 * builtinFont->bbox[2];
431 fontBBox[3] = 0.001 * builtinFont->bbox[3]; 431 fontBBox[3] = 0.001 * builtinFont->bbox[3];
432 } else { 432 } else {
433 ascent = 0.95; 433 ascent = 0.95;
434 descent = -0.35; 434 descent = -0.35;
435 fontBBox[0] = fontBBox[1] = fontBBox[2] = fontBBox[3] = 0; 435 fontBBox[0] = fontBBox[1] = fontBBox[2] = fontBBox[3] = 0;
436 } 436 }
437 437
438 // get info from font descriptor 438 // get info from font descriptor
439 readFontDescriptor(xref, fontDict); 439 readFontDescriptor(xref, fontDict);
440 440
441 // look for an external font file 441 // look for an external font file
442 findExtFontFile(); 442 findExtFontFile();
443 443
444 // get font matrix 444 // get font matrix
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
476 // - others --> StandardEncoding 487 // - others --> StandardEncoding
477 // and then add a list of differences (if any) from 488 // and then add a list of differences (if any) from
478 // FontDict.Encoding.Differences. 489 // FontDict.Encoding.Differences.
479 490
480 // check FontDict for base encoding 491 // check FontDict for base encoding
481 hasEncoding = gFalse; 492 hasEncoding = gFalse;
482 baseEnc = NULL; 493 baseEnc = NULL;
483 baseEncFromFontFile = gFalse; 494 baseEncFromFontFile = gFalse;
484 fontDict->lookup("Encoding", &obj1); 495 fontDict->lookup("Encoding", &obj1);
485 if (obj1.isDict()) { 496 if (obj1.isDict()) {
486 obj1.dictLookup("BaseEncoding", &obj2); 497 obj1.dictLookup("BaseEncoding", &obj2);
487 if (obj2.isName("MacRomanEncoding")) { 498 if (obj2.isName("MacRomanEncoding")) {
488 hasEncoding = gTrue; 499 hasEncoding = gTrue;
489 baseEnc = macRomanEncoding; 500 baseEnc = macRomanEncoding;
490 } else if (obj2.isName("MacExpertEncoding")) { 501 } else if (obj2.isName("MacExpertEncoding")) {
491 hasEncoding = gTrue; 502 hasEncoding = gTrue;
492 baseEnc = macExpertEncoding; 503 baseEnc = macExpertEncoding;
493 } else if (obj2.isName("WinAnsiEncoding")) { 504 } else if (obj2.isName("WinAnsiEncoding")) {
494 hasEncoding = gTrue; 505 hasEncoding = gTrue;
495 baseEnc = winAnsiEncoding; 506 baseEnc = winAnsiEncoding;
496 } else if (obj2.isName("StandardEncoding")) { 507 } else if (obj2.isName("StandardEncoding")) {
497 hasEncoding = gTrue; 508 hasEncoding = gTrue;
498 baseEnc = standardEncoding; 509 baseEnc = standardEncoding;
499 } 510 }
500 obj2.free(); 511 obj2.free();
501 } else if (obj1.isName("MacRomanEncoding")) { 512 } else if (obj1.isName("MacRomanEncoding")) {
502 hasEncoding = gTrue; 513 hasEncoding = gTrue;
503 baseEnc = macRomanEncoding; 514 baseEnc = macRomanEncoding;
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
545 gfree(buf); 561 gfree(buf);
546 } 562 }
547 } 563 }
548 564
549 // get default base encoding 565 // get default base encoding
550 if (!baseEnc) { 566 if (!baseEnc) {
551 if (builtinFont) { 567 if (builtinFont) {
552 baseEnc = builtinFont->defaultBaseEnc; 568 baseEnc = builtinFont->defaultBaseEnc;
553 } else if (type == fontTrueType) { 569 } else if (type == fontTrueType) {
554 baseEnc = macRomanEncoding; 570 baseEnc = macRomanEncoding;
555 } else { 571 } else {
556 baseEnc = standardEncoding; 572 baseEnc = standardEncoding;
557 } 573 }
558 } 574 }
559 575
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;
584 } 601 }
585 ++code; 602 ++code;
586 } else { 603 } else {
587 error(-1, "Wrong type in font encoding resource differences (%s)", 604 error(-1, "Wrong type in font encoding resource differences (%s)",
588 obj3.getTypeName()); 605 obj3.getTypeName());
589 } 606 }
590 obj3.free(); 607 obj3.free();
591 } 608 }
592 } 609 }
593 obj2.free(); 610 obj2.free();
594 } 611 }
595 obj1.free(); 612 obj1.free();
596 if (fontFile) { 613 if (fontFile) {
597 delete fontFile; 614 delete fontFile;
598 } 615 }
599 616
600 //----- build the mapping to Unicode ----- 617 //----- build the mapping to Unicode -----
601 618
602 // look for a ToUnicode CMap 619 // look for a ToUnicode CMap
603 if (!(ctu = readToUnicodeCMap(fontDict, 8))) { 620 if (!(ctu = readToUnicodeCMap(fontDict, 8))) {
604 621
605 // no ToUnicode CMap, so use the char names 622 // no ToUnicode CMap, so use the char names
606 623
607 // pass 1: use the name-to-Unicode mapping table 624 // pass 1: use the name-to-Unicode mapping table
608 missing = hex = gFalse; 625 missing = hex = gFalse;
609 for (code = 0; code < 256; ++code) { 626 for (code = 0; code < 256; ++code) {
610 if ((charName = enc[code])) { 627 if ((charName = enc[code])) {
611 if (!(toUnicode[code] = globalParams->mapNameToUnicode(charName)) && 628 if (!(toUnicode[code] = globalParams->mapNameToUnicode(charName)) &&
612 strcmp(charName, ".notdef")) { 629 strcmp(charName, ".notdef")) {
613 // if it wasn't in the name-to-Unicode table, check for a 630 // if it wasn't in the name-to-Unicode table, check for a
614 // name that looks like 'Axx' or 'xx', where 'A' is any letter 631 // name that looks like 'Axx' or 'xx', where 'A' is any letter
615 // and 'xx' is two hex digits 632 // and 'xx' is two hex digits
616 if ((strlen(charName) == 3 && 633 if ((strlen(charName) == 3 &&
617 isalpha(charName[0]) && 634 isalpha(charName[0]) &&
618 isxdigit(charName[1]) && isxdigit(charName[2]) && 635 isxdigit(charName[1]) && isxdigit(charName[2]) &&
619 ((charName[1] >= 'a' && charName[1] <= 'f') || 636 ((charName[1] >= 'a' && charName[1] <= 'f') ||
620 (charName[1] >= 'A' && charName[1] <= 'F') || 637 (charName[1] >= 'A' && charName[1] <= 'F') ||
621 (charName[2] >= 'a' && charName[2] <= 'f') || 638 (charName[2] >= 'a' && charName[2] <= 'f') ||
622 (charName[2] >= 'A' && charName[2] <= 'F'))) || 639 (charName[2] >= 'A' && charName[2] <= 'F'))) ||
623 (strlen(charName) == 2 && 640 (strlen(charName) == 2 &&
624 isxdigit(charName[0]) && isxdigit(charName[1]) && 641 isxdigit(charName[0]) && isxdigit(charName[1]) &&
625 ((charName[0] >= 'a' && charName[0] <= 'f') || 642 ((charName[0] >= 'a' && charName[0] <= 'f') ||
626 (charName[0] >= 'A' && charName[0] <= 'F') || 643 (charName[0] >= 'A' && charName[0] <= 'F') ||
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 -----
671 692
672 // initialize all widths 693 // initialize all widths
673 for (code = 0; code < 256; ++code) { 694 for (code = 0; code < 256; ++code) {
674 widths[code] = missingWidth * 0.001; 695 widths[code] = missingWidth * 0.001;
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) {
703 if (enc[code] && builtinFont->widths->getWidth(enc[code], &w)) { 728 if (enc[code] && builtinFont->widths->getWidth(enc[code], &w)) {
704 widths[code] = 0.001 * w; 729 widths[code] = 0.001 * w;
705 } 730 }
706 } 731 }
707 732
708 // couldn't find widths -- use defaults 733 // couldn't find widths -- use defaults
709 } else { 734 } else {
710 // this is technically an error -- the Widths entry is required 735 // this is technically an error -- the Widths entry is required
711 // for all but the Base-14 fonts -- but certain PDF generators 736 // for all but the Base-14 fonts -- but certain PDF generators
712 // apparently don't include widths for Arial and TimesNewRoman 737 // apparently don't include widths for Arial and TimesNewRoman
713 if (isFixedWidth()) { 738 if (isFixedWidth()) {
714 i = 0; 739 i = 0;
715 } else if (isSerif()) { 740 } else if (isSerif()) {
716 i = 8; 741 i = 8;
717 } else { 742 } else {
718 i = 4; 743 i = 4;
719 } 744 }
720 if (isBold()) { 745 if (isBold()) {
721 i += 2; 746 i += 2;
722 } 747 }
723 if (isItalic()) { 748 if (isItalic()) {
724 i += 1; 749 i += 1;
725 } 750 }
726 builtinFont = builtinFontSubst[i]; 751 builtinFont = builtinFontSubst[i];
727 // this is a kludge for broken PDF files that encode char 32 752 // this is a kludge for broken PDF files that encode char 32
728 // as .notdef 753 // as .notdef
729 if (builtinFont->widths->getWidth("space", &w)) { 754 if (builtinFont->widths->getWidth("space", &w)) {
730 widths[32] = 0.001 * w; 755 widths[32] = 0.001 * w;
731 } 756 }
732 for (code = 0; code < 256; ++code) { 757 for (code = 0; code < 256; ++code) {
733 if (enc[code] && builtinFont->widths->getWidth(enc[code], &w)) { 758 if (enc[code] && builtinFont->widths->getWidth(enc[code], &w)) {
734 widths[code] = 0.001 * w; 759 widths[code] = 0.001 * w;
735 } 760 }
736 } 761 }
737 } 762 }
738 obj1.free(); 763 obj1.free();
739 764
740 ok = gTrue; 765 ok = gTrue;
741} 766}
742 767
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;
795} 831}
796 832
797GfxCIDFont::GfxCIDFont(XRef *xref, char *tagA, Ref idA, GString *nameA, 833GfxCIDFont::GfxCIDFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
798 Dict *fontDict): 834 Dict *fontDict):
799 GfxFont(tagA, idA, nameA) 835 GfxFont(tagA, idA, nameA)
800{ 836{
801 Dict *desFontDict; 837 Dict *desFontDict;
802 GString *collection, *cMapName; 838 GString *collection, *cMapName;
803 Object desFontDictObj; 839 Object desFontDictObj;
804 Object obj1, obj2, obj3, obj4, obj5, obj6; 840 Object obj1, obj2, obj3, obj4, obj5, obj6;
805 int c1, c2; 841 int c1, c2;
806 int excepsSize, i, j, k; 842 int excepsSize, i, j, k;
807 843
808 ascent = 0.95; 844 ascent = 0.95;
809 descent = -0.35; 845 descent = -0.35;
810 fontBBox[0] = fontBBox[1] = fontBBox[2] = fontBBox[3] = 0; 846 fontBBox[0] = fontBBox[1] = fontBBox[2] = fontBBox[3] = 0;
811 cMap = NULL; 847 cMap = NULL;
812 ctu = NULL; 848 ctu = NULL;
813 widths.defWidth = 1.0; 849 widths.defWidth = 1.0;
814 widths.defHeight = -1.0; 850 widths.defHeight = -1.0;
815 widths.defVY = 0.880; 851 widths.defVY = 0.880;
816 widths.exceps = NULL; 852 widths.exceps = NULL;
817 widths.nExceps = 0; 853 widths.nExceps = 0;
818 widths.excepsV = NULL; 854 widths.excepsV = NULL;
819 widths.nExcepsV = 0; 855 widths.nExcepsV = 0;
820 cidToGID = NULL; 856 cidToGID = NULL;
821 cidToGIDLen = 0; 857 cidToGIDLen = 0;
822 858
823 // get the descendant font 859 // get the descendant font
824 if (!fontDict->lookup("DescendantFonts", &obj1)->isArray()) { 860 if (!fontDict->lookup("DescendantFonts", &obj1)->isArray()) {
825 error(-1, "Missing DescendantFonts entry in Type 0 font"); 861 error(-1, "Missing DescendantFonts entry in Type 0 font");
826 obj1.free(); 862 obj1.free();
827 goto err1; 863 goto err1;
828 } 864 }
829 if (!obj1.arrayGet(0, &desFontDictObj)->isDict()) { 865 if (!obj1.arrayGet(0, &desFontDictObj)->isDict()) {
830 error(-1, "Bad descendant font in Type 0 font"); 866 error(-1, "Bad descendant font in Type 0 font");
831 goto err3; 867 goto err3;
832 } 868 }
833 obj1.free(); 869 obj1.free();
834 desFontDict = desFontDictObj.getDict(); 870 desFontDict = desFontDictObj.getDict();
835 871
836 // font type 872 // font type
837 if (!desFontDict->lookup("Subtype", &obj1)) { 873 if (!desFontDict->lookup("Subtype", &obj1)) {
838 error(-1, "Missing Subtype entry in Type 0 descendant font"); 874 error(-1, "Missing Subtype entry in Type 0 descendant font");
839 goto err3; 875 goto err3;
840 } 876 }
841 if (obj1.isName("CIDFontType0")) { 877 if (obj1.isName("CIDFontType0")) {
842 type = fontCIDType0; 878 type = fontCIDType0;
843 } else if (obj1.isName("CIDFontType2")) { 879 } else if (obj1.isName("CIDFontType2")) {
844 type = fontCIDType2; 880 type = fontCIDType2;
845 } else { 881 } else {
846 error(-1, "Unknown Type 0 descendant font type '%s'", 882 error(-1, "Unknown Type 0 descendant font type '%s'",
847 obj1.isName() ? obj1.getName() : "???"); 883 obj1.isName() ? obj1.getName() : "???");
848 goto err3; 884 goto err3;
849 } 885 }
850 obj1.free(); 886 obj1.free();
851 887
852 // get info from font descriptor 888 // get info from font descriptor
853 readFontDescriptor(xref, desFontDict); 889 readFontDescriptor(xref, desFontDict);
854 890
855 // look for an external font file 891 // look for an external font file
856 findExtFontFile(); 892 findExtFontFile();
857 893
858 //----- encoding info ----- 894 //----- encoding info -----
859 895
860 // char collection 896 // char collection
861 if (!desFontDict->lookup("CIDSystemInfo", &obj1)->isDict()) { 897 if (!desFontDict->lookup("CIDSystemInfo", &obj1)->isDict()) {
862 error(-1, "Missing CIDSystemInfo dictionary in Type 0 descendant font"); 898 error(-1, "Missing CIDSystemInfo dictionary in Type 0 descendant font");
863 goto err3; 899 goto err3;
864 } 900 }
865 obj1.dictLookup("Registry", &obj2); 901 obj1.dictLookup("Registry", &obj2);
866 obj1.dictLookup("Ordering", &obj3); 902 obj1.dictLookup("Ordering", &obj3);
867 if (!obj2.isString() || !obj3.isString()) { 903 if (!obj2.isString() || !obj3.isString()) {
868 error(-1, "Invalid CIDSystemInfo dictionary in Type 0 descendant font"); 904 error(-1, "Invalid CIDSystemInfo dictionary in Type 0 descendant font");
869 goto err4; 905 goto err4;
870 } 906 }
871 collection = obj2.getString()->copy()->append('-')->append(obj3.getString()); 907 collection = obj2.getString()->copy()->append('-')->append(obj3.getString());
872 obj3.free(); 908 obj3.free();
873 obj2.free(); 909 obj2.free();
874 obj1.free(); 910 obj1.free();
875 911
876 // look for a ToUnicode CMap 912 // look for a ToUnicode CMap
877 if (!(ctu = readToUnicodeCMap(fontDict, 16))) { 913 if (!(ctu = readToUnicodeCMap(fontDict, 16))) {
878 914
879 // the "Adobe-Identity" and "Adobe-UCS" collections don't have 915 // the "Adobe-Identity" and "Adobe-UCS" collections don't have
880 // cidToUnicode files 916 // cidToUnicode files
881 if (collection->cmp("Adobe-Identity") && 917 if (collection->cmp("Adobe-Identity") &&
882 collection->cmp("Adobe-UCS")) { 918 collection->cmp("Adobe-UCS")) {
883 919
884 // look for a user-supplied .cidToUnicode file 920 // look for a user-supplied .cidToUnicode file
885 if (!(ctu = globalParams->getCIDToUnicode(collection))) { 921 if (!(ctu = globalParams->getCIDToUnicode(collection))) {
886 error(-1, "Unknown character collection '%s'", 922 error(-1, "Unknown character collection '%s'",
887 collection->getCString()); 923 collection->getCString());
888 delete collection; 924 delete collection;
889 goto err2; 925 goto err2;
890 } 926 }
891 } 927 }
892 } 928 }
893 929
894 // encoding (i.e., CMap) 930 // encoding (i.e., CMap)
895 //~ need to handle a CMap stream here 931 //~ need to handle a CMap stream here
896 //~ also need to deal with the UseCMap entry in the stream dict 932 //~ also need to deal with the UseCMap entry in the stream dict
897 if (!fontDict->lookup("Encoding", &obj1)->isName()) { 933 if (!fontDict->lookup("Encoding", &obj1)->isName()) {
898 error(-1, "Missing or invalid Encoding entry in Type 0 font"); 934 error(-1, "Missing or invalid Encoding entry in Type 0 font");
899 delete collection; 935 delete collection;
900 goto err3; 936 goto err3;
901 } 937 }
902 cMapName = new GString(obj1.getName()); 938 cMapName = new GString(obj1.getName());
903 obj1.free(); 939 obj1.free();
904 if (!(cMap = globalParams->getCMap(collection, cMapName))) { 940 if (!(cMap = globalParams->getCMap(collection, cMapName))) {
905 error(-1, "Unknown CMap '%s' for character collection '%s'", 941 error(-1, "Unknown CMap '%s' for character collection '%s'",
906 cMapName->getCString(), collection->getCString()); 942 cMapName->getCString(), collection->getCString());
907 delete collection; 943 delete collection;
908 delete cMapName; 944 delete cMapName;
909 goto err2; 945 goto err2;
910 } 946 }
911 delete collection; 947 delete collection;
912 delete cMapName; 948 delete cMapName;
913 949
914 // CIDToGIDMap (for embedded TrueType fonts) 950 // CIDToGIDMap (for embedded TrueType fonts)
915 if (type == fontCIDType2) { 951 if (type == fontCIDType2) {
916 fontDict->lookup("CIDToGIDMap", &obj1); 952 fontDict->lookup("CIDToGIDMap", &obj1);
917 if (obj1.isStream()) { 953 if (obj1.isStream()) {
918 cidToGIDLen = 0; 954 cidToGIDLen = 0;
919 i = 64; 955 i = 64;
920 cidToGID = (Gushort *)gmalloc(i * sizeof(Gushort)); 956 cidToGID = (Gushort *)gmalloc(i * sizeof(Gushort));
921 obj1.streamReset(); 957 obj1.streamReset();
922 while ((c1 = obj1.streamGetChar()) != EOF && 958 while ((c1 = obj1.streamGetChar()) != EOF &&
923 (c2 = obj1.streamGetChar()) != EOF) { 959 (c2 = obj1.streamGetChar()) != EOF) {
924 if (cidToGIDLen == i) { 960 if (cidToGIDLen == i) {
925 i *= 2; 961 i *= 2;
926 cidToGID = (Gushort *)grealloc(cidToGID, i * sizeof(Gushort)); 962 cidToGID = (Gushort *)grealloc(cidToGID, i * sizeof(Gushort));
927 } 963 }
928 cidToGID[cidToGIDLen++] = (Gushort)((c1 << 8) + c2); 964 cidToGID[cidToGIDLen++] = (Gushort)((c1 << 8) + c2);
929 } 965 }
930 } else if (!obj1.isName("Identity") && !obj1.isNull()) { 966 } else if (!obj1.isName("Identity") && !obj1.isNull()) {
931 error(-1, "Invalid CIDToGIDMap entry in CID font"); 967 error(-1, "Invalid CIDToGIDMap entry in CID font");
932 } 968 }
933 obj1.free(); 969 obj1.free();
934 } 970 }
935 971
936 //----- character metrics ----- 972 //----- character metrics -----
937 973
938 // default char width 974 // default char width
939 if (desFontDict->lookup("DW", &obj1)->isInt()) { 975 if (desFontDict->lookup("DW", &obj1)->isInt()) {
940 widths.defWidth = obj1.getInt() * 0.001; 976 widths.defWidth = obj1.getInt() * 0.001;
941 } 977 }
942 obj1.free(); 978 obj1.free();
943 979
944 // char width exceptions 980 // char width exceptions
945 if (desFontDict->lookup("W", &obj1)->isArray()) { 981 if (desFontDict->lookup("W", &obj1)->isArray()) {
946 excepsSize = 0; 982 excepsSize = 0;
947 i = 0; 983 i = 0;
948 while (i + 1 < obj1.arrayGetLength()) { 984 while (i + 1 < obj1.arrayGetLength()) {
949 obj1.arrayGet(i, &obj2); 985 obj1.arrayGet(i, &obj2);
950 obj1.arrayGet(i + 1, &obj3); 986 obj1.arrayGet(i + 1, &obj3);
951 if (obj2.isInt() && obj3.isInt() && i + 2 < obj1.arrayGetLength()) { 987 if (obj2.isInt() && obj3.isInt() && i + 2 < obj1.arrayGetLength()) {
952 if (obj1.arrayGet(i + 2, &obj4)->isNum()) { 988 if (obj1.arrayGet(i + 2, &obj4)->isNum()) {
953 if (widths.nExceps == excepsSize) { 989 if (widths.nExceps == excepsSize) {
954 excepsSize += 16; 990 excepsSize += 16;
955 widths.exceps = (GfxFontCIDWidthExcep *) 991 widths.exceps = (GfxFontCIDWidthExcep *)
956 grealloc(widths.exceps, 992 grealloc(widths.exceps,
957 excepsSize * sizeof(GfxFontCIDWidthExcep)); 993 excepsSize * sizeof(GfxFontCIDWidthExcep));
958 } 994 }
959 widths.exceps[widths.nExceps].first = obj2.getInt(); 995 widths.exceps[widths.nExceps].first = obj2.getInt();
960 widths.exceps[widths.nExceps].last = obj3.getInt(); 996 widths.exceps[widths.nExceps].last = obj3.getInt();
961 widths.exceps[widths.nExceps].width = obj4.getNum() * 0.001; 997 widths.exceps[widths.nExceps].width = obj4.getNum() * 0.001;
962 ++widths.nExceps; 998 ++widths.nExceps;
963 } else { 999 } else {
964 error(-1, "Bad widths array in Type 0 font"); 1000 error(-1, "Bad widths array in Type 0 font");
965 } 1001 }
966 obj4.free(); 1002 obj4.free();
967 i += 3; 1003 i += 3;
968 } else if (obj2.isInt() && obj3.isArray()) { 1004 } else if (obj2.isInt() && obj3.isArray()) {
969 if (widths.nExceps + obj3.arrayGetLength() > excepsSize) { 1005 if (widths.nExceps + obj3.arrayGetLength() > excepsSize) {
970 excepsSize = (widths.nExceps + obj3.arrayGetLength() + 15) & ~15; 1006 excepsSize = (widths.nExceps + obj3.arrayGetLength() + 15) & ~15;
971 widths.exceps = (GfxFontCIDWidthExcep *) 1007 widths.exceps = (GfxFontCIDWidthExcep *)
972 grealloc(widths.exceps, 1008 grealloc(widths.exceps,
973 excepsSize * sizeof(GfxFontCIDWidthExcep)); 1009 excepsSize * sizeof(GfxFontCIDWidthExcep));
974 } 1010 }
@@ -997,251 +1033,255 @@ GfxCIDFont::GfxCIDFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
997 &cmpWidthExcep); 1033 &cmpWidthExcep);
998 } 1034 }
999 obj1.free(); 1035 obj1.free();
1000 1036
1001 // default metrics for vertical font 1037 // default metrics for vertical font
1002 if (desFontDict->lookup("DW2", &obj1)->isArray() && 1038 if (desFontDict->lookup("DW2", &obj1)->isArray() &&
1003 obj1.arrayGetLength() == 2) { 1039 obj1.arrayGetLength() == 2) {
1004 if (obj1.arrayGet(0, &obj2)->isNum()) { 1040 if (obj1.arrayGet(0, &obj2)->isNum()) {
1005 widths.defVY = obj1.getNum() * 0.001; 1041 widths.defVY = obj1.getNum() * 0.001;
1006 } 1042 }
1007 obj2.free(); 1043 obj2.free();
1008 if (obj1.arrayGet(1, &obj2)->isNum()) { 1044 if (obj1.arrayGet(1, &obj2)->isNum()) {
1009 widths.defHeight = obj1.getNum() * 0.001; 1045 widths.defHeight = obj1.getNum() * 0.001;
1010 } 1046 }
1011 obj2.free(); 1047 obj2.free();
1012 } 1048 }
1013 obj1.free(); 1049 obj1.free();
1014 1050
1015 // char metric exceptions for vertical font 1051 // char metric exceptions for vertical font
1016 if (desFontDict->lookup("W2", &obj1)->isArray()) { 1052 if (desFontDict->lookup("W2", &obj1)->isArray()) {
1017 excepsSize = 0; 1053 excepsSize = 0;
1018 i = 0; 1054 i = 0;
1019 while (i + 1 < obj1.arrayGetLength()) { 1055 while (i + 1 < obj1.arrayGetLength()) {
1020 obj1.arrayGet(0, &obj2); 1056 obj1.arrayGet(0, &obj2);
1021 obj2.arrayGet(0, &obj3); 1057 obj2.arrayGet(0, &obj3);
1022 if (obj2.isInt() && obj3.isInt() && i + 4 < obj1.arrayGetLength()) { 1058 if (obj2.isInt() && obj3.isInt() && i + 4 < obj1.arrayGetLength()) {
1023 if (obj1.arrayGet(i + 2, &obj4)->isNum() && 1059 if (obj1.arrayGet(i + 2, &obj4)->isNum() &&
1024 obj1.arrayGet(i + 3, &obj5)->isNum() && 1060 obj1.arrayGet(i + 3, &obj5)->isNum() &&
1025 obj1.arrayGet(i + 4, &obj6)->isNum()) { 1061 obj1.arrayGet(i + 4, &obj6)->isNum()) {
1026 if (widths.nExcepsV == excepsSize) { 1062 if (widths.nExcepsV == excepsSize) {
1027 excepsSize += 16; 1063 excepsSize += 16;
1028 widths.excepsV = (GfxFontCIDWidthExcepV *) 1064 widths.excepsV = (GfxFontCIDWidthExcepV *)
1029 grealloc(widths.excepsV, 1065 grealloc(widths.excepsV,
1030 excepsSize * sizeof(GfxFontCIDWidthExcepV)); 1066 excepsSize * sizeof(GfxFontCIDWidthExcepV));
1031 } 1067 }
1032 widths.excepsV[widths.nExcepsV].first = obj2.getInt(); 1068 widths.excepsV[widths.nExcepsV].first = obj2.getInt();
1033 widths.excepsV[widths.nExcepsV].last = obj3.getInt(); 1069 widths.excepsV[widths.nExcepsV].last = obj3.getInt();
1034 widths.excepsV[widths.nExcepsV].height = obj4.getNum() * 0.001; 1070 widths.excepsV[widths.nExcepsV].height = obj4.getNum() * 0.001;
1035 widths.excepsV[widths.nExcepsV].vx = obj5.getNum() * 0.001; 1071 widths.excepsV[widths.nExcepsV].vx = obj5.getNum() * 0.001;
1036 widths.excepsV[widths.nExcepsV].vy = obj6.getNum() * 0.001; 1072 widths.excepsV[widths.nExcepsV].vy = obj6.getNum() * 0.001;
1037 ++widths.nExcepsV; 1073 ++widths.nExcepsV;
1038 } else { 1074 } else {
1039 error(-1, "Bad widths (W2) array in Type 0 font"); 1075 error(-1, "Bad widths (W2) array in Type 0 font");
1040 } 1076 }
1041 obj6.free(); 1077 obj6.free();
1042 obj5.free(); 1078 obj5.free();
1043 obj4.free(); 1079 obj4.free();
1044 i += 5; 1080 i += 5;
1045 } else if (obj2.isInt() && obj3.isArray()) { 1081 } else if (obj2.isInt() && obj3.isArray()) {
1046 if (widths.nExcepsV + obj3.arrayGetLength() / 3 > excepsSize) { 1082 if (widths.nExcepsV + obj3.arrayGetLength() / 3 > excepsSize) {
1047 excepsSize = 1083 excepsSize =
1048 (widths.nExcepsV + obj3.arrayGetLength() / 3 + 15) & ~15; 1084 (widths.nExcepsV + obj3.arrayGetLength() / 3 + 15) & ~15;
1049 widths.excepsV = (GfxFontCIDWidthExcepV *) 1085 widths.excepsV = (GfxFontCIDWidthExcepV *)
1050 grealloc(widths.excepsV, 1086 grealloc(widths.excepsV,
1051 excepsSize * sizeof(GfxFontCIDWidthExcepV)); 1087 excepsSize * sizeof(GfxFontCIDWidthExcepV));
1052 } 1088 }
1053 j = obj2.getInt(); 1089 j = obj2.getInt();
1054 for (k = 0; k < obj3.arrayGetLength(); ++k) { 1090 for (k = 0; k < obj3.arrayGetLength(); ++k) {
1055 if (obj3.arrayGet(k, &obj4)->isNum() && 1091 if (obj3.arrayGet(k, &obj4)->isNum() &&
1056 obj3.arrayGet(k, &obj5)->isNum() && 1092 obj3.arrayGet(k, &obj5)->isNum() &&
1057 obj3.arrayGet(k, &obj6)->isNum()) { 1093 obj3.arrayGet(k, &obj6)->isNum()) {
1058 widths.excepsV[widths.nExceps].first = j; 1094 widths.excepsV[widths.nExceps].first = j;
1059 widths.excepsV[widths.nExceps].last = j; 1095 widths.excepsV[widths.nExceps].last = j;
1060 widths.excepsV[widths.nExceps].height = obj4.getNum() * 0.001; 1096 widths.excepsV[widths.nExceps].height = obj4.getNum() * 0.001;
1061 widths.excepsV[widths.nExceps].vx = obj5.getNum() * 0.001; 1097 widths.excepsV[widths.nExceps].vx = obj5.getNum() * 0.001;
1062 widths.excepsV[widths.nExceps].vy = obj6.getNum() * 0.001; 1098 widths.excepsV[widths.nExceps].vy = obj6.getNum() * 0.001;
1063 ++j; 1099 ++j;
1064 ++widths.nExcepsV; 1100 ++widths.nExcepsV;
1065 } else { 1101 } else {
1066 error(-1, "Bad widths (W2) array in Type 0 font"); 1102 error(-1, "Bad widths (W2) array in Type 0 font");
1067 } 1103 }
1068 obj6.free(); 1104 obj6.free();
1069 obj5.free(); 1105 obj5.free();
1070 obj4.free(); 1106 obj4.free();
1071 } 1107 }
1072 i += 2; 1108 i += 2;
1073 } else { 1109 } else {
1074 error(-1, "Bad widths (W2) array in Type 0 font"); 1110 error(-1, "Bad widths (W2) array in Type 0 font");
1075 ++i; 1111 ++i;
1076 } 1112 }
1077 obj3.free(); 1113 obj3.free();
1078 obj2.free(); 1114 obj2.free();
1079 } 1115 }
1080 qsort(widths.excepsV, widths.nExcepsV, sizeof(GfxFontCIDWidthExcepV), 1116 qsort(widths.excepsV, widths.nExcepsV, sizeof(GfxFontCIDWidthExcepV),
1081 &cmpWidthExcepV); 1117 &cmpWidthExcepV);
1082 } 1118 }
1083 obj1.free(); 1119 obj1.free();
1084 1120
1085 desFontDictObj.free(); 1121 desFontDictObj.free();
1086 ok = gTrue; 1122 ok = gTrue;
1087 return; 1123 return;
1088 1124
1089 err4: 1125 err4:
1090 obj3.free(); 1126 obj3.free();
1091 obj2.free(); 1127 obj2.free();
1092 err3: 1128 err3:
1093 obj1.free(); 1129 obj1.free();
1094 err2: 1130 err2:
1095 desFontDictObj.free(); 1131 desFontDictObj.free();
1096 err1:; 1132 err1:;
1097} 1133}
1098 1134
1099GfxCIDFont::~GfxCIDFont() { 1135GfxCIDFont::~GfxCIDFont() {
1100 if (cMap) { 1136 if (cMap) {
1101 cMap->decRefCnt(); 1137 cMap->decRefCnt();
1102 } 1138 }
1103 if (ctu) { 1139 if (ctu) {
1104 ctu->decRefCnt(); 1140 ctu->decRefCnt();
1105 } 1141 }
1106 gfree(widths.exceps); 1142 gfree(widths.exceps);
1107 gfree(widths.excepsV); 1143 gfree(widths.excepsV);
1108 if (cidToGID) { 1144 if (cidToGID) {
1109 gfree(cidToGID); 1145 gfree(cidToGID);
1110 } 1146 }
1111} 1147}
1112 1148
1113int GfxCIDFont::getNextChar(char *s, int len, CharCode *code, 1149int GfxCIDFont::getNextChar(char *s, int len, CharCode *code,
1114 Unicode *u, int uSize, int *uLen, 1150 Unicode *u, int uSize, int *uLen,
1115 fouble *dx, fouble *dy, fouble *ox, fouble *oy) { 1151 fouble *dx, fouble *dy, fouble *ox, fouble *oy) {
1116 CID cid; 1152 CID cid;
1117 fouble w, h, vx, vy; 1153 fouble w, h, vx, vy;
1118 int n, a, b, m; 1154 int n, a, b, m;
1119 1155
1120 if (!cMap) { 1156 if (!cMap) {
1121 *code = 0; 1157 *code = 0;
1122 *uLen = 0; 1158 *uLen = 0;
1123 *dx = *dy = 0; 1159 *dx = *dy = 0;
1124 return 1; 1160 return 1;
1125 } 1161 }
1126 1162
1127 *code = (CharCode)(cid = cMap->getCID(s, len, &n)); 1163 *code = (CharCode)(cid = cMap->getCID(s, len, &n));
1128 if (ctu) { 1164 if (ctu) {
1129 *uLen = ctu->mapToUnicode(cid, u, uSize); 1165 *uLen = ctu->mapToUnicode(cid, u, uSize);
1130 } else { 1166 } else {
1131 *uLen = 0; 1167 *uLen = 0;
1132 } 1168 }
1133 1169
1134 // horizontal 1170 // horizontal
1135 if (cMap->getWMode() == 0) { 1171 if (cMap->getWMode() == 0) {
1136 w = widths.defWidth; 1172 w = widths.defWidth;
1137 h = vx = vy = 0; 1173 h = vx = vy = 0;
1138 if (widths.nExceps > 0 && cid >= widths.exceps[0].first) { 1174 if (widths.nExceps > 0 && cid >= widths.exceps[0].first) {
1139 a = 0; 1175 a = 0;
1140 b = widths.nExceps; 1176 b = widths.nExceps;
1141 // invariant: widths.exceps[a].first <= cid < widths.exceps[b].first 1177 // invariant: widths.exceps[a].first <= cid < widths.exceps[b].first
1142 while (b - a > 1) { 1178 while (b - a > 1) {
1143 m = (a + b) / 2; 1179 m = (a + b) / 2;
1144 if (widths.exceps[m].first <= cid) { 1180 if (widths.exceps[m].first <= cid) {
1145 a = m; 1181 a = m;
1146 } else { 1182 } else {
1147 b = m; 1183 b = m;
1148 } 1184 }
1149 } 1185 }
1150 if (cid <= widths.exceps[a].last) { 1186 if (cid <= widths.exceps[a].last) {
1151 w = widths.exceps[a].width; 1187 w = widths.exceps[a].width;
1152 } 1188 }
1153 } 1189 }
1154 1190
1155 // vertical 1191 // vertical
1156 } else { 1192 } else {
1157 w = 0; 1193 w = 0;
1158 h = widths.defHeight; 1194 h = widths.defHeight;
1159 vx = widths.defWidth / 2; 1195 vx = widths.defWidth / 2;
1160 vy = widths.defVY; 1196 vy = widths.defVY;
1161 if (widths.nExcepsV > 0 && cid >= widths.excepsV[0].first) { 1197 if (widths.nExcepsV > 0 && cid >= widths.excepsV[0].first) {
1162 a = 0; 1198 a = 0;
1163 b = widths.nExcepsV; 1199 b = widths.nExcepsV;
1164 // invariant: widths.excepsV[a].first <= cid < widths.excepsV[b].first 1200 // invariant: widths.excepsV[a].first <= cid < widths.excepsV[b].first
1165 while (b - a > 1) { 1201 while (b - a > 1) {
1166 m = (a + b) / 2; 1202 m = (a + b) / 2;
1167 if (widths.excepsV[m].last <= cid) { 1203 if (widths.excepsV[m].last <= cid) {
1168 a = m; 1204 a = m;
1169 } else { 1205 } else {
1170 b = m; 1206 b = m;
1171 } 1207 }
1172 } 1208 }
1173 if (cid <= widths.excepsV[a].last) { 1209 if (cid <= widths.excepsV[a].last) {
1174 h = widths.excepsV[a].height; 1210 h = widths.excepsV[a].height;
1175 vx = widths.excepsV[a].vx; 1211 vx = widths.excepsV[a].vx;
1176 vy = widths.excepsV[a].vy; 1212 vy = widths.excepsV[a].vy;
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//------------------------------------------------------------------------
1201 1241
1202GfxFontDict::GfxFontDict(XRef *xref, Dict *fontDict) { 1242GfxFontDict::GfxFontDict(XRef *xref, Dict *fontDict) {
1203 int i; 1243 int i;
1204 Object obj1, obj2; 1244 Object obj1, obj2;
1205 1245
1206 numFonts = fontDict->getLength(); 1246 numFonts = fontDict->getLength();
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]) {
1232 delete fonts[i]; 1272 delete fonts[i];
1233 } 1273 }
1234 } 1274 }
1235 gfree(fonts); 1275 gfree(fonts);
1236} 1276}
1237 1277
1238GfxFont *GfxFontDict::lookup(char *tag) { 1278GfxFont *GfxFontDict::lookup(char *tag) {
1239 int i; 1279 int i;
1240 1280
1241 for (i = 0; i < numFonts; ++i) { 1281 for (i = 0; i < numFonts; ++i) {
1242 if (fonts[i] && fonts[i]->matches(tag)) { 1282 if (fonts[i] && fonts[i]->matches(tag)) {
1243 return fonts[i]; 1283 return fonts[i];
1244 } 1284 }
1245 } 1285 }
1246 return NULL; 1286 return NULL;
1247} 1287}
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,286 +1,298 @@
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"
18#include "Object.h" 18#include "Object.h"
19#include "CharTypes.h" 19#include "CharTypes.h"
20 20
21class Dict; 21class Dict;
22class CMap; 22class CMap;
23class CharCodeToUnicode; 23class CharCodeToUnicode;
24struct GfxFontCIDWidths; 24struct GfxFontCIDWidths;
25 25
26//------------------------------------------------------------------------ 26//------------------------------------------------------------------------
27// GfxFontType 27// GfxFontType
28//------------------------------------------------------------------------ 28//------------------------------------------------------------------------
29 29
30enum GfxFontType { 30enum GfxFontType {
31 //----- Gfx8BitFont 31 //----- Gfx8BitFont
32 fontUnknownType, 32 fontUnknownType,
33 fontType1, 33 fontType1,
34 fontType1C, 34 fontType1C,
35 fontType3, 35 fontType3,
36 fontTrueType, 36 fontTrueType,
37 //----- GfxCIDFont 37 //----- GfxCIDFont
38 fontCIDType0, 38 fontCIDType0,
39 fontCIDType0C, 39 fontCIDType0C,
40 fontCIDType2 40 fontCIDType2
41}; 41};
42 42
43//------------------------------------------------------------------------ 43//------------------------------------------------------------------------
44// GfxFontCIDWidths 44// GfxFontCIDWidths
45//------------------------------------------------------------------------ 45//------------------------------------------------------------------------
46 46
47struct GfxFontCIDWidthExcep { 47struct GfxFontCIDWidthExcep {
48 CID first; // this record applies to 48 CID first; // this record applies to
49 CID last; // CIDs <first>..<last> 49 CID last; // CIDs <first>..<last>
50 fouble width; // char width 50 fouble width; // char width
51}; 51};
52 52
53struct GfxFontCIDWidthExcepV { 53struct GfxFontCIDWidthExcepV {
54 CID first; // this record applies to 54 CID first; // this record applies to
55 CID last; // CIDs <first>..<last> 55 CID last; // CIDs <first>..<last>
56 fouble height; // char height 56 fouble height; // char height
57 fouble vx, vy; // origin position 57 fouble vx, vy; // origin position
58}; 58};
59 59
60struct GfxFontCIDWidths { 60struct GfxFontCIDWidths {
61 fouble defWidth; // default char width 61 fouble defWidth; // default char width
62 fouble defHeight; // default char height 62 fouble defHeight; // default char height
63 fouble defVY; // default origin position 63 fouble defVY; // default origin position
64 GfxFontCIDWidthExcep *exceps;// exceptions 64 GfxFontCIDWidthExcep *exceps;// exceptions
65 int nExceps; // number of valid entries in exceps 65 int nExceps; // number of valid entries in exceps
66 GfxFontCIDWidthExcepV *// exceptions for vertical font 66 GfxFontCIDWidthExcepV *// exceptions for vertical font
67 excepsV; 67 excepsV;
68 int nExcepsV; // number of valid entries in excepsV 68 int nExcepsV; // number of valid entries in excepsV
69}; 69};
70 70
71//------------------------------------------------------------------------ 71//------------------------------------------------------------------------
72// GfxFont 72// GfxFont
73//------------------------------------------------------------------------ 73//------------------------------------------------------------------------
74 74
75#define fontFixedWidth (1 << 0) 75#define fontFixedWidth (1 << 0)
76#define fontSerif (1 << 1) 76#define fontSerif (1 << 1)
77#define fontSymbolic (1 << 2) 77#define fontSymbolic (1 << 2)
78#define fontItalic (1 << 6) 78#define fontItalic (1 << 6)
79#define fontBold (1 << 18) 79#define fontBold (1 << 18)
80 80
81class GfxFont { 81class GfxFont {
82public: 82public:
83 83
84 // Build a GfxFont object. 84 // Build a GfxFont object.
85 static GfxFont *makeFont(XRef *xref, char *tagA, Ref idA, Dict *fontDict); 85 static GfxFont *makeFont(XRef *xref, char *tagA, Ref idA, Dict *fontDict);
86 86
87 GfxFont(char *tagA, Ref idA, GString *nameA); 87 GfxFont(char *tagA, Ref idA, GString *nameA);
88 88
89 virtual ~GfxFont(); 89 virtual ~GfxFont();
90 90
91 GBool isOk() { return ok; } 91 GBool isOk() { return ok; }
92 92
93 // Get font tag. 93 // Get font tag.
94 GString *getTag() { return tag; } 94 GString *getTag() { return tag; }
95 95
96 // Get font dictionary ID. 96 // Get font dictionary ID.
97 Ref *getID() { return &id; } 97 Ref *getID() { return &id; }
98 98
99 // Does this font match the tag? 99 // Does this font match the tag?
100 GBool matches(char *tagA) { return !tag->cmp(tagA); } 100 GBool matches(char *tagA) { return !tag->cmp(tagA); }
101 101
102 // Get base font name. 102 // Get base font name.
103 GString *getName() { return name; } 103 GString *getName() { return name; }
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:
182 184
183 Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA, 185 Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
184 GfxFontType typeA, Dict *fontDict); 186 GfxFontType typeA, Dict *fontDict);
185 187
186 virtual ~Gfx8BitFont(); 188 virtual ~Gfx8BitFont();
187 189
188 virtual int getNextChar(char *s, int len, CharCode *code, 190 virtual int getNextChar(char *s, int len, CharCode *code,
189 Unicode *u, int uSize, int *uLen, 191 Unicode *u, int uSize, int *uLen,
190 fouble *dx, fouble *dy, fouble *ox, fouble *oy); 192 fouble *dx, fouble *dy, fouble *ox, fouble *oy);
191 193
192 // Return the encoding. 194 // Return the encoding.
193 char **getEncoding() { return enc; } 195 char **getEncoding() { return enc; }
194 196
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:
251 263
252 CMap *cMap; // char code --> CID 264 CMap *cMap; // char code --> CID
253 CharCodeToUnicode *ctu;// CID --> Unicode 265 CharCodeToUnicode *ctu;// CID --> Unicode
254 GfxFontCIDWidths widths;// character widths 266 GfxFontCIDWidths widths;// character widths
255 Gushort *cidToGID; // CID --> GID mapping (for embedded 267 Gushort *cidToGID; // CID --> GID mapping (for embedded
256 // TrueType fonts) 268 // TrueType fonts)
257 int cidToGIDLen; 269 int cidToGIDLen;
258}; 270};
259 271
260//------------------------------------------------------------------------ 272//------------------------------------------------------------------------
261// GfxFontDict 273// GfxFontDict
262//------------------------------------------------------------------------ 274//------------------------------------------------------------------------
263 275
264class GfxFontDict { 276class GfxFontDict {
265public: 277public:
266 278
267 // Build the font dictionary, given the PDF font dictionary. 279 // Build the font dictionary, given the PDF font dictionary.
268 GfxFontDict(XRef *xref, Dict *fontDict); 280 GfxFontDict(XRef *xref, Dict *fontDict);
269 281
270 // Destructor. 282 // Destructor.
271 ~GfxFontDict(); 283 ~GfxFontDict();
272 284
273 // Get the specified font. 285 // Get the specified font.
274 GfxFont *lookup(char *tag); 286 GfxFont *lookup(char *tag);
275 287
276 // Iterative access. 288 // Iterative access.
277 int getNumFonts() { return numFonts; } 289 int getNumFonts() { return numFonts; }
278 GfxFont *getFont(int i) { return fonts[i]; } 290 GfxFont *getFont(int i) { return fonts[i]; }
279 291
280private: 292private:
281 293
282 GfxFont **fonts; // list of fonts 294 GfxFont **fonts; // list of fonts
283 int numFonts; // number of fonts 295 int numFonts; // number of fonts
284}; 296};
285 297
286#endif 298#endif
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,197 +1,197 @@
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"
18#include "Error.h" 18#include "Error.h"
19#include "Object.h" 19#include "Object.h"
20#include "Array.h" 20#include "Array.h"
21#include "Page.h" 21#include "Page.h"
22#include "GfxState.h" 22#include "GfxState.h"
23 23
24//------------------------------------------------------------------------ 24//------------------------------------------------------------------------
25 25
26static inline fouble clip01(fouble x) { 26static inline fouble clip01(fouble x) {
27 return (x < 0) ? fouble(0) : ((x > 1) ? fouble(1) : x); 27 return (x < 0) ? fouble(0) : ((x > 1) ? fouble(1) : x);
28} 28}
29 29
30//------------------------------------------------------------------------ 30//------------------------------------------------------------------------
31// GfxColorSpace 31// GfxColorSpace
32//------------------------------------------------------------------------ 32//------------------------------------------------------------------------
33 33
34GfxColorSpace::GfxColorSpace() { 34GfxColorSpace::GfxColorSpace() {
35} 35}
36 36
37GfxColorSpace::~GfxColorSpace() { 37GfxColorSpace::~GfxColorSpace() {
38} 38}
39 39
40GfxColorSpace *GfxColorSpace::parse(Object *csObj) { 40GfxColorSpace *GfxColorSpace::parse(Object *csObj) {
41 GfxColorSpace *cs; 41 GfxColorSpace *cs;
42 Object obj1; 42 Object obj1;
43 43
44 cs = NULL; 44 cs = NULL;
45 if (csObj->isName()) { 45 if (csObj->isName()) {
46 if (csObj->isName("DeviceGray") || csObj->isName("G")) { 46 if (csObj->isName("DeviceGray") || csObj->isName("G")) {
47 cs = new GfxDeviceGrayColorSpace(); 47 cs = new GfxDeviceGrayColorSpace();
48 } else if (csObj->isName("DeviceRGB") || csObj->isName("RGB")) { 48 } else if (csObj->isName("DeviceRGB") || csObj->isName("RGB")) {
49 cs = new GfxDeviceRGBColorSpace(); 49 cs = new GfxDeviceRGBColorSpace();
50 } else if (csObj->isName("DeviceCMYK") || csObj->isName("CMYK")) { 50 } else if (csObj->isName("DeviceCMYK") || csObj->isName("CMYK")) {
51 cs = new GfxDeviceCMYKColorSpace(); 51 cs = new GfxDeviceCMYKColorSpace();
52 } else if (csObj->isName("Pattern")) { 52 } else if (csObj->isName("Pattern")) {
53 cs = new GfxPatternColorSpace(NULL); 53 cs = new GfxPatternColorSpace(NULL);
54 } else { 54 } else {
55 error(-1, "Bad color space '%s'", csObj->getName()); 55 error(-1, "Bad color space '%s'", csObj->getName());
56 } 56 }
57 } else if (csObj->isArray()) { 57 } else if (csObj->isArray()) {
58 csObj->arrayGet(0, &obj1); 58 csObj->arrayGet(0, &obj1);
59 if (obj1.isName("DeviceGray") || obj1.isName("G")) { 59 if (obj1.isName("DeviceGray") || obj1.isName("G")) {
60 cs = new GfxDeviceGrayColorSpace(); 60 cs = new GfxDeviceGrayColorSpace();
61 } else if (obj1.isName("DeviceRGB") || obj1.isName("RGB")) { 61 } else if (obj1.isName("DeviceRGB") || obj1.isName("RGB")) {
62 cs = new GfxDeviceRGBColorSpace(); 62 cs = new GfxDeviceRGBColorSpace();
63 } else if (obj1.isName("DeviceCMYK") || obj1.isName("CMYK")) { 63 } else if (obj1.isName("DeviceCMYK") || obj1.isName("CMYK")) {
64 cs = new GfxDeviceCMYKColorSpace(); 64 cs = new GfxDeviceCMYKColorSpace();
65 } else if (obj1.isName("CalGray")) { 65 } else if (obj1.isName("CalGray")) {
66 cs = GfxCalGrayColorSpace::parse(csObj->getArray()); 66 cs = GfxCalGrayColorSpace::parse(csObj->getArray());
67 } else if (obj1.isName("CalRGB")) { 67 } else if (obj1.isName("CalRGB")) {
68 cs = GfxCalRGBColorSpace::parse(csObj->getArray()); 68 cs = GfxCalRGBColorSpace::parse(csObj->getArray());
69 } else if (obj1.isName("Lab")) { 69 } else if (obj1.isName("Lab")) {
70 cs = GfxLabColorSpace::parse(csObj->getArray()); 70 cs = GfxLabColorSpace::parse(csObj->getArray());
71 } else if (obj1.isName("ICCBased")) { 71 } else if (obj1.isName("ICCBased")) {
72 cs = GfxICCBasedColorSpace::parse(csObj->getArray()); 72 cs = GfxICCBasedColorSpace::parse(csObj->getArray());
73 } else if (obj1.isName("Indexed") || obj1.isName("I")) { 73 } else if (obj1.isName("Indexed") || obj1.isName("I")) {
74 cs = GfxIndexedColorSpace::parse(csObj->getArray()); 74 cs = GfxIndexedColorSpace::parse(csObj->getArray());
75 } else if (obj1.isName("Separation")) { 75 } else if (obj1.isName("Separation")) {
76 cs = GfxSeparationColorSpace::parse(csObj->getArray()); 76 cs = GfxSeparationColorSpace::parse(csObj->getArray());
77 } else if (obj1.isName("DeviceN")) { 77 } else if (obj1.isName("DeviceN")) {
78 cs = GfxDeviceNColorSpace::parse(csObj->getArray()); 78 cs = GfxDeviceNColorSpace::parse(csObj->getArray());
79 } else if (obj1.isName("Pattern")) { 79 } else if (obj1.isName("Pattern")) {
80 cs = GfxPatternColorSpace::parse(csObj->getArray()); 80 cs = GfxPatternColorSpace::parse(csObj->getArray());
81 } else { 81 } else {
82 error(-1, "Bad color space '%s'", csObj->getName()); 82 error(-1, "Bad color space '%s'", csObj->getName());
83 } 83 }
84 obj1.free(); 84 obj1.free();
85 } else { 85 } else {
86 error(-1, "Bad color space - expected name or array"); 86 error(-1, "Bad color space - expected name or array");
87 } 87 }
88 return cs; 88 return cs;
89} 89}
90 90
91void GfxColorSpace::getDefaultRanges(fouble *decodeLow, fouble *decodeRange, 91void GfxColorSpace::getDefaultRanges(fouble *decodeLow, fouble *decodeRange,
92 int maxImgPixel) { 92 int maxImgPixel) {
93 int i; 93 int i;
94 94
95 for (i = 0; i < getNComps(); ++i) { 95 for (i = 0; i < getNComps(); ++i) {
96 decodeLow[i] = 0; 96 decodeLow[i] = 0;
97 decodeRange[i] = 1; 97 decodeRange[i] = 1;
98 } 98 }
99} 99}
100 100
101//------------------------------------------------------------------------ 101//------------------------------------------------------------------------
102// GfxDeviceGrayColorSpace 102// GfxDeviceGrayColorSpace
103//------------------------------------------------------------------------ 103//------------------------------------------------------------------------
104 104
105GfxDeviceGrayColorSpace::GfxDeviceGrayColorSpace() { 105GfxDeviceGrayColorSpace::GfxDeviceGrayColorSpace() {
106} 106}
107 107
108GfxDeviceGrayColorSpace::~GfxDeviceGrayColorSpace() { 108GfxDeviceGrayColorSpace::~GfxDeviceGrayColorSpace() {
109} 109}
110 110
111GfxColorSpace *GfxDeviceGrayColorSpace::copy() { 111GfxColorSpace *GfxDeviceGrayColorSpace::copy() {
112 return new GfxDeviceGrayColorSpace(); 112 return new GfxDeviceGrayColorSpace();
113} 113}
114 114
115void GfxDeviceGrayColorSpace::getGray(GfxColor *color, fouble *gray) { 115void GfxDeviceGrayColorSpace::getGray(GfxColor *color, fouble *gray) {
116 *gray = clip01(color->c[0]); 116 *gray = clip01(color->c[0]);
117} 117}
118 118
119void GfxDeviceGrayColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) { 119void GfxDeviceGrayColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
120 rgb->r = rgb->g = rgb->b = clip01(color->c[0]); 120 rgb->r = rgb->g = rgb->b = clip01(color->c[0]);
121} 121}
122 122
123void GfxDeviceGrayColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) { 123void GfxDeviceGrayColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {
124 cmyk->c = cmyk->m = cmyk->y = 0; 124 cmyk->c = cmyk->m = cmyk->y = 0;
125 cmyk->k = clip01(1 - color->c[0]); 125 cmyk->k = clip01(1 - color->c[0]);
126} 126}
127 127
128//------------------------------------------------------------------------ 128//------------------------------------------------------------------------
129// GfxCalGrayColorSpace 129// GfxCalGrayColorSpace
130//------------------------------------------------------------------------ 130//------------------------------------------------------------------------
131 131
132GfxCalGrayColorSpace::GfxCalGrayColorSpace() { 132GfxCalGrayColorSpace::GfxCalGrayColorSpace() {
133 whiteX = whiteY = whiteZ = 1; 133 whiteX = whiteY = whiteZ = 1;
134 blackX = blackY = blackZ = 0; 134 blackX = blackY = blackZ = 0;
135 gamma = 1; 135 gamma = 1;
136} 136}
137 137
138GfxCalGrayColorSpace::~GfxCalGrayColorSpace() { 138GfxCalGrayColorSpace::~GfxCalGrayColorSpace() {
139} 139}
140 140
141GfxColorSpace *GfxCalGrayColorSpace::copy() { 141GfxColorSpace *GfxCalGrayColorSpace::copy() {
142 GfxCalGrayColorSpace *cs; 142 GfxCalGrayColorSpace *cs;
143 143
144 cs = new GfxCalGrayColorSpace(); 144 cs = new GfxCalGrayColorSpace();
145 cs->whiteX = whiteX; 145 cs->whiteX = whiteX;
146 cs->whiteY = whiteY; 146 cs->whiteY = whiteY;
147 cs->whiteZ = whiteZ; 147 cs->whiteZ = whiteZ;
148 cs->blackX = blackX; 148 cs->blackX = blackX;
149 cs->blackY = blackY; 149 cs->blackY = blackY;
150 cs->blackZ = blackZ; 150 cs->blackZ = blackZ;
151 cs->gamma = gamma; 151 cs->gamma = gamma;
152 return cs; 152 return cs;
153} 153}
154 154
155GfxColorSpace *GfxCalGrayColorSpace::parse(Array *arr) { 155GfxColorSpace *GfxCalGrayColorSpace::parse(Array *arr) {
156 GfxCalGrayColorSpace *cs; 156 GfxCalGrayColorSpace *cs;
157 Object obj1, obj2, obj3; 157 Object obj1, obj2, obj3;
158 158
159 arr->get(1, &obj1); 159 arr->get(1, &obj1);
160 if (!obj1.isDict()) { 160 if (!obj1.isDict()) {
161 error(-1, "Bad CalGray color space"); 161 error(-1, "Bad CalGray color space");
162 obj1.free(); 162 obj1.free();
163 return NULL; 163 return NULL;
164 } 164 }
165 cs = new GfxCalGrayColorSpace(); 165 cs = new GfxCalGrayColorSpace();
166 if (obj1.dictLookup("WhitePoint", &obj2)->isArray() && 166 if (obj1.dictLookup("WhitePoint", &obj2)->isArray() &&
167 obj2.arrayGetLength() == 3) { 167 obj2.arrayGetLength() == 3) {
168 obj2.arrayGet(0, &obj3); 168 obj2.arrayGet(0, &obj3);
169 cs->whiteX = obj3.getNum(); 169 cs->whiteX = obj3.getNum();
170 obj3.free(); 170 obj3.free();
171 obj2.arrayGet(1, &obj3); 171 obj2.arrayGet(1, &obj3);
172 cs->whiteY = obj3.getNum(); 172 cs->whiteY = obj3.getNum();
173 obj3.free(); 173 obj3.free();
174 obj2.arrayGet(2, &obj3); 174 obj2.arrayGet(2, &obj3);
175 cs->whiteZ = obj3.getNum(); 175 cs->whiteZ = obj3.getNum();
176 obj3.free(); 176 obj3.free();
177 } 177 }
178 obj2.free(); 178 obj2.free();
179 if (obj1.dictLookup("BlackPoint", &obj2)->isArray() && 179 if (obj1.dictLookup("BlackPoint", &obj2)->isArray() &&
180 obj2.arrayGetLength() == 3) { 180 obj2.arrayGetLength() == 3) {
181 obj2.arrayGet(0, &obj3); 181 obj2.arrayGet(0, &obj3);
182 cs->blackX = obj3.getNum(); 182 cs->blackX = obj3.getNum();
183 obj3.free(); 183 obj3.free();
184 obj2.arrayGet(1, &obj3); 184 obj2.arrayGet(1, &obj3);
185 cs->blackY = obj3.getNum(); 185 cs->blackY = obj3.getNum();
186 obj3.free(); 186 obj3.free();
187 obj2.arrayGet(2, &obj3); 187 obj2.arrayGet(2, &obj3);
188 cs->blackZ = obj3.getNum(); 188 cs->blackZ = obj3.getNum();
189 obj3.free(); 189 obj3.free();
190 } 190 }
191 obj2.free(); 191 obj2.free();
192 if (obj1.dictLookup("Gamma", &obj2)->isNum()) { 192 if (obj1.dictLookup("Gamma", &obj2)->isNum()) {
193 cs->gamma = obj2.getNum(); 193 cs->gamma = obj2.getNum();
194 } 194 }
195 obj2.free(); 195 obj2.free();
196 obj1.free(); 196 obj1.free();
197 return cs; 197 return cs;
@@ -219,387 +219,400 @@ GfxDeviceRGBColorSpace::GfxDeviceRGBColorSpace() {
219 219
220GfxDeviceRGBColorSpace::~GfxDeviceRGBColorSpace() { 220GfxDeviceRGBColorSpace::~GfxDeviceRGBColorSpace() {
221} 221}
222 222
223GfxColorSpace *GfxDeviceRGBColorSpace::copy() { 223GfxColorSpace *GfxDeviceRGBColorSpace::copy() {
224 return new GfxDeviceRGBColorSpace(); 224 return new GfxDeviceRGBColorSpace();
225} 225}
226 226
227void GfxDeviceRGBColorSpace::getGray(GfxColor *color, fouble *gray) { 227void GfxDeviceRGBColorSpace::getGray(GfxColor *color, fouble *gray) {
228 *gray = clip01(0.299 * color->c[0] + 228 *gray = clip01(0.299 * color->c[0] +
229 0.587 * color->c[1] + 229 0.587 * color->c[1] +
230 0.114 * color->c[2]); 230 0.114 * color->c[2]);
231} 231}
232 232
233void GfxDeviceRGBColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) { 233void GfxDeviceRGBColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
234 rgb->r = clip01(color->c[0]); 234 rgb->r = clip01(color->c[0]);
235 rgb->g = clip01(color->c[1]); 235 rgb->g = clip01(color->c[1]);
236 rgb->b = clip01(color->c[2]); 236 rgb->b = clip01(color->c[2]);
237} 237}
238 238
239void GfxDeviceRGBColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) { 239void GfxDeviceRGBColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {
240 fouble c, m, y, k; 240 fouble c, m, y, k;
241 241
242 c = clip01(1 - color->c[0]); 242 c = clip01(1 - color->c[0]);
243 m = clip01(1 - color->c[1]); 243 m = clip01(1 - color->c[1]);
244 y = clip01(1 - color->c[2]); 244 y = clip01(1 - color->c[2]);
245 k = c; 245 k = c;
246 if (m < k) { 246 if (m < k) {
247 k = m; 247 k = m;
248 } 248 }
249 if (y < k) { 249 if (y < k) {
250 k = y; 250 k = y;
251 } 251 }
252 cmyk->c = c - k; 252 cmyk->c = c - k;
253 cmyk->m = m - k; 253 cmyk->m = m - k;
254 cmyk->y = y - k; 254 cmyk->y = y - k;
255 cmyk->k = k; 255 cmyk->k = k;
256} 256}
257 257
258//------------------------------------------------------------------------ 258//------------------------------------------------------------------------
259// GfxCalRGBColorSpace 259// GfxCalRGBColorSpace
260//------------------------------------------------------------------------ 260//------------------------------------------------------------------------
261 261
262GfxCalRGBColorSpace::GfxCalRGBColorSpace() { 262GfxCalRGBColorSpace::GfxCalRGBColorSpace() {
263 whiteX = whiteY = whiteZ = 1; 263 whiteX = whiteY = whiteZ = 1;
264 blackX = blackY = blackZ = 0; 264 blackX = blackY = blackZ = 0;
265 gammaR = gammaG = gammaB = 1; 265 gammaR = gammaG = gammaB = 1;
266 mat[0] = 1; mat[1] = 0; mat[2] = 0; 266 mat[0] = 1; mat[1] = 0; mat[2] = 0;
267 mat[3] = 0; mat[4] = 1; mat[5] = 0; 267 mat[3] = 0; mat[4] = 1; mat[5] = 0;
268 mat[6] = 0; mat[7] = 0; mat[8] = 1; 268 mat[6] = 0; mat[7] = 0; mat[8] = 1;
269} 269}
270 270
271GfxCalRGBColorSpace::~GfxCalRGBColorSpace() { 271GfxCalRGBColorSpace::~GfxCalRGBColorSpace() {
272} 272}
273 273
274GfxColorSpace *GfxCalRGBColorSpace::copy() { 274GfxColorSpace *GfxCalRGBColorSpace::copy() {
275 GfxCalRGBColorSpace *cs; 275 GfxCalRGBColorSpace *cs;
276 int i; 276 int i;
277 277
278 cs = new GfxCalRGBColorSpace(); 278 cs = new GfxCalRGBColorSpace();
279 cs->whiteX = whiteX; 279 cs->whiteX = whiteX;
280 cs->whiteY = whiteY; 280 cs->whiteY = whiteY;
281 cs->whiteZ = whiteZ; 281 cs->whiteZ = whiteZ;
282 cs->blackX = blackX; 282 cs->blackX = blackX;
283 cs->blackY = blackY; 283 cs->blackY = blackY;
284 cs->blackZ = blackZ; 284 cs->blackZ = blackZ;
285 cs->gammaR = gammaR; 285 cs->gammaR = gammaR;
286 cs->gammaG = gammaG; 286 cs->gammaG = gammaG;
287 cs->gammaB = gammaB; 287 cs->gammaB = gammaB;
288 for (i = 0; i < 9; ++i) { 288 for (i = 0; i < 9; ++i) {
289 cs->mat[i] = mat[i]; 289 cs->mat[i] = mat[i];
290 } 290 }
291 return cs; 291 return cs;
292} 292}
293 293
294GfxColorSpace *GfxCalRGBColorSpace::parse(Array *arr) { 294GfxColorSpace *GfxCalRGBColorSpace::parse(Array *arr) {
295 GfxCalRGBColorSpace *cs; 295 GfxCalRGBColorSpace *cs;
296 Object obj1, obj2, obj3; 296 Object obj1, obj2, obj3;
297 int i; 297 int i;
298 298
299 arr->get(1, &obj1); 299 arr->get(1, &obj1);
300 if (!obj1.isDict()) { 300 if (!obj1.isDict()) {
301 error(-1, "Bad CalRGB color space"); 301 error(-1, "Bad CalRGB color space");
302 obj1.free(); 302 obj1.free();
303 return NULL; 303 return NULL;
304 } 304 }
305 cs = new GfxCalRGBColorSpace(); 305 cs = new GfxCalRGBColorSpace();
306 if (obj1.dictLookup("WhitePoint", &obj2)->isArray() && 306 if (obj1.dictLookup("WhitePoint", &obj2)->isArray() &&
307 obj2.arrayGetLength() == 3) { 307 obj2.arrayGetLength() == 3) {
308 obj2.arrayGet(0, &obj3); 308 obj2.arrayGet(0, &obj3);
309 cs->whiteX = obj3.getNum(); 309 cs->whiteX = obj3.getNum();
310 obj3.free(); 310 obj3.free();
311 obj2.arrayGet(1, &obj3); 311 obj2.arrayGet(1, &obj3);
312 cs->whiteY = obj3.getNum(); 312 cs->whiteY = obj3.getNum();
313 obj3.free(); 313 obj3.free();
314 obj2.arrayGet(2, &obj3); 314 obj2.arrayGet(2, &obj3);
315 cs->whiteZ = obj3.getNum(); 315 cs->whiteZ = obj3.getNum();
316 obj3.free(); 316 obj3.free();
317 } 317 }
318 obj2.free(); 318 obj2.free();
319 if (obj1.dictLookup("BlackPoint", &obj2)->isArray() && 319 if (obj1.dictLookup("BlackPoint", &obj2)->isArray() &&
320 obj2.arrayGetLength() == 3) { 320 obj2.arrayGetLength() == 3) {
321 obj2.arrayGet(0, &obj3); 321 obj2.arrayGet(0, &obj3);
322 cs->blackX = obj3.getNum(); 322 cs->blackX = obj3.getNum();
323 obj3.free(); 323 obj3.free();
324 obj2.arrayGet(1, &obj3); 324 obj2.arrayGet(1, &obj3);
325 cs->blackY = obj3.getNum(); 325 cs->blackY = obj3.getNum();
326 obj3.free(); 326 obj3.free();
327 obj2.arrayGet(2, &obj3); 327 obj2.arrayGet(2, &obj3);
328 cs->blackZ = obj3.getNum(); 328 cs->blackZ = obj3.getNum();
329 obj3.free(); 329 obj3.free();
330 } 330 }
331 obj2.free(); 331 obj2.free();
332 if (obj1.dictLookup("Gamma", &obj2)->isArray() && 332 if (obj1.dictLookup("Gamma", &obj2)->isArray() &&
333 obj2.arrayGetLength() == 3) { 333 obj2.arrayGetLength() == 3) {
334 obj2.arrayGet(0, &obj3); 334 obj2.arrayGet(0, &obj3);
335 cs->gammaR = obj3.getNum(); 335 cs->gammaR = obj3.getNum();
336 obj3.free(); 336 obj3.free();
337 obj2.arrayGet(1, &obj3); 337 obj2.arrayGet(1, &obj3);
338 cs->gammaG = obj3.getNum(); 338 cs->gammaG = obj3.getNum();
339 obj3.free(); 339 obj3.free();
340 obj2.arrayGet(2, &obj3); 340 obj2.arrayGet(2, &obj3);
341 cs->gammaB = obj3.getNum(); 341 cs->gammaB = obj3.getNum();
342 obj3.free(); 342 obj3.free();
343 } 343 }
344 obj2.free(); 344 obj2.free();
345 if (obj1.dictLookup("Matrix", &obj2)->isArray() && 345 if (obj1.dictLookup("Matrix", &obj2)->isArray() &&
346 obj2.arrayGetLength() == 9) { 346 obj2.arrayGetLength() == 9) {
347 for (i = 0; i < 9; ++i) { 347 for (i = 0; i < 9; ++i) {
348 obj2.arrayGet(i, &obj3); 348 obj2.arrayGet(i, &obj3);
349 cs->mat[i] = obj3.getNum(); 349 cs->mat[i] = obj3.getNum();
350 obj3.free(); 350 obj3.free();
351 } 351 }
352 } 352 }
353 obj2.free(); 353 obj2.free();
354 obj1.free(); 354 obj1.free();
355 return cs; 355 return cs;
356} 356}
357 357
358void GfxCalRGBColorSpace::getGray(GfxColor *color, fouble *gray) { 358void GfxCalRGBColorSpace::getGray(GfxColor *color, fouble *gray) {
359 *gray = clip01(0.299 * color->c[0] + 359 *gray = clip01(0.299 * color->c[0] +
360 0.587 * color->c[1] + 360 0.587 * color->c[1] +
361 0.114 * color->c[2]); 361 0.114 * color->c[2]);
362} 362}
363 363
364void GfxCalRGBColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) { 364void GfxCalRGBColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
365 rgb->r = clip01(color->c[0]); 365 rgb->r = clip01(color->c[0]);
366 rgb->g = clip01(color->c[1]); 366 rgb->g = clip01(color->c[1]);
367 rgb->b = clip01(color->c[2]); 367 rgb->b = clip01(color->c[2]);
368} 368}
369 369
370void GfxCalRGBColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) { 370void GfxCalRGBColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {
371 fouble c, m, y, k; 371 fouble c, m, y, k;
372 372
373 c = clip01(1 - color->c[0]); 373 c = clip01(1 - color->c[0]);
374 m = clip01(1 - color->c[1]); 374 m = clip01(1 - color->c[1]);
375 y = clip01(1 - color->c[2]); 375 y = clip01(1 - color->c[2]);
376 k = c; 376 k = c;
377 if (m < k) { 377 if (m < k) {
378 k = m; 378 k = m;
379 } 379 }
380 if (y < k) { 380 if (y < k) {
381 k = y; 381 k = y;
382 } 382 }
383 cmyk->c = c - k; 383 cmyk->c = c - k;
384 cmyk->m = m - k; 384 cmyk->m = m - k;
385 cmyk->y = y - k; 385 cmyk->y = y - k;
386 cmyk->k = k; 386 cmyk->k = k;
387} 387}
388 388
389//------------------------------------------------------------------------ 389//------------------------------------------------------------------------
390// GfxDeviceCMYKColorSpace 390// GfxDeviceCMYKColorSpace
391//------------------------------------------------------------------------ 391//------------------------------------------------------------------------
392 392
393GfxDeviceCMYKColorSpace::GfxDeviceCMYKColorSpace() { 393GfxDeviceCMYKColorSpace::GfxDeviceCMYKColorSpace() {
394} 394}
395 395
396GfxDeviceCMYKColorSpace::~GfxDeviceCMYKColorSpace() { 396GfxDeviceCMYKColorSpace::~GfxDeviceCMYKColorSpace() {
397} 397}
398 398
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//------------------------------------------------------------------------
426 439
427// This is the inverse of MatrixLMN in Example 4.10 from the PostScript 440// This is the inverse of MatrixLMN in Example 4.10 from the PostScript
428// Language Reference, Third Edition. 441// Language Reference, Third Edition.
429static fouble xyzrgb[3][3] = { 442static fouble xyzrgb[3][3] = {
430 { 3.240449, -1.537136, -0.498531 }, 443 { 3.240449, -1.537136, -0.498531 },
431 { -0.969265, 1.876011, 0.041556 }, 444 { -0.969265, 1.876011, 0.041556 },
432 { 0.055643, -0.204026, 1.057229 } 445 { 0.055643, -0.204026, 1.057229 }
433}; 446};
434 447
435GfxLabColorSpace::GfxLabColorSpace() { 448GfxLabColorSpace::GfxLabColorSpace() {
436 whiteX = whiteY = whiteZ = 1; 449 whiteX = whiteY = whiteZ = 1;
437 blackX = blackY = blackZ = 0; 450 blackX = blackY = blackZ = 0;
438 aMin = bMin = -100; 451 aMin = bMin = -100;
439 aMax = bMax = 100; 452 aMax = bMax = 100;
440} 453}
441 454
442GfxLabColorSpace::~GfxLabColorSpace() { 455GfxLabColorSpace::~GfxLabColorSpace() {
443} 456}
444 457
445GfxColorSpace *GfxLabColorSpace::copy() { 458GfxColorSpace *GfxLabColorSpace::copy() {
446 GfxLabColorSpace *cs; 459 GfxLabColorSpace *cs;
447 460
448 cs = new GfxLabColorSpace(); 461 cs = new GfxLabColorSpace();
449 cs->whiteX = whiteX; 462 cs->whiteX = whiteX;
450 cs->whiteY = whiteY; 463 cs->whiteY = whiteY;
451 cs->whiteZ = whiteZ; 464 cs->whiteZ = whiteZ;
452 cs->blackX = blackX; 465 cs->blackX = blackX;
453 cs->blackY = blackY; 466 cs->blackY = blackY;
454 cs->blackZ = blackZ; 467 cs->blackZ = blackZ;
455 cs->aMin = aMin; 468 cs->aMin = aMin;
456 cs->aMax = aMax; 469 cs->aMax = aMax;
457 cs->bMin = bMin; 470 cs->bMin = bMin;
458 cs->bMax = bMax; 471 cs->bMax = bMax;
459 cs->kr = kr; 472 cs->kr = kr;
460 cs->kg = kg; 473 cs->kg = kg;
461 cs->kb = kb; 474 cs->kb = kb;
462 return cs; 475 return cs;
463} 476}
464 477
465GfxColorSpace *GfxLabColorSpace::parse(Array *arr) { 478GfxColorSpace *GfxLabColorSpace::parse(Array *arr) {
466 GfxLabColorSpace *cs; 479 GfxLabColorSpace *cs;
467 Object obj1, obj2, obj3; 480 Object obj1, obj2, obj3;
468 481
469 arr->get(1, &obj1); 482 arr->get(1, &obj1);
470 if (!obj1.isDict()) { 483 if (!obj1.isDict()) {
471 error(-1, "Bad Lab color space"); 484 error(-1, "Bad Lab color space");
472 obj1.free(); 485 obj1.free();
473 return NULL; 486 return NULL;
474 } 487 }
475 cs = new GfxLabColorSpace(); 488 cs = new GfxLabColorSpace();
476 if (obj1.dictLookup("WhitePoint", &obj2)->isArray() && 489 if (obj1.dictLookup("WhitePoint", &obj2)->isArray() &&
477 obj2.arrayGetLength() == 3) { 490 obj2.arrayGetLength() == 3) {
478 obj2.arrayGet(0, &obj3); 491 obj2.arrayGet(0, &obj3);
479 cs->whiteX = obj3.getNum(); 492 cs->whiteX = obj3.getNum();
480 obj3.free(); 493 obj3.free();
481 obj2.arrayGet(1, &obj3); 494 obj2.arrayGet(1, &obj3);
482 cs->whiteY = obj3.getNum(); 495 cs->whiteY = obj3.getNum();
483 obj3.free(); 496 obj3.free();
484 obj2.arrayGet(2, &obj3); 497 obj2.arrayGet(2, &obj3);
485 cs->whiteZ = obj3.getNum(); 498 cs->whiteZ = obj3.getNum();
486 obj3.free(); 499 obj3.free();
487 } 500 }
488 obj2.free(); 501 obj2.free();
489 if (obj1.dictLookup("BlackPoint", &obj2)->isArray() && 502 if (obj1.dictLookup("BlackPoint", &obj2)->isArray() &&
490 obj2.arrayGetLength() == 3) { 503 obj2.arrayGetLength() == 3) {
491 obj2.arrayGet(0, &obj3); 504 obj2.arrayGet(0, &obj3);
492 cs->blackX = obj3.getNum(); 505 cs->blackX = obj3.getNum();
493 obj3.free(); 506 obj3.free();
494 obj2.arrayGet(1, &obj3); 507 obj2.arrayGet(1, &obj3);
495 cs->blackY = obj3.getNum(); 508 cs->blackY = obj3.getNum();
496 obj3.free(); 509 obj3.free();
497 obj2.arrayGet(2, &obj3); 510 obj2.arrayGet(2, &obj3);
498 cs->blackZ = obj3.getNum(); 511 cs->blackZ = obj3.getNum();
499 obj3.free(); 512 obj3.free();
500 } 513 }
501 obj2.free(); 514 obj2.free();
502 if (obj1.dictLookup("Range", &obj2)->isArray() && 515 if (obj1.dictLookup("Range", &obj2)->isArray() &&
503 obj2.arrayGetLength() == 4) { 516 obj2.arrayGetLength() == 4) {
504 obj2.arrayGet(0, &obj3); 517 obj2.arrayGet(0, &obj3);
505 cs->aMin = obj3.getNum(); 518 cs->aMin = obj3.getNum();
506 obj3.free(); 519 obj3.free();
507 obj2.arrayGet(1, &obj3); 520 obj2.arrayGet(1, &obj3);
508 cs->aMax = obj3.getNum(); 521 cs->aMax = obj3.getNum();
509 obj3.free(); 522 obj3.free();
510 obj2.arrayGet(2, &obj3); 523 obj2.arrayGet(2, &obj3);
511 cs->bMin = obj3.getNum(); 524 cs->bMin = obj3.getNum();
512 obj3.free(); 525 obj3.free();
513 obj2.arrayGet(3, &obj3); 526 obj2.arrayGet(3, &obj3);
514 cs->bMax = obj3.getNum(); 527 cs->bMax = obj3.getNum();
515 obj3.free(); 528 obj3.free();
516 } 529 }
517 obj2.free(); 530 obj2.free();
518 obj1.free(); 531 obj1.free();
519 532
520 cs->kr = 1 / (xyzrgb[0][0] * cs->whiteX + 533 cs->kr = 1 / (xyzrgb[0][0] * cs->whiteX +
521 xyzrgb[0][1] * cs->whiteY + 534 xyzrgb[0][1] * cs->whiteY +
522 xyzrgb[0][2] * cs->whiteZ); 535 xyzrgb[0][2] * cs->whiteZ);
523 cs->kg = 1 / (xyzrgb[1][0] * cs->whiteX + 536 cs->kg = 1 / (xyzrgb[1][0] * cs->whiteX +
524 xyzrgb[1][1] * cs->whiteY + 537 xyzrgb[1][1] * cs->whiteY +
525 xyzrgb[1][2] * cs->whiteZ); 538 xyzrgb[1][2] * cs->whiteZ);
526 cs->kb = 1 / (xyzrgb[2][0] * cs->whiteX + 539 cs->kb = 1 / (xyzrgb[2][0] * cs->whiteX +
527 xyzrgb[2][1] * cs->whiteY + 540 xyzrgb[2][1] * cs->whiteY +
528 xyzrgb[2][2] * cs->whiteZ); 541 xyzrgb[2][2] * cs->whiteZ);
529 542
530 return cs; 543 return cs;
531} 544}
532 545
533void GfxLabColorSpace::getGray(GfxColor *color, fouble *gray) { 546void GfxLabColorSpace::getGray(GfxColor *color, fouble *gray) {
534 GfxRGB rgb; 547 GfxRGB rgb;
535 548
536 getRGB(color, &rgb); 549 getRGB(color, &rgb);
537 *gray = clip01(0.299 * rgb.r + 550 *gray = clip01(0.299 * rgb.r +
538 0.587 * rgb.g + 551 0.587 * rgb.g +
539 0.114 * rgb.b); 552 0.114 * rgb.b);
540} 553}
541 554
542void GfxLabColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) { 555void GfxLabColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
543 fouble X, Y, Z; 556 fouble X, Y, Z;
544 fouble t1, t2; 557 fouble t1, t2;
545 fouble r, g, b; 558 fouble r, g, b;
546 559
547 // convert L*a*b* to CIE 1931 XYZ color space 560 // convert L*a*b* to CIE 1931 XYZ color space
548 t1 = (color->c[0] + 16) / 116; 561 t1 = (color->c[0] + 16) / 116;
549 t2 = t1 + color->c[1] / 500; 562 t2 = t1 + color->c[1] / 500;
550 if (t2 >= (6.0 / 29.0)) { 563 if (t2 >= (6.0 / 29.0)) {
551 X = t2 * t2 * t2; 564 X = t2 * t2 * t2;
552 } else { 565 } else {
553 X = (108.0 / 841.0) * (t2 - (4.0 / 29.0)); 566 X = (108.0 / 841.0) * (t2 - (4.0 / 29.0));
554 } 567 }
555 X *= whiteX; 568 X *= whiteX;
556 if (t1 >= (6.0 / 29.0)) { 569 if (t1 >= (6.0 / 29.0)) {
557 Y = t1 * t1 * t1; 570 Y = t1 * t1 * t1;
558 } else { 571 } else {
559 Y = (108.0 / 841.0) * (t1 - (4.0 / 29.0)); 572 Y = (108.0 / 841.0) * (t1 - (4.0 / 29.0));
560 } 573 }
561 Y *= whiteY; 574 Y *= whiteY;
562 t2 = t1 - color->c[2] / 200; 575 t2 = t1 - color->c[2] / 200;
563 if (t2 >= (6.0 / 29.0)) { 576 if (t2 >= (6.0 / 29.0)) {
564 Z = t2 * t2 * t2; 577 Z = t2 * t2 * t2;
565 } else { 578 } else {
566 Z = (108.0 / 841.0) * (t2 - (4.0 / 29.0)); 579 Z = (108.0 / 841.0) * (t2 - (4.0 / 29.0));
567 } 580 }
568 Z *= whiteZ; 581 Z *= whiteZ;
569 582
570 // convert XYZ to RGB, including gamut mapping and gamma correction 583 // convert XYZ to RGB, including gamut mapping and gamma correction
571 r = xyzrgb[0][0] * X + xyzrgb[0][1] * Y + xyzrgb[0][2] * Z; 584 r = xyzrgb[0][0] * X + xyzrgb[0][1] * Y + xyzrgb[0][2] * Z;
572 g = xyzrgb[1][0] * X + xyzrgb[1][1] * Y + xyzrgb[1][2] * Z; 585 g = xyzrgb[1][0] * X + xyzrgb[1][1] * Y + xyzrgb[1][2] * Z;
573 b = xyzrgb[2][0] * X + xyzrgb[2][1] * Y + xyzrgb[2][2] * Z; 586 b = xyzrgb[2][0] * X + xyzrgb[2][1] * Y + xyzrgb[2][2] * Z;
574 rgb->r = pow(clip01(r * kr), 0.5); 587 rgb->r = pow(clip01(r * kr), 0.5);
575 rgb->g = pow(clip01(g * kg), 0.5); 588 rgb->g = pow(clip01(g * kg), 0.5);
576 rgb->b = pow(clip01(b * kb), 0.5); 589 rgb->b = pow(clip01(b * kb), 0.5);
577} 590}
578 591
579void GfxLabColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) { 592void GfxLabColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {
580 GfxRGB rgb; 593 GfxRGB rgb;
581 fouble c, m, y, k; 594 fouble c, m, y, k;
582 595
583 getRGB(color, &rgb); 596 getRGB(color, &rgb);
584 c = clip01(1 - rgb.r); 597 c = clip01(1 - rgb.r);
585 m = clip01(1 - rgb.g); 598 m = clip01(1 - rgb.g);
586 y = clip01(1 - rgb.b); 599 y = clip01(1 - rgb.b);
587 k = c; 600 k = c;
588 if (m < k) { 601 if (m < k) {
589 k = m; 602 k = m;
590 } 603 }
591 if (y < k) { 604 if (y < k) {
592 k = y; 605 k = y;
593 } 606 }
594 cmyk->c = c - k; 607 cmyk->c = c - k;
595 cmyk->m = m - k; 608 cmyk->m = m - k;
596 cmyk->y = y - k; 609 cmyk->y = y - k;
597 cmyk->k = k; 610 cmyk->k = k;
598} 611}
599 612
600void GfxLabColorSpace::getDefaultRanges(fouble *decodeLow, fouble *decodeRange, 613void GfxLabColorSpace::getDefaultRanges(fouble *decodeLow, fouble *decodeRange,
601 int maxImgPixel) { 614 int maxImgPixel) {
602 decodeLow[0] = 0; 615 decodeLow[0] = 0;
603 decodeRange[0] = 100; 616 decodeRange[0] = 100;
604 decodeLow[1] = aMin; 617 decodeLow[1] = aMin;
605 decodeRange[1] = aMax - aMin; 618 decodeRange[1] = aMax - aMin;
@@ -1079,573 +1092,701 @@ GfxPatternColorSpace::~GfxPatternColorSpace() {
1079 1092
1080GfxColorSpace *GfxPatternColorSpace::copy() { 1093GfxColorSpace *GfxPatternColorSpace::copy() {
1081 return new GfxPatternColorSpace(under ? under->copy() : 1094 return new GfxPatternColorSpace(under ? under->copy() :
1082 (GfxColorSpace *)NULL); 1095 (GfxColorSpace *)NULL);
1083} 1096}
1084 1097
1085GfxColorSpace *GfxPatternColorSpace::parse(Array *arr) { 1098GfxColorSpace *GfxPatternColorSpace::parse(Array *arr) {
1086 GfxPatternColorSpace *cs; 1099 GfxPatternColorSpace *cs;
1087 GfxColorSpace *underA; 1100 GfxColorSpace *underA;
1088 Object obj1; 1101 Object obj1;
1089 1102
1090 if (arr->getLength() != 1 && arr->getLength() != 2) { 1103 if (arr->getLength() != 1 && arr->getLength() != 2) {
1091 error(-1, "Bad Pattern color space"); 1104 error(-1, "Bad Pattern color space");
1092 return NULL; 1105 return NULL;
1093 } 1106 }
1094 underA = NULL; 1107 underA = NULL;
1095 if (arr->getLength() == 2) { 1108 if (arr->getLength() == 2) {
1096 arr->get(1, &obj1); 1109 arr->get(1, &obj1);
1097 if (!(underA = GfxColorSpace::parse(&obj1))) { 1110 if (!(underA = GfxColorSpace::parse(&obj1))) {
1098 error(-1, "Bad Pattern color space (underlying color space)"); 1111 error(-1, "Bad Pattern color space (underlying color space)");
1099 obj1.free(); 1112 obj1.free();
1100 return NULL; 1113 return NULL;
1101 } 1114 }
1102 obj1.free(); 1115 obj1.free();
1103 } 1116 }
1104 cs = new GfxPatternColorSpace(underA); 1117 cs = new GfxPatternColorSpace(underA);
1105 return cs; 1118 return cs;
1106} 1119}
1107 1120
1108void GfxPatternColorSpace::getGray(GfxColor *color, fouble *gray) { 1121void GfxPatternColorSpace::getGray(GfxColor *color, fouble *gray) {
1109 *gray = 0; 1122 *gray = 0;
1110} 1123}
1111 1124
1112void GfxPatternColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) { 1125void GfxPatternColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
1113 rgb->r = rgb->g = rgb->b = 0; 1126 rgb->r = rgb->g = rgb->b = 0;
1114} 1127}
1115 1128
1116void GfxPatternColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) { 1129void GfxPatternColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {
1117 cmyk->c = cmyk->m = cmyk->y = 0; 1130 cmyk->c = cmyk->m = cmyk->y = 0;
1118 cmyk->k = 1; 1131 cmyk->k = 1;
1119} 1132}
1120 1133
1121//------------------------------------------------------------------------ 1134//------------------------------------------------------------------------
1122// Pattern 1135// Pattern
1123//------------------------------------------------------------------------ 1136//------------------------------------------------------------------------
1124 1137
1125GfxPattern::GfxPattern(int typeA) { 1138GfxPattern::GfxPattern(int typeA) {
1126 type = typeA; 1139 type = typeA;
1127} 1140}
1128 1141
1129GfxPattern::~GfxPattern() { 1142GfxPattern::~GfxPattern() {
1130} 1143}
1131 1144
1132GfxPattern *GfxPattern::parse(Object *obj) { 1145GfxPattern *GfxPattern::parse(Object *obj) {
1133 GfxPattern *pattern; 1146 GfxPattern *pattern;
1134 Dict *dict; 1147 Dict *dict;
1135 Object obj1; 1148 Object obj1;
1136 1149
1137 pattern = NULL; 1150 pattern = NULL;
1138 if (obj->isStream()) { 1151 if (obj->isStream()) {
1139 dict = obj->streamGetDict(); 1152 dict = obj->streamGetDict();
1140 dict->lookup("PatternType", &obj1); 1153 dict->lookup("PatternType", &obj1);
1141 if (obj1.isInt() && obj1.getInt() == 1) { 1154 if (obj1.isInt() && obj1.getInt() == 1) {
1142 pattern = new GfxTilingPattern(dict, obj); 1155 pattern = new GfxTilingPattern(dict, obj);
1143 } 1156 }
1144 obj1.free(); 1157 obj1.free();
1145 } 1158 }
1146 return pattern; 1159 return pattern;
1147} 1160}
1148 1161
1149//------------------------------------------------------------------------ 1162//------------------------------------------------------------------------
1150// GfxTilingPattern 1163// GfxTilingPattern
1151//------------------------------------------------------------------------ 1164//------------------------------------------------------------------------
1152 1165
1153GfxTilingPattern::GfxTilingPattern(Dict *streamDict, Object *stream): 1166GfxTilingPattern::GfxTilingPattern(Dict *streamDict, Object *stream):
1154 GfxPattern(1) 1167 GfxPattern(1)
1155{ 1168{
1156 Object obj1, obj2; 1169 Object obj1, obj2;
1157 int i; 1170 int i;
1158 1171
1159 if (streamDict->lookup("PaintType", &obj1)->isInt()) { 1172 if (streamDict->lookup("PaintType", &obj1)->isInt()) {
1160 paintType = obj1.getInt(); 1173 paintType = obj1.getInt();
1161 } else { 1174 } else {
1162 paintType = 1; 1175 paintType = 1;
1163 error(-1, "Invalid or missing PaintType in pattern"); 1176 error(-1, "Invalid or missing PaintType in pattern");
1164 } 1177 }
1165 obj1.free(); 1178 obj1.free();
1166 if (streamDict->lookup("TilingType", &obj1)->isInt()) { 1179 if (streamDict->lookup("TilingType", &obj1)->isInt()) {
1167 tilingType = obj1.getInt(); 1180 tilingType = obj1.getInt();
1168 } else { 1181 } else {
1169 tilingType = 1; 1182 tilingType = 1;
1170 error(-1, "Invalid or missing TilingType in pattern"); 1183 error(-1, "Invalid or missing TilingType in pattern");
1171 } 1184 }
1172 obj1.free(); 1185 obj1.free();
1173 bbox[0] = bbox[1] = 0; 1186 bbox[0] = bbox[1] = 0;
1174 bbox[2] = bbox[3] = 1; 1187 bbox[2] = bbox[3] = 1;
1175 if (streamDict->lookup("BBox", &obj1)->isArray() && 1188 if (streamDict->lookup("BBox", &obj1)->isArray() &&
1176 obj1.arrayGetLength() == 4) { 1189 obj1.arrayGetLength() == 4) {
1177 for (i = 0; i < 4; ++i) { 1190 for (i = 0; i < 4; ++i) {
1178 if (obj1.arrayGet(i, &obj2)->isNum()) { 1191 if (obj1.arrayGet(i, &obj2)->isNum()) {
1179 bbox[i] = obj2.getNum(); 1192 bbox[i] = obj2.getNum();
1180 } 1193 }
1181 obj2.free(); 1194 obj2.free();
1182 } 1195 }
1183 } else { 1196 } else {
1184 error(-1, "Invalid or missing BBox in pattern"); 1197 error(-1, "Invalid or missing BBox in pattern");
1185 } 1198 }
1186 obj1.free(); 1199 obj1.free();
1187 if (streamDict->lookup("XStep", &obj1)->isNum()) { 1200 if (streamDict->lookup("XStep", &obj1)->isNum()) {
1188 xStep = obj1.getNum(); 1201 xStep = obj1.getNum();
1189 } else { 1202 } else {
1190 xStep = 1; 1203 xStep = 1;
1191 error(-1, "Invalid or missing XStep in pattern"); 1204 error(-1, "Invalid or missing XStep in pattern");
1192 } 1205 }
1193 obj1.free(); 1206 obj1.free();
1194 if (streamDict->lookup("YStep", &obj1)->isNum()) { 1207 if (streamDict->lookup("YStep", &obj1)->isNum()) {
1195 yStep = obj1.getNum(); 1208 yStep = obj1.getNum();
1196 } else { 1209 } else {
1197 yStep = 1; 1210 yStep = 1;
1198 error(-1, "Invalid or missing YStep in pattern"); 1211 error(-1, "Invalid or missing YStep in pattern");
1199 } 1212 }
1200 obj1.free(); 1213 obj1.free();
1201 if (!streamDict->lookup("Resources", &resDict)->isDict()) { 1214 if (!streamDict->lookup("Resources", &resDict)->isDict()) {
1202 resDict.free(); 1215 resDict.free();
1203 resDict.initNull(); 1216 resDict.initNull();
1204 error(-1, "Invalid or missing Resources in pattern"); 1217 error(-1, "Invalid or missing Resources in pattern");
1205 } 1218 }
1206 matrix[0] = 1; matrix[1] = 0; 1219 matrix[0] = 1; matrix[1] = 0;
1207 matrix[2] = 0; matrix[3] = 1; 1220 matrix[2] = 0; matrix[3] = 1;
1208 matrix[4] = 0; matrix[5] = 0; 1221 matrix[4] = 0; matrix[5] = 0;
1209 if (streamDict->lookup("Matrix", &obj1)->isArray() && 1222 if (streamDict->lookup("Matrix", &obj1)->isArray() &&
1210 obj1.arrayGetLength() == 6) { 1223 obj1.arrayGetLength() == 6) {
1211 for (i = 0; i < 6; ++i) { 1224 for (i = 0; i < 6; ++i) {
1212 if (obj1.arrayGet(i, &obj2)->isNum()) { 1225 if (obj1.arrayGet(i, &obj2)->isNum()) {
1213 matrix[i] = obj2.getNum(); 1226 matrix[i] = obj2.getNum();
1214 } 1227 }
1215 obj2.free(); 1228 obj2.free();
1216 } 1229 }
1217 } 1230 }
1218 obj1.free(); 1231 obj1.free();
1219 stream->copy(&contentStream); 1232 stream->copy(&contentStream);
1220} 1233}
1221 1234
1222GfxTilingPattern::~GfxTilingPattern() { 1235GfxTilingPattern::~GfxTilingPattern() {
1223 resDict.free(); 1236 resDict.free();
1224 contentStream.free(); 1237 contentStream.free();
1225} 1238}
1226 1239
1227GfxPattern *GfxTilingPattern::copy() { 1240GfxPattern *GfxTilingPattern::copy() {
1228 return new GfxTilingPattern(this); 1241 return new GfxTilingPattern(this);
1229} 1242}
1230 1243
1231GfxTilingPattern::GfxTilingPattern(GfxTilingPattern *pat): 1244GfxTilingPattern::GfxTilingPattern(GfxTilingPattern *pat):
1232 GfxPattern(1) 1245 GfxPattern(1)
1233{ 1246{
1234 memcpy(this, pat, sizeof(GfxTilingPattern)); 1247 memcpy(this, pat, sizeof(GfxTilingPattern));
1235 pat->resDict.copy(&resDict); 1248 pat->resDict.copy(&resDict);
1236 pat->contentStream.copy(&contentStream); 1249 pat->contentStream.copy(&contentStream);
1237} 1250}
1238 1251
1239//------------------------------------------------------------------------ 1252//------------------------------------------------------------------------
1240// GfxShading 1253// GfxShading
1241//------------------------------------------------------------------------ 1254//------------------------------------------------------------------------
1242 1255
1243GfxShading::GfxShading() { 1256GfxShading::GfxShading() {
1244} 1257}
1245 1258
1246GfxShading::~GfxShading() { 1259GfxShading::~GfxShading() {
1247 delete colorSpace; 1260 delete colorSpace;
1248} 1261}
1249 1262
1250GfxShading *GfxShading::parse(Object *obj) { 1263GfxShading *GfxShading::parse(Object *obj) {
1251 GfxShading *shading; 1264 GfxShading *shading;
1252 int typeA; 1265 int typeA;
1253 GfxColorSpace *colorSpaceA; 1266 GfxColorSpace *colorSpaceA;
1254 GfxColor backgroundA; 1267 GfxColor backgroundA;
1255 GBool hasBackgroundA; 1268 GBool hasBackgroundA;
1256 fouble xMinA, yMinA, xMaxA, yMaxA; 1269 fouble xMinA, yMinA, xMaxA, yMaxA;
1257 GBool hasBBoxA; 1270 GBool hasBBoxA;
1258 Object obj1, obj2; 1271 Object obj1, obj2;
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 }
1287 hasBackgroundA = gFalse; 1296 hasBackgroundA = gFalse;
1288 if (obj->dictLookup("Background", &obj1)->isArray()) { 1297 if (obj->dictLookup("Background", &obj1)->isArray()) {
1289 if (obj1.arrayGetLength() == colorSpaceA->getNComps()) { 1298 if (obj1.arrayGetLength() == colorSpaceA->getNComps()) {
1290 hasBackgroundA = gTrue; 1299 hasBackgroundA = gTrue;
1291 for (i = 0; i < colorSpaceA->getNComps(); ++i) { 1300 for (i = 0; i < colorSpaceA->getNComps(); ++i) {
1292 backgroundA.c[i] = obj1.arrayGet(i, &obj2)->getNum(); 1301 backgroundA.c[i] = obj1.arrayGet(i, &obj2)->getNum();
1293 obj2.free(); 1302 obj2.free();
1294 } 1303 }
1295 } else { 1304 } else {
1296 error(-1, "Bad Background in shading dictionary"); 1305 error(-1, "Bad Background in shading dictionary");
1297 } 1306 }
1298 } 1307 }
1299 obj1.free(); 1308 obj1.free();
1300 1309
1301 xMinA = yMinA = xMaxA = yMaxA = 0; 1310 xMinA = yMinA = xMaxA = yMaxA = 0;
1302 hasBBoxA = gFalse; 1311 hasBBoxA = gFalse;
1303 if (obj->dictLookup("BBox", &obj1)->isArray()) { 1312 if (obj->dictLookup("BBox", &obj1)->isArray()) {
1304 if (obj1.arrayGetLength() == 4) { 1313 if (obj1.arrayGetLength() == 4) {
1305 hasBBoxA = gTrue; 1314 hasBBoxA = gTrue;
1306 xMinA = obj1.arrayGet(0, &obj2)->getNum(); 1315 xMinA = obj1.arrayGet(0, &obj2)->getNum();
1307 obj2.free(); 1316 obj2.free();
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 {
1333 delete colorSpaceA; 1352 delete colorSpaceA;
1334 } 1353 }
1335 } 1354 }
1336 1355
1337 return shading; 1356 return shading;
1338 1357
1339 err1: 1358 err1:
1340 return NULL; 1359 return NULL;
1341} 1360}
1342 1361
1343//------------------------------------------------------------------------ 1362//------------------------------------------------------------------------
1344// GfxAxialShading 1363// GfxAxialShading
1345//------------------------------------------------------------------------ 1364//------------------------------------------------------------------------
1346 1365
1347GfxAxialShading::GfxAxialShading(fouble x0A, fouble y0A, 1366GfxAxialShading::GfxAxialShading(fouble x0A, fouble y0A,
1348 fouble x1A, fouble y1A, 1367 fouble x1A, fouble y1A,
1349 fouble t0A, fouble t1A, 1368 fouble t0A, fouble t1A,
1350 Function **funcsA, int nFuncsA, 1369 Function **funcsA, int nFuncsA,
1351 GBool extend0A, GBool extend1A) { 1370 GBool extend0A, GBool extend1A) {
1352 int i; 1371 int i;
1353 1372
1354 x0 = x0A; 1373 x0 = x0A;
1355 y0 = y0A; 1374 y0 = y0A;
1356 x1 = x1A; 1375 x1 = x1A;
1357 y1 = y1A; 1376 y1 = y1A;
1358 t0 = t0A; 1377 t0 = t0A;
1359 t1 = t1A; 1378 t1 = t1A;
1360 nFuncs = nFuncsA; 1379 nFuncs = nFuncsA;
1361 for (i = 0; i < nFuncs; ++i) { 1380 for (i = 0; i < nFuncs; ++i) {
1362 funcs[i] = funcsA[i]; 1381 funcs[i] = funcsA[i];
1363 } 1382 }
1364 extend0 = extend0A; 1383 extend0 = extend0A;
1365 extend1 = extend1A; 1384 extend1 = extend1A;
1366} 1385}
1367 1386
1368GfxAxialShading::~GfxAxialShading() { 1387GfxAxialShading::~GfxAxialShading() {
1369 int i; 1388 int i;
1370 1389
1371 for (i = 0; i < nFuncs; ++i) { 1390 for (i = 0; i < nFuncs; ++i) {
1372 delete funcs[i]; 1391 delete funcs[i];
1373 } 1392 }
1374} 1393}
1375 1394
1376GfxAxialShading *GfxAxialShading::parse(Dict *dict) { 1395GfxAxialShading *GfxAxialShading::parse(Dict *dict) {
1377 fouble x0A, y0A, x1A, y1A; 1396 fouble x0A, y0A, x1A, y1A;
1378 fouble t0A, t1A; 1397 fouble t0A, t1A;
1379 Function *funcsA[gfxColorMaxComps]; 1398 Function *funcsA[gfxColorMaxComps];
1380 int nFuncsA; 1399 int nFuncsA;
1381 GBool extend0A, extend1A; 1400 GBool extend0A, extend1A;
1382 Object obj1, obj2; 1401 Object obj1, obj2;
1383 int i; 1402 int i;
1384 1403
1385 x0A = y0A = x1A = y1A = 0; 1404 x0A = y0A = x1A = y1A = 0;
1386 if (dict->lookup("Coords", &obj1)->isArray() && 1405 if (dict->lookup("Coords", &obj1)->isArray() &&
1387 obj1.arrayGetLength() == 4) { 1406 obj1.arrayGetLength() == 4) {
1388 x0A = obj1.arrayGet(0, &obj2)->getNum(); 1407 x0A = obj1.arrayGet(0, &obj2)->getNum();
1389 obj2.free(); 1408 obj2.free();
1390 y0A = obj1.arrayGet(1, &obj2)->getNum(); 1409 y0A = obj1.arrayGet(1, &obj2)->getNum();
1391 obj2.free(); 1410 obj2.free();
1392 x1A = obj1.arrayGet(2, &obj2)->getNum(); 1411 x1A = obj1.arrayGet(2, &obj2)->getNum();
1393 obj2.free(); 1412 obj2.free();
1394 y1A = obj1.arrayGet(3, &obj2)->getNum(); 1413 y1A = obj1.arrayGet(3, &obj2)->getNum();
1395 obj2.free(); 1414 obj2.free();
1396 } else { 1415 } else {
1397 error(-1, "Missing or invalid Coords in shading dictionary"); 1416 error(-1, "Missing or invalid Coords in shading dictionary");
1398 goto err1; 1417 goto err1;
1399 } 1418 }
1400 obj1.free(); 1419 obj1.free();
1401 1420
1402 t0A = 0; 1421 t0A = 0;
1403 t1A = 1; 1422 t1A = 1;
1404 if (dict->lookup("Domain", &obj1)->isArray() && 1423 if (dict->lookup("Domain", &obj1)->isArray() &&
1405 obj1.arrayGetLength() == 2) { 1424 obj1.arrayGetLength() == 2) {
1406 t0A = obj1.arrayGet(0, &obj2)->getNum(); 1425 t0A = obj1.arrayGet(0, &obj2)->getNum();
1407 obj2.free(); 1426 obj2.free();
1408 t1A = obj1.arrayGet(1, &obj2)->getNum(); 1427 t1A = obj1.arrayGet(1, &obj2)->getNum();
1409 obj2.free(); 1428 obj2.free();
1410 } 1429 }
1411 obj1.free(); 1430 obj1.free();
1412 1431
1413 dict->lookup("Function", &obj1); 1432 dict->lookup("Function", &obj1);
1414 if (obj1.isArray()) { 1433 if (obj1.isArray()) {
1415 nFuncsA = obj1.arrayGetLength(); 1434 nFuncsA = obj1.arrayGetLength();
1416 for (i = 0; i < nFuncsA; ++i) { 1435 for (i = 0; i < nFuncsA; ++i) {
1417 obj1.arrayGet(i, &obj2); 1436 obj1.arrayGet(i, &obj2);
1418 if (!(funcsA[i] = Function::parse(&obj2))) { 1437 if (!(funcsA[i] = Function::parse(&obj2))) {
1419 obj1.free(); 1438 obj1.free();
1420 obj2.free(); 1439 obj2.free();
1421 goto err1; 1440 goto err1;
1422 } 1441 }
1423 obj2.free(); 1442 obj2.free();
1424 } 1443 }
1425 } else { 1444 } else {
1426 nFuncsA = 1; 1445 nFuncsA = 1;
1427 if (!(funcsA[0] = Function::parse(&obj1))) { 1446 if (!(funcsA[0] = Function::parse(&obj1))) {
1428 obj1.free(); 1447 obj1.free();
1429 goto err1; 1448 goto err1;
1430 } 1449 }
1431 } 1450 }
1432 obj1.free(); 1451 obj1.free();
1433 1452
1434 extend0A = extend1A = gFalse; 1453 extend0A = extend1A = gFalse;
1435 if (dict->lookup("Extend", &obj1)->isArray() && 1454 if (dict->lookup("Extend", &obj1)->isArray() &&
1436 obj1.arrayGetLength() == 2) { 1455 obj1.arrayGetLength() == 2) {
1437 extend0A = obj1.arrayGet(0, &obj2)->getBool(); 1456 extend0A = obj1.arrayGet(0, &obj2)->getBool();
1438 obj2.free(); 1457 obj2.free();
1439 extend1A = obj1.arrayGet(1, &obj2)->getBool(); 1458 extend1A = obj1.arrayGet(1, &obj2)->getBool();
1440 obj2.free(); 1459 obj2.free();
1441 } 1460 }
1442 obj1.free(); 1461 obj1.free();
1443 1462
1444 return new GfxAxialShading(x0A, y0A, x1A, y1A, t0A, t1A, 1463 return new GfxAxialShading(x0A, y0A, x1A, y1A, t0A, t1A,
1445 funcsA, nFuncsA, extend0A, extend1A); 1464 funcsA, nFuncsA, extend0A, extend1A);
1446 1465
1447 err1: 1466 err1:
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];
1472 fouble y[gfxColorMaxComps]; 1613 fouble y[gfxColorMaxComps];
1473 int i, j, k; 1614 int i, j, k;
1474 1615
1475 ok = gTrue; 1616 ok = gTrue;
1476 1617
1477 // bits per component and color space 1618 // bits per component and color space
1478 bits = bitsA; 1619 bits = bitsA;
1479 maxPixel = (1 << bits) - 1; 1620 maxPixel = (1 << bits) - 1;
1480 colorSpace = colorSpaceA; 1621 colorSpace = colorSpaceA;
1481 1622
1482 // get decode map 1623 // get decode map
1483 if (decode->isNull()) { 1624 if (decode->isNull()) {
1484 nComps = colorSpace->getNComps(); 1625 nComps = colorSpace->getNComps();
1485 colorSpace->getDefaultRanges(decodeLow, decodeRange, maxPixel); 1626 colorSpace->getDefaultRanges(decodeLow, decodeRange, maxPixel);
1486 } else if (decode->isArray()) { 1627 } else if (decode->isArray()) {
1487 nComps = decode->arrayGetLength() / 2; 1628 nComps = decode->arrayGetLength() / 2;
1488 if (nComps != colorSpace->getNComps()) { 1629 if (nComps != colorSpace->getNComps()) {
1489 goto err1; 1630 goto err1;
1490 } 1631 }
1491 for (i = 0; i < nComps; ++i) { 1632 for (i = 0; i < nComps; ++i) {
1492 decode->arrayGet(2*i, &obj); 1633 decode->arrayGet(2*i, &obj);
1493 if (!obj.isNum()) { 1634 if (!obj.isNum()) {
1494 goto err2; 1635 goto err2;
1495 } 1636 }
1496 decodeLow[i] = obj.getNum(); 1637 decodeLow[i] = obj.getNum();
1497 obj.free(); 1638 obj.free();
1498 decode->arrayGet(2*i+1, &obj); 1639 decode->arrayGet(2*i+1, &obj);
1499 if (!obj.isNum()) { 1640 if (!obj.isNum()) {
1500 goto err2; 1641 goto err2;
1501 } 1642 }
1502 decodeRange[i] = obj.getNum() - decodeLow[i]; 1643 decodeRange[i] = obj.getNum() - decodeLow[i];
1503 obj.free(); 1644 obj.free();
1504 } 1645 }
1505 } else { 1646 } else {
1506 goto err1; 1647 goto err1;
1507 } 1648 }
1508 1649
1509 // Construct a lookup table -- this stores pre-computed decoded 1650 // Construct a lookup table -- this stores pre-computed decoded
1510 // values for each component, i.e., the result of applying the 1651 // values for each component, i.e., the result of applying the
1511 // decode mapping to each possible image pixel component value. 1652 // decode mapping to each possible image pixel component value.
1512 // 1653 //
1513 // Optimization: for Indexed and Separation color spaces (which have 1654 // Optimization: for Indexed and Separation color spaces (which have
1514 // only one component), we store color values in the lookup table 1655 // only one component), we store color values in the lookup table
1515 // rather than component values. 1656 // rather than component values.
1516 colorSpace2 = NULL; 1657 colorSpace2 = NULL;
1517 nComps2 = 0; 1658 nComps2 = 0;
1518 if (colorSpace->getMode() == csIndexed) { 1659 if (colorSpace->getMode() == csIndexed) {
1519 // Note that indexHigh may not be the same as maxPixel -- 1660 // Note that indexHigh may not be the same as maxPixel --
1520 // Distiller will remove unused palette entries, resulting in 1661 // Distiller will remove unused palette entries, resulting in
1521 // indexHigh < maxPixel. 1662 // indexHigh < maxPixel.
1522 indexedCS = (GfxIndexedColorSpace *)colorSpace; 1663 indexedCS = (GfxIndexedColorSpace *)colorSpace;
1523 colorSpace2 = indexedCS->getBase(); 1664 colorSpace2 = indexedCS->getBase();
1524 indexHigh = indexedCS->getIndexHigh(); 1665 indexHigh = indexedCS->getIndexHigh();
1525 nComps2 = colorSpace2->getNComps(); 1666 nComps2 = colorSpace2->getNComps();
1526 lookup = (fouble *)gmalloc((indexHigh + 1) * nComps2 * sizeof(fouble)); 1667 lookup = (fouble *)gmalloc((indexHigh + 1) * nComps2 * sizeof(fouble));
1527 lookup2 = indexedCS->getLookup(); 1668 lookup2 = indexedCS->getLookup();
1528 for (i = 0; i <= indexHigh; ++i) { 1669 for (i = 0; i <= indexHigh; ++i) {
1529 j = (int)(decodeLow[0] +(i * decodeRange[0]) / maxPixel + 0.5); 1670 j = (int)(decodeLow[0] +(i * decodeRange[0]) / maxPixel + 0.5);
1530 for (k = 0; k < nComps2; ++k) { 1671 for (k = 0; k < nComps2; ++k) {
1531 lookup[i*nComps2 + k] = lookup2[i*nComps2 + k] / 255.0; 1672 lookup[i*nComps2 + k] = lookup2[i*nComps2 + k] / 255.0;
1532 } 1673 }
1533 } 1674 }
1534 } else if (colorSpace->getMode() == csSeparation) { 1675 } else if (colorSpace->getMode() == csSeparation) {
1535 sepCS = (GfxSeparationColorSpace *)colorSpace; 1676 sepCS = (GfxSeparationColorSpace *)colorSpace;
1536 colorSpace2 = sepCS->getAlt(); 1677 colorSpace2 = sepCS->getAlt();
1537 nComps2 = colorSpace2->getNComps(); 1678 nComps2 = colorSpace2->getNComps();
1538 lookup = (fouble *)gmalloc((maxPixel + 1) * nComps2 * sizeof(fouble)); 1679 lookup = (fouble *)gmalloc((maxPixel + 1) * nComps2 * sizeof(fouble));
1539 sepFunc = sepCS->getFunc(); 1680 sepFunc = sepCS->getFunc();
1540 for (i = 0; i <= maxPixel; ++i) { 1681 for (i = 0; i <= maxPixel; ++i) {
1541 x[0] = decodeLow[0] + (i * decodeRange[0]) / maxPixel; 1682 x[0] = decodeLow[0] + (i * decodeRange[0]) / maxPixel;
1542 sepFunc->transform(x, y); 1683 sepFunc->transform(x, y);
1543 for (k = 0; k < nComps2; ++k) { 1684 for (k = 0; k < nComps2; ++k) {
1544 lookup[i*nComps2 + k] = y[k]; 1685 lookup[i*nComps2 + k] = y[k];
1545 } 1686 }
1546 } 1687 }
1547 } else { 1688 } else {
1548 lookup = (fouble *)gmalloc((maxPixel + 1) * nComps * sizeof(fouble)); 1689 lookup = (fouble *)gmalloc((maxPixel + 1) * nComps * sizeof(fouble));
1549 for (i = 0; i <= maxPixel; ++i) { 1690 for (i = 0; i <= maxPixel; ++i) {
1550 for (k = 0; k < nComps; ++k) { 1691 for (k = 0; k < nComps; ++k) {
1551 lookup[i*nComps + k] = decodeLow[k] + 1692 lookup[i*nComps + k] = decodeLow[k] +
1552 (i * decodeRange[k]) / maxPixel; 1693 (i * decodeRange[k]) / maxPixel;
1553 } 1694 }
1554 } 1695 }
1555 } 1696 }
1556 1697
1557 return; 1698 return;
1558 1699
1559 err2: 1700 err2:
1560 obj.free(); 1701 obj.free();
1561 err1: 1702 err1:
1562 ok = gFalse; 1703 ok = gFalse;
1563} 1704}
1564 1705
1565GfxImageColorMap::~GfxImageColorMap() { 1706GfxImageColorMap::~GfxImageColorMap() {
1566 delete colorSpace; 1707 delete colorSpace;
1567 gfree(lookup); 1708 gfree(lookup);
1568} 1709}
1569 1710
1570void GfxImageColorMap::getGray(Guchar *x, fouble *gray) { 1711void GfxImageColorMap::getGray(Guchar *x, fouble *gray) {
1571 GfxColor color; 1712 GfxColor color;
1572 fouble *p; 1713 fouble *p;
1573 int i; 1714 int i;
1574 1715
1575 if (colorSpace2) { 1716 if (colorSpace2) {
1576 p = &lookup[x[0] * nComps2]; 1717 p = &lookup[x[0] * nComps2];
1577 for (i = 0; i < nComps2; ++i) { 1718 for (i = 0; i < nComps2; ++i) {
1578 color.c[i] = *p++; 1719 color.c[i] = *p++;
1579 } 1720 }
1580 colorSpace2->getGray(&color, gray); 1721 colorSpace2->getGray(&color, gray);
1581 } else { 1722 } else {
1582 for (i = 0; i < nComps; ++i) { 1723 for (i = 0; i < nComps; ++i) {
1583 color.c[i] = lookup[x[i] * nComps + i]; 1724 color.c[i] = lookup[x[i] * nComps + i];
1584 } 1725 }
1585 colorSpace->getGray(&color, gray); 1726 colorSpace->getGray(&color, gray);
1586 } 1727 }
1587} 1728}
1588 1729
1589void GfxImageColorMap::getRGB(Guchar *x, GfxRGB *rgb) { 1730void GfxImageColorMap::getRGB(Guchar *x, GfxRGB *rgb) {
1590 GfxColor color; 1731 GfxColor color;
1591 fouble *p; 1732 fouble *p;
1592 int i; 1733 int i;
1593 1734
1594 if (colorSpace2) { 1735 if (colorSpace2) {
1595 p = &lookup[x[0] * nComps2]; 1736 p = &lookup[x[0] * nComps2];
1596 for (i = 0; i < nComps2; ++i) { 1737 for (i = 0; i < nComps2; ++i) {
1597 color.c[i] = *p++; 1738 color.c[i] = *p++;
1598 } 1739 }
1599 colorSpace2->getRGB(&color, rgb); 1740 colorSpace2->getRGB(&color, rgb);
1600 } else { 1741 } else {
1601 for (i = 0; i < nComps; ++i) { 1742 for (i = 0; i < nComps; ++i) {
1602 color.c[i] = lookup[x[i] * nComps + i]; 1743 color.c[i] = lookup[x[i] * nComps + i];
1603 } 1744 }
1604 colorSpace->getRGB(&color, rgb); 1745 colorSpace->getRGB(&color, rgb);
1605 } 1746 }
1606} 1747}
1607 1748
1608void GfxImageColorMap::getCMYK(Guchar *x, GfxCMYK *cmyk) { 1749void GfxImageColorMap::getCMYK(Guchar *x, GfxCMYK *cmyk) {
1609 GfxColor color; 1750 GfxColor color;
1610 fouble *p; 1751 fouble *p;
1611 int i; 1752 int i;
1612 1753
1613 if (colorSpace2) { 1754 if (colorSpace2) {
1614 p = &lookup[x[0] * nComps2]; 1755 p = &lookup[x[0] * nComps2];
1615 for (i = 0; i < nComps2; ++i) { 1756 for (i = 0; i < nComps2; ++i) {
1616 color.c[i] = *p++; 1757 color.c[i] = *p++;
1617 } 1758 }
1618 colorSpace2->getCMYK(&color, cmyk); 1759 colorSpace2->getCMYK(&color, cmyk);
1619 } else { 1760 } else {
1620 for (i = 0; i < nComps; ++i) { 1761 for (i = 0; i < nComps; ++i) {
1621 color.c[i] = lookup[x[i] * nComps + i]; 1762 color.c[i] = lookup[x[i] * nComps + i];
1622 } 1763 }
1623 colorSpace->getCMYK(&color, cmyk); 1764 colorSpace->getCMYK(&color, cmyk);
1624 } 1765 }
1625} 1766}
1626 1767
1627//------------------------------------------------------------------------ 1768//------------------------------------------------------------------------
1628// GfxSubpath and GfxPath 1769// GfxSubpath and GfxPath
1629//------------------------------------------------------------------------ 1770//------------------------------------------------------------------------
1630 1771
1631GfxSubpath::GfxSubpath(fouble x1, fouble y1) { 1772GfxSubpath::GfxSubpath(fouble x1, fouble y1) {
1632 size = 16; 1773 size = 16;
1633 x = (fouble *)gmalloc(size * sizeof(fouble)); 1774 x = (fouble *)gmalloc(size * sizeof(fouble));
1634 y = (fouble *)gmalloc(size * sizeof(fouble)); 1775 y = (fouble *)gmalloc(size * sizeof(fouble));
1635 curve = (GBool *)gmalloc(size * sizeof(GBool)); 1776 curve = (GBool *)gmalloc(size * sizeof(GBool));
1636 n = 1; 1777 n = 1;
1637 x[0] = x1; 1778 x[0] = x1;
1638 y[0] = y1; 1779 y[0] = y1;
1639 curve[0] = gFalse; 1780 curve[0] = gFalse;
1640 closed = gFalse; 1781 closed = gFalse;
1641} 1782}
1642 1783
1643GfxSubpath::~GfxSubpath() { 1784GfxSubpath::~GfxSubpath() {
1644 gfree(x); 1785 gfree(x);
1645 gfree(y); 1786 gfree(y);
1646 gfree(curve); 1787 gfree(curve);
1647} 1788}
1648 1789
1649// Used for copy(). 1790// Used for copy().
1650GfxSubpath::GfxSubpath(GfxSubpath *subpath) { 1791GfxSubpath::GfxSubpath(GfxSubpath *subpath) {
1651 size = subpath->size; 1792 size = subpath->size;
@@ -1729,369 +1870,452 @@ GfxPath::GfxPath(GBool justMoved1, fouble firstX1, fouble firstY1,
1729 subpaths[i] = subpaths1[i]->copy(); 1870 subpaths[i] = subpaths1[i]->copy();
1730} 1871}
1731 1872
1732void GfxPath::moveTo(fouble x, fouble y) { 1873void GfxPath::moveTo(fouble x, fouble y) {
1733 justMoved = gTrue; 1874 justMoved = gTrue;
1734 firstX = x; 1875 firstX = x;
1735 firstY = y; 1876 firstY = y;
1736} 1877}
1737 1878
1738void GfxPath::lineTo(fouble x, fouble y) { 1879void GfxPath::lineTo(fouble x, fouble y) {
1739 if (justMoved) { 1880 if (justMoved) {
1740 if (n >= size) { 1881 if (n >= size) {
1741 size += 16; 1882 size += 16;
1742 subpaths = (GfxSubpath **) 1883 subpaths = (GfxSubpath **)
1743 grealloc(subpaths, size * sizeof(GfxSubpath *)); 1884 grealloc(subpaths, size * sizeof(GfxSubpath *));
1744 } 1885 }
1745 subpaths[n] = new GfxSubpath(firstX, firstY); 1886 subpaths[n] = new GfxSubpath(firstX, firstY);
1746 ++n; 1887 ++n;
1747 justMoved = gFalse; 1888 justMoved = gFalse;
1748 } 1889 }
1749 subpaths[n-1]->lineTo(x, y); 1890 subpaths[n-1]->lineTo(x, y);
1750} 1891}
1751 1892
1752void GfxPath::curveTo(fouble x1, fouble y1, fouble x2, fouble y2, 1893void GfxPath::curveTo(fouble x1, fouble y1, fouble x2, fouble y2,
1753 fouble x3, fouble y3) { 1894 fouble x3, fouble y3) {
1754 if (justMoved) { 1895 if (justMoved) {
1755 if (n >= size) { 1896 if (n >= size) {
1756 size += 16; 1897 size += 16;
1757 subpaths = (GfxSubpath **) 1898 subpaths = (GfxSubpath **)
1758 grealloc(subpaths, size * sizeof(GfxSubpath *)); 1899 grealloc(subpaths, size * sizeof(GfxSubpath *));
1759 } 1900 }
1760 subpaths[n] = new GfxSubpath(firstX, firstY); 1901 subpaths[n] = new GfxSubpath(firstX, firstY);
1761 ++n; 1902 ++n;
1762 justMoved = gFalse; 1903 justMoved = gFalse;
1763 } 1904 }
1764 subpaths[n-1]->curveTo(x1, y1, x2, y2, x3, y3); 1905 subpaths[n-1]->curveTo(x1, y1, x2, y2, x3, y3);
1765} 1906}
1766 1907
1767void GfxPath::close() { 1908void GfxPath::close() {
1768 // this is necessary to handle the pathological case of 1909 // this is necessary to handle the pathological case of
1769 // moveto/closepath/clip, which defines an empty clipping region 1910 // moveto/closepath/clip, which defines an empty clipping region
1770 if (justMoved) { 1911 if (justMoved) {
1771 if (n >= size) { 1912 if (n >= size) {
1772 size += 16; 1913 size += 16;
1773 subpaths = (GfxSubpath **) 1914 subpaths = (GfxSubpath **)
1774 grealloc(subpaths, size * sizeof(GfxSubpath *)); 1915 grealloc(subpaths, size * sizeof(GfxSubpath *));
1775 } 1916 }
1776 subpaths[n] = new GfxSubpath(firstX, firstY); 1917 subpaths[n] = new GfxSubpath(firstX, firstY);
1777 ++n; 1918 ++n;
1778 justMoved = gFalse; 1919 justMoved = gFalse;
1779 } 1920 }
1780 subpaths[n-1]->close(); 1921 subpaths[n-1]->close();
1781} 1922}
1782 1923
1783//------------------------------------------------------------------------ 1924//------------------------------------------------------------------------
1784// GfxState 1925// GfxState
1785//------------------------------------------------------------------------ 1926//------------------------------------------------------------------------
1786 1927
1787GfxState::GfxState(fouble dpi, PDFRectangle *pageBox, int rotate, 1928GfxState::GfxState(fouble dpi, PDFRectangle *pageBox, int rotate,
1788 GBool upsideDown) { 1929 GBool upsideDown) {
1789 fouble k; 1930 fouble k;
1790 1931
1791 px1 = pageBox->x1; 1932 px1 = pageBox->x1;
1792 py1 = pageBox->y1; 1933 py1 = pageBox->y1;
1793 px2 = pageBox->x2; 1934 px2 = pageBox->x2;
1794 py2 = pageBox->y2; 1935 py2 = pageBox->y2;
1795 k = dpi / 72.0; 1936 k = dpi / 72.0;
1796 if (rotate == 90) { 1937 if (rotate == 90) {
1797 ctm[0] = 0; 1938 ctm[0] = 0;
1798 ctm[1] = upsideDown ? k : -k; 1939 ctm[1] = upsideDown ? k : -k;
1799 ctm[2] = k; 1940 ctm[2] = k;
1800 ctm[3] = 0; 1941 ctm[3] = 0;
1801 ctm[4] = -k * py1; 1942 ctm[4] = -k * py1;
1802 ctm[5] = k * (upsideDown ? -px1 : px2); 1943 ctm[5] = k * (upsideDown ? -px1 : px2);
1803 pageWidth = k * (py2 - py1); 1944 pageWidth = k * (py2 - py1);
1804 pageHeight = k * (px2 - px1); 1945 pageHeight = k * (px2 - px1);
1805 } else if (rotate == 180) { 1946 } else if (rotate == 180) {
1806 ctm[0] = -k; 1947 ctm[0] = -k;
1807 ctm[1] = 0; 1948 ctm[1] = 0;
1808 ctm[2] = 0; 1949 ctm[2] = 0;
1809 ctm[3] = upsideDown ? k : -k; 1950 ctm[3] = upsideDown ? k : -k;
1810 ctm[4] = k * px2; 1951 ctm[4] = k * px2;
1811 ctm[5] = k * (upsideDown ? -py1 : py2); 1952 ctm[5] = k * (upsideDown ? -py1 : py2);
1812 pageWidth = k * (px2 - px1); 1953 pageWidth = k * (px2 - px1);
1813 pageHeight = k * (py2 - py1); 1954 pageHeight = k * (py2 - py1);
1814 } else if (rotate == 270) { 1955 } else if (rotate == 270) {
1815 ctm[0] = 0; 1956 ctm[0] = 0;
1816 ctm[1] = upsideDown ? -k : k; 1957 ctm[1] = upsideDown ? -k : k;
1817 ctm[2] = -k; 1958 ctm[2] = -k;
1818 ctm[3] = 0; 1959 ctm[3] = 0;
1819 ctm[4] = k * py2; 1960 ctm[4] = k * py2;
1820 ctm[5] = k * (upsideDown ? px2 : -px1); 1961 ctm[5] = k * (upsideDown ? px2 : -px1);
1821 pageWidth = k * (py2 - py1); 1962 pageWidth = k * (py2 - py1);
1822 pageHeight = k * (px2 - px1); 1963 pageHeight = k * (px2 - px1);
1823 } else { 1964 } else {
1824 ctm[0] = k; 1965 ctm[0] = k;
1825 ctm[1] = 0; 1966 ctm[1] = 0;
1826 ctm[2] = 0; 1967 ctm[2] = 0;
1827 ctm[3] = upsideDown ? -k : k; 1968 ctm[3] = upsideDown ? -k : k;
1828 ctm[4] = -k * px1; 1969 ctm[4] = -k * px1;
1829 ctm[5] = k * (upsideDown ? py2 : -py1); 1970 ctm[5] = k * (upsideDown ? py2 : -py1);
1830 pageWidth = k * (px2 - px1); 1971 pageWidth = k * (px2 - px1);
1831 pageHeight = k * (py2 - py1); 1972 pageHeight = k * (py2 - py1);
1832 } 1973 }
1833 1974
1834 fillColorSpace = new GfxDeviceGrayColorSpace(); 1975 fillColorSpace = new GfxDeviceGrayColorSpace();
1835 strokeColorSpace = new GfxDeviceGrayColorSpace(); 1976 strokeColorSpace = new GfxDeviceGrayColorSpace();
1836 fillColor.c[0] = 0; 1977 fillColor.c[0] = 0;
1837 strokeColor.c[0] = 0; 1978 strokeColor.c[0] = 0;
1838 fillPattern = NULL; 1979 fillPattern = NULL;
1839 strokePattern = NULL; 1980 strokePattern = NULL;
1840 fillOpacity = 1; 1981 fillOpacity = 1;
1841 strokeOpacity = 1; 1982 strokeOpacity = 1;
1842 1983
1843 lineWidth = 1; 1984 lineWidth = 1;
1844 lineDash = NULL; 1985 lineDash = NULL;
1845 lineDashLength = 0; 1986 lineDashLength = 0;
1846 lineDashStart = 0; 1987 lineDashStart = 0;
1847 flatness = 0; 1988 flatness = 0;
1848 lineJoin = 0; 1989 lineJoin = 0;
1849 lineCap = 0; 1990 lineCap = 0;
1850 miterLimit = 10; 1991 miterLimit = 10;
1851 1992
1852 font = NULL; 1993 font = NULL;
1853 fontSize = 0; 1994 fontSize = 0;
1854 textMat[0] = 1; textMat[1] = 0; 1995 textMat[0] = 1; textMat[1] = 0;
1855 textMat[2] = 0; textMat[3] = 1; 1996 textMat[2] = 0; textMat[3] = 1;
1856 textMat[4] = 0; textMat[5] = 0; 1997 textMat[4] = 0; textMat[5] = 0;
1857 charSpace = 0; 1998 charSpace = 0;
1858 wordSpace = 0; 1999 wordSpace = 0;
1859 horizScaling = 1; 2000 horizScaling = 1;
1860 leading = 0; 2001 leading = 0;
1861 rise = 0; 2002 rise = 0;
1862 render = 0; 2003 render = 0;
1863 2004
1864 path = new GfxPath(); 2005 path = new GfxPath();
1865 curX = curY = 0; 2006 curX = curY = 0;
1866 lineX = lineY = 0; 2007 lineX = lineY = 0;
1867 2008
1868 clipXMin = 0; 2009 clipXMin = 0;
1869 clipYMin = 0; 2010 clipYMin = 0;
1870 clipXMax = pageWidth; 2011 clipXMax = pageWidth;
1871 clipYMax = pageHeight; 2012 clipYMax = pageHeight;
1872 2013
1873 saved = NULL; 2014 saved = NULL;
1874} 2015}
1875 2016
1876GfxState::~GfxState() { 2017GfxState::~GfxState() {
1877 if (fillColorSpace) { 2018 if (fillColorSpace) {
1878 delete fillColorSpace; 2019 delete fillColorSpace;
1879 } 2020 }
1880 if (strokeColorSpace) { 2021 if (strokeColorSpace) {
1881 delete strokeColorSpace; 2022 delete strokeColorSpace;
1882 } 2023 }
1883 if (fillPattern) { 2024 if (fillPattern) {
1884 delete fillPattern; 2025 delete fillPattern;
1885 } 2026 }
1886 if (strokePattern) { 2027 if (strokePattern) {
1887 delete strokePattern; 2028 delete strokePattern;
1888 } 2029 }
1889 gfree(lineDash); 2030 gfree(lineDash);
1890 if (path) { 2031 if (path) {
1891 // this gets set to NULL by restore() 2032 // this gets set to NULL by restore()
1892 delete path; 2033 delete path;
1893 } 2034 }
1894 if (saved) { 2035 if (saved) {
1895 delete saved; 2036 delete saved;
1896 } 2037 }
1897} 2038}
1898 2039
1899// Used for copy(); 2040// Used for copy();
1900GfxState::GfxState(GfxState *state) { 2041GfxState::GfxState(GfxState *state) {
1901 memcpy(this, state, sizeof(GfxState)); 2042 memcpy(this, state, sizeof(GfxState));
1902 if (fillColorSpace) { 2043 if (fillColorSpace) {
1903 fillColorSpace = state->fillColorSpace->copy(); 2044 fillColorSpace = state->fillColorSpace->copy();
1904 } 2045 }
1905 if (strokeColorSpace) { 2046 if (strokeColorSpace) {
1906 strokeColorSpace = state->strokeColorSpace->copy(); 2047 strokeColorSpace = state->strokeColorSpace->copy();
1907 } 2048 }
1908 if (fillPattern) { 2049 if (fillPattern) {
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;
1933 y1 = textMat[3] * fontSize; 2135 y1 = textMat[3] * fontSize;
1934 x2 = ctm[0] * x1 + ctm[2] * y1; 2136 x2 = ctm[0] * x1 + ctm[2] * y1;
1935 y2 = ctm[1] * x1 + ctm[3] * y1; 2137 y2 = ctm[1] * x1 + ctm[3] * y1;
1936 return sqrt(x2 * x2 + y2 * y2); 2138 return sqrt(x2 * x2 + y2 * y2);
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;
1982 } 2205 }
1983 strokeColorSpace = colorSpace; 2206 strokeColorSpace = colorSpace;
1984} 2207}
1985 2208
1986void GfxState::setFillPattern(GfxPattern *pattern) { 2209void GfxState::setFillPattern(GfxPattern *pattern) {
1987 if (fillPattern) { 2210 if (fillPattern) {
1988 delete fillPattern; 2211 delete fillPattern;
1989 } 2212 }
1990 fillPattern = pattern; 2213 fillPattern = pattern;
1991} 2214}
1992 2215
1993void GfxState::setStrokePattern(GfxPattern *pattern) { 2216void GfxState::setStrokePattern(GfxPattern *pattern) {
1994 if (strokePattern) { 2217 if (strokePattern) {
1995 delete strokePattern; 2218 delete strokePattern;
1996 } 2219 }
1997 strokePattern = pattern; 2220 strokePattern = pattern;
1998} 2221}
1999 2222
2000void GfxState::setLineDash(fouble *dash, int length, fouble start) { 2223void GfxState::setLineDash(fouble *dash, int length, fouble start) {
2001 if (lineDash) 2224 if (lineDash)
2002 gfree(lineDash); 2225 gfree(lineDash);
2003 lineDash = dash; 2226 lineDash = dash;
2004 lineDashLength = length; 2227 lineDashLength = length;
2005 lineDashStart = start; 2228 lineDashStart = start;
2006} 2229}
2007 2230
2008void GfxState::clearPath() { 2231void GfxState::clearPath() {
2009 delete path; 2232 delete path;
2010 path = new GfxPath(); 2233 path = new GfxPath();
2011} 2234}
2012 2235
2013void GfxState::clip() { 2236void GfxState::clip() {
2014 fouble xMin, yMin, xMax, yMax, x, y; 2237 fouble xMin, yMin, xMax, yMax, x, y;
2015 GfxSubpath *subpath; 2238 GfxSubpath *subpath;
2016 int i, j; 2239 int i, j;
2017 2240
2018 xMin = xMax = yMin = yMax = 0; // make gcc happy 2241 xMin = xMax = yMin = yMax = 0; // make gcc happy
2019 for (i = 0; i < path->getNumSubpaths(); ++i) { 2242 for (i = 0; i < path->getNumSubpaths(); ++i) {
2020 subpath = path->getSubpath(i); 2243 subpath = path->getSubpath(i);
2021 for (j = 0; j < subpath->getNumPoints(); ++j) { 2244 for (j = 0; j < subpath->getNumPoints(); ++j) {
2022 transform(subpath->getX(j), subpath->getY(j), &x, &y); 2245 transform(subpath->getX(j), subpath->getY(j), &x, &y);
2023 if (i == 0 && j == 0) { 2246 if (i == 0 && j == 0) {
2024 xMin = xMax = x; 2247 xMin = xMax = x;
2025 yMin = yMax = y; 2248 yMin = yMax = y;
2026 } else { 2249 } else {
2027 if (x < xMin) { 2250 if (x < xMin) {
2028 xMin = x; 2251 xMin = x;
2029 } else if (x > xMax) { 2252 } else if (x > xMax) {
2030 xMax = x; 2253 xMax = x;
2031 } 2254 }
2032 if (y < yMin) { 2255 if (y < yMin) {
2033 yMin = y; 2256 yMin = y;
2034 } else if (y > yMax) { 2257 } else if (y > yMax) {
2035 yMax = y; 2258 yMax = y;
2036 } 2259 }
2037 } 2260 }
2038 } 2261 }
2039 } 2262 }
2040 if (xMin > clipXMin) { 2263 if (xMin > clipXMin) {
2041 clipXMin = xMin; 2264 clipXMin = xMin;
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
2070 newState = copy(); 2293 newState = copy();
2071 newState->saved = this; 2294 newState->saved = this;
2072 return newState; 2295 return newState;
2073} 2296}
2074 2297
2075GfxState *GfxState::restore() { 2298GfxState *GfxState::restore() {
2076 GfxState *oldState; 2299 GfxState *oldState;
2077 2300
2078 if (saved) { 2301 if (saved) {
2079 oldState = saved; 2302 oldState = saved;
2080 2303
2081 // these attributes aren't saved/restored by the q/Q operators 2304 // these attributes aren't saved/restored by the q/Q operators
2082 oldState->path = path; 2305 oldState->path = path;
2083 oldState->curX = curX; 2306 oldState->curX = curX;
2084 oldState->curY = curY; 2307 oldState->curY = curY;
2085 oldState->lineX = lineX; 2308 oldState->lineX = lineX;
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,197 +1,197 @@
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"
18#include "Function.h" 18#include "Function.h"
19 19
20class Array; 20class Array;
21class GfxFont; 21class GfxFont;
22struct PDFRectangle; 22struct PDFRectangle;
23 23
24//------------------------------------------------------------------------ 24//------------------------------------------------------------------------
25// GfxColor 25// GfxColor
26//------------------------------------------------------------------------ 26//------------------------------------------------------------------------
27 27
28#define gfxColorMaxComps funcMaxOutputs 28#define gfxColorMaxComps funcMaxOutputs
29 29
30struct GfxColor { 30struct GfxColor {
31 fouble c[gfxColorMaxComps]; 31 fouble c[gfxColorMaxComps];
32}; 32};
33 33
34//------------------------------------------------------------------------ 34//------------------------------------------------------------------------
35// GfxRGB 35// GfxRGB
36//------------------------------------------------------------------------ 36//------------------------------------------------------------------------
37 37
38struct GfxRGB { 38struct GfxRGB {
39 fouble r, g, b; 39 fouble r, g, b;
40}; 40};
41 41
42//------------------------------------------------------------------------ 42//------------------------------------------------------------------------
43// GfxCMYK 43// GfxCMYK
44//------------------------------------------------------------------------ 44//------------------------------------------------------------------------
45 45
46struct GfxCMYK { 46struct GfxCMYK {
47 fouble c, m, y, k; 47 fouble c, m, y, k;
48}; 48};
49 49
50//------------------------------------------------------------------------ 50//------------------------------------------------------------------------
51// GfxColorSpace 51// GfxColorSpace
52//------------------------------------------------------------------------ 52//------------------------------------------------------------------------
53 53
54enum GfxColorSpaceMode { 54enum GfxColorSpaceMode {
55 csDeviceGray, 55 csDeviceGray,
56 csCalGray, 56 csCalGray,
57 csDeviceRGB, 57 csDeviceRGB,
58 csCalRGB, 58 csCalRGB,
59 csDeviceCMYK, 59 csDeviceCMYK,
60 csLab, 60 csLab,
61 csICCBased, 61 csICCBased,
62 csIndexed, 62 csIndexed,
63 csSeparation, 63 csSeparation,
64 csDeviceN, 64 csDeviceN,
65 csPattern 65 csPattern
66}; 66};
67 67
68class GfxColorSpace { 68class GfxColorSpace {
69public: 69public:
70 70
71 GfxColorSpace(); 71 GfxColorSpace();
72 virtual ~GfxColorSpace(); 72 virtual ~GfxColorSpace();
73 virtual GfxColorSpace *copy() = 0; 73 virtual GfxColorSpace *copy() = 0;
74 virtual GfxColorSpaceMode getMode() = 0; 74 virtual GfxColorSpaceMode getMode() = 0;
75 75
76 // Construct a color space. Returns NULL if unsuccessful. 76 // Construct a color space. Returns NULL if unsuccessful.
77 static GfxColorSpace *parse(Object *csObj); 77 static GfxColorSpace *parse(Object *csObj);
78 78
79 // Convert to gray, RGB, or CMYK. 79 // Convert to gray, RGB, or CMYK.
80 virtual void getGray(GfxColor *color, fouble *gray) = 0; 80 virtual void getGray(GfxColor *color, fouble *gray) = 0;
81 virtual void getRGB(GfxColor *color, GfxRGB *rgb) = 0; 81 virtual void getRGB(GfxColor *color, GfxRGB *rgb) = 0;
82 virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk) = 0; 82 virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk) = 0;
83 83
84 // Return the number of color components. 84 // Return the number of color components.
85 virtual int getNComps() = 0; 85 virtual int getNComps() = 0;
86 86
87 // Return the default ranges for each component, assuming an image 87 // Return the default ranges for each component, assuming an image
88 // with a max pixel value of <maxImgPixel>. 88 // with a max pixel value of <maxImgPixel>.
89 virtual void getDefaultRanges(fouble *decodeLow, fouble *decodeRange, 89 virtual void getDefaultRanges(fouble *decodeLow, fouble *decodeRange,
90 int maxImgPixel); 90 int maxImgPixel);
91 91
92private: 92private:
93}; 93};
94 94
95//------------------------------------------------------------------------ 95//------------------------------------------------------------------------
96// GfxDeviceGrayColorSpace 96// GfxDeviceGrayColorSpace
97//------------------------------------------------------------------------ 97//------------------------------------------------------------------------
98 98
99class GfxDeviceGrayColorSpace: public GfxColorSpace { 99class GfxDeviceGrayColorSpace: public GfxColorSpace {
100public: 100public:
101 101
102 GfxDeviceGrayColorSpace(); 102 GfxDeviceGrayColorSpace();
103 virtual ~GfxDeviceGrayColorSpace(); 103 virtual ~GfxDeviceGrayColorSpace();
104 virtual GfxColorSpace *copy(); 104 virtual GfxColorSpace *copy();
105 virtual GfxColorSpaceMode getMode() { return csDeviceGray; } 105 virtual GfxColorSpaceMode getMode() { return csDeviceGray; }
106 106
107 virtual void getGray(GfxColor *color, fouble *gray); 107 virtual void getGray(GfxColor *color, fouble *gray);
108 virtual void getRGB(GfxColor *color, GfxRGB *rgb); 108 virtual void getRGB(GfxColor *color, GfxRGB *rgb);
109 virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk); 109 virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
110 110
111 virtual int getNComps() { return 1; } 111 virtual int getNComps() { return 1; }
112 112
113private: 113private:
114}; 114};
115 115
116//------------------------------------------------------------------------ 116//------------------------------------------------------------------------
117// GfxCalGrayColorSpace 117// GfxCalGrayColorSpace
118//------------------------------------------------------------------------ 118//------------------------------------------------------------------------
119 119
120class GfxCalGrayColorSpace: public GfxColorSpace { 120class GfxCalGrayColorSpace: public GfxColorSpace {
121public: 121public:
122 122
123 GfxCalGrayColorSpace(); 123 GfxCalGrayColorSpace();
124 virtual ~GfxCalGrayColorSpace(); 124 virtual ~GfxCalGrayColorSpace();
125 virtual GfxColorSpace *copy(); 125 virtual GfxColorSpace *copy();
126 virtual GfxColorSpaceMode getMode() { return csCalGray; } 126 virtual GfxColorSpaceMode getMode() { return csCalGray; }
127 127
128 // Construct a CalGray color space. Returns NULL if unsuccessful. 128 // Construct a CalGray color space. Returns NULL if unsuccessful.
129 static GfxColorSpace *parse(Array *arr); 129 static GfxColorSpace *parse(Array *arr);
130 130
131 virtual void getGray(GfxColor *color, fouble *gray); 131 virtual void getGray(GfxColor *color, fouble *gray);
132 virtual void getRGB(GfxColor *color, GfxRGB *rgb); 132 virtual void getRGB(GfxColor *color, GfxRGB *rgb);
133 virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk); 133 virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
134 134
135 virtual int getNComps() { return 1; } 135 virtual int getNComps() { return 1; }
136 136
137 // CalGray-specific access. 137 // CalGray-specific access.
138 fouble getWhiteX() { return whiteX; } 138 fouble getWhiteX() { return whiteX; }
139 fouble getWhiteY() { return whiteY; } 139 fouble getWhiteY() { return whiteY; }
140 fouble getWhiteZ() { return whiteZ; } 140 fouble getWhiteZ() { return whiteZ; }
141 fouble getBlackX() { return blackX; } 141 fouble getBlackX() { return blackX; }
142 fouble getBlackY() { return blackY; } 142 fouble getBlackY() { return blackY; }
143 fouble getBlackZ() { return blackZ; } 143 fouble getBlackZ() { return blackZ; }
144 fouble getGamma() { return gamma; } 144 fouble getGamma() { return gamma; }
145 145
146private: 146private:
147 147
148 fouble whiteX, whiteY, whiteZ; // white point 148 fouble whiteX, whiteY, whiteZ; // white point
149 fouble blackX, blackY, blackZ; // black point 149 fouble blackX, blackY, blackZ; // black point
150 fouble gamma; // gamma value 150 fouble gamma; // gamma value
151}; 151};
152 152
153//------------------------------------------------------------------------ 153//------------------------------------------------------------------------
154// GfxDeviceRGBColorSpace 154// GfxDeviceRGBColorSpace
155//------------------------------------------------------------------------ 155//------------------------------------------------------------------------
156 156
157class GfxDeviceRGBColorSpace: public GfxColorSpace { 157class GfxDeviceRGBColorSpace: public GfxColorSpace {
158public: 158public:
159 159
160 GfxDeviceRGBColorSpace(); 160 GfxDeviceRGBColorSpace();
161 virtual ~GfxDeviceRGBColorSpace(); 161 virtual ~GfxDeviceRGBColorSpace();
162 virtual GfxColorSpace *copy(); 162 virtual GfxColorSpace *copy();
163 virtual GfxColorSpaceMode getMode() { return csDeviceRGB; } 163 virtual GfxColorSpaceMode getMode() { return csDeviceRGB; }
164 164
165 virtual void getGray(GfxColor *color, fouble *gray); 165 virtual void getGray(GfxColor *color, fouble *gray);
166 virtual void getRGB(GfxColor *color, GfxRGB *rgb); 166 virtual void getRGB(GfxColor *color, GfxRGB *rgb);
167 virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk); 167 virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
168 168
169 virtual int getNComps() { return 3; } 169 virtual int getNComps() { return 3; }
170 170
171private: 171private:
172}; 172};
173 173
174//------------------------------------------------------------------------ 174//------------------------------------------------------------------------
175// GfxCalRGBColorSpace 175// GfxCalRGBColorSpace
176//------------------------------------------------------------------------ 176//------------------------------------------------------------------------
177 177
178class GfxCalRGBColorSpace: public GfxColorSpace { 178class GfxCalRGBColorSpace: public GfxColorSpace {
179public: 179public:
180 180
181 GfxCalRGBColorSpace(); 181 GfxCalRGBColorSpace();
182 virtual ~GfxCalRGBColorSpace(); 182 virtual ~GfxCalRGBColorSpace();
183 virtual GfxColorSpace *copy(); 183 virtual GfxColorSpace *copy();
184 virtual GfxColorSpaceMode getMode() { return csCalRGB; } 184 virtual GfxColorSpaceMode getMode() { return csCalRGB; }
185 185
186 // Construct a CalRGB color space. Returns NULL if unsuccessful. 186 // Construct a CalRGB color space. Returns NULL if unsuccessful.
187 static GfxColorSpace *parse(Array *arr); 187 static GfxColorSpace *parse(Array *arr);
188 188
189 virtual void getGray(GfxColor *color, fouble *gray); 189 virtual void getGray(GfxColor *color, fouble *gray);
190 virtual void getRGB(GfxColor *color, GfxRGB *rgb); 190 virtual void getRGB(GfxColor *color, GfxRGB *rgb);
191 virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk); 191 virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
192 192
193 virtual int getNComps() { return 3; } 193 virtual int getNComps() { return 3; }
194 194
195 // CalRGB-specific access. 195 // CalRGB-specific access.
196 fouble getWhiteX() { return whiteX; } 196 fouble getWhiteX() { return whiteX; }
197 fouble getWhiteY() { return whiteY; } 197 fouble getWhiteY() { return whiteY; }
@@ -379,544 +379,579 @@ public:
379 379
380private: 380private:
381 381
382 GString *name; // colorant name 382 GString *name; // colorant name
383 GfxColorSpace *alt; // alternate color space 383 GfxColorSpace *alt; // alternate color space
384 Function *func; // tint transform (into alternate color space) 384 Function *func; // tint transform (into alternate color space)
385}; 385};
386 386
387//------------------------------------------------------------------------ 387//------------------------------------------------------------------------
388// GfxDeviceNColorSpace 388// GfxDeviceNColorSpace
389//------------------------------------------------------------------------ 389//------------------------------------------------------------------------
390 390
391class GfxDeviceNColorSpace: public GfxColorSpace { 391class GfxDeviceNColorSpace: public GfxColorSpace {
392public: 392public:
393 393
394 GfxDeviceNColorSpace(int nComps, GfxColorSpace *alt, Function *func); 394 GfxDeviceNColorSpace(int nComps, GfxColorSpace *alt, Function *func);
395 virtual ~GfxDeviceNColorSpace(); 395 virtual ~GfxDeviceNColorSpace();
396 virtual GfxColorSpace *copy(); 396 virtual GfxColorSpace *copy();
397 virtual GfxColorSpaceMode getMode() { return csDeviceN; } 397 virtual GfxColorSpaceMode getMode() { return csDeviceN; }
398 398
399 // Construct a DeviceN color space. Returns NULL if unsuccessful. 399 // Construct a DeviceN color space. Returns NULL if unsuccessful.
400 static GfxColorSpace *parse(Array *arr); 400 static GfxColorSpace *parse(Array *arr);
401 401
402 virtual void getGray(GfxColor *color, fouble *gray); 402 virtual void getGray(GfxColor *color, fouble *gray);
403 virtual void getRGB(GfxColor *color, GfxRGB *rgb); 403 virtual void getRGB(GfxColor *color, GfxRGB *rgb);
404 virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk); 404 virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
405 405
406 virtual int getNComps() { return nComps; } 406 virtual int getNComps() { return nComps; }
407 407
408 // DeviceN-specific access. 408 // DeviceN-specific access.
409 GfxColorSpace *getAlt() { return alt; } 409 GfxColorSpace *getAlt() { return alt; }
410 410
411private: 411private:
412 412
413 int nComps; // number of components 413 int nComps; // number of components
414 GString // colorant names 414 GString // colorant names
415 *names[gfxColorMaxComps]; 415 *names[gfxColorMaxComps];
416 GfxColorSpace *alt; // alternate color space 416 GfxColorSpace *alt; // alternate color space
417 Function *func; // tint transform (into alternate color space) 417 Function *func; // tint transform (into alternate color space)
418 418
419}; 419};
420 420
421//------------------------------------------------------------------------ 421//------------------------------------------------------------------------
422// GfxPatternColorSpace 422// GfxPatternColorSpace
423//------------------------------------------------------------------------ 423//------------------------------------------------------------------------
424 424
425class GfxPatternColorSpace: public GfxColorSpace { 425class GfxPatternColorSpace: public GfxColorSpace {
426public: 426public:
427 427
428 GfxPatternColorSpace(GfxColorSpace *underA); 428 GfxPatternColorSpace(GfxColorSpace *underA);
429 virtual ~GfxPatternColorSpace(); 429 virtual ~GfxPatternColorSpace();
430 virtual GfxColorSpace *copy(); 430 virtual GfxColorSpace *copy();
431 virtual GfxColorSpaceMode getMode() { return csPattern; } 431 virtual GfxColorSpaceMode getMode() { return csPattern; }
432 432
433 // Construct a Pattern color space. Returns NULL if unsuccessful. 433 // Construct a Pattern color space. Returns NULL if unsuccessful.
434 static GfxColorSpace *parse(Array *arr); 434 static GfxColorSpace *parse(Array *arr);
435 435
436 virtual void getGray(GfxColor *color, fouble *gray); 436 virtual void getGray(GfxColor *color, fouble *gray);
437 virtual void getRGB(GfxColor *color, GfxRGB *rgb); 437 virtual void getRGB(GfxColor *color, GfxRGB *rgb);
438 virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk); 438 virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
439 439
440 virtual int getNComps() { return 0; } 440 virtual int getNComps() { return 0; }
441 441
442 // Pattern-specific access. 442 // Pattern-specific access.
443 GfxColorSpace *getUnder() { return under; } 443 GfxColorSpace *getUnder() { return under; }
444 444
445private: 445private:
446 446
447 GfxColorSpace *under; // underlying color space (for uncolored 447 GfxColorSpace *under; // underlying color space (for uncolored
448 // patterns) 448 // patterns)
449}; 449};
450 450
451//------------------------------------------------------------------------ 451//------------------------------------------------------------------------
452// GfxPattern 452// GfxPattern
453//------------------------------------------------------------------------ 453//------------------------------------------------------------------------
454 454
455class GfxPattern { 455class GfxPattern {
456public: 456public:
457 457
458 GfxPattern(int typeA); 458 GfxPattern(int typeA);
459 virtual ~GfxPattern(); 459 virtual ~GfxPattern();
460 460
461 static GfxPattern *parse(Object *obj); 461 static GfxPattern *parse(Object *obj);
462 462
463 virtual GfxPattern *copy() = 0; 463 virtual GfxPattern *copy() = 0;
464 464
465 int getType() { return type; } 465 int getType() { return type; }
466 466
467private: 467private:
468 468
469 int type; 469 int type;
470}; 470};
471 471
472//------------------------------------------------------------------------ 472//------------------------------------------------------------------------
473// GfxTilingPattern 473// GfxTilingPattern
474//------------------------------------------------------------------------ 474//------------------------------------------------------------------------
475 475
476class GfxTilingPattern: public GfxPattern { 476class GfxTilingPattern: public GfxPattern {
477public: 477public:
478 478
479 GfxTilingPattern(Dict *streamDict, Object *stream); 479 GfxTilingPattern(Dict *streamDict, Object *stream);
480 virtual ~GfxTilingPattern(); 480 virtual ~GfxTilingPattern();
481 481
482 virtual GfxPattern *copy(); 482 virtual GfxPattern *copy();
483 483
484 int getPaintType() { return paintType; } 484 int getPaintType() { return paintType; }
485 int getTilingType() { return tilingType; } 485 int getTilingType() { return tilingType; }
486 fouble *getBBox() { return bbox; } 486 fouble *getBBox() { return bbox; }
487 fouble getXStep() { return xStep; } 487 fouble getXStep() { return xStep; }
488 fouble getYStep() { return yStep; } 488 fouble getYStep() { return yStep; }
489 Dict *getResDict() 489 Dict *getResDict()
490 { return resDict.isDict() ? resDict.getDict() : (Dict *)NULL; } 490 { return resDict.isDict() ? resDict.getDict() : (Dict *)NULL; }
491 fouble *getMatrix() { return matrix; } 491 fouble *getMatrix() { return matrix; }
492 Object *getContentStream() { return &contentStream; } 492 Object *getContentStream() { return &contentStream; }
493 493
494private: 494private:
495 495
496 GfxTilingPattern(GfxTilingPattern *pat); 496 GfxTilingPattern(GfxTilingPattern *pat);
497 497
498 int paintType; 498 int paintType;
499 int tilingType; 499 int tilingType;
500 fouble bbox[4]; 500 fouble bbox[4];
501 fouble xStep, yStep; 501 fouble xStep, yStep;
502 Object resDict; 502 Object resDict;
503 fouble matrix[6]; 503 fouble matrix[6];
504 Object contentStream; 504 Object contentStream;
505}; 505};
506 506
507//------------------------------------------------------------------------ 507//------------------------------------------------------------------------
508// GfxShading 508// GfxShading
509//------------------------------------------------------------------------ 509//------------------------------------------------------------------------
510 510
511class GfxShading { 511class GfxShading {
512public: 512public:
513 513
514 GfxShading(); 514 GfxShading();
515 virtual ~GfxShading(); 515 virtual ~GfxShading();
516 516
517 static GfxShading *parse(Object *obj); 517 static GfxShading *parse(Object *obj);
518 518
519 int getType() { return type; } 519 int getType() { return type; }
520 GfxColorSpace *getColorSpace() { return colorSpace; } 520 GfxColorSpace *getColorSpace() { return colorSpace; }
521 GfxColor *getBackground() { return &background; } 521 GfxColor *getBackground() { return &background; }
522 GBool getHasBackground() { return hasBackground; } 522 GBool getHasBackground() { return hasBackground; }
523 void getBBox(fouble *xMinA, fouble *yMinA, fouble *xMaxA, fouble *yMaxA) 523 void getBBox(fouble *xMinA, fouble *yMinA, fouble *xMaxA, fouble *yMaxA)
524 { *xMinA = xMin; *yMinA = yMin; *xMaxA = xMax; *yMaxA = yMax; } 524 { *xMinA = xMin; *yMinA = yMin; *xMaxA = xMax; *yMaxA = yMax; }
525 GBool getHasBBox() { return hasBBox; } 525 GBool getHasBBox() { return hasBBox; }
526 526
527private: 527private:
528 528
529 int type; 529 int type;
530 GfxColorSpace *colorSpace; 530 GfxColorSpace *colorSpace;
531 GfxColor background; 531 GfxColor background;
532 GBool hasBackground; 532 GBool hasBackground;
533 fouble xMin, yMin, xMax, yMax; 533 fouble xMin, yMin, xMax, yMax;
534 GBool hasBBox; 534 GBool hasBBox;
535}; 535};
536 536
537//------------------------------------------------------------------------ 537//------------------------------------------------------------------------
538// GfxAxialShading 538// GfxAxialShading
539//------------------------------------------------------------------------ 539//------------------------------------------------------------------------
540 540
541class GfxAxialShading: public GfxShading { 541class GfxAxialShading: public GfxShading {
542public: 542public:
543 543
544 GfxAxialShading(fouble x0A, fouble y0A, 544 GfxAxialShading(fouble x0A, fouble y0A,
545 fouble x1A, fouble y1A, 545 fouble x1A, fouble y1A,
546 fouble t0A, fouble t1A, 546 fouble t0A, fouble t1A,
547 Function **funcsA, int nFuncsA, 547 Function **funcsA, int nFuncsA,
548 GBool extend0A, GBool extend1A); 548 GBool extend0A, GBool extend1A);
549 virtual ~GfxAxialShading(); 549 virtual ~GfxAxialShading();
550 550
551 static GfxAxialShading *parse(Dict *dict); 551 static GfxAxialShading *parse(Dict *dict);
552 552
553 void getCoords(fouble *x0A, fouble *y0A, fouble *x1A, fouble *y1A) 553 void getCoords(fouble *x0A, fouble *y0A, fouble *x1A, fouble *y1A)
554 { *x0A = x0; *y0A = y0; *x1A = x1; *y1A = y1; } 554 { *x0A = x0; *y0A = y0; *x1A = x1; *y1A = y1; }
555 fouble getDomain0() { return t0; } 555 fouble getDomain0() { return t0; }
556 fouble getDomain1() { return t1; } 556 fouble getDomain1() { return t1; }
557 void getColor(fouble t, GfxColor *color); 557 void getColor(fouble t, GfxColor *color);
558 GBool getExtend0() { return extend0; } 558 GBool getExtend0() { return extend0; }
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
583 // Is color map valid? 617 // Is color map valid?
584 GBool isOk() { return ok; } 618 GBool isOk() { return ok; }
585 619
586 // Get the color space. 620 // Get the color space.
587 GfxColorSpace *getColorSpace() { return colorSpace; } 621 GfxColorSpace *getColorSpace() { return colorSpace; }
588 622
589 // Get stream decoding info. 623 // Get stream decoding info.
590 int getNumPixelComps() { return nComps; } 624 int getNumPixelComps() { return nComps; }
591 int getBits() { return bits; } 625 int getBits() { return bits; }
592 626
593 // Get decode table. 627 // Get decode table.
594 fouble getDecodeLow(int i) { return decodeLow[i]; } 628 fouble getDecodeLow(int i) { return decodeLow[i]; }
595 fouble getDecodeHigh(int i) { return decodeLow[i] + decodeRange[i]; } 629 fouble getDecodeHigh(int i) { return decodeLow[i] + decodeRange[i]; }
596 630
597 // Convert an image pixel to a color. 631 // Convert an image pixel to a color.
598 void getGray(Guchar *x, fouble *gray); 632 void getGray(Guchar *x, fouble *gray);
599 void getRGB(Guchar *x, GfxRGB *rgb); 633 void getRGB(Guchar *x, GfxRGB *rgb);
600 void getCMYK(Guchar *x, GfxCMYK *cmyk); 634 void getCMYK(Guchar *x, GfxCMYK *cmyk);
601 635
602private: 636private:
603 637
604 GfxColorSpace *colorSpace;// the image color space 638 GfxColorSpace *colorSpace;// the image color space
605 int bits; // bits per component 639 int bits; // bits per component
606 int nComps; // number of components in a pixel 640 int nComps; // number of components in a pixel
607 GfxColorSpace *colorSpace2;// secondary color space 641 GfxColorSpace *colorSpace2;// secondary color space
608 int nComps2; // number of components in colorSpace2 642 int nComps2; // number of components in colorSpace2
609 fouble *lookup; // lookup table 643 fouble *lookup; // lookup table
610 fouble // minimum values for each component 644 fouble // minimum values for each component
611 decodeLow[gfxColorMaxComps]; 645 decodeLow[gfxColorMaxComps];
612 fouble // max - min value for each component 646 fouble // max - min value for each component
613 decodeRange[gfxColorMaxComps]; 647 decodeRange[gfxColorMaxComps];
614 GBool ok; 648 GBool ok;
615}; 649};
616 650
617//------------------------------------------------------------------------ 651//------------------------------------------------------------------------
618// GfxSubpath and GfxPath 652// GfxSubpath and GfxPath
619//------------------------------------------------------------------------ 653//------------------------------------------------------------------------
620 654
621class GfxSubpath { 655class GfxSubpath {
622public: 656public:
623 657
624 // Constructor. 658 // Constructor.
625 GfxSubpath(fouble x1, fouble y1); 659 GfxSubpath(fouble x1, fouble y1);
626 660
627 // Destructor. 661 // Destructor.
628 ~GfxSubpath(); 662 ~GfxSubpath();
629 663
630 // Copy. 664 // Copy.
631 GfxSubpath *copy() { return new GfxSubpath(this); } 665 GfxSubpath *copy() { return new GfxSubpath(this); }
632 666
633 // Get points. 667 // Get points.
634 int getNumPoints() { return n; } 668 int getNumPoints() { return n; }
635 fouble getX(int i) { return x[i]; } 669 fouble getX(int i) { return x[i]; }
636 fouble getY(int i) { return y[i]; } 670 fouble getY(int i) { return y[i]; }
637 GBool getCurve(int i) { return curve[i]; } 671 GBool getCurve(int i) { return curve[i]; }
638 672
639 // Get last point. 673 // Get last point.
640 fouble getLastX() { return x[n-1]; } 674 fouble getLastX() { return x[n-1]; }
641 fouble getLastY() { return y[n-1]; } 675 fouble getLastY() { return y[n-1]; }
642 676
643 // Add a line segment. 677 // Add a line segment.
644 void lineTo(fouble x1, fouble y1); 678 void lineTo(fouble x1, fouble y1);
645 679
646 // Add a Bezier curve. 680 // Add a Bezier curve.
647 void curveTo(fouble x1, fouble y1, fouble x2, fouble y2, 681 void curveTo(fouble x1, fouble y1, fouble x2, fouble y2,
648 fouble x3, fouble y3); 682 fouble x3, fouble y3);
649 683
650 // Close the subpath. 684 // Close the subpath.
651 void close(); 685 void close();
652 GBool isClosed() { return closed; } 686 GBool isClosed() { return closed; }
653 687
654private: 688private:
655 689
656 fouble *x, *y; // points 690 fouble *x, *y; // points
657 GBool *curve; // curve[i] => point i is a control point 691 GBool *curve; // curve[i] => point i is a control point
658 // for a Bezier curve 692 // for a Bezier curve
659 int n; // number of points 693 int n; // number of points
660 int size; // size of x/y arrays 694 int size; // size of x/y arrays
661 GBool closed; // set if path is closed 695 GBool closed; // set if path is closed
662 696
663 GfxSubpath(GfxSubpath *subpath); 697 GfxSubpath(GfxSubpath *subpath);
664}; 698};
665 699
666class GfxPath { 700class GfxPath {
667public: 701public:
668 702
669 // Constructor. 703 // Constructor.
670 GfxPath(); 704 GfxPath();
671 705
672 // Destructor. 706 // Destructor.
673 ~GfxPath(); 707 ~GfxPath();
674 708
675 // Copy. 709 // Copy.
676 GfxPath *copy() 710 GfxPath *copy()
677 { return new GfxPath(justMoved, firstX, firstY, subpaths, n, size); } 711 { return new GfxPath(justMoved, firstX, firstY, subpaths, n, size); }
678 712
679 // Is there a current point? 713 // Is there a current point?
680 GBool isCurPt() { return n > 0 || justMoved; } 714 GBool isCurPt() { return n > 0 || justMoved; }
681 715
682 // Is the path non-empty, i.e., is there at least one segment? 716 // Is the path non-empty, i.e., is there at least one segment?
683 GBool isPath() { return n > 0; } 717 GBool isPath() { return n > 0; }
684 718
685 // Get subpaths. 719 // Get subpaths.
686 int getNumSubpaths() { return n; } 720 int getNumSubpaths() { return n; }
687 GfxSubpath *getSubpath(int i) { return subpaths[i]; } 721 GfxSubpath *getSubpath(int i) { return subpaths[i]; }
688 722
689 // Get last point on last subpath. 723 // Get last point on last subpath.
690 fouble getLastX() { return subpaths[n-1]->getLastX(); } 724 fouble getLastX() { return subpaths[n-1]->getLastX(); }
691 fouble getLastY() { return subpaths[n-1]->getLastY(); } 725 fouble getLastY() { return subpaths[n-1]->getLastY(); }
692 726
693 // Move the current point. 727 // Move the current point.
694 void moveTo(fouble x, fouble y); 728 void moveTo(fouble x, fouble y);
695 729
696 // Add a segment to the last subpath. 730 // Add a segment to the last subpath.
697 void lineTo(fouble x, fouble y); 731 void lineTo(fouble x, fouble y);
698 732
699 // Add a Bezier curve to the last subpath 733 // Add a Bezier curve to the last subpath
700 void curveTo(fouble x1, fouble y1, fouble x2, fouble y2, 734 void curveTo(fouble x1, fouble y1, fouble x2, fouble y2,
701 fouble x3, fouble y3); 735 fouble x3, fouble y3);
702 736
703 // Close the last subpath. 737 // Close the last subpath.
704 void close(); 738 void close();
705 739
706private: 740private:
707 741
708 GBool justMoved; // set if a new subpath was just started 742 GBool justMoved; // set if a new subpath was just started
709 fouble firstX, firstY;// first point in new subpath 743 fouble firstX, firstY;// first point in new subpath
710 GfxSubpath **subpaths;// subpaths 744 GfxSubpath **subpaths;// subpaths
711 int n; // number of subpaths 745 int n; // number of subpaths
712 int size; // size of subpaths array 746 int size; // size of subpaths array
713 747
714 GfxPath(GBool justMoved1, fouble firstX1, fouble firstY1, 748 GfxPath(GBool justMoved1, fouble firstX1, fouble firstY1,
715 GfxSubpath **subpaths1, int n1, int size1); 749 GfxSubpath **subpaths1, int n1, int size1);
716}; 750};
717 751
718//------------------------------------------------------------------------ 752//------------------------------------------------------------------------
719// GfxState 753// GfxState
720//------------------------------------------------------------------------ 754//------------------------------------------------------------------------
721 755
722class GfxState { 756class GfxState {
723public: 757public:
724 758
725 // Construct a default GfxState, for a device with resolution <dpi>, 759 // Construct a default GfxState, for a device with resolution <dpi>,
726 // page box <pageBox>, page rotation <rotate>, and coordinate system 760 // page box <pageBox>, page rotation <rotate>, and coordinate system
727 // specified by <upsideDown>. 761 // specified by <upsideDown>.
728 GfxState(fouble dpi, PDFRectangle *pageBox, int rotate, 762 GfxState(fouble dpi, PDFRectangle *pageBox, int rotate,
729 GBool upsideDown); 763 GBool upsideDown);
730 764
731 // Destructor. 765 // Destructor.
732 ~GfxState(); 766 ~GfxState();
733 767
734 // Copy. 768 // Copy.
735 GfxState *copy() { return new GfxState(this); } 769 GfxState *copy() { return new GfxState(this); }
736 770
737 // Accessors. 771 // Accessors.
738 fouble *getCTM() { return ctm; } 772 fouble *getCTM() { return ctm; }
739 fouble getX1() { return px1; } 773 fouble getX1() { return px1; }
740 fouble getY1() { return py1; } 774 fouble getY1() { return py1; }
741 fouble getX2() { return px2; } 775 fouble getX2() { return px2; }
742 fouble getY2() { return py2; } 776 fouble getY2() { return py2; }
743 fouble getPageWidth() { return pageWidth; } 777 fouble getPageWidth() { return pageWidth; }
744 fouble getPageHeight() { return pageHeight; } 778 fouble getPageHeight() { return pageHeight; }
745 GfxColor *getFillColor() { return &fillColor; } 779 GfxColor *getFillColor() { return &fillColor; }
746 GfxColor *getStrokeColor() { return &strokeColor; } 780 GfxColor *getStrokeColor() { return &strokeColor; }
747 void getFillGray(fouble *gray) 781 void getFillGray(fouble *gray)
748 { fillColorSpace->getGray(&fillColor, gray); } 782 { fillColorSpace->getGray(&fillColor, gray); }
749 void getStrokeGray(fouble *gray) 783 void getStrokeGray(fouble *gray)
750 { strokeColorSpace->getGray(&fillColor, gray); } 784 { strokeColorSpace->getGray(&fillColor, gray); }
751 void getFillRGB(GfxRGB *rgb) 785 void getFillRGB(GfxRGB *rgb)
752 { fillColorSpace->getRGB(&fillColor, rgb); } 786 { fillColorSpace->getRGB(&fillColor, rgb); }
753 void getStrokeRGB(GfxRGB *rgb) 787 void getStrokeRGB(GfxRGB *rgb)
754 { strokeColorSpace->getRGB(&strokeColor, rgb); } 788 { strokeColorSpace->getRGB(&strokeColor, rgb); }
755 void getFillCMYK(GfxCMYK *cmyk) 789 void getFillCMYK(GfxCMYK *cmyk)
756 { fillColorSpace->getCMYK(&fillColor, cmyk); } 790 { fillColorSpace->getCMYK(&fillColor, cmyk); }
757 void getStrokeCMYK(GfxCMYK *cmyk) 791 void getStrokeCMYK(GfxCMYK *cmyk)
758 { strokeColorSpace->getCMYK(&strokeColor, cmyk); } 792 { strokeColorSpace->getCMYK(&strokeColor, cmyk); }
759 GfxColorSpace *getFillColorSpace() { return fillColorSpace; } 793 GfxColorSpace *getFillColorSpace() { return fillColorSpace; }
760 GfxColorSpace *getStrokeColorSpace() { return strokeColorSpace; } 794 GfxColorSpace *getStrokeColorSpace() { return strokeColorSpace; }
761 GfxPattern *getFillPattern() { return fillPattern; } 795 GfxPattern *getFillPattern() { return fillPattern; }
762 GfxPattern *getStrokePattern() { return strokePattern; } 796 GfxPattern *getStrokePattern() { return strokePattern; }
763 fouble getFillOpacity() { return fillOpacity; } 797 fouble getFillOpacity() { return fillOpacity; }
764 fouble getStrokeOpacity() { return strokeOpacity; } 798 fouble getStrokeOpacity() { return strokeOpacity; }
765 fouble getLineWidth() { return lineWidth; } 799 fouble getLineWidth() { return lineWidth; }
766 void getLineDash(fouble **dash, int *length, fouble *start) 800 void getLineDash(fouble **dash, int *length, fouble *start)
767 { *dash = lineDash; *length = lineDashLength; *start = lineDashStart; } 801 { *dash = lineDash; *length = lineDashLength; *start = lineDashStart; }
768 int getFlatness() { return flatness; } 802 int getFlatness() { return flatness; }
769 int getLineJoin() { return lineJoin; } 803 int getLineJoin() { return lineJoin; }
770 int getLineCap() { return lineCap; } 804 int getLineCap() { return lineCap; }
771 fouble getMiterLimit() { return miterLimit; } 805 fouble getMiterLimit() { return miterLimit; }
772 GfxFont *getFont() { return font; } 806 GfxFont *getFont() { return font; }
773 fouble getFontSize() { return fontSize; } 807 fouble getFontSize() { return fontSize; }
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)
798 { *x2 = ctm[0] * x1 + ctm[2] * y1; 833 { *x2 = ctm[0] * x1 + ctm[2] * y1;
799 *y2 = ctm[1] * x1 + ctm[3] * y1; } 834 *y2 = ctm[1] * x1 + ctm[3] * y1; }
800 void textTransform(fouble x1, fouble y1, fouble *x2, fouble *y2) 835 void textTransform(fouble x1, fouble y1, fouble *x2, fouble *y2)
801 { *x2 = textMat[0] * x1 + textMat[2] * y1 + textMat[4]; 836 { *x2 = textMat[0] * x1 + textMat[2] * y1 + textMat[4];
802 *y2 = textMat[1] * x1 + textMat[3] * y1 + textMat[5]; } 837 *y2 = textMat[1] * x1 + textMat[3] * y1 + textMat[5]; }
803 void textTransformDelta(fouble x1, fouble y1, fouble *x2, fouble *y2) 838 void textTransformDelta(fouble x1, fouble y1, fouble *x2, fouble *y2)
804 { *x2 = textMat[0] * x1 + textMat[2] * y1; 839 { *x2 = textMat[0] * x1 + textMat[2] * y1;
805 *y2 = textMat[1] * x1 + textMat[3] * y1; } 840 *y2 = textMat[1] * x1 + textMat[3] * y1; }
806 fouble transformWidth(fouble w); 841 fouble transformWidth(fouble w);
807 fouble getTransformedLineWidth() 842 fouble getTransformedLineWidth()
808 { return transformWidth(lineWidth); } 843 { return transformWidth(lineWidth); }
809 fouble getTransformedFontSize(); 844 fouble getTransformedFontSize();
810 void getFontTransMat(fouble *m11, fouble *m12, fouble *m21, fouble *m22); 845 void getFontTransMat(fouble *m11, fouble *m12, fouble *m21, fouble *m22);
811 846
812 // Change state parameters. 847 // Change state parameters.
813 void setCTM(fouble a, fouble b, fouble c, 848 void setCTM(fouble a, fouble b, fouble c,
814 fouble d, fouble e, fouble f); 849 fouble d, fouble e, fouble f);
815 void concatCTM(fouble a, fouble b, fouble c, 850 void concatCTM(fouble a, fouble b, fouble c,
816 fouble d, fouble e, fouble f); 851 fouble d, fouble e, fouble f);
817 void setFillColorSpace(GfxColorSpace *colorSpace); 852 void setFillColorSpace(GfxColorSpace *colorSpace);
818 void setStrokeColorSpace(GfxColorSpace *colorSpace); 853 void setStrokeColorSpace(GfxColorSpace *colorSpace);
819 void setFillColor(GfxColor *color) { fillColor = *color; } 854 void setFillColor(GfxColor *color) { fillColor = *color; }
820 void setStrokeColor(GfxColor *color) { strokeColor = *color; } 855 void setStrokeColor(GfxColor *color) { strokeColor = *color; }
821 void setFillPattern(GfxPattern *pattern); 856 void setFillPattern(GfxPattern *pattern);
822 void setStrokePattern(GfxPattern *pattern); 857 void setStrokePattern(GfxPattern *pattern);
823 void setFillOpacity(fouble opac) { fillOpacity = opac; } 858 void setFillOpacity(fouble opac) { fillOpacity = opac; }
824 void setStrokeOpacity(fouble opac) { strokeOpacity = opac; } 859 void setStrokeOpacity(fouble opac) { strokeOpacity = opac; }
825 void setLineWidth(fouble width) { lineWidth = width; } 860 void setLineWidth(fouble width) { lineWidth = width; }
826 void setLineDash(fouble *dash, int length, fouble start); 861 void setLineDash(fouble *dash, int length, fouble start);
827 void setFlatness(int flatness1) { flatness = flatness1; } 862 void setFlatness(int flatness1) { flatness = flatness1; }
828 void setLineJoin(int lineJoin1) { lineJoin = lineJoin1; } 863 void setLineJoin(int lineJoin1) { lineJoin = lineJoin1; }
829 void setLineCap(int lineCap1) { lineCap = lineCap1; } 864 void setLineCap(int lineCap1) { lineCap = lineCap1; }
830 void setMiterLimit(fouble limit) { miterLimit = limit; } 865 void setMiterLimit(fouble limit) { miterLimit = limit; }
831 void setFont(GfxFont *fontA, fouble fontSizeA) 866 void setFont(GfxFont *fontA, fouble fontSizeA)
832 { font = fontA; fontSize = fontSizeA; } 867 { font = fontA; fontSize = fontSizeA; }
833 void setTextMat(fouble a, fouble b, fouble c, 868 void setTextMat(fouble a, fouble b, fouble c,
834 fouble d, fouble e, fouble f) 869 fouble d, fouble e, fouble f)
835 { textMat[0] = a; textMat[1] = b; textMat[2] = c; 870 { textMat[0] = a; textMat[1] = b; textMat[2] = c;
836 textMat[3] = d; textMat[4] = e; textMat[5] = f; } 871 textMat[3] = d; textMat[4] = e; textMat[5] = f; }
837 void setCharSpace(fouble space) 872 void setCharSpace(fouble space)
838 { charSpace = space; } 873 { charSpace = space; }
839 void setWordSpace(fouble space) 874 void setWordSpace(fouble space)
840 { wordSpace = space; } 875 { wordSpace = space; }
841 void setHorizScaling(fouble scale) 876 void setHorizScaling(fouble scale)
842 { horizScaling = 0.01 * scale; } 877 { horizScaling = 0.01 * scale; }
843 void setLeading(fouble leadingA) 878 void setLeading(fouble leadingA)
844 { leading = leadingA; } 879 { leading = leadingA; }
845 void setRise(fouble riseA) 880 void setRise(fouble riseA)
846 { rise = riseA; } 881 { rise = riseA; }
847 void setRender(int renderA) 882 void setRender(int renderA)
848 { render = renderA; } 883 { render = renderA; }
849 884
850 // Add to path. 885 // Add to path.
851 void moveTo(fouble x, fouble y) 886 void moveTo(fouble x, fouble y)
852 { path->moveTo(curX = x, curY = y); } 887 { path->moveTo(curX = x, curY = y); }
853 void lineTo(fouble x, fouble y) 888 void lineTo(fouble x, fouble y)
854 { path->lineTo(curX = x, curY = y); } 889 { path->lineTo(curX = x, curY = y); }
855 void curveTo(fouble x1, fouble y1, fouble x2, fouble y2, 890 void curveTo(fouble x1, fouble y1, fouble x2, fouble y2,
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)
881 916
882 GfxColorSpace *fillColorSpace; // fill color space 917 GfxColorSpace *fillColorSpace; // fill color space
883 GfxColorSpace *strokeColorSpace; // stroke color space 918 GfxColorSpace *strokeColorSpace; // stroke color space
884 GfxColor fillColor; // fill color 919 GfxColor fillColor; // fill color
885 GfxColor strokeColor; // stroke color 920 GfxColor strokeColor; // stroke color
886 GfxPattern *fillPattern;// fill pattern 921 GfxPattern *fillPattern;// fill pattern
887 GfxPattern *strokePattern;// stroke pattern 922 GfxPattern *strokePattern;// stroke pattern
888 fouble fillOpacity; // fill opacity 923 fouble fillOpacity; // fill opacity
889 fouble strokeOpacity; // stroke opacity 924 fouble strokeOpacity; // stroke opacity
890 925
891 fouble lineWidth; // line width 926 fouble lineWidth; // line width
892 fouble *lineDash; // line dash 927 fouble *lineDash; // line dash
893 int lineDashLength; 928 int lineDashLength;
894 fouble lineDashStart; 929 fouble lineDashStart;
895 int flatness; // curve flatness 930 int flatness; // curve flatness
896 int lineJoin; // line join style 931 int lineJoin; // line join style
897 int lineCap; // line cap style 932 int lineCap; // line cap style
898 fouble miterLimit; // line miter limit 933 fouble miterLimit; // line miter limit
899 934
900 GfxFont *font; // font 935 GfxFont *font; // font
901 fouble fontSize; // font size 936 fouble fontSize; // font size
902 fouble textMat[6]; // text matrix 937 fouble textMat[6]; // text matrix
903 fouble charSpace; // character spacing 938 fouble charSpace; // character spacing
904 fouble wordSpace; // word spacing 939 fouble wordSpace; // word spacing
905 fouble horizScaling; // horizontal scaling 940 fouble horizScaling; // horizontal scaling
906 fouble leading; // text leading 941 fouble leading; // text leading
907 fouble rise; // text rise 942 fouble rise; // text rise
908 int render; // text rendering mode 943 int render; // text rendering mode
909 944
910 GfxPath *path; // array of path elements 945 GfxPath *path; // array of path elements
911 fouble curX, curY; // current point (user coords) 946 fouble curX, curY; // current point (user coords)
912 fouble lineX, lineY; // start of current text line (text coords) 947 fouble lineX, lineY; // start of current text line (text coords)
913 948
914 fouble clipXMin, clipYMin,// bounding box for clip region 949 fouble clipXMin, clipYMin,// bounding box for clip region
915 clipXMax, clipYMax; 950 clipXMax, clipYMax;
916 951
917 GfxState *saved; // next GfxState on stack 952 GfxState *saved; // next GfxState on stack
918 953
919 GfxState(GfxState *state); 954 GfxState(GfxState *state);
920}; 955};
921 956
922#endif 957#endif
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,916 +1,1065 @@
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>
18#endif 18#endif
19#include "gmem.h" 19#include "gmem.h"
20#include "GString.h" 20#include "GString.h"
21#include "GList.h" 21#include "GList.h"
22#include "GHash.h" 22#include "GHash.h"
23#include "gfile.h" 23#include "gfile.h"
24#include "Error.h" 24#include "Error.h"
25#include "NameToCharCode.h" 25#include "NameToCharCode.h"
26#include "CharCodeToUnicode.h" 26#include "CharCodeToUnicode.h"
27#include "UnicodeMap.h" 27#include "UnicodeMap.h"
28#include "CMap.h" 28#include "CMap.h"
29#include "BuiltinFontTables.h" 29#include "BuiltinFontTables.h"
30#include "FontEncodingTables.h" 30#include "FontEncodingTables.h"
31#include "GlobalParams.h" 31#include "GlobalParams.h"
32 32
33#include "NameToUnicodeTable.h" 33#include "NameToUnicodeTable.h"
34#include "UnicodeMapTables.h" 34#include "UnicodeMapTables.h"
35#include "DisplayFontTable.h" 35#include "DisplayFontTable.h"
36#include "UTF8.h" 36#include "UTF8.h"
37 37
38//------------------------------------------------------------------------ 38//------------------------------------------------------------------------
39 39
40GlobalParams *globalParams = NULL; 40GlobalParams *globalParams = NULL;
41 41
42//------------------------------------------------------------------------ 42//------------------------------------------------------------------------
43// DisplayFontParam 43// DisplayFontParam
44//------------------------------------------------------------------------ 44//------------------------------------------------------------------------
45 45
46DisplayFontParam::DisplayFontParam(GString *nameA, 46DisplayFontParam::DisplayFontParam(GString *nameA,
47 DisplayFontParamKind kindA) { 47 DisplayFontParamKind kindA) {
48 name = nameA; 48 name = nameA;
49 kind = kindA; 49 kind = kindA;
50 switch (kind) { 50 switch (kind) {
51 case displayFontX: 51 case displayFontX:
52 x.xlfd = NULL; 52 x.xlfd = NULL;
53 x.encoding = NULL; 53 x.encoding = NULL;
54 break; 54 break;
55 case displayFontT1: 55 case displayFontT1:
56 t1.fileName = NULL; 56 t1.fileName = NULL;
57 break; 57 break;
58 case displayFontTT: 58 case displayFontTT:
59 tt.fileName = NULL; 59 tt.fileName = NULL;
60 break; 60 break;
61 } 61 }
62} 62}
63 63
64DisplayFontParam::DisplayFontParam(char *nameA, char *xlfdA, char *encodingA) { 64DisplayFontParam::DisplayFontParam(char *nameA, char *xlfdA, char *encodingA) {
65 name = new GString(nameA); 65 name = new GString(nameA);
66 kind = displayFontX; 66 kind = displayFontX;
67 x.xlfd = new GString(xlfdA); 67 x.xlfd = new GString(xlfdA);
68 x.encoding = new GString(encodingA); 68 x.encoding = new GString(encodingA);
69} 69}
70 70
71DisplayFontParam::~DisplayFontParam() { 71DisplayFontParam::~DisplayFontParam() {
72 delete name; 72 delete name;
73 switch (kind) { 73 switch (kind) {
74 case displayFontX: 74 case displayFontX:
75 if (x.xlfd) { 75 if (x.xlfd) {
76 delete x.xlfd; 76 delete x.xlfd;
77 } 77 }
78 if (x.encoding) { 78 if (x.encoding) {
79 delete x.encoding; 79 delete x.encoding;
80 } 80 }
81 break; 81 break;
82 case displayFontT1: 82 case displayFontT1:
83 if (t1.fileName) { 83 if (t1.fileName) {
84 delete t1.fileName; 84 delete t1.fileName;
85 } 85 }
86 break; 86 break;
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) {
181 nameToUnicode->add(nameToUnicodeTab[i].name, nameToUnicodeTab[i].u); 191 nameToUnicode->add(nameToUnicodeTab[i].name, nameToUnicodeTab[i].u);
182 } 192 }
183 193
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;
208 if (cfgFileName && cfgFileName[0]) { 220 if (cfgFileName && cfgFileName[0]) {
209 fileName = new GString(cfgFileName); 221 fileName = new GString(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
341 if (tokens->getLength() != 2) { 397 if (tokens->getLength() != 2) {
342 error(-1, "Bad 'nameToUnicode' config file command (%s:%d)", 398 error(-1, "Bad 'nameToUnicode' config file command (%s:%d)",
343 fileName->getCString(), line); 399 fileName->getCString(), line);
344 return; 400 return;
345 } 401 }
346 name = (GString *)tokens->get(1); 402 name = (GString *)tokens->get(1);
347 if (!(f = fopen(name->getCString(), "r"))) { 403 if (!(f = fopen(name->getCString(), "r"))) {
348 error(-1, "Couldn't open 'nameToUnicode' file '%s'", 404 error(-1, "Couldn't open 'nameToUnicode' file '%s'",
349 name->getCString()); 405 name->getCString());
350 return; 406 return;
351 } 407 }
352 line2 = 1; 408 line2 = 1;
353 while (fgets(buf, sizeof(buf), f)) { 409 while (fgets(buf, sizeof(buf), f)) {
354 tok1 = strtok(buf, " \t\r\n"); 410 tok1 = strtok(buf, " \t\r\n");
355 tok2 = strtok(NULL, " \t\r\n"); 411 tok2 = strtok(NULL, " \t\r\n");
356 if (tok1 && tok2) { 412 if (tok1 && tok2) {
357 sscanf(tok1, "%x", &u); 413 sscanf(tok1, "%x", &u);
358 nameToUnicode->add(tok2, u); 414 nameToUnicode->add(tok2, u);
359 } else { 415 } else {
360 error(-1, "Bad line in 'nameToUnicode' file (%s:%d)", name, line2); 416 error(-1, "Bad line in 'nameToUnicode' file (%s:%d)", name, line2);
361 } 417 }
362 ++line2; 418 ++line2;
363 } 419 }
364 fclose(f); 420 fclose(f);
365} 421}
366 422
367void GlobalParams::parseCIDToUnicode(GList *tokens, GString *fileName, 423void GlobalParams::parseCIDToUnicode(GList *tokens, GString *fileName,
368 int line) { 424 int line) {
369 GString *collection, *name, *old; 425 GString *collection, *name, *old;
370 426
371 if (tokens->getLength() != 3) { 427 if (tokens->getLength() != 3) {
372 error(-1, "Bad 'cidToUnicode' config file command (%s:%d)", 428 error(-1, "Bad 'cidToUnicode' config file command (%s:%d)",
373 fileName->getCString(), line); 429 fileName->getCString(), line);
374 return; 430 return;
375 } 431 }
376 collection = (GString *)tokens->get(1); 432 collection = (GString *)tokens->get(1);
377 name = (GString *)tokens->get(2); 433 name = (GString *)tokens->get(2);
378 if ((old = (GString *)cidToUnicodes->remove(collection))) { 434 if ((old = (GString *)cidToUnicodes->remove(collection))) {
379 delete old; 435 delete old;
380 } 436 }
381 cidToUnicodes->add(collection->copy(), name->copy()); 437 cidToUnicodes->add(collection->copy(), name->copy());
382} 438}
383 439
384void GlobalParams::parseUnicodeMap(GList *tokens, GString *fileName, 440void GlobalParams::parseUnicodeMap(GList *tokens, GString *fileName,
385 int line) { 441 int line) {
386 GString *encodingName, *name, *old; 442 GString *encodingName, *name, *old;
387 443
388 if (tokens->getLength() != 3) { 444 if (tokens->getLength() != 3) {
389 error(-1, "Bad 'unicodeMap' config file command (%s:%d)", 445 error(-1, "Bad 'unicodeMap' config file command (%s:%d)",
390 fileName->getCString(), line); 446 fileName->getCString(), line);
391 return; 447 return;
392 } 448 }
393 encodingName = (GString *)tokens->get(1); 449 encodingName = (GString *)tokens->get(1);
394 name = (GString *)tokens->get(2); 450 name = (GString *)tokens->get(2);
395 if ((old = (GString *)unicodeMaps->remove(encodingName))) { 451 if ((old = (GString *)unicodeMaps->remove(encodingName))) {
396 delete old; 452 delete old;
397 } 453 }
398 unicodeMaps->add(encodingName->copy(), name->copy()); 454 unicodeMaps->add(encodingName->copy(), name->copy());
399} 455}
400 456
401void GlobalParams::parseCMapDir(GList *tokens, GString *fileName, int line) { 457void GlobalParams::parseCMapDir(GList *tokens, GString *fileName, int line) {
402 GString *collection, *dir; 458 GString *collection, *dir;
403 GList *list; 459 GList *list;
404 460
405 if (tokens->getLength() != 3) { 461 if (tokens->getLength() != 3) {
406 error(-1, "Bad 'cMapDir' config file command (%s:%d)", 462 error(-1, "Bad 'cMapDir' config file command (%s:%d)",
407 fileName->getCString(), line); 463 fileName->getCString(), line);
408 return; 464 return;
409 } 465 }
410 collection = (GString *)tokens->get(1); 466 collection = (GString *)tokens->get(1);
411 dir = (GString *)tokens->get(2); 467 dir = (GString *)tokens->get(2);
412 if (!(list = (GList *)cMapDirs->lookup(collection))) { 468 if (!(list = (GList *)cMapDirs->lookup(collection))) {
413 list = new GList(); 469 list = new GList();
414 cMapDirs->add(collection->copy(), list); 470 cMapDirs->add(collection->copy(), list);
415 } 471 }
416 list->append(dir->copy()); 472 list->append(dir->copy());
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) {
442 goto err2; 498 goto err2;
443 } 499 }
444 param->x.xlfd = ((GString *)tokens->get(2))->copy(); 500 param->x.xlfd = ((GString *)tokens->get(2))->copy();
445 param->x.encoding = ((GString *)tokens->get(3))->copy(); 501 param->x.encoding = ((GString *)tokens->get(3))->copy();
446 break; 502 break;
447 case displayFontT1: 503 case displayFontT1:
448 if (tokens->getLength() != 3) { 504 if (tokens->getLength() != 3) {
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);
490 } 539 }
491 } else if (tokens->getLength() == 3) { 540 } else if (tokens->getLength() == 3) {
492 tok = (GString *)tokens->get(1); 541 tok = (GString *)tokens->get(1);
493 psPaperWidth = atoi(tok->getCString()); 542 psPaperWidth = atoi(tok->getCString());
494 tok = (GString *)tokens->get(2); 543 tok = (GString *)tokens->get(2);
495 psPaperHeight = atoi(tok->getCString()); 544 psPaperHeight = atoi(tok->getCString());
496 } else { 545 } else {
497 error(-1, "Bad 'psPaperSize' config file command (%s:%d)", 546 error(-1, "Bad 'psPaperSize' config file command (%s:%d)",
498 fileName->getCString(), line); 547 fileName->getCString(), line);
499 } 548 }
500} 549}
501 550
502void GlobalParams::parsePSLevel(GList *tokens, GString *fileName, int line) { 551void GlobalParams::parsePSLevel(GList *tokens, GString *fileName, int line) {
503 GString *tok; 552 GString *tok;
504 553
505 if (tokens->getLength() != 2) { 554 if (tokens->getLength() != 2) {
506 error(-1, "Bad 'psLevel' config file command (%s:%d)", 555 error(-1, "Bad 'psLevel' config file command (%s:%d)",
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 }
531 if (psFile) { 584 if (psFile) {
532 delete psFile; 585 delete psFile;
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) {
562 GString *tok; 643 GString *tok;
563 644
564 if (tokens->getLength() != 2) { 645 if (tokens->getLength() != 2) {
565 error(-1, "Bad 'textEOL' config file command (%s:%d)", 646 error(-1, "Bad 'textEOL' config file command (%s:%d)",
566 fileName->getCString(), line); 647 fileName->getCString(), line);
567 return; 648 return;
568 } 649 }
569 tok = (GString *)tokens->get(1); 650 tok = (GString *)tokens->get(1);
570 if (!tok->cmp("unix")) { 651 if (!tok->cmp("unix")) {
571 textEOL = eolUnix; 652 textEOL = eolUnix;
572 } else if (!tok->cmp("dos")) { 653 } else if (!tok->cmp("dos")) {
573 textEOL = eolDOS; 654 textEOL = eolDOS;
574 } else if (!tok->cmp("mac")) { 655 } else if (!tok->cmp("mac")) {
575 textEOL = eolMac; 656 textEOL = eolMac;
576 } else { 657 } else {
577 error(-1, "Bad 'textEOL' config file command (%s:%d)", 658 error(-1, "Bad 'textEOL' config file command (%s:%d)",
578 fileName->getCString(), line); 659 fileName->getCString(), 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;
633 } else if (!tok->cmp("no")) { 725 } else if (!tok->cmp("no")) {
634 *flag = gFalse; 726 *flag = gFalse;
635 } else { 727 } else {
636 error(-1, "Bad '%s' config file command (%s:%d)", 728 error(-1, "Bad '%s' config file command (%s:%d)",
637 cmdName, fileName->getCString(), line); 729 cmdName, fileName->getCString(), line);
638 } 730 }
639} 731}
640 732
641GlobalParams::~GlobalParams() { 733GlobalParams::~GlobalParams() {
642 GHashIter *iter; 734 GHashIter *iter;
643 GString *key; 735 GString *key;
644 GList *list; 736 GList *list;
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;
675 delete cMapCache; 771 delete cMapCache;
676} 772}
677 773
678//------------------------------------------------------------------------ 774//------------------------------------------------------------------------
679// accessors 775// accessors
680//------------------------------------------------------------------------ 776//------------------------------------------------------------------------
681 777
682CharCode GlobalParams::getMacRomanCharCode(char *charName) { 778CharCode GlobalParams::getMacRomanCharCode(char *charName) {
683 return macRomanReverseMap->lookup(charName); 779 return macRomanReverseMap->lookup(charName);
684} 780}
685 781
686Unicode GlobalParams::mapNameToUnicode(char *charName) { 782Unicode GlobalParams::mapNameToUnicode(char *charName) {
687 return nameToUnicode->lookup(charName); 783 return nameToUnicode->lookup(charName);
688} 784}
689 785
690FILE *GlobalParams::getCIDToUnicodeFile(GString *collection) { 786FILE *GlobalParams::getCIDToUnicodeFile(GString *collection) {
691 GString *fileName; 787 GString *fileName;
692 788
693 if (!(fileName = (GString *)cidToUnicodes->lookup(collection))) { 789 if (!(fileName = (GString *)cidToUnicodes->lookup(collection))) {
694 return NULL; 790 return NULL;
695 } 791 }
696 return fopen(fileName->getCString(), "r"); 792 return fopen(fileName->getCString(), "r");
697} 793}
698 794
699UnicodeMap *GlobalParams::getResidentUnicodeMap(GString *encodingName) { 795UnicodeMap *GlobalParams::getResidentUnicodeMap(GString *encodingName) {
700 return (UnicodeMap *)residentUnicodeMaps->lookup(encodingName); 796 return (UnicodeMap *)residentUnicodeMaps->lookup(encodingName);
701} 797}
702 798
703FILE *GlobalParams::getUnicodeMapFile(GString *encodingName) { 799FILE *GlobalParams::getUnicodeMapFile(GString *encodingName) {
704 GString *fileName; 800 GString *fileName;
705 801
706 if (!(fileName = (GString *)unicodeMaps->lookup(encodingName))) { 802 if (!(fileName = (GString *)unicodeMaps->lookup(encodingName))) {
707 return NULL; 803 return NULL;
708 } 804 }
709 return fopen(fileName->getCString(), "r"); 805 return fopen(fileName->getCString(), "r");
710} 806}
711 807
712FILE *GlobalParams::findCMapFile(GString *collection, GString *cMapName) { 808FILE *GlobalParams::findCMapFile(GString *collection, GString *cMapName) {
713 GList *list; 809 GList *list;
714 GString *dir; 810 GString *dir;
715 GString *fileName; 811 GString *fileName;
716 FILE *f; 812 FILE *f;
717 int i; 813 int i;
718 814
719 if (!(list = (GList *)cMapDirs->lookup(collection))) { 815 if (!(list = (GList *)cMapDirs->lookup(collection))) {
720 return NULL; 816 return NULL;
721 } 817 }
722 for (i = 0; i < list->getLength(); ++i) { 818 for (i = 0; i < list->getLength(); ++i) {
723 dir = (GString *)list->get(i); 819 dir = (GString *)list->get(i);
724 fileName = appendToPath(dir->copy(), cMapName->getCString()); 820 fileName = appendToPath(dir->copy(), cMapName->getCString());
725 f = fopen(fileName->getCString(), "r"); 821 f = fopen(fileName->getCString(), "r");
726 delete fileName; 822 delete fileName;
727 if (f) { 823 if (f) {
728 return f; 824 return f;
729 } 825 }
730 } 826 }
731 return NULL; 827 return NULL;
732} 828}
733 829
734FILE *GlobalParams::findToUnicodeFile(GString *name) { 830FILE *GlobalParams::findToUnicodeFile(GString *name) {
735 GString *dir, *fileName; 831 GString *dir, *fileName;
736 FILE *f; 832 FILE *f;
737 int i; 833 int i;
738 834
739 for (i = 0; i < toUnicodeDirs->getLength(); ++i) { 835 for (i = 0; i < toUnicodeDirs->getLength(); ++i) {
740 dir = (GString *)toUnicodeDirs->get(i); 836 dir = (GString *)toUnicodeDirs->get(i);
741 fileName = appendToPath(dir->copy(), name->getCString()); 837 fileName = appendToPath(dir->copy(), name->getCString());
742 f = fopen(fileName->getCString(), "r"); 838 f = fopen(fileName->getCString(), "r");
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"))) {
775 fclose(f); 907 fclose(f);
776 return fileName; 908 return fileName;
777 } 909 }
778 delete fileName; 910 delete fileName;
779 } 911 }
780 if (ext2) { 912 if (ext2) {
781 fileName = appendToPath(dir->copy(), fontName->getCString()); 913 fileName = appendToPath(dir->copy(), fontName->getCString());
782 fileName->append(ext2); 914 fileName->append(ext2);
783 if ((f = fopen(fileName->getCString(), "r"))) { 915 if ((f = fopen(fileName->getCString(), "r"))) {
784 fclose(f); 916 fclose(f);
785 return fileName; 917 return fileName;
786 } 918 }
787 delete fileName; 919 delete fileName;
788 } 920 }
789 } 921 }
790 return NULL; 922 return NULL;
791} 923}
792 924
793CharCodeToUnicode *GlobalParams::getCIDToUnicode(GString *collection) { 925CharCodeToUnicode *GlobalParams::getCIDToUnicode(GString *collection) {
794 return cidToUnicodeCache->getCIDToUnicode(collection); 926 return cidToUnicodeCache->getCIDToUnicode(collection);
795} 927}
796 928
797UnicodeMap *GlobalParams::getUnicodeMap(GString *encodingName) { 929UnicodeMap *GlobalParams::getUnicodeMap(GString *encodingName) {
798 UnicodeMap *map; 930 UnicodeMap *map;
799 931
800 if ((map = getResidentUnicodeMap(encodingName))) { 932 if ((map = getResidentUnicodeMap(encodingName))) {
801 map->incRefCnt(); 933 map->incRefCnt();
802 return map; 934 return map;
803 } 935 }
804 return unicodeMapCache->getUnicodeMap(encodingName); 936 return unicodeMapCache->getUnicodeMap(encodingName);
805} 937}
806 938
807CMap *GlobalParams::getCMap(GString *collection, GString *cMapName) { 939CMap *GlobalParams::getCMap(GString *collection, GString *cMapName) {
808 return cMapCache->getCMap(collection, cMapName); 940 return cMapCache->getCMap(collection, cMapName);
809} 941}
810 942
811UnicodeMap *GlobalParams::getTextEncoding() { 943UnicodeMap *GlobalParams::getTextEncoding() {
812 return getUnicodeMap(textEncoding); 944 return getUnicodeMap(textEncoding);
813} 945}
814 946
815//------------------------------------------------------------------------ 947//------------------------------------------------------------------------
816// functions to set parameters 948// functions to set parameters
817//------------------------------------------------------------------------ 949//------------------------------------------------------------------------
818 950
819void GlobalParams::setPSFile(char *file) { 951void GlobalParams::setPSFile(char *file) {
820 if (psFile) { 952 if (psFile) {
821 delete psFile; 953 delete psFile;
822 } 954 }
823 psFile = new GString(file); 955 psFile = new GString(file);
824} 956}
825 957
826GBool GlobalParams::setPSPaperSize(char *size) { 958GBool GlobalParams::setPSPaperSize(char *size) {
827 if (!strcmp(size, "letter")) { 959 if (!strcmp(size, "letter")) {
828 psPaperWidth = 612; 960 psPaperWidth = 612;
829 psPaperHeight = 792; 961 psPaperHeight = 792;
830 } else if (!strcmp(size, "legal")) { 962 } else if (!strcmp(size, "legal")) {
831 psPaperWidth = 612; 963 psPaperWidth = 612;
832 psPaperHeight = 1008; 964 psPaperHeight = 1008;
833 } else if (!strcmp(size, "A4")) { 965 } else if (!strcmp(size, "A4")) {
834 psPaperWidth = 595; 966 psPaperWidth = 595;
835 psPaperHeight = 842; 967 psPaperHeight = 842;
836 } else if (!strcmp(size, "A3")) { 968 } else if (!strcmp(size, "A3")) {
837 psPaperWidth = 842; 969 psPaperWidth = 842;
838 psPaperHeight = 1190; 970 psPaperHeight = 1190;
839 } else { 971 } else {
840 return gFalse; 972 return gFalse;
841 } 973 }
842 return gTrue; 974 return gTrue;
843} 975}
844 976
845void GlobalParams::setPSPaperWidth(int width) { 977void GlobalParams::setPSPaperWidth(int width) {
846 psPaperWidth = width; 978 psPaperWidth = width;
847} 979}
848 980
849void GlobalParams::setPSPaperHeight(int height) { 981void GlobalParams::setPSPaperHeight(int height) {
850 psPaperHeight = height; 982 psPaperHeight = height;
851} 983}
852 984
853void GlobalParams::setPSDuplex(GBool duplex) { 985void GlobalParams::setPSDuplex(GBool duplex) {
854 psDuplex = duplex; 986 psDuplex = duplex;
855} 987}
856 988
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")) {
903 *val = fontRastPlain; 1052 *val = fontRastPlain;
904 } else if (!strcmp(s, "low")) { 1053 } else if (!strcmp(s, "low")) {
905 *val = fontRastAALow; 1054 *val = fontRastAALow;
906 } else if (!strcmp(s, "high")) { 1055 } else if (!strcmp(s, "high")) {
907 *val = fontRastAAHigh; 1056 *val = fontRastAAHigh;
908 } else { 1057 } else {
909 return gFalse; 1058 return gFalse;
910 } 1059 }
911 return gTrue; 1060 return gTrue;
912} 1061}
913 1062
914void GlobalParams::setErrQuiet(GBool errQuietA) { 1063void GlobalParams::setErrQuiet(GBool errQuietA) {
915 errQuiet = errQuietA; 1064 errQuiet = errQuietA;
916} 1065}
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,242 +1,273 @@
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"
18#include "CharTypes.h" 18#include "CharTypes.h"
19 19
20class GString; 20class GString;
21class GList; 21class GList;
22class GHash; 22class GHash;
23class NameToCharCode; 23class NameToCharCode;
24class CharCodeToUnicode; 24class CharCodeToUnicode;
25class CIDToUnicodeCache; 25class CIDToUnicodeCache;
26class UnicodeMap; 26class UnicodeMap;
27class UnicodeMapCache; 27class UnicodeMapCache;
28class CMap; 28class CMap;
29class CMapCache; 29class CMapCache;
30class GlobalParams; 30class GlobalParams;
31 31
32//------------------------------------------------------------------------ 32//------------------------------------------------------------------------
33 33
34// The global parameters object. 34// The global parameters object.
35extern GlobalParams *globalParams; 35extern 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;
62 }; 63 };
63 64
64 DisplayFontParam(GString *nameA, DisplayFontParamKind kindA); 65 DisplayFontParam(GString *nameA, DisplayFontParamKind kindA);
65 DisplayFontParam(char *nameA, char *xlfdA, char *encodingA); 66 DisplayFontParam(char *nameA, char *xlfdA, char *encodingA);
66 ~DisplayFontParam(); 67 ~DisplayFontParam();
67}; 68};
68 69
69// Font rasterizer control. 70// Font rasterizer control.
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
108class GlobalParams { 117class GlobalParams {
109public: 118public:
110 119
111 // Initialize the global parameters by attempting to read a config 120 // Initialize the global parameters by attempting to read a config
112 // file. 121 // file.
113 GlobalParams(char *cfgFileName); 122 GlobalParams(char *cfgFileName);
114 123
115 ~GlobalParams(); 124 ~GlobalParams();
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
197 //----- user-modifiable settings 220 //----- user-modifiable settings
198 221
199 NameToCharCode * // mapping from char name to Unicode 222 NameToCharCode * // mapping from char name to Unicode
200 nameToUnicode; 223 nameToUnicode;
201 GHash *cidToUnicodes; // files for mappings from char collections 224 GHash *cidToUnicodes; // files for mappings from char collections
202 // to Unicode, indexed by collection name 225 // to Unicode, indexed by collection name
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
242#endif 273#endif
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,197 +1,197 @@
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>
18#include "Lexer.h" 18#include "Lexer.h"
19#include "Error.h" 19#include "Error.h"
20 20
21//------------------------------------------------------------------------ 21//------------------------------------------------------------------------
22 22
23// A '1' in this array means the character is white space. A '1' or 23// A '1' in this array means the character is white space. A '1' or
24// '2' means the character ends a name or command. 24// '2' means the character ends a name or command.
25static char specialChars[256] = { 25static char specialChars[256] = {
26 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, // 0x 26 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, // 0x
27 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x 27 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
28 1, 0, 0, 0, 0, 2, 0, 0, 2, 2, 0, 0, 0, 0, 0, 2, // 2x 28 1, 0, 0, 0, 0, 2, 0, 0, 2, 2, 0, 0, 0, 0, 0, 2, // 2x
29 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, // 3x 29 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, // 3x
30 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 4x 30 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 4x
31 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 0, // 5x 31 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 0, // 5x
32 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 6x 32 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 6x
33 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 0, // 7x 33 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 0, // 7x
34 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x 34 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x
35 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x 35 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x
36 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // ax 36 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // ax
37 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // bx 37 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // bx
38 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // cx 38 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // cx
39 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // dx 39 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // dx
40 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // ex 40 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // ex
41 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // fx 41 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // fx
42}; 42};
43 43
44//------------------------------------------------------------------------ 44//------------------------------------------------------------------------
45// Lexer 45// Lexer
46//------------------------------------------------------------------------ 46//------------------------------------------------------------------------
47 47
48Lexer::Lexer(XRef *xref, Stream *str) { 48Lexer::Lexer(XRef *xref, Stream *str) {
49 Object obj; 49 Object obj;
50 50
51 curStr.initStream(str); 51 curStr.initStream(str);
52 streams = new Array(xref); 52 streams = new Array(xref);
53 streams->add(curStr.copy(&obj)); 53 streams->add(curStr.copy(&obj));
54 strPtr = 0; 54 strPtr = 0;
55 freeArray = gTrue; 55 freeArray = gTrue;
56 curStr.streamReset(); 56 curStr.streamReset();
57} 57}
58 58
59Lexer::Lexer(XRef *xref, Object *obj) { 59Lexer::Lexer(XRef *xref, Object *obj) {
60 Object obj2; 60 Object obj2;
61 61
62 if (obj->isStream()) { 62 if (obj->isStream()) {
63 streams = new Array(xref); 63 streams = new Array(xref);
64 freeArray = gTrue; 64 freeArray = gTrue;
65 streams->add(obj->copy(&obj2)); 65 streams->add(obj->copy(&obj2));
66 } else { 66 } else {
67 streams = obj->getArray(); 67 streams = obj->getArray();
68 freeArray = gFalse; 68 freeArray = gFalse;
69 } 69 }
70 strPtr = 0; 70 strPtr = 0;
71 if (streams->getLength() > 0) { 71 if (streams->getLength() > 0) {
72 streams->get(strPtr, &curStr); 72 streams->get(strPtr, &curStr);
73 curStr.streamReset(); 73 curStr.streamReset();
74 } 74 }
75} 75}
76 76
77Lexer::~Lexer() { 77Lexer::~Lexer() {
78 if (!curStr.isNone()) { 78 if (!curStr.isNone()) {
79 curStr.streamClose(); 79 curStr.streamClose();
80 curStr.free(); 80 curStr.free();
81 } 81 }
82 if (freeArray) { 82 if (freeArray) {
83 delete streams; 83 delete streams;
84 } 84 }
85} 85}
86 86
87int Lexer::getChar() { 87int Lexer::getChar() {
88 int c; 88 int c;
89 89
90 c = EOF; 90 c = EOF;
91 while (!curStr.isNone() && (c = curStr.streamGetChar()) == EOF) { 91 while (!curStr.isNone() && (c = curStr.streamGetChar()) == EOF) {
92 curStr.streamClose(); 92 curStr.streamClose();
93 curStr.free(); 93 curStr.free();
94 ++strPtr; 94 ++strPtr;
95 if (strPtr < streams->getLength()) { 95 if (strPtr < streams->getLength()) {
96 streams->get(strPtr, &curStr); 96 streams->get(strPtr, &curStr);
97 curStr.streamReset(); 97 curStr.streamReset();
98 } 98 }
99 } 99 }
100 return c; 100 return c;
101} 101}
102 102
103int Lexer::lookChar() { 103int Lexer::lookChar() {
104 if (curStr.isNone()) { 104 if (curStr.isNone()) {
105 return EOF; 105 return EOF;
106 } 106 }
107 return curStr.streamLookChar(); 107 return curStr.streamLookChar();
108} 108}
109 109
110Object *Lexer::getObj(Object *obj) { 110Object *Lexer::getObj(Object *obj) {
111 char *p; 111 char *p;
112 int c, c2; 112 int c, c2;
113 GBool comment, neg, done; 113 GBool comment, neg, done;
114 int numParen; 114 int numParen;
115 int xi; 115 int xi;
116 fouble xf, scale; 116 fouble xf, scale;
117 GString *s; 117 GString *s;
118 int n, m; 118 int n, m;
119 119
120 // skip whitespace and comments 120 // skip whitespace and comments
121 comment = gFalse; 121 comment = gFalse;
122 while (1) { 122 while (1) {
123 if ((c = getChar()) == EOF) { 123 if ((c = getChar()) == EOF) {
124 return obj->initEOF(); 124 return obj->initEOF();
125 } 125 }
126 if (comment) { 126 if (comment) {
127 if (c == '\r' || c == '\n') 127 if (c == '\r' || c == '\n')
128 comment = gFalse; 128 comment = gFalse;
129 } else if (c == '%') { 129 } else if (c == '%') {
130 comment = gTrue; 130 comment = gTrue;
131 } else if (specialChars[c] != 1) { 131 } else if (specialChars[c] != 1) {
132 break; 132 break;
133 } 133 }
134 } 134 }
135 135
136 // start reading token 136 // start reading token
137 switch (c) { 137 switch (c) {
138 138
139 // number 139 // number
140 case '0': case '1': case '2': case '3': case '4': 140 case '0': case '1': case '2': case '3': case '4':
141 case '5': case '6': case '7': case '8': case '9': 141 case '5': case '6': case '7': case '8': case '9':
142 case '-': case '.': 142 case '-': case '.':
143 neg = gFalse; 143 neg = gFalse;
144 xi = 0; 144 xi = 0;
145 if (c == '-') { 145 if (c == '-') {
146 neg = gTrue; 146 neg = gTrue;
147 } else if (c == '.') { 147 } else if (c == '.') {
148 goto doReal; 148 goto doReal;
149 } else { 149 } else {
150 xi = c - '0'; 150 xi = c - '0';
151 } 151 }
152 while (1) { 152 while (1) {
153 c = lookChar(); 153 c = lookChar();
154 if (isdigit(c)) { 154 if (isdigit(c)) {
155 getChar(); 155 getChar();
156 xi = xi * 10 + (c - '0'); 156 xi = xi * 10 + (c - '0');
157 } else if (c == '.') { 157 } else if (c == '.') {
158 getChar(); 158 getChar();
159 goto doReal; 159 goto doReal;
160 } else { 160 } else {
161 break; 161 break;
162 } 162 }
163 } 163 }
164 if (neg) 164 if (neg)
165 xi = -xi; 165 xi = -xi;
166 obj->initInt(xi); 166 obj->initInt(xi);
167 break; 167 break;
168 doReal: 168 doReal:
169 xf = xi; 169 xf = xi;
170 scale = 0.1; 170 scale = 0.1;
171 while (1) { 171 while (1) {
172 c = lookChar(); 172 c = lookChar();
173 if (!isdigit(c)) { 173 if (!isdigit(c)) {
174 break; 174 break;
175 } 175 }
176 getChar(); 176 getChar();
177 xf = xf + scale * (c - '0'); 177 xf = xf + scale * (c - '0');
178 scale *= 0.1; 178 scale *= 0.1;
179 } 179 }
180 if (neg) 180 if (neg)
181 xf = -xf; 181 xf = -xf;
182 obj->initReal(xf); 182 obj->initReal(xf);
183 break; 183 break;
184 184
185 // string 185 // string
186 case '(': 186 case '(':
187 p = tokBuf; 187 p = tokBuf;
188 n = 0; 188 n = 0;
189 numParen = 1; 189 numParen = 1;
190 done = gFalse; 190 done = gFalse;
191 s = NULL; 191 s = NULL;
192 do { 192 do {
193 c2 = EOF; 193 c2 = EOF;
194 switch (c = getChar()) { 194 switch (c = getChar()) {
195 195
196 case EOF: 196 case EOF:
197#if 0 197#if 0
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,74 +1,75 @@
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"
18 18
19class XRef; 19class XRef;
20 20
21 #define tokBufSize 128 // size of token buffer 21 #define tokBufSize 128 // size of token buffer
22 22
23//------------------------------------------------------------------------ 23//------------------------------------------------------------------------
24// Lexer 24// Lexer
25//------------------------------------------------------------------------ 25//------------------------------------------------------------------------
26 26
27class Lexer { 27class Lexer {
28public: 28public:
29 29
30 // Construct a lexer for a single stream. Deletes the stream when 30 // Construct a lexer for a single stream. Deletes the stream when
31 // lexer is deleted. 31 // lexer is deleted.
32 Lexer(XRef *xref, Stream *str); 32 Lexer(XRef *xref, Stream *str);
33 33
34 // Construct a lexer for a stream or array of streams (assumes obj 34 // Construct a lexer for a stream or array of streams (assumes obj
35 // is either a stream or array of streams). 35 // is either a stream or array of streams).
36 Lexer(XRef *xref, Object *obj); 36 Lexer(XRef *xref, Object *obj);
37 37
38 // Destructor. 38 // Destructor.
39 ~Lexer(); 39 ~Lexer();
40 40
41 // Get the next object from the input stream. 41 // Get the next object from the input stream.
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};
73 74
74#endif 75#endif
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,634 +1,630 @@
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"
18#include "Error.h" 18#include "Error.h"
19#include "Object.h" 19#include "Object.h"
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;
69 left = obj2.getNum(); 65 left = obj2.getNum();
70 } else { 66 } else {
71 error(-1, "Bad annotation destination position"); 67 error(-1, "Bad annotation destination position");
72 goto err1; 68 goto err1;
73 } 69 }
74 obj2.free(); 70 obj2.free();
75 a->get(3, &obj2); 71 a->get(3, &obj2);
76 if (obj2.isNull()) { 72 if (obj2.isNull()) {
77 changeTop = gFalse; 73 changeTop = gFalse;
78 } else if (obj2.isNum()) { 74 } else if (obj2.isNum()) {
79 changeTop = gTrue; 75 changeTop = gTrue;
80 top = obj2.getNum(); 76 top = obj2.getNum();
81 } else { 77 } else {
82 error(-1, "Bad annotation destination position"); 78 error(-1, "Bad annotation destination position");
83 goto err1; 79 goto err1;
84 } 80 }
85 obj2.free(); 81 obj2.free();
86 a->get(4, &obj2); 82 a->get(4, &obj2);
87 if (obj2.isNull()) { 83 if (obj2.isNull()) {
88 changeZoom = gFalse; 84 changeZoom = gFalse;
89 } else if (obj2.isNum()) { 85 } else if (obj2.isNum()) {
90 changeZoom = gTrue; 86 changeZoom = gTrue;
91 zoom = obj2.getNum(); 87 zoom = obj2.getNum();
92 } else { 88 } else {
93 error(-1, "Bad annotation destination position"); 89 error(-1, "Bad annotation destination position");
94 goto err1; 90 goto err1;
95 } 91 }
96 obj2.free(); 92 obj2.free();
97 93
98 // Fit link 94 // Fit link
99 } else if (obj1.isName("Fit")) { 95 } else if (obj1.isName("Fit")) {
100 kind = destFit; 96 kind = destFit;
101 97
102 // FitH link 98 // FitH link
103 } else if (obj1.isName("FitH")) { 99 } else if (obj1.isName("FitH")) {
104 kind = destFitH; 100 kind = destFitH;
105 if (!a->get(2, &obj2)->isNum()) { 101 if (!a->get(2, &obj2)->isNum()) {
106 error(-1, "Bad annotation destination position"); 102 error(-1, "Bad annotation destination position");
107 goto err1; 103 goto err1;
108 } 104 }
109 top = obj2.getNum(); 105 top = obj2.getNum();
110 obj2.free(); 106 obj2.free();
111 107
112 // FitV link 108 // FitV link
113 } else if (obj1.isName("FitV")) { 109 } else if (obj1.isName("FitV")) {
114 kind = destFitV; 110 kind = destFitV;
115 if (!a->get(2, &obj2)->isNum()) { 111 if (!a->get(2, &obj2)->isNum()) {
116 error(-1, "Bad annotation destination position"); 112 error(-1, "Bad annotation destination position");
117 goto err1; 113 goto err1;
118 } 114 }
119 left = obj2.getNum(); 115 left = obj2.getNum();
120 obj2.free(); 116 obj2.free();
121 117
122 // FitR link 118 // FitR link
123 } else if (obj1.isName("FitR")) { 119 } else if (obj1.isName("FitR")) {
124 kind = destFitR; 120 kind = destFitR;
125 if (!a->get(2, &obj2)->isNum()) { 121 if (!a->get(2, &obj2)->isNum()) {
126 error(-1, "Bad annotation destination position"); 122 error(-1, "Bad annotation destination position");
127 goto err1; 123 goto err1;
128 } 124 }
129 left = obj2.getNum(); 125 left = obj2.getNum();
130 obj2.free(); 126 obj2.free();
131 if (!a->get(3, &obj2)->isNum()) { 127 if (!a->get(3, &obj2)->isNum()) {
132 error(-1, "Bad annotation destination position"); 128 error(-1, "Bad annotation destination position");
133 goto err1; 129 goto err1;
134 } 130 }
135 bottom = obj2.getNum(); 131 bottom = obj2.getNum();
136 obj2.free(); 132 obj2.free();
137 if (!a->get(4, &obj2)->isNum()) { 133 if (!a->get(4, &obj2)->isNum()) {
138 error(-1, "Bad annotation destination position"); 134 error(-1, "Bad annotation destination position");
139 goto err1; 135 goto err1;
140 } 136 }
141 right = obj2.getNum(); 137 right = obj2.getNum();
142 obj2.free(); 138 obj2.free();
143 if (!a->get(5, &obj2)->isNum()) { 139 if (!a->get(5, &obj2)->isNum()) {
144 error(-1, "Bad annotation destination position"); 140 error(-1, "Bad annotation destination position");
145 goto err1; 141 goto err1;
146 } 142 }
147 top = obj2.getNum(); 143 top = obj2.getNum();
148 obj2.free(); 144 obj2.free();
149 145
150 // FitB link 146 // FitB link
151 } else if (obj1.isName("FitB")) { 147 } else if (obj1.isName("FitB")) {
152 kind = destFitB; 148 kind = destFitB;
153 149
154 // FitBH link 150 // FitBH link
155 } else if (obj1.isName("FitBH")) { 151 } else if (obj1.isName("FitBH")) {
156 kind = destFitBH; 152 kind = destFitBH;
157 if (!a->get(2, &obj2)->isNum()) { 153 if (!a->get(2, &obj2)->isNum()) {
158 error(-1, "Bad annotation destination position"); 154 error(-1, "Bad annotation destination position");
159 goto err1; 155 goto err1;
160 } 156 }
161 top = obj2.getNum(); 157 top = obj2.getNum();
162 obj2.free(); 158 obj2.free();
163 159
164 // FitBV link 160 // FitBV link
165 } else if (obj1.isName("FitBV")) { 161 } else if (obj1.isName("FitBV")) {
166 kind = destFitBV; 162 kind = destFitBV;
167 if (!a->get(2, &obj2)->isNum()) { 163 if (!a->get(2, &obj2)->isNum()) {
168 error(-1, "Bad annotation destination position"); 164 error(-1, "Bad annotation destination position");
169 goto err1; 165 goto err1;
170 } 166 }
171 left = obj2.getNum(); 167 left = obj2.getNum();
172 obj2.free(); 168 obj2.free();
173 169
174 // unknown link kind 170 // unknown link kind
175 } else { 171 } else {
176 error(-1, "Unknown annotation destination type"); 172 error(-1, "Unknown annotation destination type");
177 goto err2; 173 goto err2;
178 } 174 }
179 175
180 obj1.free(); 176 obj1.free();
181 ok = gTrue; 177 ok = gTrue;
182 return; 178 return;
183 179
184 err1: 180 err1:
185 obj2.free(); 181 obj2.free();
186 err2: 182 err2:
187 obj1.free(); 183 obj1.free();
188} 184}
189 185
190LinkDest::LinkDest(LinkDest *dest) { 186LinkDest::LinkDest(LinkDest *dest) {
191 kind = dest->kind; 187 kind = dest->kind;
192 pageIsRef = dest->pageIsRef; 188 pageIsRef = dest->pageIsRef;
193 if (pageIsRef) 189 if (pageIsRef)
194 pageRef = dest->pageRef; 190 pageRef = dest->pageRef;
195 else 191 else
196 pageNum = dest->pageNum; 192 pageNum = dest->pageNum;
197 left = dest->left; 193 left = dest->left;
198 bottom = dest->bottom; 194 bottom = dest->bottom;
199 right = dest->right; 195 right = dest->right;
200 top = dest->top; 196 top = dest->top;
201 zoom = dest->zoom; 197 zoom = dest->zoom;
202 changeLeft = dest->changeLeft; 198 changeLeft = dest->changeLeft;
203 changeTop = dest->changeTop; 199 changeTop = dest->changeTop;
204 changeZoom = dest->changeZoom; 200 changeZoom = dest->changeZoom;
205 ok = gTrue; 201 ok = gTrue;
206} 202}
207 203
208//------------------------------------------------------------------------ 204//------------------------------------------------------------------------
209// LinkGoTo 205// LinkGoTo
210//------------------------------------------------------------------------ 206//------------------------------------------------------------------------
211 207
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() {
237 if (dest) 233 if (dest)
238 delete dest; 234 delete dest;
239 if (namedDest) 235 if (namedDest)
240 delete namedDest; 236 delete namedDest;
241} 237}
242 238
243//------------------------------------------------------------------------ 239//------------------------------------------------------------------------
244// LinkGoToR 240// LinkGoToR
245//------------------------------------------------------------------------ 241//------------------------------------------------------------------------
246 242
247LinkGoToR::LinkGoToR(Object *fileSpecObj, Object *destObj) { 243LinkGoToR::LinkGoToR(Object *fileSpecObj, Object *destObj) {
248 dest = NULL; 244 dest = NULL;
249 namedDest = NULL; 245 namedDest = NULL;
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() {
275 if (fileName) 271 if (fileName)
276 delete fileName; 272 delete fileName;
277 if (dest) 273 if (dest)
278 delete dest; 274 delete dest;
279 if (namedDest) 275 if (namedDest)
280 delete namedDest; 276 delete namedDest;
281} 277}
282 278
283 279
284//------------------------------------------------------------------------ 280//------------------------------------------------------------------------
285// LinkLaunch 281// LinkLaunch
286//------------------------------------------------------------------------ 282//------------------------------------------------------------------------
287 283
288LinkLaunch::LinkLaunch(Object *actionObj) { 284LinkLaunch::LinkLaunch(Object *actionObj) {
289 Object obj1, obj2; 285 Object obj1, obj2;
290 286
291 fileName = NULL; 287 fileName = NULL;
292 params = NULL; 288 params = NULL;
293 289
294 if (actionObj->isDict()) { 290 if (actionObj->isDict()) {
295 if (!actionObj->dictLookup("F", &obj1)->isNull()) { 291 if (!actionObj->dictLookup("F", &obj1)->isNull()) {
296 fileName = getFileSpecName(&obj1); 292 fileName = getFileSpecName(&obj1);
297 } else { 293 } else {
298 obj1.free(); 294 obj1.free();
299 //~ This hasn't been defined by Adobe yet, so assume it looks 295 //~ This hasn't been defined by Adobe yet, so assume it looks
300 //~ just like the Win dictionary until they say otherwise. 296 //~ just like the Win dictionary until they say otherwise.
301 if (actionObj->dictLookup("Unix", &obj1)->isDict()) { 297 if (actionObj->dictLookup("Unix", &obj1)->isDict()) {
302 obj1.dictLookup("F", &obj2); 298 obj1.dictLookup("F", &obj2);
303 fileName = getFileSpecName(&obj2); 299 fileName = getFileSpecName(&obj2);
304 obj2.free(); 300 obj2.free();
305 if (obj1.dictLookup("P", &obj2)->isString()) 301 if (obj1.dictLookup("P", &obj2)->isString())
306 params = obj2.getString()->copy(); 302 params = obj2.getString()->copy();
307 obj2.free(); 303 obj2.free();
308 } else { 304 } else {
309 error(-1, "Bad launch-type link action"); 305 error(-1, "Bad launch-type link action");
310 } 306 }
311 } 307 }
312 obj1.free(); 308 obj1.free();
313 } 309 }
314} 310}
315 311
316LinkLaunch::~LinkLaunch() { 312LinkLaunch::~LinkLaunch() {
317 if (fileName) 313 if (fileName)
318 delete fileName; 314 delete fileName;
319 if (params) 315 if (params)
320 delete params; 316 delete params;
321} 317}
322 318
323//------------------------------------------------------------------------ 319//------------------------------------------------------------------------
324// LinkURI 320// LinkURI
325//------------------------------------------------------------------------ 321//------------------------------------------------------------------------
326 322
327LinkURI::LinkURI(Object *uriObj, GString *baseURI) { 323LinkURI::LinkURI(Object *uriObj, GString *baseURI) {
328 GString *uri2; 324 GString *uri2;
329 int n; 325 int n;
330 char c; 326 char c;
331 327
332 uri = NULL; 328 uri = NULL;
333 if (uriObj->isString()) { 329 if (uriObj->isString()) {
334 uri2 = uriObj->getString()->copy(); 330 uri2 = uriObj->getString()->copy();
335 if (baseURI) { 331 if (baseURI) {
336 n = strcspn(uri2->getCString(), "/:"); 332 n = strcspn(uri2->getCString(), "/:");
337 if (n == uri2->getLength() || uri2->getChar(n) == '/') { 333 if (n == uri2->getLength() || uri2->getChar(n) == '/') {
338 uri = baseURI->copy(); 334 uri = baseURI->copy();
339 c = uri->getChar(uri->getLength() - 1); 335 c = uri->getChar(uri->getLength() - 1);
340 if (c == '/' || c == '?') { 336 if (c == '/' || c == '?') {
341 if (uri2->getChar(0) == '/') { 337 if (uri2->getChar(0) == '/') {
342 uri2->del(0); 338 uri2->del(0);
343 } 339 }
344 } else { 340 } else {
345 if (uri2->getChar(0) != '/') { 341 if (uri2->getChar(0) != '/') {
346 uri->append('/'); 342 uri->append('/');
347 } 343 }
348 } 344 }
349 uri->append(uri2); 345 uri->append(uri2);
350 delete uri2; 346 delete uri2;
351 } else { 347 } else {
352 uri = uri2; 348 uri = uri2;
353 } 349 }
354 } else { 350 } else {
355 uri = uri2; 351 uri = uri2;
356 } 352 }
357 } else { 353 } else {
358 error(-1, "Illegal URI-type link"); 354 error(-1, "Illegal URI-type link");
359 } 355 }
360} 356}
361 357
362LinkURI::~LinkURI() { 358LinkURI::~LinkURI() {
363 if (uri) 359 if (uri)
364 delete uri; 360 delete uri;
365} 361}
366 362
367//------------------------------------------------------------------------ 363//------------------------------------------------------------------------
368// LinkNamed 364// LinkNamed
369//------------------------------------------------------------------------ 365//------------------------------------------------------------------------
370 366
371LinkNamed::LinkNamed(Object *nameObj) { 367LinkNamed::LinkNamed(Object *nameObj) {
372 name = NULL; 368 name = NULL;
373 if (nameObj->isName()) { 369 if (nameObj->isName()) {
374 name = new GString(nameObj->getName()); 370 name = new GString(nameObj->getName());
375 } 371 }
376} 372}
377 373
378LinkNamed::~LinkNamed() { 374LinkNamed::~LinkNamed() {
379 if (name) { 375 if (name) {
380 delete name; 376 delete name;
381 } 377 }
382} 378}
383 379
384//------------------------------------------------------------------------ 380//------------------------------------------------------------------------
385// LinkUnknown 381// LinkUnknown
386//------------------------------------------------------------------------ 382//------------------------------------------------------------------------
387 383
388LinkUnknown::LinkUnknown(char *actionA) { 384LinkUnknown::LinkUnknown(char *actionA) {
389 action = new GString(actionA); 385 action = new GString(actionA);
390} 386}
391 387
392LinkUnknown::~LinkUnknown() { 388LinkUnknown::~LinkUnknown() {
393 delete action; 389 delete action;
394} 390}
395 391
396//------------------------------------------------------------------------ 392//------------------------------------------------------------------------
397// Link 393// Link
398//------------------------------------------------------------------------ 394//------------------------------------------------------------------------
399 395
400Link::Link(Dict *dict, GString *baseURI) { 396Link::Link(Dict *dict, GString *baseURI) {
401 Object obj1, obj2, obj3, obj4; 397 Object obj1, obj2, obj3, obj4;
402 fouble t; 398 fouble t;
403 399
404 action = NULL; 400 action = NULL;
405 ok = gFalse; 401 ok = gFalse;
406 402
407 // get rectangle 403 // get rectangle
408 if (!dict->lookup("Rect", &obj1)->isArray()) { 404 if (!dict->lookup("Rect", &obj1)->isArray()) {
409 error(-1, "Annotation rectangle is wrong type"); 405 error(-1, "Annotation rectangle is wrong type");
410 goto err2; 406 goto err2;
411 } 407 }
412 if (!obj1.arrayGet(0, &obj2)->isNum()) { 408 if (!obj1.arrayGet(0, &obj2)->isNum()) {
413 error(-1, "Bad annotation rectangle"); 409 error(-1, "Bad annotation rectangle");
414 goto err1; 410 goto err1;
415 } 411 }
416 x1 = obj2.getNum(); 412 x1 = obj2.getNum();
417 obj2.free(); 413 obj2.free();
418 if (!obj1.arrayGet(1, &obj2)->isNum()) { 414 if (!obj1.arrayGet(1, &obj2)->isNum()) {
419 error(-1, "Bad annotation rectangle"); 415 error(-1, "Bad annotation rectangle");
420 goto err1; 416 goto err1;
421 } 417 }
422 y1 = obj2.getNum(); 418 y1 = obj2.getNum();
423 obj2.free(); 419 obj2.free();
424 if (!obj1.arrayGet(2, &obj2)->isNum()) { 420 if (!obj1.arrayGet(2, &obj2)->isNum()) {
425 error(-1, "Bad annotation rectangle"); 421 error(-1, "Bad annotation rectangle");
426 goto err1; 422 goto err1;
427 } 423 }
428 x2 = obj2.getNum(); 424 x2 = obj2.getNum();
429 obj2.free(); 425 obj2.free();
430 if (!obj1.arrayGet(3, &obj2)->isNum()) { 426 if (!obj1.arrayGet(3, &obj2)->isNum()) {
431 error(-1, "Bad annotation rectangle"); 427 error(-1, "Bad annotation rectangle");
432 goto err1; 428 goto err1;
433 } 429 }
434 y2 = obj2.getNum(); 430 y2 = obj2.getNum();
435 obj2.free(); 431 obj2.free();
436 obj1.free(); 432 obj1.free();
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
462 // look for destination 458 // look for destination
463 if (!dict->lookup("Dest", &obj1)->isNull()) { 459 if (!dict->lookup("Dest", &obj1)->isNull()) {
464 action = new LinkGoTo(&obj1); 460 action = new LinkGoTo(&obj1);
465 461
466 // look for action 462 // look for action
467 } else { 463 } else {
468 obj1.free(); 464 obj1.free();
469 if (dict->lookup("A", &obj1)->isDict()) { 465 if (dict->lookup("A", &obj1)->isDict()) {
470 obj1.dictLookup("S", &obj2); 466 obj1.dictLookup("S", &obj2);
471 467
472 // GoTo action 468 // GoTo action
473 if (obj2.isName("GoTo")) { 469 if (obj2.isName("GoTo")) {
474 obj1.dictLookup("D", &obj3); 470 obj1.dictLookup("D", &obj3);
475 action = new LinkGoTo(&obj3); 471 action = new LinkGoTo(&obj3);
476 obj3.free(); 472 obj3.free();
477 473
478 // GoToR action 474 // GoToR action
479 } else if (obj2.isName("GoToR")) { 475 } else if (obj2.isName("GoToR")) {
480 obj1.dictLookup("F", &obj3); 476 obj1.dictLookup("F", &obj3);
481 obj1.dictLookup("D", &obj4); 477 obj1.dictLookup("D", &obj4);
482 action = new LinkGoToR(&obj3, &obj4); 478 action = new LinkGoToR(&obj3, &obj4);
483 obj3.free(); 479 obj3.free();
484 obj4.free(); 480 obj4.free();
485 481
486 // Launch action 482 // Launch action
487 } else if (obj2.isName("Launch")) { 483 } else if (obj2.isName("Launch")) {
488 action = new LinkLaunch(&obj1); 484 action = new LinkLaunch(&obj1);
489 485
490 // URI action 486 // URI action
491 } else if (obj2.isName("URI")) { 487 } else if (obj2.isName("URI")) {
492 obj1.dictLookup("URI", &obj3); 488 obj1.dictLookup("URI", &obj3);
493 action = new LinkURI(&obj3, baseURI); 489 action = new LinkURI(&obj3, baseURI);
494 obj3.free(); 490 obj3.free();
495 491
496 // Named action 492 // Named action
497 } else if (obj2.isName("Named")) { 493 } else if (obj2.isName("Named")) {
498 obj1.dictLookup("N", &obj3); 494 obj1.dictLookup("N", &obj3);
499 action = new LinkNamed(&obj3); 495 action = new LinkNamed(&obj3);
500 obj3.free(); 496 obj3.free();
501 497
502 // unknown action 498 // unknown action
503 } else if (obj2.isName()) { 499 } else if (obj2.isName()) {
504 action = new LinkUnknown(obj2.getName()); 500 action = new LinkUnknown(obj2.getName());
505 501
506 // action is missing or wrong type 502 // action is missing or wrong type
507 } else { 503 } else {
508 error(-1, "Bad annotation action"); 504 error(-1, "Bad annotation action");
509 action = NULL; 505 action = NULL;
510 } 506 }
511 507
512 obj2.free(); 508 obj2.free();
513 509
514 } else { 510 } else {
515 error(-1, "Missing annotation destination/action"); 511 error(-1, "Missing annotation destination/action");
516 action = NULL; 512 action = NULL;
517 } 513 }
518 } 514 }
519 obj1.free(); 515 obj1.free();
520 516
521 // check for bad action 517 // check for bad action
522 if (action && action->isOk()) 518 if (action && action->isOk())
523 ok = gTrue; 519 ok = gTrue;
524 520
525 return; 521 return;
526 522
527 err1: 523 err1:
528 obj2.free(); 524 obj2.free();
529 err2: 525 err2:
530 obj1.free(); 526 obj1.free();
531} 527}
532 528
533Link::~Link() { 529Link::~Link() {
534 if (action) 530 if (action)
535 delete action; 531 delete action;
536} 532}
537 533
538//------------------------------------------------------------------------ 534//------------------------------------------------------------------------
539// Links 535// Links
540//------------------------------------------------------------------------ 536//------------------------------------------------------------------------
541 537
542Links::Links(Object *annots, GString *baseURI) { 538Links::Links(Object *annots, GString *baseURI) {
543 Link *link; 539 Link *link;
544 Object obj1, obj2; 540 Object obj1, obj2;
545 int size; 541 int size;
546 int i; 542 int i;
547 543
548 links = NULL; 544 links = NULL;
549 size = 0; 545 size = 0;
550 numLinks = 0; 546 numLinks = 0;
551 547
552 if (annots->isArray()) { 548 if (annots->isArray()) {
553 for (i = 0; i < annots->arrayGetLength(); ++i) { 549 for (i = 0; i < annots->arrayGetLength(); ++i) {
554 if (annots->arrayGet(i, &obj1)->isDict()) { 550 if (annots->arrayGet(i, &obj1)->isDict()) {
555 if (obj1.dictLookup("Subtype", &obj2)->isName("Link")) { 551 if (obj1.dictLookup("Subtype", &obj2)->isName("Link")) {
556 link = new Link(obj1.getDict(), baseURI); 552 link = new Link(obj1.getDict(), baseURI);
557 if (link->isOk()) { 553 if (link->isOk()) {
558 if (numLinks >= size) { 554 if (numLinks >= size) {
559 size += 16; 555 size += 16;
560 links = (Link **)grealloc(links, size * sizeof(Link *)); 556 links = (Link **)grealloc(links, size * sizeof(Link *));
561 } 557 }
562 links[numLinks++] = link; 558 links[numLinks++] = link;
563 } else { 559 } else {
564 delete link; 560 delete link;
565 } 561 }
566 } 562 }
567 obj2.free(); 563 obj2.free();
568 } 564 }
569 obj1.free(); 565 obj1.free();
570 } 566 }
571 } 567 }
572} 568}
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))
598 return gTrue; 594 return gTrue;
599 } 595 }
600 return gFalse; 596 return gFalse;
601} 597}
602 598
603//------------------------------------------------------------------------ 599//------------------------------------------------------------------------
604 600
605// Extract a file name from a file specification (string or dictionary). 601// Extract a file name from a file specification (string or dictionary).
606static GString *getFileSpecName(Object *fileSpecObj) { 602static GString *getFileSpecName(Object *fileSpecObj) {
607 GString *name; 603 GString *name;
608 Object obj1; 604 Object obj1;
609 605
610 name = NULL; 606 name = NULL;
611 607
612 // string 608 // string
613 if (fileSpecObj->isString()) { 609 if (fileSpecObj->isString()) {
614 name = fileSpecObj->getString()->copy(); 610 name = fileSpecObj->getString()->copy();
615 611
616 // dictionary 612 // dictionary
617 } else if (fileSpecObj->isDict()) { 613 } else if (fileSpecObj->isDict()) {
618 if (!fileSpecObj->dictLookup("Unix", &obj1)->isString()) { 614 if (!fileSpecObj->dictLookup("Unix", &obj1)->isString()) {
619 obj1.free(); 615 obj1.free();
620 fileSpecObj->dictLookup("F", &obj1); 616 fileSpecObj->dictLookup("F", &obj1);
621 } 617 }
622 if (obj1.isString()) 618 if (obj1.isString())
623 name = obj1.getString()->copy(); 619 name = obj1.getString()->copy();
624 else 620 else
625 error(-1, "Illegal file spec in link"); 621 error(-1, "Illegal file spec in link");
626 obj1.free(); 622 obj1.free();
627 623
628 // error 624 // error
629 } else { 625 } else {
630 error(-1, "Illegal file spec in link"); 626 error(-1, "Illegal file spec in link");
631 } 627 }
632 628
633 return name; 629 return name;
634} 630}
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,261 +1,259 @@
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
18class GString; 18class GString;
19class Array; 19class Array;
20class Dict; 20class Dict;
21 21
22//------------------------------------------------------------------------ 22//------------------------------------------------------------------------
23// LinkAction 23// LinkAction
24//------------------------------------------------------------------------ 24//------------------------------------------------------------------------
25 25
26enum LinkActionKind { 26enum LinkActionKind {
27 actionGoTo, // go to destination 27 actionGoTo, // go to destination
28 actionGoToR, // go to destination in new file 28 actionGoToR, // go to destination in new file
29 actionLaunch, // launch app (or open document) 29 actionLaunch, // launch app (or open document)
30 actionURI, // URI 30 actionURI, // URI
31 actionNamed, // named action 31 actionNamed, // named action
32 actionUnknown // anything else 32 actionUnknown // anything else
33}; 33};
34 34
35class LinkAction { 35class LinkAction {
36public: 36public:
37 37
38 // Destructor. 38 // Destructor.
39 virtual ~LinkAction() {} 39 virtual ~LinkAction() {}
40 40
41 // Was the LinkAction created successfully? 41 // Was the LinkAction created successfully?
42 virtual GBool isOk() = 0; 42 virtual GBool isOk() = 0;
43 43
44 // Check link action type. 44 // Check link action type.
45 virtual LinkActionKind getKind() = 0; 45 virtual LinkActionKind getKind() = 0;
46}; 46};
47 47
48//------------------------------------------------------------------------ 48//------------------------------------------------------------------------
49// LinkDest 49// LinkDest
50//------------------------------------------------------------------------ 50//------------------------------------------------------------------------
51 51
52enum LinkDestKind { 52enum LinkDestKind {
53 destXYZ, 53 destXYZ,
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; }
82 fouble getLeft() { return left; } 80 fouble getLeft() { return left; }
83 fouble getBottom() { return bottom; } 81 fouble getBottom() { return bottom; }
84 fouble getRight() { return right; } 82 fouble getRight() { return right; }
85 fouble getTop() { return top; } 83 fouble getTop() { return top; }
86 fouble getZoom() { return zoom; } 84 fouble getZoom() { return zoom; }
87 GBool getChangeLeft() { return changeLeft; } 85 GBool getChangeLeft() { return changeLeft; }
88 GBool getChangeTop() { return changeTop; } 86 GBool getChangeTop() { return changeTop; }
89 GBool getChangeZoom() { return changeZoom; } 87 GBool getChangeZoom() { return changeZoom; }
90 88
91private: 89private:
92 90
93 LinkDestKind kind; // destination type 91 LinkDestKind kind; // destination type
94 GBool pageIsRef; // is the page a reference or number? 92 GBool pageIsRef; // is the page a reference or number?
95 union { 93 union {
96 Ref pageRef; // reference to page 94 Ref pageRef; // reference to page
97 int pageNum; // one-relative page number 95 int pageNum; // one-relative page number
98 }; 96 };
99 fouble left, bottom; // position 97 fouble left, bottom; // position
100 fouble right, top; 98 fouble right, top;
101 fouble zoom; // zoom factor 99 fouble zoom; // zoom factor
102 GBool changeLeft, changeTop;// for destXYZ links, which position 100 GBool changeLeft, changeTop;// for destXYZ links, which position
103 GBool changeZoom; // components to change 101 GBool changeZoom; // components to change
104 GBool ok; // set if created successfully 102 GBool ok; // set if created successfully
105 103
106 LinkDest(LinkDest *dest); 104 LinkDest(LinkDest *dest);
107}; 105};
108 106
109//------------------------------------------------------------------------ 107//------------------------------------------------------------------------
110// LinkGoTo 108// LinkGoTo
111//------------------------------------------------------------------------ 109//------------------------------------------------------------------------
112 110
113class LinkGoTo: public LinkAction { 111class LinkGoTo: public LinkAction {
114public: 112public:
115 113
116 // Build a LinkGoTo from a destination (dictionary, name, or string). 114 // Build a LinkGoTo from a destination (dictionary, name, or string).
117 LinkGoTo(Object *destObj); 115 LinkGoTo(Object *destObj);
118 116
119 // Destructor. 117 // Destructor.
120 virtual ~LinkGoTo(); 118 virtual ~LinkGoTo();
121 119
122 // Was the LinkGoTo created successfully? 120 // Was the LinkGoTo created successfully?
123 virtual GBool isOk() { return dest || namedDest; } 121 virtual GBool isOk() { return dest || namedDest; }
124 122
125 // Accessors. 123 // Accessors.
126 virtual LinkActionKind getKind() { return actionGoTo; } 124 virtual LinkActionKind getKind() { return actionGoTo; }
127 LinkDest *getDest() { return dest; } 125 LinkDest *getDest() { return dest; }
128 GString *getNamedDest() { return namedDest; } 126 GString *getNamedDest() { return namedDest; }
129 127
130private: 128private:
131 129
132 LinkDest *dest; // regular destination (NULL for remote 130 LinkDest *dest; // regular destination (NULL for remote
133 // link with bad destination) 131 // link with bad destination)
134 GString *namedDest; // named destination (only one of dest and 132 GString *namedDest; // named destination (only one of dest and
135 // and namedDest may be non-NULL) 133 // and namedDest may be non-NULL)
136}; 134};
137 135
138//------------------------------------------------------------------------ 136//------------------------------------------------------------------------
139// LinkGoToR 137// LinkGoToR
140//------------------------------------------------------------------------ 138//------------------------------------------------------------------------
141 139
142class LinkGoToR: public LinkAction { 140class LinkGoToR: public LinkAction {
143public: 141public:
144 142
145 // Build a LinkGoToR from a file spec (dictionary) and destination 143 // Build a LinkGoToR from a file spec (dictionary) and destination
146 // (dictionary, name, or string). 144 // (dictionary, name, or string).
147 LinkGoToR(Object *fileSpecObj, Object *destObj); 145 LinkGoToR(Object *fileSpecObj, Object *destObj);
148 146
149 // Destructor. 147 // Destructor.
150 virtual ~LinkGoToR(); 148 virtual ~LinkGoToR();
151 149
152 // Was the LinkGoToR created successfully? 150 // Was the LinkGoToR created successfully?
153 virtual GBool isOk() { return fileName && (dest || namedDest); } 151 virtual GBool isOk() { return fileName && (dest || namedDest); }
154 152
155 // Accessors. 153 // Accessors.
156 virtual LinkActionKind getKind() { return actionGoToR; } 154 virtual LinkActionKind getKind() { return actionGoToR; }
157 GString *getFileName() { return fileName; } 155 GString *getFileName() { return fileName; }
158 LinkDest *getDest() { return dest; } 156 LinkDest *getDest() { return dest; }
159 GString *getNamedDest() { return namedDest; } 157 GString *getNamedDest() { return namedDest; }
160 158
161private: 159private:
162 160
163 GString *fileName; // file name 161 GString *fileName; // file name
164 LinkDest *dest; // regular destination (NULL for remote 162 LinkDest *dest; // regular destination (NULL for remote
165 // link with bad destination) 163 // link with bad destination)
166 GString *namedDest; // named destination (only one of dest and 164 GString *namedDest; // named destination (only one of dest and
167 // and namedDest may be non-NULL) 165 // and namedDest may be non-NULL)
168}; 166};
169 167
170//------------------------------------------------------------------------ 168//------------------------------------------------------------------------
171// LinkLaunch 169// LinkLaunch
172//------------------------------------------------------------------------ 170//------------------------------------------------------------------------
173 171
174class LinkLaunch: public LinkAction { 172class LinkLaunch: public LinkAction {
175public: 173public:
176 174
177 // Build a LinkLaunch from an action dictionary. 175 // Build a LinkLaunch from an action dictionary.
178 LinkLaunch(Object *actionObj); 176 LinkLaunch(Object *actionObj);
179 177
180 // Destructor. 178 // Destructor.
181 virtual ~LinkLaunch(); 179 virtual ~LinkLaunch();
182 180
183 // Was the LinkLaunch created successfully? 181 // Was the LinkLaunch created successfully?
184 virtual GBool isOk() { return fileName != NULL; } 182 virtual GBool isOk() { return fileName != NULL; }
185 183
186 // Accessors. 184 // Accessors.
187 virtual LinkActionKind getKind() { return actionLaunch; } 185 virtual LinkActionKind getKind() { return actionLaunch; }
188 GString *getFileName() { return fileName; } 186 GString *getFileName() { return fileName; }
189 GString *getParams() { return params; } 187 GString *getParams() { return params; }
190 188
191private: 189private:
192 190
193 GString *fileName; // file name 191 GString *fileName; // file name
194 GString *params; // parameters 192 GString *params; // parameters
195}; 193};
196 194
197//------------------------------------------------------------------------ 195//------------------------------------------------------------------------
198// LinkURI 196// LinkURI
199//------------------------------------------------------------------------ 197//------------------------------------------------------------------------
200 198
201class LinkURI: public LinkAction { 199class LinkURI: public LinkAction {
202public: 200public:
203 201
204 // Build a LinkURI given the URI (string) and base URI. 202 // Build a LinkURI given the URI (string) and base URI.
205 LinkURI(Object *uriObj, GString *baseURI); 203 LinkURI(Object *uriObj, GString *baseURI);
206 204
207 // Destructor. 205 // Destructor.
208 virtual ~LinkURI(); 206 virtual ~LinkURI();
209 207
210 // Was the LinkURI created successfully? 208 // Was the LinkURI created successfully?
211 virtual GBool isOk() { return uri != NULL; } 209 virtual GBool isOk() { return uri != NULL; }
212 210
213 // Accessors. 211 // Accessors.
214 virtual LinkActionKind getKind() { return actionURI; } 212 virtual LinkActionKind getKind() { return actionURI; }
215 GString *getURI() { return uri; } 213 GString *getURI() { return uri; }
216 214
217private: 215private:
218 216
219 GString *uri; // the URI 217 GString *uri; // the URI
220}; 218};
221 219
222//------------------------------------------------------------------------ 220//------------------------------------------------------------------------
223// LinkNamed 221// LinkNamed
224//------------------------------------------------------------------------ 222//------------------------------------------------------------------------
225 223
226class LinkNamed: public LinkAction { 224class LinkNamed: public LinkAction {
227public: 225public:
228 226
229 // Build a LinkNamed given the action name. 227 // Build a LinkNamed given the action name.
230 LinkNamed(Object *nameObj); 228 LinkNamed(Object *nameObj);
231 229
232 virtual ~LinkNamed(); 230 virtual ~LinkNamed();
233 231
234 virtual GBool isOk() { return name != NULL; } 232 virtual GBool isOk() { return name != NULL; }
235 233
236 virtual LinkActionKind getKind() { return actionNamed; } 234 virtual LinkActionKind getKind() { return actionNamed; }
237 GString *getName() { return name; } 235 GString *getName() { return name; }
238 236
239private: 237private:
240 238
241 GString *name; 239 GString *name;
242}; 240};
243 241
244//------------------------------------------------------------------------ 242//------------------------------------------------------------------------
245// LinkUnknown 243// LinkUnknown
246//------------------------------------------------------------------------ 244//------------------------------------------------------------------------
247 245
248class LinkUnknown: public LinkAction { 246class LinkUnknown: public LinkAction {
249public: 247public:
250 248
251 // Build a LinkUnknown with the specified action type. 249 // Build a LinkUnknown with the specified action type.
252 LinkUnknown(char *actionA); 250 LinkUnknown(char *actionA);
253 251
254 // Destructor. 252 // Destructor.
255 virtual ~LinkUnknown(); 253 virtual ~LinkUnknown();
256 254
257 // Was the LinkUnknown create successfully? 255 // Was the LinkUnknown create successfully?
258 virtual GBool isOk() { return action != NULL; } 256 virtual GBool isOk() { return action != NULL; }
259 257
260 // Accessors. 258 // Accessors.
261 virtual LinkActionKind getKind() { return actionUnknown; } 259 virtual LinkActionKind getKind() { return actionUnknown; }
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,115 +1,115 @@
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
18//------------------------------------------------------------------------ 18//------------------------------------------------------------------------
19 19
20struct NameToCharCodeEntry { 20struct NameToCharCodeEntry {
21 char *name; 21 char *name;
22 CharCode c; 22 CharCode c;
23}; 23};
24 24
25//------------------------------------------------------------------------ 25//------------------------------------------------------------------------
26 26
27NameToCharCode::NameToCharCode() { 27NameToCharCode::NameToCharCode() {
28 int i; 28 int i;
29 29
30 size = 31; 30 size = 31;
31 len = 0; 31 len = 0;
32 tab = (NameToCharCodeEntry *)gmalloc(size * sizeof(NameToCharCodeEntry)); 32 tab = (NameToCharCodeEntry *)gmalloc(size * sizeof(NameToCharCodeEntry));
33 for (i = 0; i < size; ++i) { 33 for (i = 0; i < size; ++i) {
34 tab[i].name = NULL; 34 tab[i].name = NULL;
35 } 35 }
36} 36}
37 37
38NameToCharCode::~NameToCharCode() { 38NameToCharCode::~NameToCharCode() {
39 int i; 39 int i;
40 40
41 for (i = 0; i < size; ++i) { 41 for (i = 0; i < size; ++i) {
42 if (tab[i].name) { 42 if (tab[i].name) {
43 gfree(tab[i].name); 43 gfree(tab[i].name);
44 } 44 }
45 } 45 }
46 gfree(tab); 46 gfree(tab);
47} 47}
48 48
49void NameToCharCode::add(char *name, CharCode c) { 49void NameToCharCode::add(char *name, CharCode c) {
50 NameToCharCodeEntry *oldTab; 50 NameToCharCodeEntry *oldTab;
51 int h, i, oldSize; 51 int h, i, oldSize;
52 52
53 // expand the table if necessary 53 // expand the table if necessary
54 if (len >= size / 2) { 54 if (len >= size / 2) {
55 oldSize = size; 55 oldSize = size;
56 oldTab = tab; 56 oldTab = tab;
57 size = 2*size + 1; 57 size = 2*size + 1;
58 tab = (NameToCharCodeEntry *)gmalloc(size * sizeof(NameToCharCodeEntry)); 58 tab = (NameToCharCodeEntry *)gmalloc(size * sizeof(NameToCharCodeEntry));
59 for (h = 0; h < size; ++h) { 59 for (h = 0; h < size; ++h) {
60 tab[h].name = NULL; 60 tab[h].name = NULL;
61 } 61 }
62 for (i = 0; i < oldSize; ++i) { 62 for (i = 0; i < oldSize; ++i) {
63 if (oldTab[i].name) { 63 if (oldTab[i].name) {
64 h = hash(oldTab[i].name); 64 h = hash(oldTab[i].name);
65 while (tab[h].name) { 65 while (tab[h].name) {
66 if (++h == size) { 66 if (++h == size) {
67 h = 0; 67 h = 0;
68 } 68 }
69 } 69 }
70 tab[h] = oldTab[i]; 70 tab[h] = oldTab[i];
71 } 71 }
72 } 72 }
73 gfree(oldTab); 73 gfree(oldTab);
74 } 74 }
75 75
76 // add the new name 76 // add the new name
77 h = hash(name); 77 h = hash(name);
78 while (tab[h].name && strcmp(tab[h].name, name)) { 78 while (tab[h].name && strcmp(tab[h].name, name)) {
79 if (++h == size) { 79 if (++h == size) {
80 h = 0; 80 h = 0;
81 } 81 }
82 } 82 }
83 if (!tab[h].name) { 83 if (!tab[h].name) {
84 tab[h].name = copyString(name); 84 tab[h].name = copyString(name);
85 } 85 }
86 tab[h].c = c; 86 tab[h].c = c;
87 87
88 ++len; 88 ++len;
89} 89}
90 90
91CharCode NameToCharCode::lookup(char *name) { 91CharCode NameToCharCode::lookup(char *name) {
92 int h; 92 int h;
93 93
94 h = hash(name); 94 h = hash(name);
95 while (tab[h].name) { 95 while (tab[h].name) {
96 if (!strcmp(tab[h].name, name)) { 96 if (!strcmp(tab[h].name, name)) {
97 return tab[h].c; 97 return tab[h].c;
98 } 98 }
99 if (++h == size) { 99 if (++h == size) {
100 h = 0; 100 h = 0;
101 } 101 }
102 } 102 }
103 return 0; 103 return 0;
104} 104}
105 105
106int NameToCharCode::hash(char *name) { 106int NameToCharCode::hash(char *name) {
107 char *p; 107 char *p;
108 unsigned int h; 108 unsigned int h;
109 109
110 h = 0; 110 h = 0;
111 for (p = name; *p; ++p) { 111 for (p = name; *p; ++p) {
112 h = 17 * h + (int)(*p & 0xff); 112 h = 17 * h + (int)(*p & 0xff);
113 } 113 }
114 return (int)(h % size); 114 return (int)(h % size);
115} 115}
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,40 +1,40 @@
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
18struct NameToCharCodeEntry; 18struct NameToCharCodeEntry;
19 19
20//------------------------------------------------------------------------ 20//------------------------------------------------------------------------
21 21
22class NameToCharCode { 22class NameToCharCode {
23public: 23public:
24 24
25 NameToCharCode(); 25 NameToCharCode();
26 ~NameToCharCode(); 26 ~NameToCharCode();
27 27
28 void add(char *name, CharCode c); 28 void add(char *name, CharCode c);
29 CharCode lookup(char *name); 29 CharCode lookup(char *name);
30 30
31private: 31private:
32 32
33 int hash(char *name); 33 int hash(char *name);
34 34
35 NameToCharCodeEntry *tab; 35 NameToCharCodeEntry *tab;
36 int size; 36 int size;
37 int len; 37 int len;
38}; 38};
39 39
40#endif 40#endif
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,197 +1,197 @@
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"},
18 {0x00c1, "Aacutesmall"}, 18 {0x00c1, "Aacutesmall"},
19 {0x0102, "Abreve"}, 19 {0x0102, "Abreve"},
20 {0x00c2, "Acircumflex"}, 20 {0x00c2, "Acircumflex"},
21 {0x00c2, "Acircumflexsmall"}, 21 {0x00c2, "Acircumflexsmall"},
22 {0xf6c9, "Acute"}, 22 {0xf6c9, "Acute"},
23 {0xf6c9, "Acutesmall"}, 23 {0xf6c9, "Acutesmall"},
24 {0x00c4, "Adieresis"}, 24 {0x00c4, "Adieresis"},
25 {0x00c4, "Adieresissmall"}, 25 {0x00c4, "Adieresissmall"},
26 {0x00c0, "Agrave"}, 26 {0x00c0, "Agrave"},
27 {0x00c0, "Agravesmall"}, 27 {0x00c0, "Agravesmall"},
28 {0x0391, "Alpha"}, 28 {0x0391, "Alpha"},
29 {0x0386, "Alphatonos"}, 29 {0x0386, "Alphatonos"},
30 {0x0100, "Amacron"}, 30 {0x0100, "Amacron"},
31 {0x0104, "Aogonek"}, 31 {0x0104, "Aogonek"},
32 {0x00c5, "Aring"}, 32 {0x00c5, "Aring"},
33 {0x01fa, "Aringacute"}, 33 {0x01fa, "Aringacute"},
34 {0x00c5, "Aringsmall"}, 34 {0x00c5, "Aringsmall"},
35 {0x0041, "Asmall"}, 35 {0x0041, "Asmall"},
36 {0x00c3, "Atilde"}, 36 {0x00c3, "Atilde"},
37 {0x00c3, "Atildesmall"}, 37 {0x00c3, "Atildesmall"},
38 {0x0042, "B"}, 38 {0x0042, "B"},
39 {0x0392, "Beta"}, 39 {0x0392, "Beta"},
40 {0xf6f4, "Brevesmall"}, 40 {0xf6f4, "Brevesmall"},
41 {0x0042, "Bsmall"}, 41 {0x0042, "Bsmall"},
42 {0x0043, "C"}, 42 {0x0043, "C"},
43 {0x0106, "Cacute"}, 43 {0x0106, "Cacute"},
44 {0xf6ca, "Caron"}, 44 {0xf6ca, "Caron"},
45 {0xf6ca, "Caronsmall"}, 45 {0xf6ca, "Caronsmall"},
46 {0x010c, "Ccaron"}, 46 {0x010c, "Ccaron"},
47 {0x00c7, "Ccedilla"}, 47 {0x00c7, "Ccedilla"},
48 {0x00c7, "Ccedillasmall"}, 48 {0x00c7, "Ccedillasmall"},
49 {0x0108, "Ccircumflex"}, 49 {0x0108, "Ccircumflex"},
50 {0x010a, "Cdotaccent"}, 50 {0x010a, "Cdotaccent"},
51 {0xf7b8, "Cedillasmall"}, 51 {0xf7b8, "Cedillasmall"},
52 {0x03a7, "Chi"}, 52 {0x03a7, "Chi"},
53 {0xf6f6, "Circumflexsmall"}, 53 {0xf6f6, "Circumflexsmall"},
54 {0x0043, "Csmall"}, 54 {0x0043, "Csmall"},
55 {0x0044, "D"}, 55 {0x0044, "D"},
56 {0x010e, "Dcaron"}, 56 {0x010e, "Dcaron"},
57 {0x0110, "Dcroat"}, 57 {0x0110, "Dcroat"},
58 {0x2206, "Delta"}, 58 {0x2206, "Delta"},
59 {0xf6cb, "Dieresis"}, 59 {0xf6cb, "Dieresis"},
60 {0xf6cc, "DieresisAcute"}, 60 {0xf6cc, "DieresisAcute"},
61 {0xf6cd, "DieresisGrave"}, 61 {0xf6cd, "DieresisGrave"},
62 {0xf6cb, "Dieresissmall"}, 62 {0xf6cb, "Dieresissmall"},
63 {0xf6f7, "Dotaccentsmall"}, 63 {0xf6f7, "Dotaccentsmall"},
64 {0x0044, "Dsmall"}, 64 {0x0044, "Dsmall"},
65 {0x0045, "E"}, 65 {0x0045, "E"},
66 {0x00c9, "Eacute"}, 66 {0x00c9, "Eacute"},
67 {0x00c9, "Eacutesmall"}, 67 {0x00c9, "Eacutesmall"},
68 {0x0114, "Ebreve"}, 68 {0x0114, "Ebreve"},
69 {0x011a, "Ecaron"}, 69 {0x011a, "Ecaron"},
70 {0x00ca, "Ecircumflex"}, 70 {0x00ca, "Ecircumflex"},
71 {0x00ca, "Ecircumflexsmall"}, 71 {0x00ca, "Ecircumflexsmall"},
72 {0x00cb, "Edieresis"}, 72 {0x00cb, "Edieresis"},
73 {0x00cb, "Edieresissmall"}, 73 {0x00cb, "Edieresissmall"},
74 {0x0116, "Edotaccent"}, 74 {0x0116, "Edotaccent"},
75 {0x00c8, "Egrave"}, 75 {0x00c8, "Egrave"},
76 {0x00c8, "Egravesmall"}, 76 {0x00c8, "Egravesmall"},
77 {0x0112, "Emacron"}, 77 {0x0112, "Emacron"},
78 {0x014a, "Eng"}, 78 {0x014a, "Eng"},
79 {0x0118, "Eogonek"}, 79 {0x0118, "Eogonek"},
80 {0x0395, "Epsilon"}, 80 {0x0395, "Epsilon"},
81 {0x0388, "Epsilontonos"}, 81 {0x0388, "Epsilontonos"},
82 {0x0045, "Esmall"}, 82 {0x0045, "Esmall"},
83 {0x0397, "Eta"}, 83 {0x0397, "Eta"},
84 {0x0389, "Etatonos"}, 84 {0x0389, "Etatonos"},
85 {0x00d0, "Eth"}, 85 {0x00d0, "Eth"},
86 {0x00d0, "Ethsmall"}, 86 {0x00d0, "Ethsmall"},
87 {0x20ac, "Euro"}, 87 {0x20ac, "Euro"},
88 {0x0046, "F"}, 88 {0x0046, "F"},
89 {0x0046, "Fsmall"}, 89 {0x0046, "Fsmall"},
90 {0x0047, "G"}, 90 {0x0047, "G"},
91 {0x0393, "Gamma"}, 91 {0x0393, "Gamma"},
92 {0x011e, "Gbreve"}, 92 {0x011e, "Gbreve"},
93 {0x01e6, "Gcaron"}, 93 {0x01e6, "Gcaron"},
94 {0x011c, "Gcircumflex"}, 94 {0x011c, "Gcircumflex"},
95 {0x0122, "Gcommaaccent"}, 95 {0x0122, "Gcommaaccent"},
96 {0x0120, "Gdotaccent"}, 96 {0x0120, "Gdotaccent"},
97 {0xf6ce, "Grave"}, 97 {0xf6ce, "Grave"},
98 {0xf6ce, "Gravesmall"}, 98 {0xf6ce, "Gravesmall"},
99 {0x0047, "Gsmall"}, 99 {0x0047, "Gsmall"},
100 {0x0048, "H"}, 100 {0x0048, "H"},
101 {0x25cf, "H18533"}, 101 {0x25cf, "H18533"},
102 {0x25aa, "H18543"}, 102 {0x25aa, "H18543"},
103 {0x25ab, "H18551"}, 103 {0x25ab, "H18551"},
104 {0x25a1, "H22073"}, 104 {0x25a1, "H22073"},
105 {0x0126, "Hbar"}, 105 {0x0126, "Hbar"},
106 {0x0124, "Hcircumflex"}, 106 {0x0124, "Hcircumflex"},
107 {0x0048, "Hsmall"}, 107 {0x0048, "Hsmall"},
108 {0xf6cf, "Hungarumlaut"}, 108 {0xf6cf, "Hungarumlaut"},
109 {0xf6cf, "Hungarumlautsmall"}, 109 {0xf6cf, "Hungarumlautsmall"},
110 {0x0049, "I"}, 110 {0x0049, "I"},
111 {0x0132, "IJ"}, 111 {0x0132, "IJ"},
112 {0x00cd, "Iacute"}, 112 {0x00cd, "Iacute"},
113 {0x00cd, "Iacutesmall"}, 113 {0x00cd, "Iacutesmall"},
114 {0x012c, "Ibreve"}, 114 {0x012c, "Ibreve"},
115 {0x00ce, "Icircumflex"}, 115 {0x00ce, "Icircumflex"},
116 {0x00ce, "Icircumflexsmall"}, 116 {0x00ce, "Icircumflexsmall"},
117 {0x00cf, "Idieresis"}, 117 {0x00cf, "Idieresis"},
118 {0x00cf, "Idieresissmall"}, 118 {0x00cf, "Idieresissmall"},
119 {0x0130, "Idotaccent"}, 119 {0x0130, "Idotaccent"},
120 {0x2111, "Ifraktur"}, 120 {0x2111, "Ifraktur"},
121 {0x00cc, "Igrave"}, 121 {0x00cc, "Igrave"},
122 {0x00cc, "Igravesmall"}, 122 {0x00cc, "Igravesmall"},
123 {0x012a, "Imacron"}, 123 {0x012a, "Imacron"},
124 {0x012e, "Iogonek"}, 124 {0x012e, "Iogonek"},
125 {0x0399, "Iota"}, 125 {0x0399, "Iota"},
126 {0x03aa, "Iotadieresis"}, 126 {0x03aa, "Iotadieresis"},
127 {0x038a, "Iotatonos"}, 127 {0x038a, "Iotatonos"},
128 {0x0049, "Ismall"}, 128 {0x0049, "Ismall"},
129 {0x0128, "Itilde"}, 129 {0x0128, "Itilde"},
130 {0x004a, "J"}, 130 {0x004a, "J"},
131 {0x0134, "Jcircumflex"}, 131 {0x0134, "Jcircumflex"},
132 {0x004a, "Jsmall"}, 132 {0x004a, "Jsmall"},
133 {0x004b, "K"}, 133 {0x004b, "K"},
134 {0x039a, "Kappa"}, 134 {0x039a, "Kappa"},
135 {0x0136, "Kcommaaccent"}, 135 {0x0136, "Kcommaaccent"},
136 {0x004b, "Ksmall"}, 136 {0x004b, "Ksmall"},
137 {0x004c, "L"}, 137 {0x004c, "L"},
138 {0xf6bf, "LL"}, 138 {0xf6bf, "LL"},
139 {0x0139, "Lacute"}, 139 {0x0139, "Lacute"},
140 {0x039b, "Lambda"}, 140 {0x039b, "Lambda"},
141 {0x013d, "Lcaron"}, 141 {0x013d, "Lcaron"},
142 {0x013b, "Lcommaaccent"}, 142 {0x013b, "Lcommaaccent"},
143 {0x013f, "Ldot"}, 143 {0x013f, "Ldot"},
144 {0x0141, "Lslash"}, 144 {0x0141, "Lslash"},
145 {0x0141, "Lslashsmall"}, 145 {0x0141, "Lslashsmall"},
146 {0x004c, "Lsmall"}, 146 {0x004c, "Lsmall"},
147 {0x004d, "M"}, 147 {0x004d, "M"},
148 {0xf6d0, "Macron"}, 148 {0xf6d0, "Macron"},
149 {0xf6d0, "Macronsmall"}, 149 {0xf6d0, "Macronsmall"},
150 {0x004d, "Msmall"}, 150 {0x004d, "Msmall"},
151 {0x039c, "Mu"}, 151 {0x039c, "Mu"},
152 {0x004e, "N"}, 152 {0x004e, "N"},
153 {0x0143, "Nacute"}, 153 {0x0143, "Nacute"},
154 {0x0147, "Ncaron"}, 154 {0x0147, "Ncaron"},
155 {0x0145, "Ncommaaccent"}, 155 {0x0145, "Ncommaaccent"},
156 {0x004e, "Nsmall"}, 156 {0x004e, "Nsmall"},
157 {0x00d1, "Ntilde"}, 157 {0x00d1, "Ntilde"},
158 {0x00d1, "Ntildesmall"}, 158 {0x00d1, "Ntildesmall"},
159 {0x039d, "Nu"}, 159 {0x039d, "Nu"},
160 {0x004f, "O"}, 160 {0x004f, "O"},
161 {0x0152, "OE"}, 161 {0x0152, "OE"},
162 {0x0152, "OEsmall"}, 162 {0x0152, "OEsmall"},
163 {0x00d3, "Oacute"}, 163 {0x00d3, "Oacute"},
164 {0x00d3, "Oacutesmall"}, 164 {0x00d3, "Oacutesmall"},
165 {0x014e, "Obreve"}, 165 {0x014e, "Obreve"},
166 {0x00d4, "Ocircumflex"}, 166 {0x00d4, "Ocircumflex"},
167 {0x00d4, "Ocircumflexsmall"}, 167 {0x00d4, "Ocircumflexsmall"},
168 {0x00d6, "Odieresis"}, 168 {0x00d6, "Odieresis"},
169 {0x00d6, "Odieresissmall"}, 169 {0x00d6, "Odieresissmall"},
170 {0xf6fb, "Ogoneksmall"}, 170 {0xf6fb, "Ogoneksmall"},
171 {0x00d2, "Ograve"}, 171 {0x00d2, "Ograve"},
172 {0x00d2, "Ogravesmall"}, 172 {0x00d2, "Ogravesmall"},
173 {0x01a0, "Ohorn"}, 173 {0x01a0, "Ohorn"},
174 {0x0150, "Ohungarumlaut"}, 174 {0x0150, "Ohungarumlaut"},
175 {0x014c, "Omacron"}, 175 {0x014c, "Omacron"},
176 {0x2126, "Omega"}, 176 {0x2126, "Omega"},
177 {0x038f, "Omegatonos"}, 177 {0x038f, "Omegatonos"},
178 {0x039f, "Omicron"}, 178 {0x039f, "Omicron"},
179 {0x038c, "Omicrontonos"}, 179 {0x038c, "Omicrontonos"},
180 {0x00d8, "Oslash"}, 180 {0x00d8, "Oslash"},
181 {0x01fe, "Oslashacute"}, 181 {0x01fe, "Oslashacute"},
182 {0x00d8, "Oslashsmall"}, 182 {0x00d8, "Oslashsmall"},
183 {0x004f, "Osmall"}, 183 {0x004f, "Osmall"},
184 {0x00d5, "Otilde"}, 184 {0x00d5, "Otilde"},
185 {0x00d5, "Otildesmall"}, 185 {0x00d5, "Otildesmall"},
186 {0x0050, "P"}, 186 {0x0050, "P"},
187 {0x03a6, "Phi"}, 187 {0x03a6, "Phi"},
188 {0x03a0, "Pi"}, 188 {0x03a0, "Pi"},
189 {0x03a8, "Psi"}, 189 {0x03a8, "Psi"},
190 {0x0050, "Psmall"}, 190 {0x0050, "Psmall"},
191 {0x0051, "Q"}, 191 {0x0051, "Q"},
192 {0x0051, "Qsmall"}, 192 {0x0051, "Qsmall"},
193 {0x0052, "R"}, 193 {0x0052, "R"},
194 {0x0154, "Racute"}, 194 {0x0154, "Racute"},
195 {0x0158, "Rcaron"}, 195 {0x0158, "Rcaron"},
196 {0x0156, "Rcommaaccent"}, 196 {0x0156, "Rcommaaccent"},
197 {0x211c, "Rfraktur"}, 197 {0x211c, "Rfraktur"},
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,197 +1,197 @@
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"
18#include "Error.h" 18#include "Error.h"
19#include "Stream.h" 19#include "Stream.h"
20#include "XRef.h" 20#include "XRef.h"
21 21
22//------------------------------------------------------------------------ 22//------------------------------------------------------------------------
23// Object 23// Object
24//------------------------------------------------------------------------ 24//------------------------------------------------------------------------
25 25
26char *objTypeNames[numObjTypes] = { 26char *objTypeNames[numObjTypes] = {
27 "boolean", 27 "boolean",
28 "integer", 28 "integer",
29 "real", 29 "real",
30 "string", 30 "string",
31 "name", 31 "name",
32 "null", 32 "null",
33 "array", 33 "array",
34 "dictionary", 34 "dictionary",
35 "stream", 35 "stream",
36 "ref", 36 "ref",
37 "cmd", 37 "cmd",
38 "error", 38 "error",
39 "eof", 39 "eof",
40 "none" 40 "none"
41}; 41};
42 42
43#ifdef DEBUG_MEM 43#ifdef DEBUG_MEM
44int Object::numAlloc[numObjTypes] = 44int Object::numAlloc[numObjTypes] =
45 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; 45 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
46#endif 46#endif
47 47
48Object *Object::initArray(XRef *xref) { 48Object *Object::initArray(XRef *xref) {
49 initObj(objArray); 49 initObj(objArray);
50 array = new Array(xref); 50 array = new Array(xref);
51 return this; 51 return this;
52} 52}
53 53
54Object *Object::initDict(XRef *xref) { 54Object *Object::initDict(XRef *xref) {
55 initObj(objDict); 55 initObj(objDict);
56 dict = new Dict(xref); 56 dict = new Dict(xref);
57 return this; 57 return this;
58} 58}
59 59
60Object *Object::initStream(Stream *streamA) { 60Object *Object::initStream(Stream *streamA) {
61 initObj(objStream); 61 initObj(objStream);
62 stream = streamA; 62 stream = streamA;
63 return this; 63 return this;
64} 64}
65 65
66Object *Object::copy(Object *obj) { 66Object *Object::copy(Object *obj) {
67 *obj = *this; 67 *obj = *this;
68 switch (type) { 68 switch (type) {
69 case objString: 69 case objString:
70 obj->string = string->copy(); 70 obj->string = string->copy();
71 break; 71 break;
72 case objName: 72 case objName:
73 obj->name = copyString(name); 73 obj->name = copyString(name);
74 break; 74 break;
75 case objArray: 75 case objArray:
76 array->incRef(); 76 array->incRef();
77 break; 77 break;
78 case objDict: 78 case objDict:
79 dict->incRef(); 79 dict->incRef();
80 break; 80 break;
81 case objStream: 81 case objStream:
82 stream->incRef(); 82 stream->incRef();
83 break; 83 break;
84 case objCmd: 84 case objCmd:
85 obj->cmd = copyString(cmd); 85 obj->cmd = copyString(cmd);
86 break; 86 break;
87 default: 87 default:
88 break; 88 break;
89 } 89 }
90#ifdef DEBUG_MEM 90#ifdef DEBUG_MEM
91 ++numAlloc[type]; 91 ++numAlloc[type];
92#endif 92#endif
93 return obj; 93 return obj;
94} 94}
95 95
96Object *Object::fetch(XRef *xref, Object *obj) { 96Object *Object::fetch(XRef *xref, Object *obj) {
97 return (type == objRef && xref) ? 97 return (type == objRef && xref) ?
98 xref->fetch(ref.num, ref.gen, obj) : copy(obj); 98 xref->fetch(ref.num, ref.gen, obj) : copy(obj);
99} 99}
100 100
101void Object::free() { 101void Object::free() {
102 switch (type) { 102 switch (type) {
103 case objString: 103 case objString:
104 delete string; 104 delete string;
105 break; 105 break;
106 case objName: 106 case objName:
107 gfree(name); 107 gfree(name);
108 break; 108 break;
109 case objArray: 109 case objArray:
110 if (!array->decRef()) { 110 if (!array->decRef()) {
111 delete array; 111 delete array;
112 } 112 }
113 break; 113 break;
114 case objDict: 114 case objDict:
115 if (!dict->decRef()) { 115 if (!dict->decRef()) {
116 delete dict; 116 delete dict;
117 } 117 }
118 break; 118 break;
119 case objStream: 119 case objStream:
120 if (!stream->decRef()) { 120 if (!stream->decRef()) {
121 delete stream; 121 delete stream;
122 } 122 }
123 break; 123 break;
124 case objCmd: 124 case objCmd:
125 gfree(cmd); 125 gfree(cmd);
126 break; 126 break;
127 default: 127 default:
128 break; 128 break;
129 } 129 }
130#ifdef DEBUG_MEM 130#ifdef DEBUG_MEM
131 --numAlloc[type]; 131 --numAlloc[type];
132#endif 132#endif
133 type = objNone; 133 type = objNone;
134} 134}
135 135
136char *Object::getTypeName() { 136char *Object::getTypeName() {
137 return objTypeNames[type]; 137 return objTypeNames[type];
138} 138}
139 139
140void Object::print(FILE *f) { 140void Object::print(FILE *f) {
141 Object obj; 141 Object obj;
142 int i; 142 int i;
143 143
144 switch (type) { 144 switch (type) {
145 case objBool: 145 case objBool:
146 fprintf(f, "%s", booln ? "true" : "false"); 146 fprintf(f, "%s", booln ? "true" : "false");
147 break; 147 break;
148 case objInt: 148 case objInt:
149 fprintf(f, "%d", intg); 149 fprintf(f, "%d", intg);
150 break; 150 break;
151 case objReal: 151 case objReal:
152 fprintf(f, "%g", real); 152 fprintf(f, "%g", real);
153 break; 153 break;
154 case objString: 154 case objString:
155 fprintf(f, "("); 155 fprintf(f, "(");
156 fwrite(string->getCString(), 1, string->getLength(), stdout); 156 fwrite(string->getCString(), 1, string->getLength(), stdout);
157 fprintf(f, ")"); 157 fprintf(f, ")");
158 break; 158 break;
159 case objName: 159 case objName:
160 fprintf(f, "/%s", name); 160 fprintf(f, "/%s", name);
161 break; 161 break;
162 case objNull: 162 case objNull:
163 fprintf(f, "null"); 163 fprintf(f, "null");
164 break; 164 break;
165 case objArray: 165 case objArray:
166 fprintf(f, "["); 166 fprintf(f, "[");
167 for (i = 0; i < arrayGetLength(); ++i) { 167 for (i = 0; i < arrayGetLength(); ++i) {
168 if (i > 0) 168 if (i > 0)
169 fprintf(f, " "); 169 fprintf(f, " ");
170 arrayGetNF(i, &obj); 170 arrayGetNF(i, &obj);
171 obj.print(f); 171 obj.print(f);
172 obj.free(); 172 obj.free();
173 } 173 }
174 fprintf(f, "]"); 174 fprintf(f, "]");
175 break; 175 break;
176 case objDict: 176 case objDict:
177 fprintf(f, "<<"); 177 fprintf(f, "<<");
178 for (i = 0; i < dictGetLength(); ++i) { 178 for (i = 0; i < dictGetLength(); ++i) {
179 fprintf(f, " /%s ", dictGetKey(i)); 179 fprintf(f, " /%s ", dictGetKey(i));
180 dictGetValNF(i, &obj); 180 dictGetValNF(i, &obj);
181 obj.print(f); 181 obj.print(f);
182 obj.free(); 182 obj.free();
183 } 183 }
184 fprintf(f, " >>"); 184 fprintf(f, " >>");
185 break; 185 break;
186 case objStream: 186 case objStream:
187 fprintf(f, "<stream>"); 187 fprintf(f, "<stream>");
188 break; 188 break;
189 case objRef: 189 case objRef:
190 fprintf(f, "%d %d R", ref.num, ref.gen); 190 fprintf(f, "%d %d R", ref.num, ref.gen);
191 break; 191 break;
192 case objCmd: 192 case objCmd:
193 fprintf(f, "%s", cmd); 193 fprintf(f, "%s", cmd);
194 break; 194 break;
195 case objError: 195 case objError:
196 fprintf(f, "<error>"); 196 fprintf(f, "<error>");
197 break; 197 break;
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,299 +1,299 @@
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>
18#include "gtypes.h" 18#include "gtypes.h"
19#include "gmem.h" 19#include "gmem.h"
20#include "GString.h" 20#include "GString.h"
21 21
22class XRef; 22class XRef;
23class Array; 23class Array;
24class Dict; 24class Dict;
25class Stream; 25class Stream;
26 26
27//------------------------------------------------------------------------ 27//------------------------------------------------------------------------
28// Ref 28// Ref
29//------------------------------------------------------------------------ 29//------------------------------------------------------------------------
30 30
31struct Ref { 31struct Ref {
32 int num; // object number 32 int num; // object number
33 int gen; // generation number 33 int gen; // generation number
34}; 34};
35 35
36//------------------------------------------------------------------------ 36//------------------------------------------------------------------------
37// object types 37// object types
38//------------------------------------------------------------------------ 38//------------------------------------------------------------------------
39 39
40enum ObjType { 40enum ObjType {
41 // simple objects 41 // simple objects
42 objBool, // boolean 42 objBool, // boolean
43 objInt, // integer 43 objInt, // integer
44 objReal, // real 44 objReal, // real
45 objString, // string 45 objString, // string
46 objName, // name 46 objName, // name
47 objNull, // null 47 objNull, // null
48 48
49 // complex objects 49 // complex objects
50 objArray, // array 50 objArray, // array
51 objDict, // dictionary 51 objDict, // dictionary
52 objStream, // stream 52 objStream, // stream
53 objRef, // indirect reference 53 objRef, // indirect reference
54 54
55 // special objects 55 // special objects
56 objCmd, // command name 56 objCmd, // command name
57 objError, // error return from Lexer 57 objError, // error return from Lexer
58 objEOF, // end of file return from Lexer 58 objEOF, // end of file return from Lexer
59 objNone // uninitialized object 59 objNone // uninitialized object
60}; 60};
61 61
62 #define numObjTypes 14 // total number of object types 62 #define numObjTypes 14 // total number of object types
63 63
64//------------------------------------------------------------------------ 64//------------------------------------------------------------------------
65// Object 65// Object
66//------------------------------------------------------------------------ 66//------------------------------------------------------------------------
67 67
68#ifdef DEBUG_MEM 68#ifdef DEBUG_MEM
69#define initObj(t) ++numAlloc[type = t] 69#define initObj(t) ++numAlloc[type = t]
70#else 70#else
71#define initObj(t) type = t 71#define initObj(t) type = t
72#endif 72#endif
73 73
74class Object { 74class Object {
75public: 75public:
76 76
77 // Default constructor. 77 // Default constructor.
78 Object(): 78 Object():
79 type(objNone) {} 79 type(objNone) {}
80 80
81 // Initialize an object. 81 // Initialize an object.
82 Object *initBool(GBool boolnA) 82 Object *initBool(GBool boolnA)
83 { initObj(objBool); booln = boolnA; return this; } 83 { initObj(objBool); booln = boolnA; return this; }
84 Object *initInt(int intgA) 84 Object *initInt(int intgA)
85 { initObj(objInt); intg = intgA; return this; } 85 { initObj(objInt); intg = intgA; return this; }
86 Object *initReal(fouble realA) 86 Object *initReal(fouble realA)
87 { initObj(objReal); real = realA; return this; } 87 { initObj(objReal); real = realA; return this; }
88 Object *initString(GString *stringA) 88 Object *initString(GString *stringA)
89 { initObj(objString); string = stringA; return this; } 89 { initObj(objString); string = stringA; return this; }
90 Object *initName(char *nameA) 90 Object *initName(char *nameA)
91 { initObj(objName); name = copyString(nameA); return this; } 91 { initObj(objName); name = copyString(nameA); return this; }
92 Object *initNull() 92 Object *initNull()
93 { initObj(objNull); return this; } 93 { initObj(objNull); return this; }
94 Object *initArray(XRef *xref); 94 Object *initArray(XRef *xref);
95 Object *initDict(XRef *xref); 95 Object *initDict(XRef *xref);
96 Object *initStream(Stream *streamA); 96 Object *initStream(Stream *streamA);
97 Object *initRef(int numA, int genA) 97 Object *initRef(int numA, int genA)
98 { initObj(objRef); ref.num = numA; ref.gen = genA; return this; } 98 { initObj(objRef); ref.num = numA; ref.gen = genA; return this; }
99 Object *initCmd(char *cmdA) 99 Object *initCmd(char *cmdA)
100 { initObj(objCmd); cmd = copyString(cmdA); return this; } 100 { initObj(objCmd); cmd = copyString(cmdA); return this; }
101 Object *initError() 101 Object *initError()
102 { initObj(objError); return this; } 102 { initObj(objError); return this; }
103 Object *initEOF() 103 Object *initEOF()
104 { initObj(objEOF); return this; } 104 { initObj(objEOF); return this; }
105 105
106 // Copy an object. 106 // Copy an object.
107 Object *copy(Object *obj); 107 Object *copy(Object *obj);
108 108
109 // If object is a Ref, fetch and return the referenced object. 109 // If object is a Ref, fetch and return the referenced object.
110 // Otherwise, return a copy of the object. 110 // Otherwise, return a copy of the object.
111 Object *fetch(XRef *xref, Object *obj); 111 Object *fetch(XRef *xref, Object *obj);
112 112
113 // Free object contents. 113 // Free object contents.
114 void free(); 114 void free();
115 115
116 // Type checking. 116 // Type checking.
117 ObjType getType() { return type; } 117 ObjType getType() { return type; }
118 GBool isBool() { return type == objBool; } 118 GBool isBool() { return type == objBool; }
119 GBool isInt() { return type == objInt; } 119 GBool isInt() { return type == objInt; }
120 GBool isReal() { return type == objReal; } 120 GBool isReal() { return type == objReal; }
121 GBool isNum() { return type == objInt || type == objReal; } 121 GBool isNum() { return type == objInt || type == objReal; }
122 GBool isString() { return type == objString; } 122 GBool isString() { return type == objString; }
123 GBool isName() { return type == objName; } 123 GBool isName() { return type == objName; }
124 GBool isNull() { return type == objNull; } 124 GBool isNull() { return type == objNull; }
125 GBool isArray() { return type == objArray; } 125 GBool isArray() { return type == objArray; }
126 GBool isDict() { return type == objDict; } 126 GBool isDict() { return type == objDict; }
127 GBool isStream() { return type == objStream; } 127 GBool isStream() { return type == objStream; }
128 GBool isRef() { return type == objRef; } 128 GBool isRef() { return type == objRef; }
129 GBool isCmd() { return type == objCmd; } 129 GBool isCmd() { return type == objCmd; }
130 GBool isError() { return type == objError; } 130 GBool isError() { return type == objError; }
131 GBool isEOF() { return type == objEOF; } 131 GBool isEOF() { return type == objEOF; }
132 GBool isNone() { return type == objNone; } 132 GBool isNone() { return type == objNone; }
133 133
134 // Special type checking. 134 // Special type checking.
135 GBool isName(char *nameA) 135 GBool isName(char *nameA)
136 { return type == objName && !strcmp(name, nameA); } 136 { return type == objName && !strcmp(name, nameA); }
137 GBool isDict(char *dictType); 137 GBool isDict(char *dictType);
138 GBool isStream(char *dictType); 138 GBool isStream(char *dictType);
139 GBool isCmd(char *cmdA) 139 GBool isCmd(char *cmdA)
140 { return type == objCmd && !strcmp(cmd, cmdA); } 140 { return type == objCmd && !strcmp(cmd, cmdA); }
141 141
142 // Accessors. NB: these assume object is of correct type. 142 // Accessors. NB: these assume object is of correct type.
143 GBool getBool() { return booln; } 143 GBool getBool() { return booln; }
144 int getInt() { return intg; } 144 int getInt() { return intg; }
145 fouble getReal() { return real; } 145 fouble getReal() { return real; }
146 fouble getNum() { return type == objInt ? (fouble)intg : real; } 146 fouble getNum() { return type == objInt ? (fouble)intg : real; }
147 GString *getString() { return string; } 147 GString *getString() { return string; }
148 char *getName() { return name; } 148 char *getName() { return name; }
149 Array *getArray() { return array; } 149 Array *getArray() { return array; }
150 Dict *getDict() { return dict; } 150 Dict *getDict() { return dict; }
151 Stream *getStream() { return stream; } 151 Stream *getStream() { return stream; }
152 Ref getRef() { return ref; } 152 Ref getRef() { return ref; }
153 int getRefNum() { return ref.num; } 153 int getRefNum() { return ref.num; }
154 int getRefGen() { return ref.gen; } 154 int getRefGen() { return ref.gen; }
155 155
156 // Array accessors. 156 // Array accessors.
157 int arrayGetLength(); 157 int arrayGetLength();
158 void arrayAdd(Object *elem); 158 void arrayAdd(Object *elem);
159 Object *arrayGet(int i, Object *obj); 159 Object *arrayGet(int i, Object *obj);
160 Object *arrayGetNF(int i, Object *obj); 160 Object *arrayGetNF(int i, Object *obj);
161 161
162 // Dict accessors. 162 // Dict accessors.
163 int dictGetLength(); 163 int dictGetLength();
164 void dictAdd(char *key, Object *val); 164 void dictAdd(char *key, Object *val);
165 GBool dictIs(char *dictType); 165 GBool dictIs(char *dictType);
166 Object *dictLookup(char *key, Object *obj); 166 Object *dictLookup(char *key, Object *obj);
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
193 fouble real; // real 193 fouble real; // real
194 union { // value for each type: 194 union { // value for each type:
195 GBool booln; // boolean 195 GBool booln; // boolean
196 int intg; // integer 196 int intg; // integer
197 GString *string; // string 197 GString *string; // string
198 char *name; // name 198 char *name; // name
199 Array *array; // array 199 Array *array; // array
200 Dict *dict; // dictionary 200 Dict *dict; // dictionary
201 Stream *stream; // stream 201 Stream *stream; // stream
202 Ref ref; // indirect reference 202 Ref ref; // indirect reference
203 char *cmd; // command 203 char *cmd; // command
204 }; 204 };
205 205
206#ifdef DEBUG_MEM 206#ifdef DEBUG_MEM
207 static int // number of each type of object 207 static int // number of each type of object
208 numAlloc[numObjTypes];// currently allocated 208 numAlloc[numObjTypes];// currently allocated
209#endif 209#endif
210}; 210};
211 211
212//------------------------------------------------------------------------ 212//------------------------------------------------------------------------
213// Array accessors. 213// Array accessors.
214//------------------------------------------------------------------------ 214//------------------------------------------------------------------------
215 215
216#include "Array.h" 216#include "Array.h"
217 217
218inline int Object::arrayGetLength() 218inline int Object::arrayGetLength()
219 { return array->getLength(); } 219 { return array->getLength(); }
220 220
221inline void Object::arrayAdd(Object *elem) 221inline void Object::arrayAdd(Object *elem)
222 { array->add(elem); } 222 { array->add(elem); }
223 223
224inline Object *Object::arrayGet(int i, Object *obj) 224inline Object *Object::arrayGet(int i, Object *obj)
225 { return array->get(i, obj); } 225 { return array->get(i, obj); }
226 226
227inline Object *Object::arrayGetNF(int i, Object *obj) 227inline Object *Object::arrayGetNF(int i, Object *obj)
228 { return array->getNF(i, obj); } 228 { return array->getNF(i, obj); }
229 229
230//------------------------------------------------------------------------ 230//------------------------------------------------------------------------
231// Dict accessors. 231// Dict accessors.
232//------------------------------------------------------------------------ 232//------------------------------------------------------------------------
233 233
234#include "Dict.h" 234#include "Dict.h"
235 235
236inline int Object::dictGetLength() 236inline int Object::dictGetLength()
237 { return dict->getLength(); } 237 { return dict->getLength(); }
238 238
239inline void Object::dictAdd(char *key, Object *val) 239inline void Object::dictAdd(char *key, Object *val)
240 { dict->add(key, val); } 240 { dict->add(key, val); }
241 241
242inline GBool Object::dictIs(char *dictType) 242inline GBool Object::dictIs(char *dictType)
243 { return dict->is(dictType); } 243 { return dict->is(dictType); }
244 244
245inline GBool Object::isDict(char *dictType) 245inline GBool Object::isDict(char *dictType)
246 { return type == objDict && dictIs(dictType); } 246 { return type == objDict && dictIs(dictType); }
247 247
248inline Object *Object::dictLookup(char *key, Object *obj) 248inline Object *Object::dictLookup(char *key, Object *obj)
249 { return dict->lookup(key, obj); } 249 { return dict->lookup(key, obj); }
250 250
251inline Object *Object::dictLookupNF(char *key, Object *obj) 251inline Object *Object::dictLookupNF(char *key, Object *obj)
252 { return dict->lookupNF(key, obj); } 252 { return dict->lookupNF(key, obj); }
253 253
254inline char *Object::dictGetKey(int i) 254inline char *Object::dictGetKey(int i)
255 { return dict->getKey(i); } 255 { return dict->getKey(i); }
256 256
257inline Object *Object::dictGetVal(int i, Object *obj) 257inline Object *Object::dictGetVal(int i, Object *obj)
258 { return dict->getVal(i, obj); } 258 { return dict->getVal(i, obj); }
259 259
260inline Object *Object::dictGetValNF(int i, Object *obj) 260inline Object *Object::dictGetValNF(int i, Object *obj)
261 { return dict->getValNF(i, obj); } 261 { return dict->getValNF(i, obj); }
262 262
263//------------------------------------------------------------------------ 263//------------------------------------------------------------------------
264// Stream accessors. 264// Stream accessors.
265//------------------------------------------------------------------------ 265//------------------------------------------------------------------------
266 266
267#include "Stream.h" 267#include "Stream.h"
268 268
269inline GBool Object::streamIs(char *dictType) 269inline GBool Object::streamIs(char *dictType)
270 { return stream->getDict()->is(dictType); } 270 { return stream->getDict()->is(dictType); }
271 271
272inline GBool Object::isStream(char *dictType) 272inline GBool Object::isStream(char *dictType)
273 { return type == objStream && streamIs(dictType); } 273 { return type == objStream && streamIs(dictType); }
274 274
275inline void Object::streamReset() 275inline void Object::streamReset()
276 { stream->reset(); } 276 { stream->reset(); }
277 277
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,97 +1,102 @@
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"
18#include "OutputDev.h" 18#include "OutputDev.h"
19 19
20//------------------------------------------------------------------------ 20//------------------------------------------------------------------------
21// OutputDev 21// OutputDev
22//------------------------------------------------------------------------ 22//------------------------------------------------------------------------
23 23
24void OutputDev::setDefaultCTM(fouble *ctm) { 24void OutputDev::setDefaultCTM(fouble *ctm) {
25 int i; 25 int i;
26 fouble det; 26 fouble det;
27 27
28 for (i = 0; i < 6; ++i) { 28 for (i = 0; i < 6; ++i) {
29 defCTM[i] = ctm[i]; 29 defCTM[i] = ctm[i];
30 } 30 }
31 det = 1 / (defCTM[0] * defCTM[3] - defCTM[1] * defCTM[2]); 31 det = 1 / (defCTM[0] * defCTM[3] - defCTM[1] * defCTM[2]);
32 defICTM[0] = defCTM[3] * det; 32 defICTM[0] = defCTM[3] * det;
33 defICTM[1] = -defCTM[1] * det; 33 defICTM[1] = -defCTM[1] * det;
34 defICTM[2] = -defCTM[2] * det; 34 defICTM[2] = -defCTM[2] * det;
35 defICTM[3] = defCTM[0] * det; 35 defICTM[3] = defCTM[0] * det;
36 defICTM[4] = (defCTM[2] * defCTM[5] - defCTM[3] * defCTM[4]) * det; 36 defICTM[4] = (defCTM[2] * defCTM[5] - defCTM[3] * defCTM[4]) * det;
37 defICTM[5] = (defCTM[1] * defCTM[4] - defCTM[0] * defCTM[5]) * det; 37 defICTM[5] = (defCTM[1] * defCTM[4] - defCTM[0] * defCTM[5]) * det;
38} 38}
39 39
40void OutputDev::cvtDevToUser(int dx, int dy, fouble *ux, fouble *uy) { 40void OutputDev::cvtDevToUser(int dx, int dy, fouble *ux, fouble *uy) {
41 *ux = defICTM[0] * dx + defICTM[2] * dy + defICTM[4]; 41 *ux = defICTM[0] * dx + defICTM[2] * dy + defICTM[4];
42 *uy = defICTM[1] * dx + defICTM[3] * dy + defICTM[5]; 42 *uy = defICTM[1] * dx + defICTM[3] * dy + defICTM[5];
43} 43}
44 44
45void OutputDev::cvtUserToDev(fouble ux, fouble uy, int *dx, int *dy) { 45void OutputDev::cvtUserToDev(fouble ux, fouble uy, int *dx, int *dy) {
46 *dx = (int)(defCTM[0] * ux + defCTM[2] * uy + defCTM[4] + 0.5); 46 *dx = (int)(defCTM[0] * ux + defCTM[2] * uy + defCTM[4] + 0.5);
47 *dy = (int)(defCTM[1] * ux + defCTM[3] * uy + defCTM[5] + 0.5); 47 *dy = (int)(defCTM[1] * ux + defCTM[3] * uy + defCTM[5] + 0.5);
48} 48}
49 49
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 }
74} 79}
75 80
76void OutputDev::drawImage(GfxState *state, Object *ref, Stream *str, 81void OutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
77 int width, int height, GfxImageColorMap *colorMap, 82 int width, int height, GfxImageColorMap *colorMap,
78 int *maskColors, GBool inlineImg) { 83 int *maskColors, GBool inlineImg) {
79 int i, j; 84 int i, j;
80 85
81 if (inlineImg) { 86 if (inlineImg) {
82 str->reset(); 87 str->reset();
83 j = height * ((width * colorMap->getNumPixelComps() * 88 j = height * ((width * colorMap->getNumPixelComps() *
84 colorMap->getBits() + 7) / 8); 89 colorMap->getBits() + 7) / 8);
85 for (i = 0; i < j; ++i) 90 for (i = 0; i < j; ++i)
86 str->getChar(); 91 str->getChar();
87 str->close(); 92 str->close();
88 } 93 }
89} 94}
90 95
91#if OPI_SUPPORT 96#if OPI_SUPPORT
92void OutputDev::opiBegin(GfxState *state, Dict *opiDict) { 97void OutputDev::opiBegin(GfxState *state, Dict *opiDict) {
93} 98}
94 99
95void OutputDev::opiEnd(GfxState *state, Dict *opiDict) { 100void OutputDev::opiEnd(GfxState *state, Dict *opiDict) {
96} 101}
97#endif 102#endif
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,143 +1,158 @@
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"
18 18
19class GString; 19class GString;
20class GfxState; 20class GfxState;
21class GfxColorSpace; 21class GfxColorSpace;
22class GfxImageColorMap; 22class GfxImageColorMap;
23class Stream; 23class Stream;
24class Link; 24class Link;
25class Catalog; 25class Catalog;
26 26
27//------------------------------------------------------------------------ 27//------------------------------------------------------------------------
28// OutputDev 28// OutputDev
29//------------------------------------------------------------------------ 29//------------------------------------------------------------------------
30 30
31class OutputDev { 31class OutputDev {
32public: 32public:
33 33
34 // Constructor. 34 // Constructor.
35 OutputDev() {} 35 OutputDev() {}
36 36
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.
61 virtual void endPage() {} 65 virtual void endPage() {}
62 66
63 // Dump page contents to display. 67 // Dump page contents to display.
64 virtual void dump() {} 68 virtual void dump() {}
65 69
66 //----- coordinate conversion 70 //----- coordinate conversion
67 71
68 // Convert between device and user coordinates. 72 // Convert between device and user coordinates.
69 virtual void cvtDevToUser(int dx, int dy, fouble *ux, fouble *uy); 73 virtual void cvtDevToUser(int dx, int dy, fouble *ux, fouble *uy);
70 virtual void cvtUserToDev(fouble ux, fouble uy, int *dx, int *dy); 74 virtual void cvtUserToDev(fouble ux, fouble uy, int *dx, int *dy);
71 75
72 //----- link borders 76 //----- link borders
73 virtual void drawLink(Link *link, Catalog *catalog) {} 77 virtual void drawLink(Link *link, Catalog *catalog) {}
74 78
75 //----- save/restore graphics state 79 //----- save/restore graphics state
76 virtual void saveState(GfxState *state) {} 80 virtual void saveState(GfxState *state) {}
77 virtual void restoreState(GfxState *state) {} 81 virtual void restoreState(GfxState *state) {}
78 82
79 //----- update graphics state 83 //----- update graphics state
80 virtual void updateAll(GfxState *state); 84 virtual void updateAll(GfxState *state);
81 virtual void updateCTM(GfxState *state, fouble m11, fouble m12, 85 virtual void updateCTM(GfxState *state, fouble m11, fouble m12,
82 fouble m21, fouble m22, fouble m31, fouble m32) {} 86 fouble m21, fouble m22, fouble m31, fouble m32) {}
83 virtual void updateLineDash(GfxState *state) {} 87 virtual void updateLineDash(GfxState *state) {}
84 virtual void updateFlatness(GfxState *state) {} 88 virtual void updateFlatness(GfxState *state) {}
85 virtual void updateLineJoin(GfxState *state) {} 89 virtual void updateLineJoin(GfxState *state) {}
86 virtual void updateLineCap(GfxState *state) {} 90 virtual void updateLineCap(GfxState *state) {}
87 virtual void updateMiterLimit(GfxState *state) {} 91 virtual void updateMiterLimit(GfxState *state) {}
88 virtual void updateLineWidth(GfxState *state) {} 92 virtual void updateLineWidth(GfxState *state) {}
89 virtual void updateFillColor(GfxState *state) {} 93 virtual void updateFillColor(GfxState *state) {}
90 virtual void updateStrokeColor(GfxState *state) {} 94 virtual void updateStrokeColor(GfxState *state) {}
91 virtual void updateFillOpacity(GfxState *state) {} 95 virtual void updateFillOpacity(GfxState *state) {}
92 virtual void updateStrokeOpacity(GfxState *state) {} 96 virtual void updateStrokeOpacity(GfxState *state) {}
93 97
94 //----- update text state 98 //----- update text state
95 virtual void updateFont(GfxState *state) {} 99 virtual void updateFont(GfxState *state) {}
96 virtual void updateTextMat(GfxState *state) {} 100 virtual void updateTextMat(GfxState *state) {}
97 virtual void updateCharSpace(GfxState *state) {} 101 virtual void updateCharSpace(GfxState *state) {}
98 virtual void updateRender(GfxState *state) {} 102 virtual void updateRender(GfxState *state) {}
99 virtual void updateRise(GfxState *state) {} 103 virtual void updateRise(GfxState *state) {}
100 virtual void updateWordSpace(GfxState *state) {} 104 virtual void updateWordSpace(GfxState *state) {}
101 virtual void updateHorizScaling(GfxState *state) {} 105 virtual void updateHorizScaling(GfxState *state) {}
102 virtual void updateTextPos(GfxState *state) {} 106 virtual void updateTextPos(GfxState *state) {}
103 virtual void updateTextShift(GfxState *state, fouble shift) {} 107 virtual void updateTextShift(GfxState *state, fouble shift) {}
104 108
105 //----- path painting 109 //----- path painting
106 virtual void stroke(GfxState *state) {} 110 virtual void stroke(GfxState *state) {}
107 virtual void fill(GfxState *state) {} 111 virtual void fill(GfxState *state) {}
108 virtual void eoFill(GfxState *state) {} 112 virtual void eoFill(GfxState *state) {}
109 113
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,251 +1,259 @@
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) {
125 delete xref; 132 delete xref;
126 } 133 }
127 if (str) { 134 if (str) {
128 delete str; 135 delete str;
129 } 136 }
130 if (file) { 137 if (file) {
131 fclose(file); 138 fclose(file);
132 } 139 }
133 if (fileName) { 140 if (fileName) {
134 delete fileName; 141 delete fileName;
135 } 142 }
136 if (links) { 143 if (links) {
137 delete links; 144 delete links;
138 } 145 }
139} 146}
140 147
141// Check for a PDF header on this stream. Skip past some garbage 148// Check for a PDF header on this stream. Skip past some garbage
142// if necessary. 149// if necessary.
143void PDFDoc::checkHeader() { 150void PDFDoc::checkHeader() {
144 char hdrBuf[headerSearchSize+1]; 151 char hdrBuf[headerSearchSize+1];
145 char *p; 152 char *p;
146 int i; 153 int i;
147 154
148 pdfVersion = 0; 155 pdfVersion = 0;
149 for (i = 0; i < headerSearchSize; ++i) { 156 for (i = 0; i < headerSearchSize; ++i) {
150 hdrBuf[i] = str->getChar(); 157 hdrBuf[i] = str->getChar();
151 } 158 }
152 hdrBuf[headerSearchSize] = '\0'; 159 hdrBuf[headerSearchSize] = '\0';
153 for (i = 0; i < headerSearchSize - 5; ++i) { 160 for (i = 0; i < headerSearchSize - 5; ++i) {
154 if (!strncmp(&hdrBuf[i], "%PDF-", 5)) { 161 if (!strncmp(&hdrBuf[i], "%PDF-", 5)) {
155 break; 162 break;
156 } 163 }
157 } 164 }
158 if (i >= headerSearchSize - 5) { 165 if (i >= headerSearchSize - 5) {
159 error(-1, "May not be a PDF file (continuing anyway)"); 166 error(-1, "May not be a PDF file (continuing anyway)");
160 return; 167 return;
161 } 168 }
162 str->moveStart(i); 169 str->moveStart(i);
163 p = strtok(&hdrBuf[i+5], " \t\n\r"); 170 p = strtok(&hdrBuf[i+5], " \t\n\r");
164 pdfVersion = atof(p); 171 pdfVersion = atof(p);
165 if (!(hdrBuf[i+5] >= '0' && hdrBuf[i+5] <= '9') || 172 if (!(hdrBuf[i+5] >= '0' && hdrBuf[i+5] <= '9') ||
166 pdfVersion > supportedPDFVersionNum + 0.0001) { 173 pdfVersion > supportedPDFVersionNum + 0.0001) {
167 error(-1, "PDF version %s -- xpdf supports version %s" 174 error(-1, "PDF version %s -- xpdf supports version %s"
168 " (continuing anyway)", p, supportedPDFVersionStr); 175 " (continuing anyway)", p, supportedPDFVersionStr);
169 } 176 }
170} 177}
171 178
172void PDFDoc::displayPage(OutputDev *out, int page, fouble zoom, 179void PDFDoc::displayPage(OutputDev *out, int page, fouble zoom,
173 int rotate, GBool doLinks) { 180 int rotate, GBool doLinks) {
174 Page *p; 181 Page *p;
175 182
176 if (printCommands) { 183 if (printCommands) {
177 printf("***** page %d *****\n", page); 184 printf("***** page %d *****\n", page);
178 } 185 }
179 p = catalog->getPage(page); 186 p = catalog->getPage(page);
180 if (doLinks) { 187 if (doLinks) {
181 if (links) { 188 if (links) {
182 delete links; 189 delete links;
183 } 190 }
184 getLinks(p); 191 getLinks(p);
185 p->display(out, zoom, rotate, links, catalog); 192 p->display(out, zoom, rotate, links, catalog);
186 } else { 193 } else {
187 p->display(out, zoom, rotate, NULL, catalog); 194 p->display(out, zoom, rotate, NULL, catalog);
188 } 195 }
189} 196}
190 197
191void PDFDoc::displayPages(OutputDev *out, int firstPage, int lastPage, 198void PDFDoc::displayPages(OutputDev *out, int firstPage, int lastPage,
192 int zoom, int rotate, GBool doLinks) { 199 int zoom, int rotate, GBool doLinks) {
193 int page; 200 int page;
194 201
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 }
221 obj4.free(); 229 obj4.free();
222 obj3.free(); 230 obj3.free();
223 obj2.free(); 231 obj2.free();
224 obj1.free(); 232 obj1.free();
225 delete parser; 233 delete parser;
226 return lin; 234 return lin;
227} 235}
228 236
229GBool PDFDoc::saveAs(GString *name) { 237GBool PDFDoc::saveAs(GString *name) {
230 FILE *f; 238 FILE *f;
231 int c; 239 int c;
232 240
233 if (!(f = fopen(name->getCString(), "wb"))) { 241 if (!(f = fopen(name->getCString(), "wb"))) {
234 error(-1, "Couldn't open file '%s'", name->getCString()); 242 error(-1, "Couldn't open file '%s'", name->getCString());
235 return gFalse; 243 return gFalse;
236 } 244 }
237 str->reset(); 245 str->reset();
238 while ((c = str->getChar()) != EOF) { 246 while ((c = str->getChar()) != EOF) {
239 fputc(c, f); 247 fputc(c, f);
240 } 248 }
241 str->close(); 249 str->close();
242 fclose(f); 250 fclose(f);
243 return gTrue; 251 return gTrue;
244} 252}
245 253
246void PDFDoc::getLinks(Page *page) { 254void PDFDoc::getLinks(Page *page) {
247 Object obj; 255 Object obj;
248 256
249 links = new Links(page->getAnnots(&obj), catalog->getBaseURI()); 257 links = new Links(page->getAnnots(&obj), catalog->getBaseURI());
250 obj.free(); 258 obj.free();
251} 259}
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,142 +1,146 @@
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"
18#include "Link.h" 18#include "Link.h"
19#include "Catalog.h" 19#include "Catalog.h"
20#include "Page.h" 20#include "Page.h"
21 21
22class GString; 22class GString;
23class BaseStream; 23class BaseStream;
24class OutputDev; 24class OutputDev;
25class Links; 25class Links;
26class LinkAction; 26class LinkAction;
27class LinkDest; 27class LinkDest;
28 28
29//------------------------------------------------------------------------ 29//------------------------------------------------------------------------
30// PDFDoc 30// PDFDoc
31//------------------------------------------------------------------------ 31//------------------------------------------------------------------------
32 32
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
57 // Get page parameters. 60 // Get page parameters.
58 fouble getPageWidth(int page) 61 fouble getPageWidth(int page)
59 { return catalog->getPage(page)->getWidth(); } 62 { return catalog->getPage(page)->getWidth(); }
60 fouble getPageHeight(int page) 63 fouble getPageHeight(int page)
61 { return catalog->getPage(page)->getHeight(); } 64 { return catalog->getPage(page)->getHeight(); }
62 int getPageRotate(int page) 65 int getPageRotate(int page)
63 { return catalog->getPage(page)->getRotate(); } 66 { return catalog->getPage(page)->getRotate(); }
64 67
65 // Get number of pages. 68 // Get number of pages.
66 int getNumPages() { return catalog->getNumPages(); } 69 int getNumPages() { return catalog->getNumPages(); }
67 70
68 // Return the contents of the metadata stream, or NULL if there is 71 // Return the contents of the metadata stream, or NULL if there is
69 // no metadata. 72 // no metadata.
70 GString *readMetadata() { return catalog->readMetadata(); } 73 GString *readMetadata() { return catalog->readMetadata(); }
71 74
72 // Return the structure tree root object. 75 // Return the structure tree root object.
73 Object *getStructTreeRoot() { return catalog->getStructTreeRoot(); } 76 Object *getStructTreeRoot() { return catalog->getStructTreeRoot(); }
74 77
75 // Display a page. 78 // Display a page.
76 void displayPage(OutputDev *out, int page, fouble zoom, 79 void displayPage(OutputDev *out, int page, fouble zoom,
77 int rotate, GBool doLinks); 80 int rotate, GBool doLinks);
78 81
79 // Display a range of pages. 82 // Display a range of pages.
80 void displayPages(OutputDev *out, int firstPage, int lastPage, 83 void displayPages(OutputDev *out, int firstPage, int lastPage,
81 int zoom, int rotate, GBool doLinks); 84 int zoom, int rotate, GBool doLinks);
82 85
83 // Find a page, given its object ID. Returns page number, or 0 if 86 // Find a page, given its object ID. Returns page number, or 0 if
84 // not found. 87 // not found.
85 int findPage(int num, int gen) { return catalog->findPage(num, gen); } 88 int findPage(int num, int gen) { return catalog->findPage(num, gen); }
86 89
87 // If point <x>,<y> is in a link, return the associated action; 90 // If point <x>,<y> is in a link, return the associated action;
88 // else return NULL. 91 // else return NULL.
89 LinkAction *findLink(fouble x, fouble y) { return links->find(x, y); } 92 LinkAction *findLink(fouble x, fouble y) { return links->find(x, y); }
90 93
91 // Return true if <x>,<y> is in a link. 94 // Return true if <x>,<y> is in a link.
92 GBool onLink(fouble x, fouble y) { return links->onLink(x, y); } 95 GBool onLink(fouble x, fouble y) { return links->onLink(x, y); }
93 96
94 // Find a named destination. Returns the link destination, or 97 // Find a named destination. Returns the link destination, or
95 // NULL if <name> is not a destination. 98 // NULL if <name> is not a destination.
96 LinkDest *findDest(GString *name) 99 LinkDest *findDest(GString *name)
97 { return catalog->findDest(name); } 100 { return catalog->findDest(name); }
98 101
99 // Is the file encrypted? 102 // Is the file encrypted?
100 GBool isEncrypted() { return xref->isEncrypted(); } 103 GBool isEncrypted() { return xref->isEncrypted(); }
101 104
102 // Check various permissions. 105 // Check various permissions.
103 GBool okToPrint(GBool ignoreOwnerPW = gFalse) 106 GBool okToPrint(GBool ignoreOwnerPW = gFalse)
104 { return xref->okToPrint(ignoreOwnerPW); } 107 { return xref->okToPrint(ignoreOwnerPW); }
105 GBool okToChange(GBool ignoreOwnerPW = gFalse) 108 GBool okToChange(GBool ignoreOwnerPW = gFalse)
106 { return xref->okToChange(ignoreOwnerPW); } 109 { return xref->okToChange(ignoreOwnerPW); }
107 GBool okToCopy(GBool ignoreOwnerPW = gFalse) 110 GBool okToCopy(GBool ignoreOwnerPW = gFalse)
108 { return xref->okToCopy(ignoreOwnerPW); } 111 { return xref->okToCopy(ignoreOwnerPW); }
109 GBool okToAddNotes(GBool ignoreOwnerPW = gFalse) 112 GBool okToAddNotes(GBool ignoreOwnerPW = gFalse)
110 { return xref->okToAddNotes(ignoreOwnerPW); } 113 { return xref->okToAddNotes(ignoreOwnerPW); }
111 114
112 // Is this document linearized? 115 // Is this document linearized?
113 GBool isLinearized(); 116 GBool isLinearized();
114 117
115 // Return the document's Info dictionary (if any). 118 // Return the document's Info dictionary (if any).
116 Object *getDocInfo(Object *obj) { return xref->getDocInfo(obj); } 119 Object *getDocInfo(Object *obj) { return xref->getDocInfo(obj); }
117 120
118 // Return the PDF version specified by the file. 121 // Return the PDF version specified by the file.
119 fouble getPDFVersion() { return pdfVersion; } 122 fouble getPDFVersion() { return pdfVersion; }
120 123
121 // Save this file with another name. 124 // Save this file with another name.
122 GBool saveAs(GString *name); 125 GBool saveAs(GString *name);
123 126
124private: 127private:
125 128
126 GBool setup(GString *ownerPassword, GString *userPassword); 129 GBool setup(GString *ownerPassword, GString *userPassword);
127 void checkHeader(); 130 void checkHeader();
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,267 +1,281 @@
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
36 // get old/default values 36 // get old/default values
37 if (attrs) { 37 if (attrs) {
38 mediaBox = attrs->mediaBox; 38 mediaBox = attrs->mediaBox;
39 cropBox = attrs->cropBox; 39 cropBox = attrs->cropBox;
40 haveCropBox = attrs->haveCropBox; 40 haveCropBox = attrs->haveCropBox;
41 rotate = attrs->rotate; 41 rotate = attrs->rotate;
42 attrs->resources.copy(&resources); 42 attrs->resources.copy(&resources);
43 } else { 43 } else {
44 // set default MediaBox to 8.5" x 11" -- this shouldn't be necessary 44 // set default MediaBox to 8.5" x 11" -- this shouldn't be necessary
45 // but some (non-compliant) PDF files don't specify a MediaBox 45 // but some (non-compliant) PDF files don't specify a MediaBox
46 mediaBox.x1 = 0; 46 mediaBox.x1 = 0;
47 mediaBox.y1 = 0; 47 mediaBox.y1 = 0;
48 mediaBox.x2 = 612; 48 mediaBox.x2 = 612;
49 mediaBox.y2 = 792; 49 mediaBox.y2 = 792;
50 cropBox.x1 = cropBox.y1 = cropBox.x2 = cropBox.y2 = 0; 50 cropBox.x1 = cropBox.y1 = cropBox.x2 = cropBox.y2 = 0;
51 haveCropBox = gFalse; 51 haveCropBox = gFalse;
52 rotate = 0; 52 rotate = 0;
53 resources.initNull(); 53 resources.initNull();
54 } 54 }
55 55
56 // media box 56 // media box
57 readBox(dict, "MediaBox", &mediaBox); 57 readBox(dict, "MediaBox", &mediaBox);
58 58
59 // crop box 59 // crop box
60 cropBox = mediaBox; 60 cropBox = mediaBox;
61 haveCropBox = readBox(dict, "CropBox", &cropBox); 61 haveCropBox = readBox(dict, "CropBox", &cropBox);
62 62
63 // if the MediaBox is excessively larger than the CropBox, 63 // if the MediaBox is excessively larger than the CropBox,
64 // just use the CropBox 64 // just use the CropBox
65 limitToCropBox = gFalse; 65 limitToCropBox = gFalse;
66 if (haveCropBox) { 66 if (haveCropBox) {
67 w = 0.25 * (cropBox.x2 - cropBox.x1); 67 w = 0.25 * (cropBox.x2 - cropBox.x1);
68 h = 0.25 * (cropBox.y2 - cropBox.y1); 68 h = 0.25 * (cropBox.y2 - cropBox.y1);
69 if ((cropBox.x1 - mediaBox.x1) + (mediaBox.x2 - cropBox.x2) > w || 69 if ((cropBox.x1 - mediaBox.x1) + (mediaBox.x2 - cropBox.x2) > w ||
70 (cropBox.y1 - mediaBox.y1) + (mediaBox.y2 - cropBox.y2) > h) { 70 (cropBox.y1 - mediaBox.y1) + (mediaBox.y2 - cropBox.y2) > h) {
71 limitToCropBox = gTrue; 71 limitToCropBox = gTrue;
72 } 72 }
73 } 73 }
74 74
75 // other boxes 75 // other boxes
76 bleedBox = cropBox; 76 bleedBox = cropBox;
77 readBox(dict, "BleedBox", &bleedBox); 77 readBox(dict, "BleedBox", &bleedBox);
78 trimBox = cropBox; 78 trimBox = cropBox;
79 readBox(dict, "TrimBox", &trimBox); 79 readBox(dict, "TrimBox", &trimBox);
80 artBox = cropBox; 80 artBox = cropBox;
81 readBox(dict, "ArtBox", &artBox); 81 readBox(dict, "ArtBox", &artBox);
82 82
83 // rotate 83 // rotate
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);
118 if (obj2.isNum()) { 132 if (obj2.isNum()) {
119 tmp.x1 = obj2.getNum(); 133 tmp.x1 = obj2.getNum();
120 } else { 134 } else {
121 ok = gFalse; 135 ok = gFalse;
122 } 136 }
123 obj2.free(); 137 obj2.free();
124 obj1.arrayGet(1, &obj2); 138 obj1.arrayGet(1, &obj2);
125 if (obj2.isNum()) { 139 if (obj2.isNum()) {
126 tmp.y1 = obj2.getNum(); 140 tmp.y1 = obj2.getNum();
127 } else { 141 } else {
128 ok = gFalse; 142 ok = gFalse;
129 } 143 }
130 obj2.free(); 144 obj2.free();
131 obj1.arrayGet(2, &obj2); 145 obj1.arrayGet(2, &obj2);
132 if (obj2.isNum()) { 146 if (obj2.isNum()) {
133 tmp.x2 = obj2.getNum(); 147 tmp.x2 = obj2.getNum();
134 } else { 148 } else {
135 ok = gFalse; 149 ok = gFalse;
136 } 150 }
137 obj2.free(); 151 obj2.free();
138 obj1.arrayGet(3, &obj2); 152 obj1.arrayGet(3, &obj2);
139 if (obj2.isNum()) { 153 if (obj2.isNum()) {
140 tmp.y2 = obj2.getNum(); 154 tmp.y2 = obj2.getNum();
141 } else { 155 } else {
142 ok = gFalse; 156 ok = gFalse;
143 } 157 }
144 obj2.free(); 158 obj2.free();
145 if (ok) { 159 if (ok) {
146 *box = tmp; 160 *box = tmp;
147 } 161 }
148 } else { 162 } else {
149 ok = gFalse; 163 ok = gFalse;
150 } 164 }
151 obj1.free(); 165 obj1.free();
152 return ok; 166 return ok;
153} 167}
154 168
155//------------------------------------------------------------------------ 169//------------------------------------------------------------------------
156// Page 170// Page
157//------------------------------------------------------------------------ 171//------------------------------------------------------------------------
158 172
159Page::Page(XRef *xrefA, int numA, Dict *pageDict, PageAttrs *attrsA, 173Page::Page(XRef *xrefA, int numA, Dict *pageDict, PageAttrs *attrsA,
160 GBool printCommandsA) { 174 GBool printCommandsA) {
161 175
162 ok = gTrue; 176 ok = gTrue;
163 xref = xrefA; 177 xref = xrefA;
164 num = numA; 178 num = numA;
165 printCommands = printCommandsA; 179 printCommands = printCommandsA;
166 180
167 // get attributes 181 // get attributes
168 attrs = attrsA; 182 attrs = attrsA;
169 183
170 // annotations 184 // annotations
171 pageDict->lookupNF("Annots", &annots); 185 pageDict->lookupNF("Annots", &annots);
172 if (!(annots.isRef() || annots.isArray() || annots.isNull())) { 186 if (!(annots.isRef() || annots.isArray() || annots.isNull())) {
173 error(-1, "Page annotations object (page %d) is wrong type (%s)", 187 error(-1, "Page annotations object (page %d) is wrong type (%s)",
174 num, annots.getTypeName()); 188 num, annots.getTypeName());
175 annots.free(); 189 annots.free();
176 goto err2; 190 goto err2;
177 } 191 }
178 192
179 // contents 193 // contents
180 pageDict->lookupNF("Contents", &contents); 194 pageDict->lookupNF("Contents", &contents);
181 if (!(contents.isRef() || contents.isArray() || 195 if (!(contents.isRef() || contents.isArray() ||
182 contents.isNull())) { 196 contents.isNull())) {
183 error(-1, "Page contents object (page %d) is wrong type (%s)", 197 error(-1, "Page contents object (page %d) is wrong type (%s)",
184 num, contents.getTypeName()); 198 num, contents.getTypeName());
185 contents.free(); 199 contents.free();
186 goto err1; 200 goto err1;
187 } 201 }
188 202
189 return; 203 return;
190 204
191 err2: 205 err2:
192 annots.initNull(); 206 annots.initNull();
193 err1: 207 err1:
194 contents.initNull(); 208 contents.initNull();
195 ok = gFalse; 209 ok = gFalse;
196} 210}
197 211
198Page::~Page() { 212Page::~Page() {
199 delete attrs; 213 delete attrs;
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());
225 } 239 }
226 240
227 rotate += getRotate(); 241 rotate += getRotate();
228 if (rotate >= 360) { 242 if (rotate >= 360) {
229 rotate -= 360; 243 rotate -= 360;
230 } else if (rotate < 0) { 244 } else if (rotate < 0) {
231 rotate += 360; 245 rotate += 360;
232 } 246 }
233 gfx = new Gfx(xref, out, num, attrs->getResourceDict(), 247 gfx = new Gfx(xref, out, num, attrs->getResourceDict(),
234 dpi, box, isCropped(), cropBox, rotate, printCommands); 248 dpi, box, isCropped(), cropBox, rotate, printCommands);
235 contents.fetch(xref, &obj); 249 contents.fetch(xref, &obj);
236 if (!obj.isNull()) { 250 if (!obj.isNull()) {
237 gfx->display(&obj); 251 gfx->display(&obj);
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,125 +1,151 @@
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
18class Dict; 18class Dict;
19class XRef; 19class XRef;
20class OutputDev; 20class OutputDev;
21class Links; 21class Links;
22class Catalog; 22class Catalog;
23 23
24//------------------------------------------------------------------------ 24//------------------------------------------------------------------------
25 25
26struct PDFRectangle { 26struct PDFRectangle {
27 fouble x1, y1, x2, y2; 27 fouble x1, y1, x2, y2;
28}; 28};
29 29
30//------------------------------------------------------------------------ 30//------------------------------------------------------------------------
31// PageAttrs 31// PageAttrs
32//------------------------------------------------------------------------ 32//------------------------------------------------------------------------
33 33
34class PageAttrs { 34class PageAttrs {
35public: 35public:
36 36
37 // Construct a new PageAttrs object by merging a dictionary 37 // Construct a new PageAttrs object by merging a dictionary
38 // (of type Pages or Page) into another PageAttrs object. If 38 // (of type Pages or Page) into another PageAttrs object. If
39 // <attrs> is NULL, uses defaults. 39 // <attrs> is NULL, uses defaults.
40 PageAttrs(PageAttrs *attrs, Dict *dict); 40 PageAttrs(PageAttrs *attrs, Dict *dict);
41 41
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,
81 GBool printCommandsA); 101 GBool printCommandsA);
82 102
83 // Destructor. 103 // Destructor.
84 ~Page(); 104 ~Page();
85 105
86 // Is page valid? 106 // Is page valid?
87 GBool isOk() { return ok; } 107 GBool isOk() { return ok; }
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,
112 Links *links, Catalog *catalog); 138 Links *links, Catalog *catalog);
113 139
114private: 140private:
115 141
116 XRef *xref; // the xref table for this PDF file 142 XRef *xref; // the xref table for this PDF file
117 int num; // page number 143 int num; // page number
118 PageAttrs *attrs; // page attributes 144 PageAttrs *attrs; // page attributes
119 Object annots; // annotations array 145 Object annots; // annotations array
120 Object contents; // page contents 146 Object contents; // page contents
121 GBool printCommands; // print the drawing commands (for debugging) 147 GBool printCommands; // print the drawing commands (for debugging)
122 GBool ok; // true if page is valid 148 GBool ok; // true if page is valid
123}; 149};
124 150
125#endif 151#endif
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,213 +1,214 @@
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"
18#include "Parser.h" 18#include "Parser.h"
19#include "XRef.h" 19#include "XRef.h"
20#include "Error.h" 20#include "Error.h"
21#ifndef NO_DECRYPTION 21#ifndef NO_DECRYPTION
22#include "Decrypt.h" 22#include "Decrypt.h"
23#endif 23#endif
24 24
25Parser::Parser(XRef *xrefA, Lexer *lexerA) { 25Parser::Parser(XRef *xrefA, Lexer *lexerA) {
26 xref = xrefA; 26 xref = xrefA;
27 lexer = lexerA; 27 lexer = lexerA;
28 inlineImg = 0; 28 inlineImg = 0;
29 lexer->getObj(&buf1); 29 lexer->getObj(&buf1);
30 lexer->getObj(&buf2); 30 lexer->getObj(&buf2);
31} 31}
32 32
33Parser::~Parser() { 33Parser::~Parser() {
34 buf1.free(); 34 buf1.free();
35 buf2.free(); 35 buf2.free();
36 delete lexer; 36 delete lexer;
37} 37}
38 38
39#ifndef NO_DECRYPTION 39#ifndef NO_DECRYPTION
40Object *Parser::getObj(Object *obj, 40Object *Parser::getObj(Object *obj,
41 Guchar *fileKey, int keyLength, 41 Guchar *fileKey, int keyLength,
42 int objNum, int objGen) { 42 int objNum, int objGen) {
43#else 43#else
44Object *Parser::getObj(Object *obj) { 44Object *Parser::getObj(Object *obj) {
45#endif 45#endif
46 char *key; 46 char *key;
47 Stream *str; 47 Stream *str;
48 Object obj2; 48 Object obj2;
49 int num; 49 int num;
50#ifndef NO_DECRYPTION 50#ifndef NO_DECRYPTION
51 Decrypt *decrypt; 51 Decrypt *decrypt;
52 GString *s; 52 GString *s;
53 char *p; 53 char *p;
54 int i; 54 int i;
55#endif 55#endif
56 56
57 // refill buffer after inline image data 57 // refill buffer after inline image data
58 if (inlineImg == 2) { 58 if (inlineImg == 2) {
59 buf1.free(); 59 buf1.free();
60 buf2.free(); 60 buf2.free();
61 lexer->getObj(&buf1); 61 lexer->getObj(&buf1);
62 lexer->getObj(&buf2); 62 lexer->getObj(&buf2);
63 inlineImg = 0; 63 inlineImg = 0;
64 } 64 }
65 65
66 // array 66 // array
67 if (buf1.isCmd("[")) { 67 if (buf1.isCmd("[")) {
68 shift(); 68 shift();
69 obj->initArray(xref); 69 obj->initArray(xref);
70 while (!buf1.isCmd("]") && !buf1.isEOF()) 70 while (!buf1.isCmd("]") && !buf1.isEOF())
71#ifndef NO_DECRYPTION 71#ifndef NO_DECRYPTION
72 obj->arrayAdd(getObj(&obj2, fileKey, keyLength, objNum, objGen)); 72 obj->arrayAdd(getObj(&obj2, fileKey, keyLength, objNum, objGen));
73#else 73#else
74 obj->arrayAdd(getObj(&obj2)); 74 obj->arrayAdd(getObj(&obj2));
75#endif 75#endif
76 if (buf1.isEOF()) 76 if (buf1.isEOF())
77 error(getPos(), "End of file inside array"); 77 error(getPos(), "End of file inside array");
78 shift(); 78 shift();
79 79
80 // dictionary or stream 80 // dictionary or stream
81 } else if (buf1.isCmd("<<")) { 81 } else if (buf1.isCmd("<<")) {
82 shift(); 82 shift();
83 obj->initDict(xref); 83 obj->initDict(xref);
84 while (!buf1.isCmd(">>") && !buf1.isEOF()) { 84 while (!buf1.isCmd(">>") && !buf1.isEOF()) {
85 if (!buf1.isName()) { 85 if (!buf1.isName()) {
86 error(getPos(), "Dictionary key must be a name object"); 86 error(getPos(), "Dictionary key must be a name object");
87 shift(); 87 shift();
88 } else { 88 } else {
89 key = copyString(buf1.getName()); 89 key = copyString(buf1.getName());
90 shift(); 90 shift();
91 if (buf1.isEOF() || buf1.isError()) 91 if (buf1.isEOF() || buf1.isError())
92 break; 92 break;
93#ifndef NO_DECRYPTION 93#ifndef NO_DECRYPTION
94 obj->dictAdd(key, getObj(&obj2, fileKey, keyLength, objNum, objGen)); 94 obj->dictAdd(key, getObj(&obj2, fileKey, keyLength, objNum, objGen));
95#else 95#else
96 obj->dictAdd(key, getObj(&obj2)); 96 obj->dictAdd(key, getObj(&obj2));
97#endif 97#endif
98 } 98 }
99 } 99 }
100 if (buf1.isEOF()) 100 if (buf1.isEOF())
101 error(getPos(), "End of file inside dictionary"); 101 error(getPos(), "End of file inside dictionary");
102 if (buf2.isCmd("stream")) { 102 if (buf2.isCmd("stream")) {
103 if ((str = makeStream(obj))) { 103 if ((str = makeStream(obj))) {
104 obj->initStream(str); 104 obj->initStream(str);
105#ifndef NO_DECRYPTION 105#ifndef NO_DECRYPTION
106 if (fileKey) { 106 if (fileKey) {
107 str->getBaseStream()->doDecryption(fileKey, keyLength, 107 str->getBaseStream()->doDecryption(fileKey, keyLength,
108 objNum, objGen); 108 objNum, objGen);
109 } 109 }
110#endif 110#endif
111 } else { 111 } else {
112 obj->free(); 112 obj->free();
113 obj->initError(); 113 obj->initError();
114 } 114 }
115 } else { 115 } else {
116 shift(); 116 shift();
117 } 117 }
118 118
119 // indirect reference or integer 119 // indirect reference or integer
120 } else if (buf1.isInt()) { 120 } else if (buf1.isInt()) {
121 num = buf1.getInt(); 121 num = buf1.getInt();
122 shift(); 122 shift();
123 if (buf1.isInt() && buf2.isCmd("R")) { 123 if (buf1.isInt() && buf2.isCmd("R")) {
124 obj->initRef(num, buf1.getInt()); 124 obj->initRef(num, buf1.getInt());
125 shift(); 125 shift();
126 shift(); 126 shift();
127 } else { 127 } else {
128 obj->initInt(num); 128 obj->initInt(num);
129 } 129 }
130 130
131#ifndef NO_DECRYPTION 131#ifndef NO_DECRYPTION
132 // string 132 // string
133 } else if (buf1.isString() && fileKey) { 133 } else if (buf1.isString() && fileKey) {
134 buf1.copy(obj); 134 buf1.copy(obj);
135 s = obj->getString(); 135 s = obj->getString();
136 decrypt = new Decrypt(fileKey, keyLength, objNum, objGen); 136 decrypt = new Decrypt(fileKey, keyLength, objNum, objGen);
137 for (i = 0, p = obj->getString()->getCString(); 137 for (i = 0, p = obj->getString()->getCString();
138 i < s->getLength(); 138 i < s->getLength();
139 ++i, ++p) { 139 ++i, ++p) {
140 *p = decrypt->decryptByte(*p); 140 *p = decrypt->decryptByte(*p);
141 } 141 }
142 delete decrypt; 142 delete decrypt;
143 shift(); 143 shift();
144#endif 144#endif
145 145
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();
194 else 195 else
195 error(getPos(), "Missing 'endstream'"); 196 error(getPos(), "Missing 'endstream'");
196 197
197 return str; 198 return str;
198} 199}
199 200
200void Parser::shift() { 201void Parser::shift() {
201 if (inlineImg > 0) { 202 if (inlineImg > 0) {
202 ++inlineImg; 203 ++inlineImg;
203 } else if (buf2.isCmd("ID")) { 204 } else if (buf2.isCmd("ID")) {
204 lexer->skipChar(); // skip char after 'ID' command 205 lexer->skipChar(); // skip char after 'ID' command
205 inlineImg = 1; 206 inlineImg = 1;
206 } 207 }
207 buf1.free(); 208 buf1.free();
208 buf1 = buf2; 209 buf1 = buf2;
209 if (inlineImg > 0) // don't buffer inline image data 210 if (inlineImg > 0) // don't buffer inline image data
210 buf2.initNull(); 211 buf2.initNull();
211 else 212 else
212 lexer->getObj(&buf2); 213 lexer->getObj(&buf2);
213} 214}
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,58 +1,58 @@
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
18//------------------------------------------------------------------------ 18//------------------------------------------------------------------------
19// Parser 19// Parser
20//------------------------------------------------------------------------ 20//------------------------------------------------------------------------
21 21
22class Parser { 22class Parser {
23public: 23public:
24 24
25 // Constructor. 25 // Constructor.
26 Parser(XRef *xrefA, Lexer *lexerA); 26 Parser(XRef *xrefA, Lexer *lexerA);
27 27
28 // Destructor. 28 // Destructor.
29 ~Parser(); 29 ~Parser();
30 30
31 // Get the next object from the input stream. 31 // Get the next object from the input stream.
32#ifndef NO_DECRYPTION 32#ifndef NO_DECRYPTION
33 Object *getObj(Object *obj, 33 Object *getObj(Object *obj,
34 Guchar *fileKey = NULL, int keyLength = 0, 34 Guchar *fileKey = NULL, int keyLength = 0,
35 int objNum = 0, int objGen = 0); 35 int objNum = 0, int objGen = 0);
36#else 36#else
37 Object *getObj(Object *obj); 37 Object *getObj(Object *obj);
38#endif 38#endif
39 39
40 // Get stream. 40 // Get stream.
41 Stream *getStream() { return lexer->getStream(); } 41 Stream *getStream() { return lexer->getStream(); }
42 42
43 // Get current position in file. 43 // Get current position in file.
44 int getPos() { return lexer->getPos(); } 44 int getPos() { return lexer->getPos(); }
45 45
46private: 46private:
47 47
48 XRef *xref; // the xref table for this PDF file 48 XRef *xref; // the xref table for this PDF file
49 Lexer *lexer; // input stream 49 Lexer *lexer; // input stream
50 Object buf1, buf2; // next two tokens 50 Object buf1, buf2; // next two tokens
51 int inlineImg; // set when inline image data is encountered 51 int inlineImg; // set when inline image data is encountered
52 52
53 Stream *makeStream(Object *dict); 53 Stream *makeStream(Object *dict);
54 void shift(); 54 void shift();
55}; 55};
56 56
57#endif 57#endif
58 58
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,199 +1,199 @@
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
20//------------------------------------------------------------------------ 20//------------------------------------------------------------------------
21 21
22#define twoDimPass 0 22#define twoDimPass 0
23#define twoDimHoriz 1 23#define twoDimHoriz 1
24#define twoDimVert0 2 24#define twoDimVert0 2
25#define twoDimVertR1 3 25#define twoDimVertR1 3
26#define twoDimVertL1 4 26#define twoDimVertL1 4
27#define twoDimVertR2 5 27#define twoDimVertR2 5
28#define twoDimVertL2 6 28#define twoDimVertL2 6
29#define twoDimVertR3 7 29#define twoDimVertR3 7
30#define twoDimVertL3 8 30#define twoDimVertL3 8
31 31
32// 1-7 bit codes 32// 1-7 bit codes
33static CCITTCode twoDimTab1[128] = { 33static CCITTCode twoDimTab1[128] = {
34 {-1, -1}, {-1, -1}, // 000000x 34 {-1, -1}, {-1, -1}, // 000000x
35 {7, twoDimVertL3}, // 0000010 35 {7, twoDimVertL3}, // 0000010
36 {7, twoDimVertR3}, // 0000011 36 {7, twoDimVertR3}, // 0000011
37 {6, twoDimVertL2}, {6, twoDimVertL2},// 000010x 37 {6, twoDimVertL2}, {6, twoDimVertL2},// 000010x
38 {6, twoDimVertR2}, {6, twoDimVertR2},// 000011x 38 {6, twoDimVertR2}, {6, twoDimVertR2},// 000011x
39 {4, twoDimPass}, {4, twoDimPass}, // 0001xxx 39 {4, twoDimPass}, {4, twoDimPass}, // 0001xxx
40 {4, twoDimPass}, {4, twoDimPass}, 40 {4, twoDimPass}, {4, twoDimPass},
41 {4, twoDimPass}, {4, twoDimPass}, 41 {4, twoDimPass}, {4, twoDimPass},
42 {4, twoDimPass}, {4, twoDimPass}, 42 {4, twoDimPass}, {4, twoDimPass},
43 {3, twoDimHoriz}, {3, twoDimHoriz},// 001xxxx 43 {3, twoDimHoriz}, {3, twoDimHoriz},// 001xxxx
44 {3, twoDimHoriz}, {3, twoDimHoriz}, 44 {3, twoDimHoriz}, {3, twoDimHoriz},
45 {3, twoDimHoriz}, {3, twoDimHoriz}, 45 {3, twoDimHoriz}, {3, twoDimHoriz},
46 {3, twoDimHoriz}, {3, twoDimHoriz}, 46 {3, twoDimHoriz}, {3, twoDimHoriz},
47 {3, twoDimHoriz}, {3, twoDimHoriz}, 47 {3, twoDimHoriz}, {3, twoDimHoriz},
48 {3, twoDimHoriz}, {3, twoDimHoriz}, 48 {3, twoDimHoriz}, {3, twoDimHoriz},
49 {3, twoDimHoriz}, {3, twoDimHoriz}, 49 {3, twoDimHoriz}, {3, twoDimHoriz},
50 {3, twoDimHoriz}, {3, twoDimHoriz}, 50 {3, twoDimHoriz}, {3, twoDimHoriz},
51 {3, twoDimVertL1}, {3, twoDimVertL1},// 010xxxx 51 {3, twoDimVertL1}, {3, twoDimVertL1},// 010xxxx
52 {3, twoDimVertL1}, {3, twoDimVertL1}, 52 {3, twoDimVertL1}, {3, twoDimVertL1},
53 {3, twoDimVertL1}, {3, twoDimVertL1}, 53 {3, twoDimVertL1}, {3, twoDimVertL1},
54 {3, twoDimVertL1}, {3, twoDimVertL1}, 54 {3, twoDimVertL1}, {3, twoDimVertL1},
55 {3, twoDimVertL1}, {3, twoDimVertL1}, 55 {3, twoDimVertL1}, {3, twoDimVertL1},
56 {3, twoDimVertL1}, {3, twoDimVertL1}, 56 {3, twoDimVertL1}, {3, twoDimVertL1},
57 {3, twoDimVertL1}, {3, twoDimVertL1}, 57 {3, twoDimVertL1}, {3, twoDimVertL1},
58 {3, twoDimVertL1}, {3, twoDimVertL1}, 58 {3, twoDimVertL1}, {3, twoDimVertL1},
59 {3, twoDimVertR1}, {3, twoDimVertR1},// 011xxxx 59 {3, twoDimVertR1}, {3, twoDimVertR1},// 011xxxx
60 {3, twoDimVertR1}, {3, twoDimVertR1}, 60 {3, twoDimVertR1}, {3, twoDimVertR1},
61 {3, twoDimVertR1}, {3, twoDimVertR1}, 61 {3, twoDimVertR1}, {3, twoDimVertR1},
62 {3, twoDimVertR1}, {3, twoDimVertR1}, 62 {3, twoDimVertR1}, {3, twoDimVertR1},
63 {3, twoDimVertR1}, {3, twoDimVertR1}, 63 {3, twoDimVertR1}, {3, twoDimVertR1},
64 {3, twoDimVertR1}, {3, twoDimVertR1}, 64 {3, twoDimVertR1}, {3, twoDimVertR1},
65 {3, twoDimVertR1}, {3, twoDimVertR1}, 65 {3, twoDimVertR1}, {3, twoDimVertR1},
66 {3, twoDimVertR1}, {3, twoDimVertR1}, 66 {3, twoDimVertR1}, {3, twoDimVertR1},
67 {1, twoDimVert0}, {1, twoDimVert0},// 1xxxxxx 67 {1, twoDimVert0}, {1, twoDimVert0},// 1xxxxxx
68 {1, twoDimVert0}, {1, twoDimVert0}, 68 {1, twoDimVert0}, {1, twoDimVert0},
69 {1, twoDimVert0}, {1, twoDimVert0}, 69 {1, twoDimVert0}, {1, twoDimVert0},
70 {1, twoDimVert0}, {1, twoDimVert0}, 70 {1, twoDimVert0}, {1, twoDimVert0},
71 {1, twoDimVert0}, {1, twoDimVert0}, 71 {1, twoDimVert0}, {1, twoDimVert0},
72 {1, twoDimVert0}, {1, twoDimVert0}, 72 {1, twoDimVert0}, {1, twoDimVert0},
73 {1, twoDimVert0}, {1, twoDimVert0}, 73 {1, twoDimVert0}, {1, twoDimVert0},
74 {1, twoDimVert0}, {1, twoDimVert0}, 74 {1, twoDimVert0}, {1, twoDimVert0},
75 {1, twoDimVert0}, {1, twoDimVert0}, 75 {1, twoDimVert0}, {1, twoDimVert0},
76 {1, twoDimVert0}, {1, twoDimVert0}, 76 {1, twoDimVert0}, {1, twoDimVert0},
77 {1, twoDimVert0}, {1, twoDimVert0}, 77 {1, twoDimVert0}, {1, twoDimVert0},
78 {1, twoDimVert0}, {1, twoDimVert0}, 78 {1, twoDimVert0}, {1, twoDimVert0},
79 {1, twoDimVert0}, {1, twoDimVert0}, 79 {1, twoDimVert0}, {1, twoDimVert0},
80 {1, twoDimVert0}, {1, twoDimVert0}, 80 {1, twoDimVert0}, {1, twoDimVert0},
81 {1, twoDimVert0}, {1, twoDimVert0}, 81 {1, twoDimVert0}, {1, twoDimVert0},
82 {1, twoDimVert0}, {1, twoDimVert0}, 82 {1, twoDimVert0}, {1, twoDimVert0},
83 {1, twoDimVert0}, {1, twoDimVert0}, 83 {1, twoDimVert0}, {1, twoDimVert0},
84 {1, twoDimVert0}, {1, twoDimVert0}, 84 {1, twoDimVert0}, {1, twoDimVert0},
85 {1, twoDimVert0}, {1, twoDimVert0}, 85 {1, twoDimVert0}, {1, twoDimVert0},
86 {1, twoDimVert0}, {1, twoDimVert0}, 86 {1, twoDimVert0}, {1, twoDimVert0},
87 {1, twoDimVert0}, {1, twoDimVert0}, 87 {1, twoDimVert0}, {1, twoDimVert0},
88 {1, twoDimVert0}, {1, twoDimVert0}, 88 {1, twoDimVert0}, {1, twoDimVert0},
89 {1, twoDimVert0}, {1, twoDimVert0}, 89 {1, twoDimVert0}, {1, twoDimVert0},
90 {1, twoDimVert0}, {1, twoDimVert0}, 90 {1, twoDimVert0}, {1, twoDimVert0},
91 {1, twoDimVert0}, {1, twoDimVert0}, 91 {1, twoDimVert0}, {1, twoDimVert0},
92 {1, twoDimVert0}, {1, twoDimVert0}, 92 {1, twoDimVert0}, {1, twoDimVert0},
93 {1, twoDimVert0}, {1, twoDimVert0}, 93 {1, twoDimVert0}, {1, twoDimVert0},
94 {1, twoDimVert0}, {1, twoDimVert0}, 94 {1, twoDimVert0}, {1, twoDimVert0},
95 {1, twoDimVert0}, {1, twoDimVert0}, 95 {1, twoDimVert0}, {1, twoDimVert0},
96 {1, twoDimVert0}, {1, twoDimVert0}, 96 {1, twoDimVert0}, {1, twoDimVert0},
97 {1, twoDimVert0}, {1, twoDimVert0}, 97 {1, twoDimVert0}, {1, twoDimVert0},
98 {1, twoDimVert0}, {1, twoDimVert0} 98 {1, twoDimVert0}, {1, twoDimVert0}
99}; 99};
100 100
101//------------------------------------------------------------------------ 101//------------------------------------------------------------------------
102// white run lengths 102// white run lengths
103//------------------------------------------------------------------------ 103//------------------------------------------------------------------------
104 104
105// 11-12 bit codes (upper 7 bits are 0) 105// 11-12 bit codes (upper 7 bits are 0)
106static CCITTCode whiteTab1[32] = { 106static CCITTCode whiteTab1[32] = {
107 {-1, -1}, // 00000 107 {-1, -1}, // 00000
108 {12, ccittEOL}, // 00001 108 {12, ccittEOL}, // 00001
109 {-1, -1}, {-1, -1}, // 0001x 109 {-1, -1}, {-1, -1}, // 0001x
110 {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1},// 001xx 110 {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1},// 001xx
111 {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1},// 010xx 111 {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1},// 010xx
112 {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1},// 011xx 112 {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1},// 011xx
113 {11, 1792}, {11, 1792}, // 1000x 113 {11, 1792}, {11, 1792}, // 1000x
114 {12, 1984}, // 10010 114 {12, 1984}, // 10010
115 {12, 2048}, // 10011 115 {12, 2048}, // 10011
116 {12, 2112}, // 10100 116 {12, 2112}, // 10100
117 {12, 2176}, // 10101 117 {12, 2176}, // 10101
118 {12, 2240}, // 10110 118 {12, 2240}, // 10110
119 {12, 2304}, // 10111 119 {12, 2304}, // 10111
120 {11, 1856}, {11, 1856}, // 1100x 120 {11, 1856}, {11, 1856}, // 1100x
121 {11, 1920}, {11, 1920}, // 1101x 121 {11, 1920}, {11, 1920}, // 1101x
122 {12, 2368}, // 11100 122 {12, 2368}, // 11100
123 {12, 2432}, // 11101 123 {12, 2432}, // 11101
124 {12, 2496}, // 11110 124 {12, 2496}, // 11110
125 {12, 2560} // 11111 125 {12, 2560} // 11111
126}; 126};
127 127
128// 1-9 bit codes 128// 1-9 bit codes
129static CCITTCode whiteTab2[512] = { 129static CCITTCode whiteTab2[512] = {
130 {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1},// 0000000xx 130 {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1},// 0000000xx
131 {8, 29}, {8, 29}, // 00000010x 131 {8, 29}, {8, 29}, // 00000010x
132 {8, 30}, {8, 30}, // 00000011x 132 {8, 30}, {8, 30}, // 00000011x
133 {8, 45}, {8, 45}, // 00000100x 133 {8, 45}, {8, 45}, // 00000100x
134 {8, 46}, {8, 46}, // 00000101x 134 {8, 46}, {8, 46}, // 00000101x
135 {7, 22}, {7, 22}, {7, 22}, {7, 22}, // 0000011xx 135 {7, 22}, {7, 22}, {7, 22}, {7, 22}, // 0000011xx
136 {7, 23}, {7, 23}, {7, 23}, {7, 23}, // 0000100xx 136 {7, 23}, {7, 23}, {7, 23}, {7, 23}, // 0000100xx
137 {8, 47}, {8, 47}, // 00001010x 137 {8, 47}, {8, 47}, // 00001010x
138 {8, 48}, {8, 48}, // 00001011x 138 {8, 48}, {8, 48}, // 00001011x
139 {6, 13}, {6, 13}, {6, 13}, {6, 13}, // 000011xxx 139 {6, 13}, {6, 13}, {6, 13}, {6, 13}, // 000011xxx
140 {6, 13}, {6, 13}, {6, 13}, {6, 13}, 140 {6, 13}, {6, 13}, {6, 13}, {6, 13},
141 {7, 20}, {7, 20}, {7, 20}, {7, 20}, // 0001000xx 141 {7, 20}, {7, 20}, {7, 20}, {7, 20}, // 0001000xx
142 {8, 33}, {8, 33}, // 00010010x 142 {8, 33}, {8, 33}, // 00010010x
143 {8, 34}, {8, 34}, // 00010011x 143 {8, 34}, {8, 34}, // 00010011x
144 {8, 35}, {8, 35}, // 00010100x 144 {8, 35}, {8, 35}, // 00010100x
145 {8, 36}, {8, 36}, // 00010101x 145 {8, 36}, {8, 36}, // 00010101x
146 {8, 37}, {8, 37}, // 00010110x 146 {8, 37}, {8, 37}, // 00010110x
147 {8, 38}, {8, 38}, // 00010111x 147 {8, 38}, {8, 38}, // 00010111x
148 {7, 19}, {7, 19}, {7, 19}, {7, 19}, // 0001100xx 148 {7, 19}, {7, 19}, {7, 19}, {7, 19}, // 0001100xx
149 {8, 31}, {8, 31}, // 00011010x 149 {8, 31}, {8, 31}, // 00011010x
150 {8, 32}, {8, 32}, // 00011011x 150 {8, 32}, {8, 32}, // 00011011x
151 {6, 1}, {6, 1}, {6, 1}, {6, 1}, // 000111xxx 151 {6, 1}, {6, 1}, {6, 1}, {6, 1}, // 000111xxx
152 {6, 1}, {6, 1}, {6, 1}, {6, 1}, 152 {6, 1}, {6, 1}, {6, 1}, {6, 1},
153 {6, 12}, {6, 12}, {6, 12}, {6, 12}, // 001000xxx 153 {6, 12}, {6, 12}, {6, 12}, {6, 12}, // 001000xxx
154 {6, 12}, {6, 12}, {6, 12}, {6, 12}, 154 {6, 12}, {6, 12}, {6, 12}, {6, 12},
155 {8, 53}, {8, 53}, // 00100100x 155 {8, 53}, {8, 53}, // 00100100x
156 {8, 54}, {8, 54}, // 00100101x 156 {8, 54}, {8, 54}, // 00100101x
157 {7, 26}, {7, 26}, {7, 26}, {7, 26}, // 0010011xx 157 {7, 26}, {7, 26}, {7, 26}, {7, 26}, // 0010011xx
158 {8, 39}, {8, 39}, // 00101000x 158 {8, 39}, {8, 39}, // 00101000x
159 {8, 40}, {8, 40}, // 00101001x 159 {8, 40}, {8, 40}, // 00101001x
160 {8, 41}, {8, 41}, // 00101010x 160 {8, 41}, {8, 41}, // 00101010x
161 {8, 42}, {8, 42}, // 00101011x 161 {8, 42}, {8, 42}, // 00101011x
162 {8, 43}, {8, 43}, // 00101100x 162 {8, 43}, {8, 43}, // 00101100x
163 {8, 44}, {8, 44}, // 00101101x 163 {8, 44}, {8, 44}, // 00101101x
164 {7, 21}, {7, 21}, {7, 21}, {7, 21}, // 0010111xx 164 {7, 21}, {7, 21}, {7, 21}, {7, 21}, // 0010111xx
165 {7, 28}, {7, 28}, {7, 28}, {7, 28}, // 0011000xx 165 {7, 28}, {7, 28}, {7, 28}, {7, 28}, // 0011000xx
166 {8, 61}, {8, 61}, // 00110010x 166 {8, 61}, {8, 61}, // 00110010x
167 {8, 62}, {8, 62}, // 00110011x 167 {8, 62}, {8, 62}, // 00110011x
168 {8, 63}, {8, 63}, // 00110100x 168 {8, 63}, {8, 63}, // 00110100x
169 {8, 0}, {8, 0}, // 00110101x 169 {8, 0}, {8, 0}, // 00110101x
170 {8, 320}, {8, 320}, // 00110110x 170 {8, 320}, {8, 320}, // 00110110x
171 {8, 384}, {8, 384}, // 00110111x 171 {8, 384}, {8, 384}, // 00110111x
172 {5, 10}, {5, 10}, {5, 10}, {5, 10}, // 00111xxxx 172 {5, 10}, {5, 10}, {5, 10}, {5, 10}, // 00111xxxx
173 {5, 10}, {5, 10}, {5, 10}, {5, 10}, 173 {5, 10}, {5, 10}, {5, 10}, {5, 10},
174 {5, 10}, {5, 10}, {5, 10}, {5, 10}, 174 {5, 10}, {5, 10}, {5, 10}, {5, 10},
175 {5, 10}, {5, 10}, {5, 10}, {5, 10}, 175 {5, 10}, {5, 10}, {5, 10}, {5, 10},
176 {5, 11}, {5, 11}, {5, 11}, {5, 11}, // 01000xxxx 176 {5, 11}, {5, 11}, {5, 11}, {5, 11}, // 01000xxxx
177 {5, 11}, {5, 11}, {5, 11}, {5, 11}, 177 {5, 11}, {5, 11}, {5, 11}, {5, 11},
178 {5, 11}, {5, 11}, {5, 11}, {5, 11}, 178 {5, 11}, {5, 11}, {5, 11}, {5, 11},
179 {5, 11}, {5, 11}, {5, 11}, {5, 11}, 179 {5, 11}, {5, 11}, {5, 11}, {5, 11},
180 {7, 27}, {7, 27}, {7, 27}, {7, 27}, // 0100100xx 180 {7, 27}, {7, 27}, {7, 27}, {7, 27}, // 0100100xx
181 {8, 59}, {8, 59}, // 01001010x 181 {8, 59}, {8, 59}, // 01001010x
182 {8, 60}, {8, 60}, // 01001011x 182 {8, 60}, {8, 60}, // 01001011x
183 {9, 1472}, // 010011000 183 {9, 1472}, // 010011000
184 {9, 1536}, // 010011001 184 {9, 1536}, // 010011001
185 {9, 1600}, // 010011010 185 {9, 1600}, // 010011010
186 {9, 1728}, // 010011011 186 {9, 1728}, // 010011011
187 {7, 18}, {7, 18}, {7, 18}, {7, 18}, // 0100111xx 187 {7, 18}, {7, 18}, {7, 18}, {7, 18}, // 0100111xx
188 {7, 24}, {7, 24}, {7, 24}, {7, 24}, // 0101000xx 188 {7, 24}, {7, 24}, {7, 24}, {7, 24}, // 0101000xx
189 {8, 49}, {8, 49}, // 01010010x 189 {8, 49}, {8, 49}, // 01010010x
190 {8, 50}, {8, 50}, // 01010011x 190 {8, 50}, {8, 50}, // 01010011x
191 {8, 51}, {8, 51}, // 01010100x 191 {8, 51}, {8, 51}, // 01010100x
192 {8, 52}, {8, 52}, // 01010101x 192 {8, 52}, {8, 52}, // 01010101x
193 {7, 25}, {7, 25}, {7, 25}, {7, 25}, // 0101011xx 193 {7, 25}, {7, 25}, {7, 25}, {7, 25}, // 0101011xx
194 {8, 55}, {8, 55}, // 01011000x 194 {8, 55}, {8, 55}, // 01011000x
195 {8, 56}, {8, 56}, // 01011001x 195 {8, 56}, {8, 56}, // 01011001x
196 {8, 57}, {8, 57}, // 01011010x 196 {8, 57}, {8, 57}, // 01011010x
197 {8, 58}, {8, 58}, // 01011011x 197 {8, 58}, {8, 58}, // 01011011x
198 {6, 192}, {6, 192}, {6, 192}, {6, 192},// 010111xxx 198 {6, 192}, {6, 192}, {6, 192}, {6, 192},// 010111xxx
199 {6, 192}, {6, 192}, {6, 192}, {6, 192}, 199 {6, 192}, {6, 192}, {6, 192}, {6, 192},
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,1158 +1,1267 @@
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
18#include <unistd.h> 18#include <unistd.h>
19#endif 19#endif
20#include <string.h> 20#include <string.h>
21#include <ctype.h> 21#include <ctype.h>
22#include "gmem.h" 22#include "gmem.h"
23#include "gfile.h" 23#include "gfile.h"
24#include "config.h" 24#include "config.h"
25#include "Error.h" 25#include "Error.h"
26#include "Object.h" 26#include "Object.h"
27#ifndef NO_DECRYPTION 27#ifndef NO_DECRYPTION
28#include "Decrypt.h" 28#include "Decrypt.h"
29#endif 29#endif
30#include "Stream.h" 30#include "Stream.h"
31#include "Stream-CCITT.h" 31#include "Stream-CCITT.h"
32 32
33#ifdef __DJGPP__ 33#ifdef __DJGPP__
34static GBool setDJSYSFLAGS = gFalse; 34static GBool setDJSYSFLAGS = gFalse;
35#endif 35#endif
36 36
37#ifdef VMS 37#ifdef VMS
38#if (__VMS_VER < 70000000) 38#if (__VMS_VER < 70000000)
39extern "C" int unlink(char *filename); 39extern "C" int unlink(char *filename);
40#endif 40#endif
41#ifdef __GNUC__ 41#ifdef __GNUC__
42#define SEEK_SET 0 42#define SEEK_SET 0
43#define SEEK_CUR 1 43#define SEEK_CUR 1
44#define SEEK_END 2 44#define SEEK_END 2
45#endif 45#endif
46#endif 46#endif
47 47
48#ifdef MACOS 48#ifdef MACOS
49#include "StuffItEngineLib.h" 49#include "StuffItEngineLib.h"
50#endif 50#endif
51 51
52//------------------------------------------------------------------------ 52//------------------------------------------------------------------------
53// Stream (base class) 53// Stream (base class)
54//------------------------------------------------------------------------ 54//------------------------------------------------------------------------
55 55
56Stream::Stream() { 56Stream::Stream() {
57 ref = 1; 57 ref = 1;
58} 58}
59 59
60Stream::~Stream() { 60Stream::~Stream() {
61} 61}
62 62
63void Stream::close() { 63void Stream::close() {
64} 64}
65 65
66int Stream::getRawChar() { 66int Stream::getRawChar() {
67 error(-1, "Internal: called getRawChar() on non-predictor stream"); 67 error(-1, "Internal: called getRawChar() on non-predictor stream");
68 return EOF; 68 return EOF;
69} 69}
70 70
71char *Stream::getLine(char *buf, int size) { 71char *Stream::getLine(char *buf, int size) {
72 int i; 72 int i;
73 int c; 73 int c;
74 74
75 if (lookChar() == EOF) 75 if (lookChar() == EOF)
76 return NULL; 76 return NULL;
77 for (i = 0; i < size - 1; ++i) { 77 for (i = 0; i < size - 1; ++i) {
78 c = getChar(); 78 c = getChar();
79 if (c == EOF || c == '\n') 79 if (c == EOF || c == '\n')
80 break; 80 break;
81 if (c == '\r') { 81 if (c == '\r') {
82 if ((c = lookChar()) == '\n') 82 if ((c = lookChar()) == '\n')
83 getChar(); 83 getChar();
84 break; 84 break;
85 } 85 }
86 buf[i] = c; 86 buf[i] = c;
87 } 87 }
88 buf[i] = '\0'; 88 buf[i] = '\0';
89 return buf; 89 return buf;
90} 90}
91 91
92GString *Stream::getPSFilter(char *indent) { 92GString *Stream::getPSFilter(char *indent) {
93 return new GString(); 93 return new GString();
94} 94}
95 95
96Stream *Stream::addFilters(Object *dict) { 96Stream *Stream::addFilters(Object *dict) {
97 Object obj, obj2; 97 Object obj, obj2;
98 Object params, params2; 98 Object params, params2;
99 Stream *str; 99 Stream *str;
100 int i; 100 int i;
101 101
102 str = this; 102 str = this;
103 dict->dictLookup("Filter", &obj); 103 dict->dictLookup("Filter", &obj);
104 if (obj.isNull()) { 104 if (obj.isNull()) {
105 obj.free(); 105 obj.free();
106 dict->dictLookup("F", &obj); 106 dict->dictLookup("F", &obj);
107 } 107 }
108 dict->dictLookup("DecodeParms", &params); 108 dict->dictLookup("DecodeParms", &params);
109 if (params.isNull()) { 109 if (params.isNull()) {
110 params.free(); 110 params.free();
111 dict->dictLookup("DP", &params); 111 dict->dictLookup("DP", &params);
112 } 112 }
113 if (obj.isName()) { 113 if (obj.isName()) {
114 str = makeFilter(obj.getName(), str, &params); 114 str = makeFilter(obj.getName(), str, &params);
115 } else if (obj.isArray()) { 115 } else if (obj.isArray()) {
116 for (i = 0; i < obj.arrayGetLength(); ++i) { 116 for (i = 0; i < obj.arrayGetLength(); ++i) {
117 obj.arrayGet(i, &obj2); 117 obj.arrayGet(i, &obj2);
118 if (params.isArray()) 118 if (params.isArray())
119 params.arrayGet(i, &params2); 119 params.arrayGet(i, &params2);
120 else 120 else
121 params2.initNull(); 121 params2.initNull();
122 if (obj2.isName()) { 122 if (obj2.isName()) {
123 str = makeFilter(obj2.getName(), str, &params2); 123 str = makeFilter(obj2.getName(), str, &params2);
124 } else { 124 } else {
125 error(getPos(), "Bad filter name"); 125 error(getPos(), "Bad filter name");
126 str = new EOFStream(str); 126 str = new EOFStream(str);
127 } 127 }
128 obj2.free(); 128 obj2.free();
129 params2.free(); 129 params2.free();
130 } 130 }
131 } else if (!obj.isNull()) { 131 } else if (!obj.isNull()) {
132 error(getPos(), "Bad 'Filter' attribute in stream"); 132 error(getPos(), "Bad 'Filter' attribute in stream");
133 } 133 }
134 obj.free(); 134 obj.free();
135 params.free(); 135 params.free();
136 136
137 return str; 137 return str;
138} 138}
139 139
140Stream *Stream::makeFilter(char *name, Stream *str, Object *params) { 140Stream *Stream::makeFilter(char *name, Stream *str, Object *params) {
141 int pred; // parameters 141 int pred; // parameters
142 int colors; 142 int colors;
143 int bits; 143 int bits;
144 int early; 144 int early;
145 int encoding; 145 int encoding;
146 GBool endOfLine, byteAlign, endOfBlock, black; 146 GBool endOfLine, byteAlign, endOfBlock, black;
147 int columns, rows; 147 int columns, rows;
148 Object obj; 148 Object obj;
149 149
150 if (!strcmp(name, "ASCIIHexDecode") || !strcmp(name, "AHx")) { 150 if (!strcmp(name, "ASCIIHexDecode") || !strcmp(name, "AHx")) {
151 str = new ASCIIHexStream(str); 151 str = new ASCIIHexStream(str);
152 } else if (!strcmp(name, "ASCII85Decode") || !strcmp(name, "A85")) { 152 } else if (!strcmp(name, "ASCII85Decode") || !strcmp(name, "A85")) {
153 str = new ASCII85Stream(str); 153 str = new ASCII85Stream(str);
154 } else if (!strcmp(name, "LZWDecode") || !strcmp(name, "LZW")) { 154 } else if (!strcmp(name, "LZWDecode") || !strcmp(name, "LZW")) {
155 pred = 1; 155 pred = 1;
156 columns = 1; 156 columns = 1;
157 colors = 1; 157 colors = 1;
158 bits = 8; 158 bits = 8;
159 early = 1; 159 early = 1;
160 if (params->isDict()) { 160 if (params->isDict()) {
161 params->dictLookup("Predictor", &obj); 161 params->dictLookup("Predictor", &obj);
162 if (obj.isInt()) 162 if (obj.isInt())
163 pred = obj.getInt(); 163 pred = obj.getInt();
164 obj.free(); 164 obj.free();
165 params->dictLookup("Columns", &obj); 165 params->dictLookup("Columns", &obj);
166 if (obj.isInt()) 166 if (obj.isInt())
167 columns = obj.getInt(); 167 columns = obj.getInt();
168 obj.free(); 168 obj.free();
169 params->dictLookup("Colors", &obj); 169 params->dictLookup("Colors", &obj);
170 if (obj.isInt()) 170 if (obj.isInt())
171 colors = obj.getInt(); 171 colors = obj.getInt();
172 obj.free(); 172 obj.free();
173 params->dictLookup("BitsPerComponent", &obj); 173 params->dictLookup("BitsPerComponent", &obj);
174 if (obj.isInt()) 174 if (obj.isInt())
175 bits = obj.getInt(); 175 bits = obj.getInt();
176 obj.free(); 176 obj.free();
177 params->dictLookup("EarlyChange", &obj); 177 params->dictLookup("EarlyChange", &obj);
178 if (obj.isInt()) 178 if (obj.isInt())
179 early = obj.getInt(); 179 early = obj.getInt();
180 obj.free(); 180 obj.free();
181 } 181 }
182 str = new LZWStream(str, pred, columns, colors, bits, early); 182 str = new LZWStream(str, pred, columns, colors, bits, early);
183 } else if (!strcmp(name, "RunLengthDecode") || !strcmp(name, "RL")) { 183 } else if (!strcmp(name, "RunLengthDecode") || !strcmp(name, "RL")) {
184 str = new RunLengthStream(str); 184 str = new RunLengthStream(str);
185 } else if (!strcmp(name, "CCITTFaxDecode") || !strcmp(name, "CCF")) { 185 } else if (!strcmp(name, "CCITTFaxDecode") || !strcmp(name, "CCF")) {
186 encoding = 0; 186 encoding = 0;
187 endOfLine = gFalse; 187 endOfLine = gFalse;
188 byteAlign = gFalse; 188 byteAlign = gFalse;
189 columns = 1728; 189 columns = 1728;
190 rows = 0; 190 rows = 0;
191 endOfBlock = gTrue; 191 endOfBlock = gTrue;
192 black = gFalse; 192 black = gFalse;
193 if (params->isDict()) { 193 if (params->isDict()) {
194 params->dictLookup("K", &obj); 194 params->dictLookup("K", &obj);
195 if (obj.isInt()) { 195 if (obj.isInt()) {
196 encoding = obj.getInt(); 196 encoding = obj.getInt();
197 } 197 }
198 obj.free(); 198 obj.free();
199 params->dictLookup("EndOfLine", &obj); 199 params->dictLookup("EndOfLine", &obj);
200 if (obj.isBool()) { 200 if (obj.isBool()) {
201 endOfLine = obj.getBool(); 201 endOfLine = obj.getBool();
202 } 202 }
203 obj.free(); 203 obj.free();
204 params->dictLookup("EncodedByteAlign", &obj); 204 params->dictLookup("EncodedByteAlign", &obj);
205 if (obj.isBool()) { 205 if (obj.isBool()) {
206 byteAlign = obj.getBool(); 206 byteAlign = obj.getBool();
207 } 207 }
208 obj.free(); 208 obj.free();
209 params->dictLookup("Columns", &obj); 209 params->dictLookup("Columns", &obj);
210 if (obj.isInt()) { 210 if (obj.isInt()) {
211 columns = obj.getInt(); 211 columns = obj.getInt();
212 } 212 }
213 obj.free(); 213 obj.free();
214 params->dictLookup("Rows", &obj); 214 params->dictLookup("Rows", &obj);
215 if (obj.isInt()) { 215 if (obj.isInt()) {
216 rows = obj.getInt(); 216 rows = obj.getInt();
217 } 217 }
218 obj.free(); 218 obj.free();
219 params->dictLookup("EndOfBlock", &obj); 219 params->dictLookup("EndOfBlock", &obj);
220 if (obj.isBool()) { 220 if (obj.isBool()) {
221 endOfBlock = obj.getBool(); 221 endOfBlock = obj.getBool();
222 } 222 }
223 obj.free(); 223 obj.free();
224 params->dictLookup("BlackIs1", &obj); 224 params->dictLookup("BlackIs1", &obj);
225 if (obj.isBool()) { 225 if (obj.isBool()) {
226 black = obj.getBool(); 226 black = obj.getBool();
227 } 227 }
228 obj.free(); 228 obj.free();
229 } 229 }
230 str = new CCITTFaxStream(str, encoding, endOfLine, byteAlign, 230 str = new CCITTFaxStream(str, encoding, endOfLine, byteAlign,
231 columns, rows, endOfBlock, black); 231 columns, rows, endOfBlock, black);
232 } else if (!strcmp(name, "DCTDecode") || !strcmp(name, "DCT")) { 232 } else if (!strcmp(name, "DCTDecode") || !strcmp(name, "DCT")) {
233 str = new DCTStream(str); 233 str = new DCTStream(str);
234 } else if (!strcmp(name, "FlateDecode") || !strcmp(name, "Fl")) { 234 } else if (!strcmp(name, "FlateDecode") || !strcmp(name, "Fl")) {
235 pred = 1; 235 pred = 1;
236 columns = 1; 236 columns = 1;
237 colors = 1; 237 colors = 1;
238 bits = 8; 238 bits = 8;
239 if (params->isDict()) { 239 if (params->isDict()) {
240 params->dictLookup("Predictor", &obj); 240 params->dictLookup("Predictor", &obj);
241 if (obj.isInt()) 241 if (obj.isInt())
242 pred = obj.getInt(); 242 pred = obj.getInt();
243 obj.free(); 243 obj.free();
244 params->dictLookup("Columns", &obj); 244 params->dictLookup("Columns", &obj);
245 if (obj.isInt()) 245 if (obj.isInt())
246 columns = obj.getInt(); 246 columns = obj.getInt();
247 obj.free(); 247 obj.free();
248 params->dictLookup("Colors", &obj); 248 params->dictLookup("Colors", &obj);
249 if (obj.isInt()) 249 if (obj.isInt())
250 colors = obj.getInt(); 250 colors = obj.getInt();
251 obj.free(); 251 obj.free();
252 params->dictLookup("BitsPerComponent", &obj); 252 params->dictLookup("BitsPerComponent", &obj);
253 if (obj.isInt()) 253 if (obj.isInt())
254 bits = obj.getInt(); 254 bits = obj.getInt();
255 obj.free(); 255 obj.free();
256 } 256 }
257 str = new FlateStream(str, pred, columns, colors, bits); 257 str = new FlateStream(str, pred, columns, colors, bits);
258 } else { 258 } else {
259 error(getPos(), "Unknown filter '%s'", name); 259 error(getPos(), "Unknown filter '%s'", name);
260 str = new EOFStream(str); 260 str = new EOFStream(str);
261 } 261 }
262 return str; 262 return str;
263} 263}
264 264
265//------------------------------------------------------------------------ 265//------------------------------------------------------------------------
266// BaseStream 266// BaseStream
267//------------------------------------------------------------------------ 267//------------------------------------------------------------------------
268 268
269BaseStream::BaseStream(Object *dictA) { 269BaseStream::BaseStream(Object *dictA) {
270 dict = *dictA; 270 dict = *dictA;
271#ifndef NO_DECRYPTION 271#ifndef NO_DECRYPTION
272 decrypt = NULL; 272 decrypt = NULL;
273#endif 273#endif
274} 274}
275 275
276BaseStream::~BaseStream() { 276BaseStream::~BaseStream() {
277 dict.free(); 277 dict.free();
278#ifndef NO_DECRYPTION 278#ifndef NO_DECRYPTION
279 if (decrypt) 279 if (decrypt)
280 delete decrypt; 280 delete decrypt;
281#endif 281#endif
282} 282}
283 283
284#ifndef NO_DECRYPTION 284#ifndef NO_DECRYPTION
285void BaseStream::doDecryption(Guchar *fileKey, int keyLength, 285void BaseStream::doDecryption(Guchar *fileKey, int keyLength,
286 int objNum, int objGen) { 286 int objNum, int objGen) {
287 decrypt = new Decrypt(fileKey, keyLength, objNum, objGen); 287 decrypt = new Decrypt(fileKey, keyLength, objNum, objGen);
288} 288}
289#endif 289#endif
290 290
291//------------------------------------------------------------------------ 291//------------------------------------------------------------------------
292// FilterStream 292// FilterStream
293//------------------------------------------------------------------------ 293//------------------------------------------------------------------------
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;
319 nComps = nCompsA; 319 nComps = nCompsA;
320 nBits = nBitsA; 320 nBits = nBitsA;
321 321
322 nVals = width * nComps; 322 nVals = width * nComps;
323 if (nBits == 1) { 323 if (nBits == 1) {
324 imgLineSize = (nVals + 7) & ~7; 324 imgLineSize = (nVals + 7) & ~7;
325 } else { 325 } else {
326 imgLineSize = nVals; 326 imgLineSize = nVals;
327 } 327 }
328 imgLine = (Guchar *)gmalloc(imgLineSize * sizeof(Guchar)); 328 imgLine = (Guchar *)gmalloc(imgLineSize * sizeof(Guchar));
329 imgIdx = nVals; 329 imgIdx = nVals;
330} 330}
331 331
332ImageStream::~ImageStream() { 332ImageStream::~ImageStream() {
333 gfree(imgLine); 333 gfree(imgLine);
334} 334}
335 335
336void ImageStream::reset() { 336void ImageStream::reset() {
337 str->reset(); 337 str->reset();
338} 338}
339 339
340GBool ImageStream::getPixel(Guchar *pix) { 340GBool ImageStream::getPixel(Guchar *pix) {
341 Gulong buf, bitMask; 341 Gulong buf, bitMask;
342 int bits; 342 int bits;
343 int c; 343 int c;
344 int i; 344 int i;
345 345
346 if (imgIdx >= nVals) { 346 if (imgIdx >= nVals) {
347 347
348 // read one line of image pixels 348 // read one line of image pixels
349 if (nBits == 1) { 349 if (nBits == 1) {
350 for (i = 0; i < nVals; i += 8) { 350 for (i = 0; i < nVals; i += 8) {
351 c = str->getChar(); 351 c = str->getChar();
352 imgLine[i+0] = (Guchar)((c >> 7) & 1); 352 imgLine[i+0] = (Guchar)((c >> 7) & 1);
353 imgLine[i+1] = (Guchar)((c >> 6) & 1); 353 imgLine[i+1] = (Guchar)((c >> 6) & 1);
354 imgLine[i+2] = (Guchar)((c >> 5) & 1); 354 imgLine[i+2] = (Guchar)((c >> 5) & 1);
355 imgLine[i+3] = (Guchar)((c >> 4) & 1); 355 imgLine[i+3] = (Guchar)((c >> 4) & 1);
356 imgLine[i+4] = (Guchar)((c >> 3) & 1); 356 imgLine[i+4] = (Guchar)((c >> 3) & 1);
357 imgLine[i+5] = (Guchar)((c >> 2) & 1); 357 imgLine[i+5] = (Guchar)((c >> 2) & 1);
358 imgLine[i+6] = (Guchar)((c >> 1) & 1); 358 imgLine[i+6] = (Guchar)((c >> 1) & 1);
359 imgLine[i+7] = (Guchar)(c & 1); 359 imgLine[i+7] = (Guchar)(c & 1);
360 } 360 }
361 } else if (nBits == 8) { 361 } else if (nBits == 8) {
362 for (i = 0; i < nVals; ++i) { 362 for (i = 0; i < nVals; ++i) {
363 imgLine[i] = str->getChar(); 363 imgLine[i] = str->getChar();
364 } 364 }
365 } else { 365 } else {
366 bitMask = (1 << nBits) - 1; 366 bitMask = (1 << nBits) - 1;
367 buf = 0; 367 buf = 0;
368 bits = 0; 368 bits = 0;
369 for (i = 0; i < nVals; ++i) { 369 for (i = 0; i < nVals; ++i) {
370 if (bits < nBits) { 370 if (bits < nBits) {
371 buf = (buf << 8) | (str->getChar() & 0xff); 371 buf = (buf << 8) | (str->getChar() & 0xff);
372 bits += 8; 372 bits += 8;
373 } 373 }
374 imgLine[i] = (Guchar)((buf >> (bits - nBits)) & bitMask); 374 imgLine[i] = (Guchar)((buf >> (bits - nBits)) & bitMask);
375 bits -= nBits; 375 bits -= nBits;
376 } 376 }
377 } 377 }
378 378
379 // reset to start of line 379 // reset to start of line
380 imgIdx = 0; 380 imgIdx = 0;
381 } 381 }
382 382
383 for (i = 0; i < nComps; ++i) 383 for (i = 0; i < nComps; ++i)
384 pix[i] = imgLine[imgIdx++]; 384 pix[i] = imgLine[imgIdx++];
385 return gTrue; 385 return gTrue;
386} 386}
387 387
388void ImageStream::skipLine() { 388void ImageStream::skipLine() {
389 int n, i; 389 int n, i;
390 390
391 n = (nVals * nBits + 7) >> 3; 391 n = (nVals * nBits + 7) >> 3;
392 for (i = 0; i < n; ++i) { 392 for (i = 0; i < n; ++i) {
393 str->getChar(); 393 str->getChar();
394 } 394 }
395} 395}
396 396
397//------------------------------------------------------------------------ 397//------------------------------------------------------------------------
398// StreamPredictor 398// StreamPredictor
399//------------------------------------------------------------------------ 399//------------------------------------------------------------------------
400 400
401StreamPredictor::StreamPredictor(Stream *strA, int predictorA, 401StreamPredictor::StreamPredictor(Stream *strA, int predictorA,
402 int widthA, int nCompsA, int nBitsA) { 402 int widthA, int nCompsA, int nBitsA) {
403 str = strA; 403 str = strA;
404 predictor = predictorA; 404 predictor = predictorA;
405 width = widthA; 405 width = widthA;
406 nComps = nCompsA; 406 nComps = nCompsA;
407 nBits = nBitsA; 407 nBits = nBitsA;
408 408
409 nVals = width * nComps; 409 nVals = width * nComps;
410 pixBytes = (nComps * nBits + 7) >> 3; 410 pixBytes = (nComps * nBits + 7) >> 3;
411 rowBytes = ((nVals * nBits + 7) >> 3) + pixBytes; 411 rowBytes = ((nVals * nBits + 7) >> 3) + pixBytes;
412 predLine = (Guchar *)gmalloc(rowBytes); 412 predLine = (Guchar *)gmalloc(rowBytes);
413 memset(predLine, 0, rowBytes); 413 memset(predLine, 0, rowBytes);
414 predIdx = rowBytes; 414 predIdx = rowBytes;
415} 415}
416 416
417StreamPredictor::~StreamPredictor() { 417StreamPredictor::~StreamPredictor() {
418 gfree(predLine); 418 gfree(predLine);
419} 419}
420 420
421int StreamPredictor::lookChar() { 421int StreamPredictor::lookChar() {
422 if (predIdx >= rowBytes) { 422 if (predIdx >= rowBytes) {
423 if (!getNextLine()) { 423 if (!getNextLine()) {
424 return EOF; 424 return EOF;
425 } 425 }
426 } 426 }
427 return predLine[predIdx]; 427 return predLine[predIdx];
428} 428}
429 429
430int StreamPredictor::getChar() { 430int StreamPredictor::getChar() {
431 if (predIdx >= rowBytes) { 431 if (predIdx >= rowBytes) {
432 if (!getNextLine()) { 432 if (!getNextLine()) {
433 return EOF; 433 return EOF;
434 } 434 }
435 } 435 }
436 return predLine[predIdx++]; 436 return predLine[predIdx++];
437} 437}
438 438
439GBool StreamPredictor::getNextLine() { 439GBool StreamPredictor::getNextLine() {
440 int curPred; 440 int curPred;
441 Guchar upLeftBuf[4]; 441 Guchar upLeftBuf[4];
442 int left, up, upLeft, p, pa, pb, pc; 442 int left, up, upLeft, p, pa, pb, pc;
443 int c; 443 int c;
444 Gulong inBuf, outBuf, bitMask; 444 Gulong inBuf, outBuf, bitMask;
445 int inBits, outBits; 445 int inBits, outBits;
446 int i, j, k; 446 int i, j, k;
447 447
448 // get PNG optimum predictor number 448 // get PNG optimum predictor number
449 if (predictor == 15) { 449 if (predictor == 15) {
450 if ((curPred = str->getRawChar()) == EOF) { 450 if ((curPred = str->getRawChar()) == EOF) {
451 return gFalse; 451 return gFalse;
452 } 452 }
453 curPred += 10; 453 curPred += 10;
454 } else { 454 } else {
455 curPred = predictor; 455 curPred = predictor;
456 } 456 }
457 457
458 // read the raw line, apply PNG (byte) predictor 458 // read the raw line, apply PNG (byte) predictor
459 upLeftBuf[0] = upLeftBuf[1] = upLeftBuf[2] = upLeftBuf[3] = 0; 459 upLeftBuf[0] = upLeftBuf[1] = upLeftBuf[2] = upLeftBuf[3] = 0;
460 for (i = pixBytes; i < rowBytes; ++i) { 460 for (i = pixBytes; i < rowBytes; ++i) {
461 upLeftBuf[3] = upLeftBuf[2]; 461 upLeftBuf[3] = upLeftBuf[2];
462 upLeftBuf[2] = upLeftBuf[1]; 462 upLeftBuf[2] = upLeftBuf[1];
463 upLeftBuf[1] = upLeftBuf[0]; 463 upLeftBuf[1] = upLeftBuf[0];
464 upLeftBuf[0] = predLine[i]; 464 upLeftBuf[0] = predLine[i];
465 if ((c = str->getRawChar()) == EOF) { 465 if ((c = str->getRawChar()) == EOF) {
466 break; 466 break;
467 } 467 }
468 switch (curPred) { 468 switch (curPred) {
469 case 11: // PNG sub 469 case 11: // PNG sub
470 predLine[i] = predLine[i - pixBytes] + (Guchar)c; 470 predLine[i] = predLine[i - pixBytes] + (Guchar)c;
471 break; 471 break;
472 case 12: // PNG up 472 case 12: // PNG up
473 predLine[i] = predLine[i] + (Guchar)c; 473 predLine[i] = predLine[i] + (Guchar)c;
474 break; 474 break;
475 case 13: // PNG average 475 case 13: // PNG average
476 predLine[i] = ((predLine[i - pixBytes] + predLine[i]) >> 1) + 476 predLine[i] = ((predLine[i - pixBytes] + predLine[i]) >> 1) +
477 (Guchar)c; 477 (Guchar)c;
478 break; 478 break;
479 case 14: // PNG Paeth 479 case 14: // PNG Paeth
480 left = predLine[i - pixBytes]; 480 left = predLine[i - pixBytes];
481 up = predLine[i]; 481 up = predLine[i];
482 upLeft = upLeftBuf[pixBytes]; 482 upLeft = upLeftBuf[pixBytes];
483 p = left + up - upLeft; 483 p = left + up - upLeft;
484 if ((pa = p - left) < 0) 484 if ((pa = p - left) < 0)
485 pa = -pa; 485 pa = -pa;
486 if ((pb = p - up) < 0) 486 if ((pb = p - up) < 0)
487 pb = -pb; 487 pb = -pb;
488 if ((pc = p - upLeft) < 0) 488 if ((pc = p - upLeft) < 0)
489 pc = -pc; 489 pc = -pc;
490 if (pa <= pb && pa <= pc) 490 if (pa <= pb && pa <= pc)
491 predLine[i] = left + (Guchar)c; 491 predLine[i] = left + (Guchar)c;
492 else if (pb <= pc) 492 else if (pb <= pc)
493 predLine[i] = up + (Guchar)c; 493 predLine[i] = up + (Guchar)c;
494 else 494 else
495 predLine[i] = upLeft + (Guchar)c; 495 predLine[i] = upLeft + (Guchar)c;
496 break; 496 break;
497 case 10: // PNG none 497 case 10: // PNG none
498 default: // no predictor or TIFF predictor 498 default: // no predictor or TIFF predictor
499 predLine[i] = (Guchar)c; 499 predLine[i] = (Guchar)c;
500 break; 500 break;
501 } 501 }
502 } 502 }
503 503
504 // apply TIFF (component) predictor 504 // apply TIFF (component) predictor
505 //~ this is completely untested 505 //~ this is completely untested
506 if (predictor == 2) { 506 if (predictor == 2) {
507 if (nBits == 1) { 507 if (nBits == 1) {
508 inBuf = predLine[pixBytes - 1]; 508 inBuf = predLine[pixBytes - 1];
509 for (i = pixBytes; i < rowBytes; i += 8) { 509 for (i = pixBytes; i < rowBytes; i += 8) {
510 // 1-bit add is just xor 510 // 1-bit add is just xor
511 inBuf = (inBuf << 8) | predLine[i]; 511 inBuf = (inBuf << 8) | predLine[i];
512 predLine[i] ^= inBuf >> nComps; 512 predLine[i] ^= inBuf >> nComps;
513 } 513 }
514 } else if (nBits == 8) { 514 } else if (nBits == 8) {
515 for (i = pixBytes; i < rowBytes; ++i) { 515 for (i = pixBytes; i < rowBytes; ++i) {
516 predLine[i] += predLine[i - nComps]; 516 predLine[i] += predLine[i - nComps];
517 } 517 }
518 } else { 518 } else {
519 upLeftBuf[0] = upLeftBuf[1] = upLeftBuf[2] = upLeftBuf[3] = 0; 519 upLeftBuf[0] = upLeftBuf[1] = upLeftBuf[2] = upLeftBuf[3] = 0;
520 bitMask = (1 << nBits) - 1; 520 bitMask = (1 << nBits) - 1;
521 inBuf = outBuf = 0; 521 inBuf = outBuf = 0;
522 inBits = outBits = 0; 522 inBits = outBits = 0;
523 j = k = pixBytes; 523 j = k = pixBytes;
524 for (i = 0; i < nVals; ++i) { 524 for (i = 0; i < nVals; ++i) {
525 if (inBits < nBits) { 525 if (inBits < nBits) {
526 inBuf = (inBuf << 8) | (predLine[j++] & 0xff); 526 inBuf = (inBuf << 8) | (predLine[j++] & 0xff);
527 inBits += 8; 527 inBits += 8;
528 } 528 }
529 upLeftBuf[3] = upLeftBuf[2]; 529 upLeftBuf[3] = upLeftBuf[2];
530 upLeftBuf[2] = upLeftBuf[1]; 530 upLeftBuf[2] = upLeftBuf[1];
531 upLeftBuf[1] = upLeftBuf[0]; 531 upLeftBuf[1] = upLeftBuf[0];
532 upLeftBuf[0] = (upLeftBuf[nComps] + 532 upLeftBuf[0] = (upLeftBuf[nComps] +
533 (inBuf >> (inBits - nBits))) & bitMask; 533 (inBuf >> (inBits - nBits))) & bitMask;
534 outBuf = (outBuf << nBits) | upLeftBuf[0]; 534 outBuf = (outBuf << nBits) | upLeftBuf[0];
535 inBits -= nBits; 535 inBits -= nBits;
536 outBits += nBits; 536 outBits += nBits;
537 if (outBits > 8) { 537 if (outBits > 8) {
538 predLine[k++] = (Guchar)(outBuf >> (outBits - 8)); 538 predLine[k++] = (Guchar)(outBuf >> (outBits - 8));
539 } 539 }
540 } 540 }
541 if (outBits > 0) { 541 if (outBits > 0) {
542 predLine[k++] = (Guchar)(outBuf << (8 - outBits)); 542 predLine[k++] = (Guchar)(outBuf << (8 - outBits));
543 } 543 }
544 } 544 }
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}
690 803
691ASCIIHexStream::~ASCIIHexStream() { 804ASCIIHexStream::~ASCIIHexStream() {
692 delete str; 805 delete str;
693} 806}
694 807
695void ASCIIHexStream::reset() { 808void ASCIIHexStream::reset() {
696 str->reset(); 809 str->reset();
697 buf = EOF; 810 buf = EOF;
698 eof = gFalse; 811 eof = gFalse;
699} 812}
700 813
701int ASCIIHexStream::lookChar() { 814int ASCIIHexStream::lookChar() {
702 int c1, c2, x; 815 int c1, c2, x;
703 816
704 if (buf != EOF) 817 if (buf != EOF)
705 return buf; 818 return buf;
706 if (eof) { 819 if (eof) {
707 buf = EOF; 820 buf = EOF;
708 return EOF; 821 return EOF;
709 } 822 }
710 do { 823 do {
711 c1 = str->getChar(); 824 c1 = str->getChar();
712 } while (isspace(c1)); 825 } while (isspace(c1));
713 if (c1 == '>') { 826 if (c1 == '>') {
714 eof = gTrue; 827 eof = gTrue;
715 buf = EOF; 828 buf = EOF;
716 return buf; 829 return buf;
717 } 830 }
718 do { 831 do {
719 c2 = str->getChar(); 832 c2 = str->getChar();
720 } while (isspace(c2)); 833 } while (isspace(c2));
721 if (c2 == '>') { 834 if (c2 == '>') {
722 eof = gTrue; 835 eof = gTrue;
723 c2 = '0'; 836 c2 = '0';
724 } 837 }
725 if (c1 >= '0' && c1 <= '9') { 838 if (c1 >= '0' && c1 <= '9') {
726 x = (c1 - '0') << 4; 839 x = (c1 - '0') << 4;
727 } else if (c1 >= 'A' && c1 <= 'F') { 840 } else if (c1 >= 'A' && c1 <= 'F') {
728 x = (c1 - 'A' + 10) << 4; 841 x = (c1 - 'A' + 10) << 4;
729 } else if (c1 >= 'a' && c1 <= 'f') { 842 } else if (c1 >= 'a' && c1 <= 'f') {
730 x = (c1 - 'a' + 10) << 4; 843 x = (c1 - 'a' + 10) << 4;
731 } else if (c1 == EOF) { 844 } else if (c1 == EOF) {
732 eof = gTrue; 845 eof = gTrue;
733 x = 0; 846 x = 0;
734 } else { 847 } else {
735 error(getPos(), "Illegal character <%02x> in ASCIIHex stream", c1); 848 error(getPos(), "Illegal character <%02x> in ASCIIHex stream", c1);
736 x = 0; 849 x = 0;
737 } 850 }
738 if (c2 >= '0' && c2 <= '9') { 851 if (c2 >= '0' && c2 <= '9') {
739 x += c2 - '0'; 852 x += c2 - '0';
740 } else if (c2 >= 'A' && c2 <= 'F') { 853 } else if (c2 >= 'A' && c2 <= 'F') {
741 x += c2 - 'A' + 10; 854 x += c2 - 'A' + 10;
742 } else if (c2 >= 'a' && c2 <= 'f') { 855 } else if (c2 >= 'a' && c2 <= 'f') {
743 x += c2 - 'a' + 10; 856 x += c2 - 'a' + 10;
744 } else if (c2 == EOF) { 857 } else if (c2 == EOF) {
745 eof = gTrue; 858 eof = gTrue;
746 x = 0; 859 x = 0;
747 } else { 860 } else {
748 error(getPos(), "Illegal character <%02x> in ASCIIHex stream", c2); 861 error(getPos(), "Illegal character <%02x> in ASCIIHex stream", c2);
749 } 862 }
750 buf = x & 0xff; 863 buf = x & 0xff;
751 return buf; 864 return buf;
752} 865}
753 866
754GString *ASCIIHexStream::getPSFilter(char *indent) { 867GString *ASCIIHexStream::getPSFilter(char *indent) {
755 GString *s; 868 GString *s;
756 869
757 if (!(s = str->getPSFilter(indent))) { 870 if (!(s = str->getPSFilter(indent))) {
758 return NULL; 871 return NULL;
759 } 872 }
760 s->append(indent)->append("/ASCIIHexDecode filter\n"); 873 s->append(indent)->append("/ASCIIHexDecode filter\n");
761 return s; 874 return s;
762} 875}
763 876
764GBool ASCIIHexStream::isBinary(GBool last) { 877GBool ASCIIHexStream::isBinary(GBool last) {
765 return str->isBinary(gFalse); 878 return str->isBinary(gFalse);
766} 879}
767 880
768//------------------------------------------------------------------------ 881//------------------------------------------------------------------------
769// ASCII85Stream 882// ASCII85Stream
770//------------------------------------------------------------------------ 883//------------------------------------------------------------------------
771 884
772ASCII85Stream::ASCII85Stream(Stream *strA): 885ASCII85Stream::ASCII85Stream(Stream *strA):
773 FilterStream(strA) { 886 FilterStream(strA) {
774 index = n = 0; 887 index = n = 0;
775 eof = gFalse; 888 eof = gFalse;
776} 889}
777 890
778ASCII85Stream::~ASCII85Stream() { 891ASCII85Stream::~ASCII85Stream() {
779 delete str; 892 delete str;
780} 893}
781 894
782void ASCII85Stream::reset() { 895void ASCII85Stream::reset() {
783 str->reset(); 896 str->reset();
784 index = n = 0; 897 index = n = 0;
785 eof = gFalse; 898 eof = gFalse;
786} 899}
787 900
788int ASCII85Stream::lookChar() { 901int ASCII85Stream::lookChar() {
789 int k; 902 int k;
790 Gulong t; 903 Gulong t;
791 904
792 if (index >= n) { 905 if (index >= n) {
793 if (eof) 906 if (eof)
794 return EOF; 907 return EOF;
795 index = 0; 908 index = 0;
796 do { 909 do {
797 c[0] = str->getChar(); 910 c[0] = str->getChar();
798 } while (c[0] == '\n' || c[0] == '\r'); 911 } while (c[0] == '\n' || c[0] == '\r');
799 if (c[0] == '~' || c[0] == EOF) { 912 if (c[0] == '~' || c[0] == EOF) {
800 eof = gTrue; 913 eof = gTrue;
801 n = 0; 914 n = 0;
802 return EOF; 915 return EOF;
803 } else if (c[0] == 'z') { 916 } else if (c[0] == 'z') {
804 b[0] = b[1] = b[2] = b[3] = 0; 917 b[0] = b[1] = b[2] = b[3] = 0;
805 n = 4; 918 n = 4;
806 } else { 919 } else {
807 for (k = 1; k < 5; ++k) { 920 for (k = 1; k < 5; ++k) {
808 do { 921 do {
809 c[k] = str->getChar(); 922 c[k] = str->getChar();
810 } while (c[k] == '\n' || c[k] == '\r'); 923 } while (c[k] == '\n' || c[k] == '\r');
811 if (c[k] == '~' || c[k] == EOF) 924 if (c[k] == '~' || c[k] == EOF)
812 break; 925 break;
813 } 926 }
814 n = k - 1; 927 n = k - 1;
815 if (k < 5 && (c[k] == '~' || c[k] == EOF)) { 928 if (k < 5 && (c[k] == '~' || c[k] == EOF)) {
816 for (++k; k < 5; ++k) 929 for (++k; k < 5; ++k)
817 c[k] = 0x21 + 84; 930 c[k] = 0x21 + 84;
818 eof = gTrue; 931 eof = gTrue;
819 } 932 }
820 t = 0; 933 t = 0;
821 for (k = 0; k < 5; ++k) 934 for (k = 0; k < 5; ++k)
822 t = t * 85 + (c[k] - 0x21); 935 t = t * 85 + (c[k] - 0x21);
823 for (k = 3; k >= 0; --k) { 936 for (k = 3; k >= 0; --k) {
824 b[k] = (int)(t & 0xff); 937 b[k] = (int)(t & 0xff);
825 t >>= 8; 938 t >>= 8;
826 } 939 }
827 } 940 }
828 } 941 }
829 return b[index]; 942 return b[index];
830} 943}
831 944
832GString *ASCII85Stream::getPSFilter(char *indent) { 945GString *ASCII85Stream::getPSFilter(char *indent) {
833 GString *s; 946 GString *s;
834 947
835 if (!(s = str->getPSFilter(indent))) { 948 if (!(s = str->getPSFilter(indent))) {
836 return NULL; 949 return NULL;
837 } 950 }
838 s->append(indent)->append("/ASCII85Decode filter\n"); 951 s->append(indent)->append("/ASCII85Decode filter\n");
839 return s; 952 return s;
840} 953}
841 954
842GBool ASCII85Stream::isBinary(GBool last) { 955GBool ASCII85Stream::isBinary(GBool last) {
843 return str->isBinary(gFalse); 956 return str->isBinary(gFalse);
844} 957}
845 958
846//------------------------------------------------------------------------ 959//------------------------------------------------------------------------
847// LZWStream 960// LZWStream
848//------------------------------------------------------------------------ 961//------------------------------------------------------------------------
849 962
850LZWStream::LZWStream(Stream *strA, int predictor, int columns, int colors, 963LZWStream::LZWStream(Stream *strA, int predictor, int columns, int colors,
851 int bits, int earlyA): 964 int bits, int earlyA):
852 FilterStream(strA) { 965 FilterStream(strA) {
853 if (predictor != 1) { 966 if (predictor != 1) {
854 pred = new StreamPredictor(this, predictor, columns, colors, bits); 967 pred = new StreamPredictor(this, predictor, columns, colors, bits);
855 } else { 968 } else {
856 pred = NULL; 969 pred = NULL;
857 } 970 }
858 early = earlyA; 971 early = earlyA;
859 zPipe = NULL; 972 zPipe = NULL;
860 bufPtr = bufEnd = buf; 973 bufPtr = bufEnd = buf;
861} 974}
862 975
863LZWStream::~LZWStream() { 976LZWStream::~LZWStream() {
864 if (zPipe) { 977 if (zPipe) {
865#ifdef HAVE_POPEN 978#ifdef HAVE_POPEN
866 pclose(zPipe); 979 pclose(zPipe);
867#else 980#else
868 fclose(zPipe); 981 fclose(zPipe);
869#endif 982#endif
870 zPipe = NULL; 983 zPipe = NULL;
871 unlink(zName->getCString()); 984 unlink(zName->getCString());
872 delete zName; 985 delete zName;
873 } 986 }
874 if (pred) { 987 if (pred) {
875 delete pred; 988 delete pred;
876 } 989 }
877 delete str; 990 delete str;
878} 991}
879 992
880int LZWStream::getChar() { 993int LZWStream::getChar() {
881 if (pred) { 994 if (pred) {
882 return pred->getChar(); 995 return pred->getChar();
883 } 996 }
884 return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); 997 return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff);
885} 998}
886 999
887int LZWStream::lookChar() { 1000int LZWStream::lookChar() {
888 if (pred) { 1001 if (pred) {
889 return pred->lookChar(); 1002 return pred->lookChar();
890 } 1003 }
891 return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); 1004 return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff);
892} 1005}
893 1006
894int LZWStream::getRawChar() { 1007int LZWStream::getRawChar() {
895 return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); 1008 return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff);
896} 1009}
897 1010
898void LZWStream::reset() { 1011void LZWStream::reset() {
899 FILE *f; 1012 FILE *f;
900 GString *zCmd; 1013 GString *zCmd;
901 1014
902 //----- close old LZW stream 1015 //----- close old LZW stream
903 if (zPipe) { 1016 if (zPipe) {
904#ifdef HAVE_POPEN 1017#ifdef HAVE_POPEN
905 pclose(zPipe); 1018 pclose(zPipe);
906#else 1019#else
907 fclose(zPipe); 1020 fclose(zPipe);
908#endif 1021#endif
909 zPipe = NULL; 1022 zPipe = NULL;
910 unlink(zName->getCString()); 1023 unlink(zName->getCString());
911 delete zName; 1024 delete zName;
912 } 1025 }
913 1026
914 //----- tell Delorie runtime to spawn a new instance of COMMAND.COM 1027 //----- tell Delorie runtime to spawn a new instance of COMMAND.COM
915 // to run gzip 1028 // to run gzip
916#if __DJGPP__ 1029#if __DJGPP__
917 if (!setDJSYSFLAGS) { 1030 if (!setDJSYSFLAGS) {
918 setenv("DJSYSFLAGS", "0x0002", 0); 1031 setenv("DJSYSFLAGS", "0x0002", 0);
919 setDJSYSFLAGS = gTrue; 1032 setDJSYSFLAGS = gTrue;
920 } 1033 }
921#endif 1034#endif
922 1035
923 //----- create the .Z file 1036 //----- create the .Z file
924 if (!openTempFile(&zName, &f, "wb", ".Z")) { 1037 if (!openTempFile(&zName, &f, "wb", ".Z")) {
925 error(getPos(), "Couldn't create temporary file for LZW stream"); 1038 error(getPos(), "Couldn't create temporary file for LZW stream");
926 return; 1039 return;
927 } 1040 }
928 dumpFile(f); 1041 dumpFile(f);
929 fclose(f); 1042 fclose(f);
930 1043
931 //----- execute uncompress / gzip 1044 //----- execute uncompress / gzip
932 zCmd = new GString(uncompressCmd); 1045 zCmd = new GString(uncompressCmd);
933 zCmd->append(' '); 1046 zCmd->append(' ');
934 zCmd->append(zName); 1047 zCmd->append(zName);
935#if defined(MACOS) 1048#if defined(MACOS)
936 long magicCookie; 1049 long magicCookie;
937 // first we open the engine up 1050 // first we open the engine up
938 OSErr err = OpenSITEngine(kUseExternalEngine, &magicCookie); 1051 OSErr err = OpenSITEngine(kUseExternalEngine, &magicCookie);
939 // if we found it - let's use it! 1052 // if we found it - let's use it!
940 if (!err && magicCookie) { 1053 if (!err && magicCookie) {
941 // make sure we have the correct version of the Engine 1054 // make sure we have the correct version of the Engine
942 if (GetSITEngineVersion(magicCookie) >= kFirstSupportedEngine) { 1055 if (GetSITEngineVersion(magicCookie) >= kFirstSupportedEngine) {
943 FSSpec myFSS; 1056 FSSpec myFSS;
944 Str255 pName; 1057 Str255 pName;
945 strcpy((char *)pName, zName->getCString()); 1058 strcpy((char *)pName, zName->getCString());
946 c2pstr((char *)pName); 1059 c2pstr((char *)pName);
947 FSMakeFSSpec(0, 0, pName, &myFSS); 1060 FSMakeFSSpec(0, 0, pName, &myFSS);
948 short ftype = DetermineFileType(magicCookie, &myFSS); 1061 short ftype = DetermineFileType(magicCookie, &myFSS);
949 OSErr expandErr = ExpandFSSpec(magicCookie, ftype, &myFSS, 1062 OSErr expandErr = ExpandFSSpec(magicCookie, ftype, &myFSS,
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 }
979#endif // HAVE_POPEN 1088#endif // HAVE_POPEN
980 1089
981 //----- clean up 1090 //----- clean up
982 delete zCmd; 1091 delete zCmd;
983 1092
984 //----- initialize buffer 1093 //----- initialize buffer
985 bufPtr = bufEnd = buf; 1094 bufPtr = bufEnd = buf;
986} 1095}
987 1096
988void LZWStream::dumpFile(FILE *f) { 1097void LZWStream::dumpFile(FILE *f) {
989 int outCodeBits; // size of output code 1098 int outCodeBits; // size of output code
990 int outBits; // max output code 1099 int outBits; // max output code
991 int outBuf[8]; // output buffer 1100 int outBuf[8]; // output buffer
992 int outData; // temporary output buffer 1101 int outData; // temporary output buffer
993 int inCode, outCode; // input and output codes 1102 int inCode, outCode; // input and output codes
994 int nextCode; // next code index 1103 int nextCode; // next code index
995 GBool eof; // set when EOF is reached 1104 GBool eof; // set when EOF is reached
996 GBool clear; // set if table needs to be cleared 1105 GBool clear; // set if table needs to be cleared
997 GBool first; // indicates first code word after clear 1106 GBool first; // indicates first code word after clear
998 int i, j; 1107 int i, j;
999 1108
1000 str->reset(); 1109 str->reset();
1001 1110
1002 // magic number 1111 // magic number
1003 fputc(0x1f, f); 1112 fputc(0x1f, f);
1004 fputc(0x9d, f); 1113 fputc(0x9d, f);
1005 1114
1006 // max code length, block mode flag 1115 // max code length, block mode flag
1007 fputc(0x8c, f); 1116 fputc(0x8c, f);
1008 1117
1009 // init input side 1118 // init input side
1010 inCodeBits = 9; 1119 inCodeBits = 9;
1011 inputBuf = 0; 1120 inputBuf = 0;
1012 inputBits = 0; 1121 inputBits = 0;
1013 eof = gFalse; 1122 eof = gFalse;
1014 1123
1015 // init output side 1124 // init output side
1016 outCodeBits = 9; 1125 outCodeBits = 9;
1017 1126
1018 // clear table 1127 // clear table
1019 first = gTrue; 1128 first = gTrue;
1020 nextCode = 258; 1129 nextCode = 258;
1021 1130
1022 clear = gFalse; 1131 clear = gFalse;
1023 do { 1132 do {
1024 for (i = 0; i < 8; ++i) { 1133 for (i = 0; i < 8; ++i) {
1025 // check for table overflow 1134 // check for table overflow
1026 if (nextCode + early > 0x1001) { 1135 if (nextCode + early > 0x1001) {
1027 inCode = 256; 1136 inCode = 256;
1028 1137
1029 // read input code 1138 // read input code
1030 } else { 1139 } else {
1031 do { 1140 do {
1032 inCode = getCode(); 1141 inCode = getCode();
1033 if (inCode == EOF) { 1142 if (inCode == EOF) {
1034 eof = gTrue; 1143 eof = gTrue;
1035 inCode = 0; 1144 inCode = 0;
1036 } 1145 }
1037 } while (first && inCode == 256); 1146 } while (first && inCode == 256);
1038 } 1147 }
1039 1148
1040 // compute output code 1149 // compute output code
1041 if (inCode < 256) { 1150 if (inCode < 256) {
1042 outCode = inCode; 1151 outCode = inCode;
1043 } else if (inCode == 256) { 1152 } else if (inCode == 256) {
1044 outCode = 256; 1153 outCode = 256;
1045 clear = gTrue; 1154 clear = gTrue;
1046 } else if (inCode == 257) { 1155 } else if (inCode == 257) {
1047 outCode = 0; 1156 outCode = 0;
1048 eof = gTrue; 1157 eof = gTrue;
1049 } else { 1158 } else {
1050 outCode = inCode - 1; 1159 outCode = inCode - 1;
1051 } 1160 }
1052 outBuf[i] = outCode; 1161 outBuf[i] = outCode;
1053 1162
1054 // next code index 1163 // next code index
1055 if (first) 1164 if (first)
1056 first = gFalse; 1165 first = gFalse;
1057 else 1166 else
1058 ++nextCode; 1167 ++nextCode;
1059 1168
1060 // check input code size 1169 // check input code size
1061 if (nextCode + early == 0x200) 1170 if (nextCode + early == 0x200)
1062 inCodeBits = 10; 1171 inCodeBits = 10;
1063 else if (nextCode + early == 0x400) { 1172 else if (nextCode + early == 0x400) {
1064 inCodeBits = 11; 1173 inCodeBits = 11;
1065 } else if (nextCode + early == 0x800) { 1174 } else if (nextCode + early == 0x800) {
1066 inCodeBits = 12; 1175 inCodeBits = 12;
1067 } 1176 }
1068 1177
1069 // check for eof/clear 1178 // check for eof/clear
1070 if (eof) 1179 if (eof)
1071 break; 1180 break;
1072 if (clear) { 1181 if (clear) {
1073 i = 8; 1182 i = 8;
1074 break; 1183 break;
1075 } 1184 }
1076 } 1185 }
1077 1186
1078 // write output block 1187 // write output block
1079 outData = 0; 1188 outData = 0;
1080 outBits = 0; 1189 outBits = 0;
1081 j = 0; 1190 j = 0;
1082 while (j < i || outBits > 0) { 1191 while (j < i || outBits > 0) {
1083 if (outBits < 8 && j < i) { 1192 if (outBits < 8 && j < i) {
1084 outData = outData | (outBuf[j++] << outBits); 1193 outData = outData | (outBuf[j++] << outBits);
1085 outBits += outCodeBits; 1194 outBits += outCodeBits;
1086 } 1195 }
1087 fputc(outData & 0xff, f); 1196 fputc(outData & 0xff, f);
1088 outData >>= 8; 1197 outData >>= 8;
1089 outBits -= 8; 1198 outBits -= 8;
1090 } 1199 }
1091 1200
1092 // check output code size 1201 // check output code size
1093 if (nextCode - 1 == 512 || 1202 if (nextCode - 1 == 512 ||
1094 nextCode - 1 == 1024 || 1203 nextCode - 1 == 1024 ||
1095 nextCode - 1 == 2048 || 1204 nextCode - 1 == 2048 ||
1096 nextCode - 1 == 4096) { 1205 nextCode - 1 == 4096) {
1097 outCodeBits = inCodeBits; 1206 outCodeBits = inCodeBits;
1098 } 1207 }
1099 1208
1100 // clear table if necessary 1209 // clear table if necessary
1101 if (clear) { 1210 if (clear) {
1102 inCodeBits = 9; 1211 inCodeBits = 9;
1103 outCodeBits = 9; 1212 outCodeBits = 9;
1104 first = gTrue; 1213 first = gTrue;
1105 nextCode = 258; 1214 nextCode = 258;
1106 clear = gFalse; 1215 clear = gFalse;
1107 } 1216 }
1108 } while (!eof); 1217 } while (!eof);
1109} 1218}
1110 1219
1111int LZWStream::getCode() { 1220int LZWStream::getCode() {
1112 int c; 1221 int c;
1113 int code; 1222 int code;
1114 1223
1115 while (inputBits < inCodeBits) { 1224 while (inputBits < inCodeBits) {
1116 if ((c = str->getChar()) == EOF) 1225 if ((c = str->getChar()) == EOF)
1117 return EOF; 1226 return EOF;
1118 inputBuf = (inputBuf << 8) | (c & 0xff); 1227 inputBuf = (inputBuf << 8) | (c & 0xff);
1119 inputBits += 8; 1228 inputBits += 8;
1120 } 1229 }
1121 code = (inputBuf >> (inputBits - inCodeBits)) & ((1 << inCodeBits) - 1); 1230 code = (inputBuf >> (inputBits - inCodeBits)) & ((1 << inCodeBits) - 1);
1122 inputBits -= inCodeBits; 1231 inputBits -= inCodeBits;
1123 return code; 1232 return code;
1124} 1233}
1125 1234
1126GBool LZWStream::fillBuf() { 1235GBool LZWStream::fillBuf() {
1127 int n; 1236 int n;
1128 1237
1129 if (!zPipe) 1238 if (!zPipe)
1130 return gFalse; 1239 return gFalse;
1131 if ((n = fread(buf, 1, 256, zPipe)) < 256) { 1240 if ((n = fread(buf, 1, 256, zPipe)) < 256) {
1132#ifdef HAVE_POPEN 1241#ifdef HAVE_POPEN
1133 pclose(zPipe); 1242 pclose(zPipe);
1134#else 1243#else
1135 fclose(zPipe); 1244 fclose(zPipe);
1136#endif 1245#endif
1137 zPipe = NULL; 1246 zPipe = NULL;
1138 unlink(zName->getCString()); 1247 unlink(zName->getCString());
1139 delete zName; 1248 delete zName;
1140 } 1249 }
1141 bufPtr = buf; 1250 bufPtr = buf;
1142 bufEnd = buf + n; 1251 bufEnd = buf + n;
1143 return n > 0; 1252 return n > 0;
1144} 1253}
1145 1254
1146GString *LZWStream::getPSFilter(char *indent) { 1255GString *LZWStream::getPSFilter(char *indent) {
1147 GString *s; 1256 GString *s;
1148 1257
1149 if (pred) { 1258 if (pred) {
1150 return NULL; 1259 return NULL;
1151 } 1260 }
1152 if (!(s = str->getPSFilter(indent))) { 1261 if (!(s = str->getPSFilter(indent))) {
1153 return NULL; 1262 return NULL;
1154 } 1263 }
1155 s->append(indent)->append("/LZWDecode filter\n"); 1264 s->append(indent)->append("/LZWDecode filter\n");
1156 return s; 1265 return s;
1157} 1266}
1158 1267
@@ -3098,370 +3207,420 @@ GBool FlateStream::readDynamicCodes() {
3098 codeLenCodeTab.codes = codeLenCodes; 3207 codeLenCodeTab.codes = codeLenCodes;
3099 for (i = 0; i < flateMaxCodeLenCodes; ++i) 3208 for (i = 0; i < flateMaxCodeLenCodes; ++i)
3100 codeLenCodes[i].len = 0; 3209 codeLenCodes[i].len = 0;
3101 for (i = 0; i < numCodeLenCodes; ++i) { 3210 for (i = 0; i < numCodeLenCodes; ++i) {
3102 if ((codeLenCodes[codeLenCodeMap[i]].len = getCodeWord(3)) == -1) 3211 if ((codeLenCodes[codeLenCodeMap[i]].len = getCodeWord(3)) == -1)
3103 goto err; 3212 goto err;
3104 } 3213 }
3105 compHuffmanCodes(&codeLenCodeTab, flateMaxCodeLenCodes); 3214 compHuffmanCodes(&codeLenCodeTab, flateMaxCodeLenCodes);
3106 3215
3107 // set up code arrays 3216 // set up code arrays
3108 litCodeTab.codes = allCodes; 3217 litCodeTab.codes = allCodes;
3109 distCodeTab.codes = allCodes + numLitCodes; 3218 distCodeTab.codes = allCodes + numLitCodes;
3110 3219
3111 // read literal and distance code tables 3220 // read literal and distance code tables
3112 len = 0; 3221 len = 0;
3113 repeat = 0; 3222 repeat = 0;
3114 i = 0; 3223 i = 0;
3115 while (i < numLitCodes + numDistCodes) { 3224 while (i < numLitCodes + numDistCodes) {
3116 if ((code = getHuffmanCodeWord(&codeLenCodeTab)) == EOF) 3225 if ((code = getHuffmanCodeWord(&codeLenCodeTab)) == EOF)
3117 goto err; 3226 goto err;
3118 if (code == 16) { 3227 if (code == 16) {
3119 if ((repeat = getCodeWord(2)) == EOF) 3228 if ((repeat = getCodeWord(2)) == EOF)
3120 goto err; 3229 goto err;
3121 for (repeat += 3; repeat > 0; --repeat) 3230 for (repeat += 3; repeat > 0; --repeat)
3122 allCodes[i++].len = len; 3231 allCodes[i++].len = len;
3123 } else if (code == 17) { 3232 } else if (code == 17) {
3124 if ((repeat = getCodeWord(3)) == EOF) 3233 if ((repeat = getCodeWord(3)) == EOF)
3125 goto err; 3234 goto err;
3126 len = 0; 3235 len = 0;
3127 for (repeat += 3; repeat > 0; --repeat) 3236 for (repeat += 3; repeat > 0; --repeat)
3128 allCodes[i++].len = 0; 3237 allCodes[i++].len = 0;
3129 } else if (code == 18) { 3238 } else if (code == 18) {
3130 if ((repeat = getCodeWord(7)) == EOF) 3239 if ((repeat = getCodeWord(7)) == EOF)
3131 goto err; 3240 goto err;
3132 len = 0; 3241 len = 0;
3133 for (repeat += 11; repeat > 0; --repeat) 3242 for (repeat += 11; repeat > 0; --repeat)
3134 allCodes[i++].len = 0; 3243 allCodes[i++].len = 0;
3135 } else { 3244 } else {
3136 allCodes[i++].len = len = code; 3245 allCodes[i++].len = len = code;
3137 } 3246 }
3138 } 3247 }
3139 compHuffmanCodes(&litCodeTab, numLitCodes); 3248 compHuffmanCodes(&litCodeTab, numLitCodes);
3140 compHuffmanCodes(&distCodeTab, numDistCodes); 3249 compHuffmanCodes(&distCodeTab, numDistCodes);
3141 3250
3142 return gTrue; 3251 return gTrue;
3143 3252
3144err: 3253err:
3145 error(getPos(), "Bad dynamic code table in flate stream"); 3254 error(getPos(), "Bad dynamic code table in flate stream");
3146 return gFalse; 3255 return gFalse;
3147} 3256}
3148 3257
3149// On entry, the <tab->codes> array contains the lengths of each code, 3258// On entry, the <tab->codes> array contains the lengths of each code,
3150// stored in code value order. This function computes the code words. 3259// stored in code value order. This function computes the code words.
3151// The result is sorted in order of (1) code length and (2) code word. 3260// The result is sorted in order of (1) code length and (2) code word.
3152// The length values are no longer valid. The <tab->start> array is 3261// The length values are no longer valid. The <tab->start> array is
3153// filled with the indexes of the first code of each length. 3262// filled with the indexes of the first code of each length.
3154void FlateStream::compHuffmanCodes(FlateHuffmanTab *tab, int n) { 3263void FlateStream::compHuffmanCodes(FlateHuffmanTab *tab, int n) {
3155 int numLengths[flateMaxHuffman+1]; 3264 int numLengths[flateMaxHuffman+1];
3156 int nextCode[flateMaxHuffman+1]; 3265 int nextCode[flateMaxHuffman+1];
3157 int nextIndex[flateMaxHuffman+2]; 3266 int nextIndex[flateMaxHuffman+2];
3158 int code; 3267 int code;
3159 int i, j; 3268 int i, j;
3160 3269
3161 // count number of codes for each code length 3270 // count number of codes for each code length
3162 for (i = 0; i <= flateMaxHuffman; ++i) 3271 for (i = 0; i <= flateMaxHuffman; ++i)
3163 numLengths[i] = 0; 3272 numLengths[i] = 0;
3164 for (i = 0; i < n; ++i) 3273 for (i = 0; i < n; ++i)
3165 ++numLengths[tab->codes[i].len]; 3274 ++numLengths[tab->codes[i].len];
3166 3275
3167 // compute first index for each length 3276 // compute first index for each length
3168 tab->start[0] = nextIndex[0] = 0; 3277 tab->start[0] = nextIndex[0] = 0;
3169 for (i = 1; i <= flateMaxHuffman + 1; ++i) 3278 for (i = 1; i <= flateMaxHuffman + 1; ++i)
3170 tab->start[i] = nextIndex[i] = tab->start[i-1] + numLengths[i-1]; 3279 tab->start[i] = nextIndex[i] = tab->start[i-1] + numLengths[i-1];
3171 3280
3172 // compute first code for each length 3281 // compute first code for each length
3173 code = 0; 3282 code = 0;
3174 numLengths[0] = 0; 3283 numLengths[0] = 0;
3175 for (i = 1; i <= flateMaxHuffman; ++i) { 3284 for (i = 1; i <= flateMaxHuffman; ++i) {
3176 code = (code + numLengths[i-1]) << 1; 3285 code = (code + numLengths[i-1]) << 1;
3177 nextCode[i] = code; 3286 nextCode[i] = code;
3178 } 3287 }
3179 3288
3180 // compute the codes -- this permutes the codes array from value 3289 // compute the codes -- this permutes the codes array from value
3181 // order to length/code order 3290 // order to length/code order
3182 for (i = 0; i < n; ++i) { 3291 for (i = 0; i < n; ++i) {
3183 j = nextIndex[tab->codes[i].len]++; 3292 j = nextIndex[tab->codes[i].len]++;
3184 if (tab->codes[i].len == 0) 3293 if (tab->codes[i].len == 0)
3185 tab->codes[j].code = 0; 3294 tab->codes[j].code = 0;
3186 else 3295 else
3187 tab->codes[j].code = nextCode[tab->codes[i].len]++; 3296 tab->codes[j].code = nextCode[tab->codes[i].len]++;
3188 tab->codes[j].val = i; 3297 tab->codes[j].val = i;
3189 } 3298 }
3190} 3299}
3191 3300
3192int FlateStream::getHuffmanCodeWord(FlateHuffmanTab *tab) { 3301int FlateStream::getHuffmanCodeWord(FlateHuffmanTab *tab) {
3193 int len; 3302 int len;
3194 int code; 3303 int code;
3195 int c; 3304 int c;
3196 int i, j; 3305 int i, j;
3197 3306
3198 code = 0; 3307 code = 0;
3199 for (len = 1; len <= flateMaxHuffman; ++len) { 3308 for (len = 1; len <= flateMaxHuffman; ++len) {
3200 3309
3201 // add a bit to the code 3310 // add a bit to the code
3202 if (codeSize == 0) { 3311 if (codeSize == 0) {
3203 if ((c = str->getChar()) == EOF) 3312 if ((c = str->getChar()) == EOF)
3204 return EOF; 3313 return EOF;
3205 codeBuf = c & 0xff; 3314 codeBuf = c & 0xff;
3206 codeSize = 8; 3315 codeSize = 8;
3207 } 3316 }
3208 code = (code << 1) | (codeBuf & 1); 3317 code = (code << 1) | (codeBuf & 1);
3209 codeBuf >>= 1; 3318 codeBuf >>= 1;
3210 --codeSize; 3319 --codeSize;
3211 3320
3212 // look for code 3321 // look for code
3213 i = tab->start[len]; 3322 i = tab->start[len];
3214 j = tab->start[len + 1]; 3323 j = tab->start[len + 1];
3215 if (i < j && code >= tab->codes[i].code && code <= tab->codes[j-1].code) { 3324 if (i < j && code >= tab->codes[i].code && code <= tab->codes[j-1].code) {
3216 i += code - tab->codes[i].code; 3325 i += code - tab->codes[i].code;
3217 return tab->codes[i].val; 3326 return tab->codes[i].val;
3218 } 3327 }
3219 } 3328 }
3220 3329
3221 // not found 3330 // not found
3222 error(getPos(), "Bad code (%04x) in flate stream", code); 3331 error(getPos(), "Bad code (%04x) in flate stream", code);
3223 return EOF; 3332 return EOF;
3224} 3333}
3225 3334
3226int FlateStream::getCodeWord(int bits) { 3335int FlateStream::getCodeWord(int bits) {
3227 int c; 3336 int c;
3228 3337
3229 while (codeSize < bits) { 3338 while (codeSize < bits) {
3230 if ((c = str->getChar()) == EOF) 3339 if ((c = str->getChar()) == EOF)
3231 return EOF; 3340 return EOF;
3232 codeBuf |= (c & 0xff) << codeSize; 3341 codeBuf |= (c & 0xff) << codeSize;
3233 codeSize += 8; 3342 codeSize += 8;
3234 } 3343 }
3235 c = codeBuf & ((1 << bits) - 1); 3344 c = codeBuf & ((1 << bits) - 1);
3236 codeBuf >>= bits; 3345 codeBuf >>= bits;
3237 codeSize -= bits; 3346 codeSize -= bits;
3238 return c; 3347 return c;
3239} 3348}
3240 3349
3241//------------------------------------------------------------------------ 3350//------------------------------------------------------------------------
3242// EOFStream 3351// EOFStream
3243//------------------------------------------------------------------------ 3352//------------------------------------------------------------------------
3244 3353
3245EOFStream::EOFStream(Stream *strA): 3354EOFStream::EOFStream(Stream *strA):
3246 FilterStream(strA) { 3355 FilterStream(strA) {
3247} 3356}
3248 3357
3249EOFStream::~EOFStream() { 3358EOFStream::~EOFStream() {
3250 delete str; 3359 delete str;
3251} 3360}
3252 3361
3253//------------------------------------------------------------------------ 3362//------------------------------------------------------------------------
3254// FixedLengthEncoder 3363// FixedLengthEncoder
3255//------------------------------------------------------------------------ 3364//------------------------------------------------------------------------
3256 3365
3257FixedLengthEncoder::FixedLengthEncoder(Stream *strA, int lengthA): 3366FixedLengthEncoder::FixedLengthEncoder(Stream *strA, int lengthA):
3258 FilterStream(strA) { 3367 FilterStream(strA) {
3259 length = lengthA; 3368 length = lengthA;
3260 count = 0; 3369 count = 0;
3261} 3370}
3262 3371
3263FixedLengthEncoder::~FixedLengthEncoder() { 3372FixedLengthEncoder::~FixedLengthEncoder() {
3264 if (str->isEncoder()) 3373 if (str->isEncoder())
3265 delete str; 3374 delete str;
3266} 3375}
3267 3376
3268void FixedLengthEncoder::reset() { 3377void FixedLengthEncoder::reset() {
3269 str->reset(); 3378 str->reset();
3270 count = 0; 3379 count = 0;
3271} 3380}
3272 3381
3273void FixedLengthEncoder::close() { 3382void FixedLengthEncoder::close() {
3274} 3383}
3275 3384
3276int FixedLengthEncoder::getChar() { 3385int FixedLengthEncoder::getChar() {
3277 if (length >= 0 && count >= length) 3386 if (length >= 0 && count >= length)
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())
3302 delete str; 3461 delete str;
3303} 3462}
3304 3463
3305void ASCII85Encoder::reset() { 3464void ASCII85Encoder::reset() {
3306 str->reset(); 3465 str->reset();
3307 bufPtr = bufEnd = buf; 3466 bufPtr = bufEnd = buf;
3308 lineLen = 0; 3467 lineLen = 0;
3309 eof = gFalse; 3468 eof = gFalse;
3310} 3469}
3311 3470
3312void ASCII85Encoder::close() { 3471void ASCII85Encoder::close() {
3313} 3472}
3314 3473
3315GBool ASCII85Encoder::fillBuf() { 3474GBool ASCII85Encoder::fillBuf() {
3316 Gulong t; 3475 Gulong t;
3317 char buf1[5]; 3476 char buf1[5];
3318 int c; 3477 int c;
3319 int n, i; 3478 int n, i;
3320 3479
3321 if (eof) 3480 if (eof)
3322 return gFalse; 3481 return gFalse;
3323 t = 0; 3482 t = 0;
3324 for (n = 0; n < 4; ++n) { 3483 for (n = 0; n < 4; ++n) {
3325 if ((c = str->getChar()) == EOF) 3484 if ((c = str->getChar()) == EOF)
3326 break; 3485 break;
3327 t = (t << 8) + c; 3486 t = (t << 8) + c;
3328 } 3487 }
3329 bufPtr = bufEnd = buf; 3488 bufPtr = bufEnd = buf;
3330 if (n > 0) { 3489 if (n > 0) {
3331 if (n == 4 && t == 0) { 3490 if (n == 4 && t == 0) {
3332 *bufEnd++ = 'z'; 3491 *bufEnd++ = 'z';
3333 if (++lineLen == 65) { 3492 if (++lineLen == 65) {
3334 *bufEnd++ = '\n'; 3493 *bufEnd++ = '\n';
3335 lineLen = 0; 3494 lineLen = 0;
3336 } 3495 }
3337 } else { 3496 } else {
3338 if (n < 4) 3497 if (n < 4)
3339 t <<= 8 * (4 - n); 3498 t <<= 8 * (4 - n);
3340 for (i = 4; i >= 0; --i) { 3499 for (i = 4; i >= 0; --i) {
3341 buf1[i] = (char)(t % 85 + 0x21); 3500 buf1[i] = (char)(t % 85 + 0x21);
3342 t /= 85; 3501 t /= 85;
3343 } 3502 }
3344 for (i = 0; i <= n; ++i) { 3503 for (i = 0; i <= n; ++i) {
3345 *bufEnd++ = buf1[i]; 3504 *bufEnd++ = buf1[i];
3346 if (++lineLen == 65) { 3505 if (++lineLen == 65) {
3347 *bufEnd++ = '\n'; 3506 *bufEnd++ = '\n';
3348 lineLen = 0; 3507 lineLen = 0;
3349 } 3508 }
3350 } 3509 }
3351 } 3510 }
3352 } 3511 }
3353 if (n < 4) { 3512 if (n < 4) {
3354 *bufEnd++ = '~'; 3513 *bufEnd++ = '~';
3355 *bufEnd++ = '>'; 3514 *bufEnd++ = '>';
3356 eof = gTrue; 3515 eof = gTrue;
3357 } 3516 }
3358 return bufPtr < bufEnd; 3517 return bufPtr < bufEnd;
3359} 3518}
3360 3519
3361//------------------------------------------------------------------------ 3520//------------------------------------------------------------------------
3362// RunLengthEncoder 3521// RunLengthEncoder
3363//------------------------------------------------------------------------ 3522//------------------------------------------------------------------------
3364 3523
3365RunLengthEncoder::RunLengthEncoder(Stream *strA): 3524RunLengthEncoder::RunLengthEncoder(Stream *strA):
3366 FilterStream(strA) { 3525 FilterStream(strA) {
3367 bufPtr = bufEnd = nextEnd = buf; 3526 bufPtr = bufEnd = nextEnd = buf;
3368 eof = gFalse; 3527 eof = gFalse;
3369} 3528}
3370 3529
3371RunLengthEncoder::~RunLengthEncoder() { 3530RunLengthEncoder::~RunLengthEncoder() {
3372 if (str->isEncoder()) 3531 if (str->isEncoder())
3373 delete str; 3532 delete str;
3374} 3533}
3375 3534
3376void RunLengthEncoder::reset() { 3535void RunLengthEncoder::reset() {
3377 str->reset(); 3536 str->reset();
3378 bufPtr = bufEnd = nextEnd = buf; 3537 bufPtr = bufEnd = nextEnd = buf;
3379 eof = gFalse; 3538 eof = gFalse;
3380} 3539}
3381 3540
3382void RunLengthEncoder::close() { 3541void RunLengthEncoder::close() {
3383} 3542}
3384 3543
3385// 3544//
3386// When fillBuf finishes, buf[] looks like this: 3545// When fillBuf finishes, buf[] looks like this:
3387// +-----+--------------+-----------------+-- 3546// +-----+--------------+-----------------+--
3388// + tag | ... data ... | next 0, 1, or 2 | 3547// + tag | ... data ... | next 0, 1, or 2 |
3389// +-----+--------------+-----------------+-- 3548// +-----+--------------+-----------------+--
3390// ^ ^ ^ 3549// ^ ^ ^
3391// bufPtr bufEnd nextEnd 3550// bufPtr bufEnd nextEnd
3392// 3551//
3393GBool RunLengthEncoder::fillBuf() { 3552GBool RunLengthEncoder::fillBuf() {
3394 int c, c1, c2; 3553 int c, c1, c2;
3395 int n; 3554 int n;
3396 3555
3397 // already hit EOF? 3556 // already hit EOF?
3398 if (eof) 3557 if (eof)
3399 return gFalse; 3558 return gFalse;
3400 3559
3401 // grab two bytes 3560 // grab two bytes
3402 if (nextEnd < bufEnd + 1) { 3561 if (nextEnd < bufEnd + 1) {
3403 if ((c1 = str->getChar()) == EOF) { 3562 if ((c1 = str->getChar()) == EOF) {
3404 eof = gTrue; 3563 eof = gTrue;
3405 return gFalse; 3564 return gFalse;
3406 } 3565 }
3407 } else { 3566 } else {
3408 c1 = bufEnd[0] & 0xff; 3567 c1 = bufEnd[0] & 0xff;
3409 } 3568 }
3410 if (nextEnd < bufEnd + 2) { 3569 if (nextEnd < bufEnd + 2) {
3411 if ((c2 = str->getChar()) == EOF) { 3570 if ((c2 = str->getChar()) == EOF) {
3412 eof = gTrue; 3571 eof = gTrue;
3413 buf[0] = 0; 3572 buf[0] = 0;
3414 buf[1] = c1; 3573 buf[1] = c1;
3415 bufPtr = buf; 3574 bufPtr = buf;
3416 bufEnd = &buf[2]; 3575 bufEnd = &buf[2];
3417 return gTrue; 3576 return gTrue;
3418 } 3577 }
3419 } else { 3578 } else {
3420 c2 = bufEnd[1] & 0xff; 3579 c2 = bufEnd[1] & 0xff;
3421 } 3580 }
3422 3581
3423 // check for repeat 3582 // check for repeat
3424 c = 0; // make gcc happy 3583 c = 0; // make gcc happy
3425 if (c1 == c2) { 3584 if (c1 == c2) {
3426 n = 2; 3585 n = 2;
3427 while (n < 128 && (c = str->getChar()) == c1) 3586 while (n < 128 && (c = str->getChar()) == c1)
3428 ++n; 3587 ++n;
3429 buf[0] = (char)(257 - n); 3588 buf[0] = (char)(257 - n);
3430 buf[1] = c1; 3589 buf[1] = c1;
3431 bufEnd = &buf[2]; 3590 bufEnd = &buf[2];
3432 if (c == EOF) { 3591 if (c == EOF) {
3433 eof = gTrue; 3592 eof = gTrue;
3434 } else if (n < 128) { 3593 } else if (n < 128) {
3435 buf[2] = c; 3594 buf[2] = c;
3436 nextEnd = &buf[3]; 3595 nextEnd = &buf[3];
3437 } else { 3596 } else {
3438 nextEnd = bufEnd; 3597 nextEnd = bufEnd;
3439 } 3598 }
3440 3599
3441 // get up to 128 chars 3600 // get up to 128 chars
3442 } else { 3601 } else {
3443 buf[1] = c1; 3602 buf[1] = c1;
3444 buf[2] = c2; 3603 buf[2] = c2;
3445 n = 2; 3604 n = 2;
3446 while (n < 128) { 3605 while (n < 128) {
3447 if ((c = str->getChar()) == EOF) { 3606 if ((c = str->getChar()) == EOF) {
3448 eof = gTrue; 3607 eof = gTrue;
3449 break; 3608 break;
3450 } 3609 }
3451 ++n; 3610 ++n;
3452 buf[n] = c; 3611 buf[n] = c;
3453 if (buf[n] == buf[n-1]) 3612 if (buf[n] == buf[n-1])
3454 break; 3613 break;
3455 } 3614 }
3456 if (buf[n] == buf[n-1]) { 3615 if (buf[n] == buf[n-1]) {
3457 buf[0] = (char)(n-2-1); 3616 buf[0] = (char)(n-2-1);
3458 bufEnd = &buf[n-1]; 3617 bufEnd = &buf[n-1];
3459 nextEnd = &buf[n+1]; 3618 nextEnd = &buf[n+1];
3460 } else { 3619 } else {
3461 buf[0] = (char)(n-1); 3620 buf[0] = (char)(n-1);
3462 bufEnd = nextEnd = &buf[n+1]; 3621 bufEnd = nextEnd = &buf[n+1];
3463 } 3622 }
3464 } 3623 }
3465 bufPtr = buf; 3624 bufPtr = buf;
3466 return gTrue; 3625 return gTrue;
3467} 3626}
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,723 +1,800 @@
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"
18#include "Object.h" 18#include "Object.h"
19 19
20#ifndef NO_DECRYPTION 20#ifndef NO_DECRYPTION
21class Decrypt; 21class Decrypt;
22#endif 22#endif
23class BaseStream; 23class BaseStream;
24 24
25//------------------------------------------------------------------------ 25//------------------------------------------------------------------------
26 26
27enum StreamKind { 27enum StreamKind {
28 strFile, 28 strFile,
29 strASCIIHex, 29 strASCIIHex,
30 strASCII85, 30 strASCII85,
31 strLZW, 31 strLZW,
32 strRunLength, 32 strRunLength,
33 strCCITTFax, 33 strCCITTFax,
34 strDCT, 34 strDCT,
35 strFlate, 35 strFlate,
36 strWeird // internal-use stream types 36 strWeird // internal-use stream types
37}; 37};
38 38
39//------------------------------------------------------------------------ 39//------------------------------------------------------------------------
40// Stream (base class) 40// Stream (base class)
41//------------------------------------------------------------------------ 41//------------------------------------------------------------------------
42 42
43class Stream { 43class Stream {
44public: 44public:
45 45
46 // Constructor. 46 // Constructor.
47 Stream(); 47 Stream();
48 48
49 // Destructor. 49 // Destructor.
50 virtual ~Stream(); 50 virtual ~Stream();
51 51
52 // Reference counting. 52 // Reference counting.
53 int incRef() { return ++ref; } 53 int incRef() { return ++ref; }
54 int decRef() { return --ref; } 54 int decRef() { return --ref; }
55 55
56 // Get kind of stream. 56 // Get kind of stream.
57 virtual StreamKind getKind() = 0; 57 virtual StreamKind getKind() = 0;
58 58
59 // Reset stream to beginning. 59 // Reset stream to beginning.
60 virtual void reset() = 0; 60 virtual void reset() = 0;
61 61
62 // Close down the stream. 62 // Close down the stream.
63 virtual void close(); 63 virtual void close();
64 64
65 // Get next char from stream. 65 // Get next char from stream.
66 virtual int getChar() = 0; 66 virtual int getChar() = 0;
67 67
68 // Peek at next char in stream. 68 // Peek at next char in stream.
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;
95 97
96 // Is this an encoding filter? 98 // Is this an encoding filter?
97 virtual GBool isEncoder() { return gFalse; } 99 virtual GBool isEncoder() { return gFalse; }
98 100
99 // Add filters to this stream according to the parameters in <dict>. 101 // Add filters to this stream according to the parameters in <dict>.
100 // Returns the new stream. 102 // Returns the new stream.
101 Stream *addFilters(Object *dict); 103 Stream *addFilters(Object *dict);
102 104
103private: 105private:
104 106
105 Stream *makeFilter(char *name, Stream *str, Object *params); 107 Stream *makeFilter(char *name, Stream *str, Object *params);
106 108
107 int ref; // reference count 109 int ref; // reference count
108}; 110};
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};
145 149
146//------------------------------------------------------------------------ 150//------------------------------------------------------------------------
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
172class ImageStream { 176class ImageStream {
173public: 177public:
174 178
175 // Create an image stream object for an image with the specified 179 // Create an image stream object for an image with the specified
176 // parameters. Note that these are the actual image parameters, 180 // parameters. Note that these are the actual image parameters,
177 // which may be different from the predictor parameters. 181 // which may be different from the predictor parameters.
178 ImageStream(Stream *strA, int widthA, int nCompsA, int nBitsA); 182 ImageStream(Stream *strA, int widthA, int nCompsA, int nBitsA);
179 183
180 ~ImageStream(); 184 ~ImageStream();
181 185
182 // Reset the stream. 186 // Reset the stream.
183 void reset(); 187 void reset();
184 188
185 // Gets the next pixel from the stream. <pix> should be able to hold 189 // Gets the next pixel from the stream. <pix> should be able to hold
186 // at least nComps elements. Returns false at end of file. 190 // at least nComps elements. Returns false at end of file.
187 GBool getPixel(Guchar *pix); 191 GBool getPixel(Guchar *pix);
188 192
189 // Skip an entire line from the image. 193 // Skip an entire line from the image.
190 void skipLine(); 194 void skipLine();
191 195
192private: 196private:
193 197
194 Stream *str; // base stream 198 Stream *str; // base stream
195 int width; // pixels per line 199 int width; // pixels per line
196 int nComps; // components per pixel 200 int nComps; // components per pixel
197 int nBits; // bits per component 201 int nBits; // bits per component
198 int nVals; // components per line 202 int nVals; // components per line
199 Guchar *imgLine; // line buffer 203 Guchar *imgLine; // line buffer
200 int imgIdx; // current index in imgLine 204 int imgIdx; // current index in imgLine
201}; 205};
202 206
203//------------------------------------------------------------------------ 207//------------------------------------------------------------------------
204// StreamPredictor 208// StreamPredictor
205//------------------------------------------------------------------------ 209//------------------------------------------------------------------------
206 210
207class StreamPredictor { 211class StreamPredictor {
208public: 212public:
209 213
210 // Create a predictor object. Note that the parameters are for the 214 // Create a predictor object. Note that the parameters are for the
211 // predictor, and may not match the actual image parameters. 215 // predictor, and may not match the actual image parameters.
212 StreamPredictor(Stream *strA, int predictorA, 216 StreamPredictor(Stream *strA, int predictorA,
213 int widthA, int nCompsA, int nBitsA); 217 int widthA, int nCompsA, int nBitsA);
214 218
215 ~StreamPredictor(); 219 ~StreamPredictor();
216 220
217 int lookChar(); 221 int lookChar();
218 int getChar(); 222 int getChar();
219 223
220private: 224private:
221 225
222 GBool getNextLine(); 226 GBool getNextLine();
223 227
224 Stream *str; // base stream 228 Stream *str; // base stream
225 int predictor; // predictor 229 int predictor; // predictor
226 int width; // pixels per line 230 int width; // pixels per line
227 int nComps; // components per pixel 231 int nComps; // components per pixel
228 int nBits; // bits per component 232 int nBits; // bits per component
229 int nVals; // components per line 233 int nVals; // components per line
230 int pixBytes; // bytes per pixel 234 int pixBytes; // bytes per pixel
231 int rowBytes; // bytes per line 235 int rowBytes; // bytes per line
232 Guchar *predLine; // line buffer 236 Guchar *predLine; // line buffer
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 {
311public: 357public:
312 358
313 ASCIIHexStream(Stream *strA); 359 ASCIIHexStream(Stream *strA);
314 virtual ~ASCIIHexStream(); 360 virtual ~ASCIIHexStream();
315 virtual StreamKind getKind() { return strASCIIHex; } 361 virtual StreamKind getKind() { return strASCIIHex; }
316 virtual void reset(); 362 virtual void reset();
317 virtual int getChar() 363 virtual int getChar()
318 { int c = lookChar(); buf = EOF; return c; } 364 { int c = lookChar(); buf = EOF; return c; }
319 virtual int lookChar(); 365 virtual int lookChar();
320 virtual GString *getPSFilter(char *indent); 366 virtual GString *getPSFilter(char *indent);
321 virtual GBool isBinary(GBool last = gTrue); 367 virtual GBool isBinary(GBool last = gTrue);
322 368
323private: 369private:
324 370
325 int buf; 371 int buf;
326 GBool eof; 372 GBool eof;
327}; 373};
328 374
329//------------------------------------------------------------------------ 375//------------------------------------------------------------------------
330// ASCII85Stream 376// ASCII85Stream
331//------------------------------------------------------------------------ 377//------------------------------------------------------------------------
332 378
333class ASCII85Stream: public FilterStream { 379class ASCII85Stream: public FilterStream {
334public: 380public:
335 381
336 ASCII85Stream(Stream *strA); 382 ASCII85Stream(Stream *strA);
337 virtual ~ASCII85Stream(); 383 virtual ~ASCII85Stream();
338 virtual StreamKind getKind() { return strASCII85; } 384 virtual StreamKind getKind() { return strASCII85; }
339 virtual void reset(); 385 virtual void reset();
340 virtual int getChar() 386 virtual int getChar()
341 { int ch = lookChar(); ++index; return ch; } 387 { int ch = lookChar(); ++index; return ch; }
342 virtual int lookChar(); 388 virtual int lookChar();
343 virtual GString *getPSFilter(char *indent); 389 virtual GString *getPSFilter(char *indent);
344 virtual GBool isBinary(GBool last = gTrue); 390 virtual GBool isBinary(GBool last = gTrue);
345 391
346private: 392private:
347 393
348 int c[5]; 394 int c[5];
349 int b[4]; 395 int b[4];
350 int index, n; 396 int index, n;
351 GBool eof; 397 GBool eof;
352}; 398};
353 399
354//------------------------------------------------------------------------ 400//------------------------------------------------------------------------
355// LZWStream 401// LZWStream
356//------------------------------------------------------------------------ 402//------------------------------------------------------------------------
357 403
358class LZWStream: public FilterStream { 404class LZWStream: public FilterStream {
359public: 405public:
360 406
361 LZWStream(Stream *strA, int predictor, int columns, int colors, 407 LZWStream(Stream *strA, int predictor, int columns, int colors,
362 int bits, int earlyA); 408 int bits, int earlyA);
363 virtual ~LZWStream(); 409 virtual ~LZWStream();
364 virtual StreamKind getKind() { return strLZW; } 410 virtual StreamKind getKind() { return strLZW; }
365 virtual void reset(); 411 virtual void reset();
366 virtual int getChar(); 412 virtual int getChar();
367 virtual int lookChar(); 413 virtual int lookChar();
368 virtual int getRawChar(); 414 virtual int getRawChar();
369 virtual GString *getPSFilter(char *indent); 415 virtual GString *getPSFilter(char *indent);
370 virtual GBool isBinary(GBool last = gTrue); 416 virtual GBool isBinary(GBool last = gTrue);
371 417
372private: 418private:
373 419
374 StreamPredictor *pred;// predictor 420 StreamPredictor *pred;// predictor
375 int early; // early parameter 421 int early; // early parameter
376 FILE *zPipe; // uncompress pipe 422 FILE *zPipe; // uncompress pipe
377 GString *zName; // .Z file name 423 GString *zName; // .Z file name
378 int inputBuf; // input buffer 424 int inputBuf; // input buffer
379 int inputBits; // number of bits in input buffer 425 int inputBits; // number of bits in input buffer
380 int inCodeBits; // size of input code 426 int inCodeBits; // size of input code
381 char buf[256]; // buffer 427 char buf[256]; // buffer
382 char *bufPtr; // next char to read 428 char *bufPtr; // next char to read
383 char *bufEnd; // end of buffer 429 char *bufEnd; // end of buffer
384 430
385 void dumpFile(FILE *f); 431 void dumpFile(FILE *f);
386 int getCode(); 432 int getCode();
387 GBool fillBuf(); 433 GBool fillBuf();
388}; 434};
389 435
390//------------------------------------------------------------------------ 436//------------------------------------------------------------------------
391// RunLengthStream 437// RunLengthStream
392//------------------------------------------------------------------------ 438//------------------------------------------------------------------------
393 439
394class RunLengthStream: public FilterStream { 440class RunLengthStream: public FilterStream {
395public: 441public:
396 442
397 RunLengthStream(Stream *strA); 443 RunLengthStream(Stream *strA);
398 virtual ~RunLengthStream(); 444 virtual ~RunLengthStream();
399 virtual StreamKind getKind() { return strRunLength; } 445 virtual StreamKind getKind() { return strRunLength; }
400 virtual void reset(); 446 virtual void reset();
401 virtual int getChar() 447 virtual int getChar()
402 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); } 448 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
403 virtual int lookChar() 449 virtual int lookChar()
404 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); } 450 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
405 virtual GString *getPSFilter(char *indent); 451 virtual GString *getPSFilter(char *indent);
406 virtual GBool isBinary(GBool last = gTrue); 452 virtual GBool isBinary(GBool last = gTrue);
407 453
408private: 454private:
409 455
410 char buf[128]; // buffer 456 char buf[128]; // buffer
411 char *bufPtr; // next char to read 457 char *bufPtr; // next char to read
412 char *bufEnd; // end of buffer 458 char *bufEnd; // end of buffer
413 GBool eof; 459 GBool eof;
414 460
415 GBool fillBuf(); 461 GBool fillBuf();
416}; 462};
417 463
418//------------------------------------------------------------------------ 464//------------------------------------------------------------------------
419// CCITTFaxStream 465// CCITTFaxStream
420//------------------------------------------------------------------------ 466//------------------------------------------------------------------------
421 467
422struct CCITTCodeTable; 468struct CCITTCodeTable;
423 469
424class CCITTFaxStream: public FilterStream { 470class CCITTFaxStream: public FilterStream {
425public: 471public:
426 472
427 CCITTFaxStream(Stream *strA, int encodingA, GBool endOfLineA, 473 CCITTFaxStream(Stream *strA, int encodingA, GBool endOfLineA,
428 GBool byteAlignA, int columnsA, int rowsA, 474 GBool byteAlignA, int columnsA, int rowsA,
429 GBool endOfBlockA, GBool blackA); 475 GBool endOfBlockA, GBool blackA);
430 virtual ~CCITTFaxStream(); 476 virtual ~CCITTFaxStream();
431 virtual StreamKind getKind() { return strCCITTFax; } 477 virtual StreamKind getKind() { return strCCITTFax; }
432 virtual void reset(); 478 virtual void reset();
433 virtual int getChar() 479 virtual int getChar()
434 { int c = lookChar(); buf = EOF; return c; } 480 { int c = lookChar(); buf = EOF; return c; }
435 virtual int lookChar(); 481 virtual int lookChar();
436 virtual GString *getPSFilter(char *indent); 482 virtual GString *getPSFilter(char *indent);
437 virtual GBool isBinary(GBool last = gTrue); 483 virtual GBool isBinary(GBool last = gTrue);
438 484
439private: 485private:
440 486
441 int encoding; // 'K' parameter 487 int encoding; // 'K' parameter
442 GBool endOfLine; // 'EndOfLine' parameter 488 GBool endOfLine; // 'EndOfLine' parameter
443 GBool byteAlign; // 'EncodedByteAlign' parameter 489 GBool byteAlign; // 'EncodedByteAlign' parameter
444 int columns; // 'Columns' parameter 490 int columns; // 'Columns' parameter
445 int rows; // 'Rows' parameter 491 int rows; // 'Rows' parameter
446 GBool endOfBlock; // 'EndOfBlock' parameter 492 GBool endOfBlock; // 'EndOfBlock' parameter
447 GBool black; // 'BlackIs1' parameter 493 GBool black; // 'BlackIs1' parameter
448 GBool eof; // true if at eof 494 GBool eof; // true if at eof
449 GBool nextLine2D; // true if next line uses 2D encoding 495 GBool nextLine2D; // true if next line uses 2D encoding
450 int row; // current row 496 int row; // current row
451 int inputBuf; // input buffer 497 int inputBuf; // input buffer
452 int inputBits; // number of bits in input buffer 498 int inputBits; // number of bits in input buffer
453 short *refLine; // reference line changing elements 499 short *refLine; // reference line changing elements
454 int b1; // index into refLine 500 int b1; // index into refLine
455 short *codingLine; // coding line changing elements 501 short *codingLine; // coding line changing elements
456 int a0; // index into codingLine 502 int a0; // index into codingLine
457 int outputBits; // remaining ouput bits 503 int outputBits; // remaining ouput bits
458 int buf; // character buffer 504 int buf; // character buffer
459 505
460 short getTwoDimCode(); 506 short getTwoDimCode();
461 short getWhiteCode(); 507 short getWhiteCode();
462 short getBlackCode(); 508 short getBlackCode();
463 short lookBits(int n); 509 short lookBits(int n);
464 void eatBits(int n) { inputBits -= n; } 510 void eatBits(int n) { inputBits -= n; }
465}; 511};
466 512
467//------------------------------------------------------------------------ 513//------------------------------------------------------------------------
468// DCTStream 514// DCTStream
469//------------------------------------------------------------------------ 515//------------------------------------------------------------------------
470 516
471// DCT component info 517// DCT component info
472struct DCTCompInfo { 518struct DCTCompInfo {
473 int id; // component ID 519 int id; // component ID
474 GBool inScan; // is this component in the current scan? 520 GBool inScan; // is this component in the current scan?
475 int hSample, vSample; // horiz/vert sampling resolutions 521 int hSample, vSample; // horiz/vert sampling resolutions
476 int quantTable; // quantization table number 522 int quantTable; // quantization table number
477 int dcHuffTable, acHuffTable;// Huffman table numbers 523 int dcHuffTable, acHuffTable;// Huffman table numbers
478 int prevDC; // DC coefficient accumulator 524 int prevDC; // DC coefficient accumulator
479}; 525};
480 526
481// DCT Huffman decoding table 527// DCT Huffman decoding table
482struct DCTHuffTable { 528struct DCTHuffTable {
483 Guchar firstSym[17]; // first symbol for this bit length 529 Guchar firstSym[17]; // first symbol for this bit length
484 Gushort firstCode[17];// first code for this bit length 530 Gushort firstCode[17];// first code for this bit length
485 Gushort numCodes[17]; // number of codes of this bit length 531 Gushort numCodes[17]; // number of codes of this bit length
486 Guchar sym[256]; // symbols 532 Guchar sym[256]; // symbols
487}; 533};
488 534
489class DCTStream: public FilterStream { 535class DCTStream: public FilterStream {
490public: 536public:
491 537
492 DCTStream(Stream *strA); 538 DCTStream(Stream *strA);
493 virtual ~DCTStream(); 539 virtual ~DCTStream();
494 virtual StreamKind getKind() { return strDCT; } 540 virtual StreamKind getKind() { return strDCT; }
495 virtual void reset(); 541 virtual void reset();
496 virtual int getChar(); 542 virtual int getChar();
497 virtual int lookChar(); 543 virtual int lookChar();
498 virtual GString *getPSFilter(char *indent); 544 virtual GString *getPSFilter(char *indent);
499 virtual GBool isBinary(GBool last = gTrue); 545 virtual GBool isBinary(GBool last = gTrue);
500 Stream *getRawStream() { return str; } 546 Stream *getRawStream() { return str; }
501 547
502private: 548private:
503 549
504 int width, height; // image size 550 int width, height; // image size
505 int mcuWidth, mcuHeight;// size of min coding unit, in data units 551 int mcuWidth, mcuHeight;// size of min coding unit, in data units
506 DCTCompInfo compInfo[4];// info for each component 552 DCTCompInfo compInfo[4];// info for each component
507 int numComps; // number of components in image 553 int numComps; // number of components in image
508 int colorXform; // need YCbCr-to-RGB transform? 554 int colorXform; // need YCbCr-to-RGB transform?
509 GBool gotAdobeMarker; // set if APP14 Adobe marker was present 555 GBool gotAdobeMarker; // set if APP14 Adobe marker was present
510 int restartInterval; // restart interval, in MCUs 556 int restartInterval; // restart interval, in MCUs
511 Guchar quantTables[4][64];// quantization tables 557 Guchar quantTables[4][64];// quantization tables
512 int numQuantTables; // number of quantization tables 558 int numQuantTables; // number of quantization tables
513 DCTHuffTable dcHuffTables[4];// DC Huffman tables 559 DCTHuffTable dcHuffTables[4];// DC Huffman tables
514 DCTHuffTable acHuffTables[4];// AC Huffman tables 560 DCTHuffTable acHuffTables[4];// AC Huffman tables
515 int numDCHuffTables; // number of DC Huffman tables 561 int numDCHuffTables; // number of DC Huffman tables
516 int numACHuffTables; // number of AC Huffman tables 562 int numACHuffTables; // number of AC Huffman tables
517 Guchar *rowBuf[4][32];// buffer for one MCU 563 Guchar *rowBuf[4][32];// buffer for one MCU
518 int comp, x, y, dy; // current position within image/MCU 564 int comp, x, y, dy; // current position within image/MCU
519 int restartCtr; // MCUs left until restart 565 int restartCtr; // MCUs left until restart
520 int restartMarker; // next restart marker 566 int restartMarker; // next restart marker
521 int inputBuf; // input buffer for variable length codes 567 int inputBuf; // input buffer for variable length codes
522 int inputBits; // number of valid bits in input buffer 568 int inputBits; // number of valid bits in input buffer
523 569
524 void restart(); 570 void restart();
525 GBool readMCURow(); 571 GBool readMCURow();
526 GBool readDataUnit(DCTHuffTable *dcHuffTable, DCTHuffTable *acHuffTable, 572 GBool readDataUnit(DCTHuffTable *dcHuffTable, DCTHuffTable *acHuffTable,
527 Guchar quantTable[64], int *prevDC, Guchar data[64]); 573 Guchar quantTable[64], int *prevDC, Guchar data[64]);
528 int readHuffSym(DCTHuffTable *table); 574 int readHuffSym(DCTHuffTable *table);
529 int readAmp(int size); 575 int readAmp(int size);
530 int readBit(); 576 int readBit();
531 GBool readHeader(); 577 GBool readHeader();
532 GBool readFrameInfo(); 578 GBool readFrameInfo();
533 GBool readScanInfo(); 579 GBool readScanInfo();
534 GBool readQuantTables(); 580 GBool readQuantTables();
535 GBool readHuffmanTables(); 581 GBool readHuffmanTables();
536 GBool readRestartInterval(); 582 GBool readRestartInterval();
537 GBool readAdobeMarker(); 583 GBool readAdobeMarker();
538 GBool readTrailer(); 584 GBool readTrailer();
539 int readMarker(); 585 int readMarker();
540 int read16(); 586 int read16();
541}; 587};
542 588
543//------------------------------------------------------------------------ 589//------------------------------------------------------------------------
544// FlateStream 590// FlateStream
545//------------------------------------------------------------------------ 591//------------------------------------------------------------------------
546 592
547#define flateWindow 32768 // buffer size 593#define flateWindow 32768 // buffer size
548#define flateMask (flateWindow-1) 594#define flateMask (flateWindow-1)
549#define flateMaxHuffman 15 // max Huffman code length 595#define flateMaxHuffman 15 // max Huffman code length
550#define flateMaxCodeLenCodes 19 // max # code length codes 596#define flateMaxCodeLenCodes 19 // max # code length codes
551#define flateMaxLitCodes 288 // max # literal codes 597#define flateMaxLitCodes 288 // max # literal codes
552#define flateMaxDistCodes 30 // max # distance codes 598#define flateMaxDistCodes 30 // max # distance codes
553 599
554// Huffman code table entry 600// Huffman code table entry
555struct FlateCode { 601struct FlateCode {
556 int len; // code length in bits 602 int len; // code length in bits
557 int code; // code word 603 int code; // code word
558 int val; // value represented by this code 604 int val; // value represented by this code
559}; 605};
560 606
561// Huffman code table 607// Huffman code table
562struct FlateHuffmanTab { 608struct FlateHuffmanTab {
563 int start[flateMaxHuffman+2];// indexes of first code of each length 609 int start[flateMaxHuffman+2];// indexes of first code of each length
564 FlateCode *codes; // codes, sorted by length and code word 610 FlateCode *codes; // codes, sorted by length and code word
565}; 611};
566 612
567// Decoding info for length and distance code words 613// Decoding info for length and distance code words
568struct FlateDecode { 614struct FlateDecode {
569 int bits; // # extra bits 615 int bits; // # extra bits
570 int first; // first length/distance 616 int first; // first length/distance
571}; 617};
572 618
573class FlateStream: public FilterStream { 619class FlateStream: public FilterStream {
574public: 620public:
575 621
576 FlateStream(Stream *strA, int predictor, int columns, 622 FlateStream(Stream *strA, int predictor, int columns,
577 int colors, int bits); 623 int colors, int bits);
578 virtual ~FlateStream(); 624 virtual ~FlateStream();
579 virtual StreamKind getKind() { return strFlate; } 625 virtual StreamKind getKind() { return strFlate; }
580 virtual void reset(); 626 virtual void reset();
581 virtual int getChar(); 627 virtual int getChar();
582 virtual int lookChar(); 628 virtual int lookChar();
583 virtual int getRawChar(); 629 virtual int getRawChar();
584 virtual GString *getPSFilter(char *indent); 630 virtual GString *getPSFilter(char *indent);
585 virtual GBool isBinary(GBool last = gTrue); 631 virtual GBool isBinary(GBool last = gTrue);
586 632
587private: 633private:
588 634
589 StreamPredictor *pred;// predictor 635 StreamPredictor *pred;// predictor
590 Guchar buf[flateWindow];// output data buffer 636 Guchar buf[flateWindow];// output data buffer
591 int index; // current index into output buffer 637 int index; // current index into output buffer
592 int remain; // number valid bytes in output buffer 638 int remain; // number valid bytes in output buffer
593 int codeBuf; // input buffer 639 int codeBuf; // input buffer
594 int codeSize; // number of bits in input buffer 640 int codeSize; // number of bits in input buffer
595 FlateCode // literal and distance codes 641 FlateCode // literal and distance codes
596 allCodes[flateMaxLitCodes + flateMaxDistCodes]; 642 allCodes[flateMaxLitCodes + flateMaxDistCodes];
597 FlateHuffmanTab litCodeTab;// literal code table 643 FlateHuffmanTab litCodeTab;// literal code table
598 FlateHuffmanTab distCodeTab;// distance code table 644 FlateHuffmanTab distCodeTab;// distance code table
599 GBool compressedBlock;// set if reading a compressed block 645 GBool compressedBlock;// set if reading a compressed block
600 int blockLen; // remaining length of uncompressed block 646 int blockLen; // remaining length of uncompressed block
601 GBool endOfBlock; // set when end of block is reached 647 GBool endOfBlock; // set when end of block is reached
602 GBool eof; // set when end of stream is reached 648 GBool eof; // set when end of stream is reached
603 649
604 static int // code length code reordering 650 static int // code length code reordering
605 codeLenCodeMap[flateMaxCodeLenCodes]; 651 codeLenCodeMap[flateMaxCodeLenCodes];
606 static FlateDecode // length decoding info 652 static FlateDecode // length decoding info
607 lengthDecode[flateMaxLitCodes-257]; 653 lengthDecode[flateMaxLitCodes-257];
608 static FlateDecode // distance decoding info 654 static FlateDecode // distance decoding info
609 distDecode[flateMaxDistCodes]; 655 distDecode[flateMaxDistCodes];
610 656
611 void readSome(); 657 void readSome();
612 GBool startBlock(); 658 GBool startBlock();
613 void loadFixedCodes(); 659 void loadFixedCodes();
614 GBool readDynamicCodes(); 660 GBool readDynamicCodes();
615 void compHuffmanCodes(FlateHuffmanTab *tab, int n); 661 void compHuffmanCodes(FlateHuffmanTab *tab, int n);
616 int getHuffmanCodeWord(FlateHuffmanTab *tab); 662 int getHuffmanCodeWord(FlateHuffmanTab *tab);
617 int getCodeWord(int bits); 663 int getCodeWord(int bits);
618}; 664};
619 665
620//------------------------------------------------------------------------ 666//------------------------------------------------------------------------
621// EOFStream 667// EOFStream
622//------------------------------------------------------------------------ 668//------------------------------------------------------------------------
623 669
624class EOFStream: public FilterStream { 670class EOFStream: public FilterStream {
625public: 671public:
626 672
627 EOFStream(Stream *strA); 673 EOFStream(Stream *strA);
628 virtual ~EOFStream(); 674 virtual ~EOFStream();
629 virtual StreamKind getKind() { return strWeird; } 675 virtual StreamKind getKind() { return strWeird; }
630 virtual void reset() {} 676 virtual void reset() {}
631 virtual int getChar() { return EOF; } 677 virtual int getChar() { return EOF; }
632 virtual int lookChar() { return EOF; } 678 virtual int lookChar() { return EOF; }
633 virtual GString *getPSFilter(char *indent) { return NULL; } 679 virtual GString *getPSFilter(char *indent) { return NULL; }
634 virtual GBool isBinary(GBool last = gTrue) { return gFalse; } 680 virtual GBool isBinary(GBool last = gTrue) { return gFalse; }
635}; 681};
636 682
637//------------------------------------------------------------------------ 683//------------------------------------------------------------------------
638// FixedLengthEncoder 684// FixedLengthEncoder
639//------------------------------------------------------------------------ 685//------------------------------------------------------------------------
640 686
641class FixedLengthEncoder: public FilterStream { 687class FixedLengthEncoder: public FilterStream {
642public: 688public:
643 689
644 FixedLengthEncoder(Stream *strA, int lengthA); 690 FixedLengthEncoder(Stream *strA, int lengthA);
645 ~FixedLengthEncoder(); 691 ~FixedLengthEncoder();
646 virtual StreamKind getKind() { return strWeird; } 692 virtual StreamKind getKind() { return strWeird; }
647 virtual void reset(); 693 virtual void reset();
648 virtual void close(); 694 virtual void close();
649 virtual int getChar(); 695 virtual int getChar();
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()
674 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); } 751 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
675 virtual int lookChar() 752 virtual int lookChar()
676 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); } 753 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
677 virtual GString *getPSFilter(char *indent) { return NULL; } 754 virtual GString *getPSFilter(char *indent) { return NULL; }
678 virtual GBool isBinary(GBool last = gTrue) { return gFalse; } 755 virtual GBool isBinary(GBool last = gTrue) { return gFalse; }
679 virtual GBool isEncoder() { return gTrue; } 756 virtual GBool isEncoder() { return gTrue; }
680 757
681private: 758private:
682 759
683 char buf[8]; 760 char buf[8];
684 char *bufPtr; 761 char *bufPtr;
685 char *bufEnd; 762 char *bufEnd;
686 int lineLen; 763 int lineLen;
687 GBool eof; 764 GBool eof;
688 765
689 GBool fillBuf(); 766 GBool fillBuf();
690}; 767};
691 768
692//------------------------------------------------------------------------ 769//------------------------------------------------------------------------
693// RunLengthEncoder 770// RunLengthEncoder
694//------------------------------------------------------------------------ 771//------------------------------------------------------------------------
695 772
696class RunLengthEncoder: public FilterStream { 773class RunLengthEncoder: public FilterStream {
697public: 774public:
698 775
699 RunLengthEncoder(Stream *strA); 776 RunLengthEncoder(Stream *strA);
700 virtual ~RunLengthEncoder(); 777 virtual ~RunLengthEncoder();
701 virtual StreamKind getKind() { return strWeird; } 778 virtual StreamKind getKind() { return strWeird; }
702 virtual void reset(); 779 virtual void reset();
703 virtual void close(); 780 virtual void close();
704 virtual int getChar() 781 virtual int getChar()
705 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); } 782 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
706 virtual int lookChar() 783 virtual int lookChar()
707 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); } 784 { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
708 virtual GString *getPSFilter(char *indent) { return NULL; } 785 virtual GString *getPSFilter(char *indent) { return NULL; }
709 virtual GBool isBinary(GBool last = gTrue) { return gFalse; } 786 virtual GBool isBinary(GBool last = gTrue) { return gFalse; }
710 virtual GBool isEncoder() { return gTrue; } 787 virtual GBool isEncoder() { return gTrue; }
711 788
712private: 789private:
713 790
714 char buf[131]; 791 char buf[131];
715 char *bufPtr; 792 char *bufPtr;
716 char *bufEnd; 793 char *bufEnd;
717 char *nextEnd; 794 char *nextEnd;
718 GBool eof; 795 GBool eof;
719 796
720 GBool fillBuf(); 797 GBool fillBuf();
721}; 798};
722 799
723#endif 800#endif
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,686 +1,713 @@
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>
18#include <ctype.h> 18#include <ctype.h>
19#include "GString.h" 19#include "GString.h"
20#include "gmem.h" 20#include "gmem.h"
21#include "config.h" 21#include "config.h"
22#include "Error.h" 22#include "Error.h"
23#include "GlobalParams.h" 23#include "GlobalParams.h"
24#include "UnicodeMap.h" 24#include "UnicodeMap.h"
25#include "GfxState.h" 25#include "GfxState.h"
26#include "TextOutputDev.h" 26#include "TextOutputDev.h"
27 27
28#ifdef MACOS 28#ifdef MACOS
29// needed for setting type/creator of MacOS files 29// needed for setting type/creator of MacOS files
30#include "ICSupport.h" 30#include "ICSupport.h"
31#endif 31#endif
32 32
33//------------------------------------------------------------------------ 33//------------------------------------------------------------------------
34// TextString 34// TextString
35//------------------------------------------------------------------------ 35//------------------------------------------------------------------------
36 36
37TextString::TextString(GfxState *state, fouble fontSize) { 37TextString::TextString(GfxState *state, fouble fontSize) {
38 GfxFont *font; 38 GfxFont *font;
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}
63 69
64void TextString::addChar(GfxState *state, fouble x, fouble y, 70void TextString::addChar(GfxState *state, fouble x, fouble y,
65 fouble dx, fouble dy, Unicode u) { 71 fouble dx, fouble dy, Unicode u) {
66 if (len == size) { 72 if (len == size) {
67 size += 16; 73 size += 16;
68 text = (Unicode *)grealloc(text, size * sizeof(Unicode)); 74 text = (Unicode *)grealloc(text, size * sizeof(Unicode));
69 xRight = (fouble *)grealloc(xRight, size * sizeof(fouble)); 75 xRight = (fouble *)grealloc(xRight, size * sizeof(fouble));
70 } 76 }
71 text[len] = u; 77 text[len] = u;
72 if (len == 0) { 78 if (len == 0) {
73 xMin = x; 79 xMin = x;
74 } 80 }
75 xMax = xRight[len] = x + dx; 81 xMax = xRight[len] = x + dx;
76 ++len; 82 ++len;
77} 83}
78 84
79//------------------------------------------------------------------------ 85//------------------------------------------------------------------------
80// TextPage 86// TextPage
81//------------------------------------------------------------------------ 87//------------------------------------------------------------------------
82 88
83TextPage::TextPage(GBool rawOrderA) { 89TextPage::TextPage(GBool rawOrderA) {
84 rawOrder = rawOrderA; 90 rawOrder = rawOrderA;
85 curStr = NULL; 91 curStr = NULL;
86 fontSize = 0; 92 fontSize = 0;
87 yxStrings = NULL; 93 yxStrings = NULL;
88 xyStrings = NULL; 94 xyStrings = NULL;
89 yxCur1 = yxCur2 = NULL; 95 yxCur1 = yxCur2 = NULL;
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) {
133 ++nest; 143 ++nest;
134 return; 144 return;
135 } 145 }
136 146
137 curStr = new TextString(state, fontSize); 147 curStr = new TextString(state, fontSize);
138} 148}
139 149
140void TextPage::addChar(GfxState *state, fouble x, fouble y, 150void TextPage::addChar(GfxState *state, fouble x, fouble y,
141 fouble dx, fouble dy, Unicode *u, int uLen) { 151 fouble dx, fouble dy, Unicode *u, int uLen) {
142 fouble x1, y1, w1, h1, dx2, dy2; 152 fouble x1, y1, w1, h1, dx2, dy2;
143 int n, i; 153 int n, i;
144 154
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) {
171 --nest; 183 --nest;
172 return; 184 return;
173 } 185 }
174 186
175 // throw away zero-length strings -- they don't have valid xMin/xMax 187 // throw away zero-length strings -- they don't have valid xMin/xMax
176 // values, and they're useless anyway 188 // values, and they're useless anyway
177 if (curStr->len == 0) { 189 if (curStr->len == 0) {
178 delete curStr; 190 delete curStr;
179 curStr = NULL; 191 curStr = NULL;
180 return; 192 return;
181 } 193 }
182 194
183 // insert string in y-major list 195 // insert string in y-major list
184 h = curStr->yMax - curStr->yMin; 196 h = curStr->yMax - curStr->yMin;
185 y1 = curStr->yMin + 0.5 * h; 197 y1 = curStr->yMin + 0.5 * h;
186 y2 = curStr->yMin + 0.8 * h; 198 y2 = curStr->yMin + 0.8 * h;
187 if (rawOrder) { 199 if (rawOrder) {
188 p1 = yxCur1; 200 p1 = yxCur1;
189 p2 = NULL; 201 p2 = NULL;
190 } else if ((!yxCur1 || 202 } else if ((!yxCur1 ||
191 (y1 >= yxCur1->yMin && 203 (y1 >= yxCur1->yMin &&
192 (y2 >= yxCur1->yMax || curStr->xMax >= yxCur1->xMin))) && 204 (y2 >= yxCur1->yMax || curStr->xMax >= yxCur1->xMin))) &&
193 (!yxCur2 || 205 (!yxCur2 ||
194 (y1 < yxCur2->yMin || 206 (y1 < yxCur2->yMin ||
195 (y2 < yxCur2->yMax && curStr->xMax < yxCur2->xMin)))) { 207 (y2 < yxCur2->yMax && curStr->xMax < yxCur2->xMin)))) {
196 p1 = yxCur1; 208 p1 = yxCur1;
197 p2 = yxCur2; 209 p2 = yxCur2;
198 } else { 210 } else {
199 for (p1 = NULL, p2 = yxStrings; p2; p1 = p2, p2 = p2->yxNext) { 211 for (p1 = NULL, p2 = yxStrings; p2; p1 = p2, p2 = p2->yxNext) {
200 if (y1 < p2->yMin || (y2 < p2->yMax && curStr->xMax < p2->xMin)) { 212 if (y1 < p2->yMin || (y2 < p2->yMax && curStr->xMax < p2->xMin)) {
201 break; 213 break;
202 } 214 }
203 } 215 }
204 yxCur2 = p2; 216 yxCur2 = p2;
205 } 217 }
206 yxCur1 = curStr; 218 yxCur1 = curStr;
207 if (p1) { 219 if (p1) {
208 p1->yxNext = curStr; 220 p1->yxNext = curStr;
209 } else { 221 } else {
210 yxStrings = curStr; 222 yxStrings = curStr;
211 } 223 }
212 curStr->yxNext = p2; 224 curStr->yxNext = p2;
213 curStr = NULL; 225 curStr = NULL;
214} 226}
215 227
216void TextPage::coalesce() { 228void TextPage::coalesce() {
217 TextString *str1, *str2; 229 TextString *str1, *str2;
218 fouble space, d; 230 fouble space, d;
219 GBool addSpace; 231 GBool addSpace;
220 int n, i; 232 int n, i;
221 233
222#if 0 //~ for debugging 234#if 0 //~ for debugging
223 for (str1 = yxStrings; str1; str1 = str1->yxNext) { 235 for (str1 = yxStrings; str1; str1 = str1->yxNext) {
224 printf("x=%3d..%3d y=%3d..%3d size=%2d '", 236 printf("x=%3d..%3d y=%3d..%3d size=%2d '",
225 (int)str1->xMin, (int)str1->xMax, (int)str1->yMin, (int)str1->yMax, 237 (int)str1->xMin, (int)str1->xMax, (int)str1->yMin, (int)str1->yMax,
226 (int)(str1->yMax - str1->yMin)); 238 (int)(str1->yMax - str1->yMin));
227 for (i = 0; i < str1->len; ++i) { 239 for (i = 0; i < str1->len; ++i) {
228 fputc(str1->text[i] & 0xff, stdout); 240 fputc(str1->text[i] & 0xff, stdout);
229 } 241 }
230 printf("'\n"); 242 printf("'\n");
231 } 243 }
232 printf("\n------------------------------------------------------------\n\n"); 244 printf("\n------------------------------------------------------------\n\n");
233#endif 245#endif
234 str1 = yxStrings; 246 str1 = yxStrings;
235 while (str1 && (str2 = str1->yxNext)) { 247 while (str1 && (str2 = str1->yxNext)) {
236 space = str1->yMax - str1->yMin; 248 space = str1->yMax - str1->yMin;
237 d = str2->xMin - str1->xMax; 249 d = str2->xMin - str1->xMax;
238 if (((rawOrder && 250 if (((rawOrder &&
239 ((str2->yMin >= str1->yMin && str2->yMin <= str1->yMax) || 251 ((str2->yMin >= str1->yMin && str2->yMin <= str1->yMax) ||
240 (str2->yMax >= str1->yMin && str2->yMax <= str1->yMax))) || 252 (str2->yMax >= str1->yMin && str2->yMax <= str1->yMax))) ||
241 (!rawOrder && str2->yMin < str1->yMax)) && 253 (!rawOrder && str2->yMin < str1->yMax)) &&
242 d > -0.5 * space && d < space) { 254 d > -0.5 * space && d < space) {
243 n = str1->len + str2->len; 255 n = str1->len + str2->len;
244 if ((addSpace = d > 0.1 * space)) { 256 if ((addSpace = d > 0.1 * space)) {
245 ++n; 257 ++n;
246 } 258 }
247 str1->size = (n + 15) & ~15; 259 str1->size = (n + 15) & ~15;
248 str1->text = (Unicode *)grealloc(str1->text, 260 str1->text = (Unicode *)grealloc(str1->text,
249 str1->size * sizeof(Unicode)); 261 str1->size * sizeof(Unicode));
250 str1->xRight = (fouble *)grealloc(str1->xRight, 262 str1->xRight = (fouble *)grealloc(str1->xRight,
251 str1->size * sizeof(fouble)); 263 str1->size * sizeof(fouble));
252 if (addSpace) { 264 if (addSpace) {
253 str1->text[str1->len] = 0x20; 265 str1->text[str1->len] = 0x20;
254 str1->xRight[str1->len] = str2->xMin; 266 str1->xRight[str1->len] = str2->xMin;
255 ++str1->len; 267 ++str1->len;
256 } 268 }
257 for (i = 0; i < str2->len; ++i) { 269 for (i = 0; i < str2->len; ++i) {
258 str1->text[str1->len] = str2->text[i]; 270 str1->text[str1->len] = str2->text[i];
259 str1->xRight[str1->len] = str2->xRight[i]; 271 str1->xRight[str1->len] = str2->xRight[i];
260 ++str1->len; 272 ++str1->len;
261 } 273 }
262 if (str2->xMax > str1->xMax) { 274 if (str2->xMax > str1->xMax) {
263 str1->xMax = str2->xMax; 275 str1->xMax = str2->xMax;
264 } 276 }
265 if (str2->yMax > str1->yMax) { 277 if (str2->yMax > str1->yMax) {
266 str1->yMax = str2->yMax; 278 str1->yMax = str2->yMax;
267 } 279 }
268 str1->yxNext = str2->yxNext; 280 str1->yxNext = str2->yxNext;
269 delete str2; 281 delete str2;
270 } else { 282 } else {
271 str1 = str2; 283 str1 = str2;
272 } 284 }
273 } 285 }
274} 286}
275 287
276GBool TextPage::findText(Unicode *s, int len, 288GBool TextPage::findText(Unicode *s, int len,
277 GBool top, GBool bottom, 289 GBool top, GBool bottom,
278 fouble *xMin, fouble *yMin, 290 fouble *xMin, fouble *yMin,
279 fouble *xMax, fouble *yMax) { 291 fouble *xMax, fouble *yMax) {
280 TextString *str; 292 TextString *str;
281 Unicode *p; 293 Unicode *p;
282 Unicode u1, u2; 294 Unicode u1, u2;
283 int m, i, j; 295 int m, i, j;
284 fouble x; 296 fouble x;
285 297
286 // scan all strings on page 298 // scan all strings on page
287 for (str = yxStrings; str; str = str->yxNext) { 299 for (str = yxStrings; str; str = str->yxNext) {
288 300
289 // check: above top limit? 301 // check: above top limit?
290 if (!top && (str->yMax < *yMin || 302 if (!top && (str->yMax < *yMin ||
291 (str->yMin < *yMin && str->xMax <= *xMin))) { 303 (str->yMin < *yMin && str->xMax <= *xMin))) {
292 continue; 304 continue;
293 } 305 }
294 306
295 // check: below bottom limit? 307 // check: below bottom limit?
296 if (!bottom && (str->yMin > *yMax || 308 if (!bottom && (str->yMin > *yMax ||
297 (str->yMax > *yMax && str->xMin >= *xMax))) { 309 (str->yMax > *yMax && str->xMin >= *xMax))) {
298 return gFalse; 310 return gFalse;
299 } 311 }
300 312
301 // search each position in this string 313 // search each position in this string
302 m = str->len; 314 m = str->len;
303 for (i = 0, p = str->text; i <= m - len; ++i, ++p) { 315 for (i = 0, p = str->text; i <= m - len; ++i, ++p) {
304 316
305 // check: above top limit? 317 // check: above top limit?
306 if (!top && str->yMin < *yMin) { 318 if (!top && str->yMin < *yMin) {
307 x = (((i == 0) ? str->xMin : str->xRight[i-1]) + str->xRight[i]) / 2; 319 x = (((i == 0) ? str->xMin : str->xRight[i-1]) + str->xRight[i]) / 2;
308 if (x < *xMin) { 320 if (x < *xMin) {
309 continue; 321 continue;
310 } 322 }
311 } 323 }
312 324
313 // check: below bottom limit? 325 // check: below bottom limit?
314 if (!bottom && str->yMax > *yMax) { 326 if (!bottom && str->yMax > *yMax) {
315 x = (((i == 0) ? str->xMin : str->xRight[i-1]) + str->xRight[i]) / 2; 327 x = (((i == 0) ? str->xMin : str->xRight[i-1]) + str->xRight[i]) / 2;
316 if (x > *xMax) { 328 if (x > *xMax) {
317 return gFalse; 329 return gFalse;
318 } 330 }
319 } 331 }
320 332
321 // compare the strings 333 // compare the strings
322 for (j = 0; j < len; ++j) { 334 for (j = 0; j < len; ++j) {
323#if 1 //~ this lowercases Latin A-Z only -- this will eventually be 335#if 1 //~ this lowercases Latin A-Z only -- this will eventually be
324 //~ extended to handle other character sets 336 //~ extended to handle other character sets
325 if (p[j] >= 0x41 && p[j] <= 0x5a) { 337 if (p[j] >= 0x41 && p[j] <= 0x5a) {
326 u1 = p[j] + 0x20; 338 u1 = p[j] + 0x20;
327 } else { 339 } else {
328 u1 = p[j]; 340 u1 = p[j];
329 } 341 }
330 if (s[j] >= 0x41 && s[j] <= 0x5a) { 342 if (s[j] >= 0x41 && s[j] <= 0x5a) {
331 u2 = s[j] + 0x20; 343 u2 = s[j] + 0x20;
332 } else { 344 } else {
333 u2 = s[j]; 345 u2 = s[j];
334 } 346 }
335#endif 347#endif
336 if (u1 != u2) { 348 if (u1 != u2) {
337 break; 349 break;
338 } 350 }
339 } 351 }
340 352
341 // found it 353 // found it
342 if (j == len) { 354 if (j == len) {
343 *xMin = (i == 0) ? str->xMin : str->xRight[i-1]; 355 *xMin = (i == 0) ? str->xMin : str->xRight[i-1];
344 *xMax = str->xRight[i + len - 1]; 356 *xMax = str->xRight[i + len - 1];
345 *yMin = str->yMin; 357 *yMin = str->yMin;
346 *yMax = str->yMax; 358 *yMax = str->yMax;
347 return gTrue; 359 return gTrue;
348 } 360 }
349 } 361 }
350 } 362 }
351 return gFalse; 363 return gFalse;
352} 364}
353 365
354GString *TextPage::getText(fouble xMin, fouble yMin, 366GString *TextPage::getText(fouble xMin, fouble yMin,
355 fouble xMax, fouble yMax) { 367 fouble xMax, fouble yMax) {
356 GString *s; 368 GString *s;
357 UnicodeMap *uMap; 369 UnicodeMap *uMap;
358 char space[8], eol[16], buf[8]; 370 char space[8], eol[16], buf[8];
359 int spaceLen, eolLen, n; 371 int spaceLen, eolLen, n;
360 TextString *str1; 372 TextString *str1;
361 fouble x0, x1, x2, y; 373 fouble x0, x1, x2, y;
362 fouble xPrev, yPrev; 374 fouble xPrev, yPrev;
363 int i1, i2, i; 375 int i1, i2, i;
364 GBool multiLine; 376 GBool multiLine;
365 377
366 s = new GString(); 378 s = new GString();
367 if (!(uMap = globalParams->getTextEncoding())) { 379 if (!(uMap = globalParams->getTextEncoding())) {
368 return s; 380 return s;
369 } 381 }
370 spaceLen = uMap->mapUnicode(0x20, space, sizeof(space)); 382 spaceLen = uMap->mapUnicode(0x20, space, sizeof(space));
371 eolLen = 0; // make gcc happy 383 eolLen = 0; // make gcc happy
372 switch (globalParams->getTextEOL()) { 384 switch (globalParams->getTextEOL()) {
373 case eolUnix: 385 case eolUnix:
374 eolLen = uMap->mapUnicode(0x0a, eol, sizeof(eol)); 386 eolLen = uMap->mapUnicode(0x0a, eol, sizeof(eol));
375 break; 387 break;
376 case eolDOS: 388 case eolDOS:
377 eolLen = uMap->mapUnicode(0x0d, eol, sizeof(eol)); 389 eolLen = uMap->mapUnicode(0x0d, eol, sizeof(eol));
378 eolLen += uMap->mapUnicode(0x0a, eol + eolLen, sizeof(eol) - eolLen); 390 eolLen += uMap->mapUnicode(0x0a, eol + eolLen, sizeof(eol) - eolLen);
379 break; 391 break;
380 case eolMac: 392 case eolMac:
381 eolLen = uMap->mapUnicode(0x0d, eol, sizeof(eol)); 393 eolLen = uMap->mapUnicode(0x0d, eol, sizeof(eol));
382 break; 394 break;
383 } 395 }
384 xPrev = yPrev = 0; 396 xPrev = yPrev = 0;
385 multiLine = gFalse; 397 multiLine = gFalse;
386 for (str1 = yxStrings; str1; str1 = str1->yxNext) { 398 for (str1 = yxStrings; str1; str1 = str1->yxNext) {
387 y = 0.5 * (str1->yMin + str1->yMax); 399 y = 0.5 * (str1->yMin + str1->yMax);
388 if (y > yMax) { 400 if (y > yMax) {
389 break; 401 break;
390 } 402 }
391 if (y > yMin && str1->xMin < xMax && str1->xMax > xMin) { 403 if (y > yMin && str1->xMin < xMax && str1->xMax > xMin) {
392 x0 = x1 = x2 = str1->xMin; 404 x0 = x1 = x2 = str1->xMin;
393 for (i1 = 0; i1 < str1->len; ++i1) { 405 for (i1 = 0; i1 < str1->len; ++i1) {
394 x0 = (i1==0) ? str1->xMin : str1->xRight[i1-1]; 406 x0 = (i1==0) ? str1->xMin : str1->xRight[i1-1];
395 x1 = str1->xRight[i1]; 407 x1 = str1->xRight[i1];
396 if (0.5 * (x0 + x1) >= xMin) { 408 if (0.5 * (x0 + x1) >= xMin) {
397 break; 409 break;
398 } 410 }
399 } 411 }
400 for (i2 = str1->len - 1; i2 > i1; --i2) { 412 for (i2 = str1->len - 1; i2 > i1; --i2) {
401 x1 = (i2==0) ? str1->xMin : str1->xRight[i2-1]; 413 x1 = (i2==0) ? str1->xMin : str1->xRight[i2-1];
402 x2 = str1->xRight[i2]; 414 x2 = str1->xRight[i2];
403 if (0.5 * (x1 + x2) <= xMax) { 415 if (0.5 * (x1 + x2) <= xMax) {
404 break; 416 break;
405 } 417 }
406 } 418 }
407 if (s->getLength() > 0) { 419 if (s->getLength() > 0) {
408 if (x0 < xPrev || str1->yMin > yPrev) { 420 if (x0 < xPrev || str1->yMin > yPrev) {
409 s->append(eol, eolLen); 421 s->append(eol, eolLen);
410 multiLine = gTrue; 422 multiLine = gTrue;
411 } else { 423 } else {
412 for (i = 0; i < 4; ++i) { 424 for (i = 0; i < 4; ++i) {
413 s->append(space, spaceLen); 425 s->append(space, spaceLen);
414 } 426 }
415 } 427 }
416 } 428 }
417 for (i = i1; i <= i2; ++i) { 429 for (i = i1; i <= i2; ++i) {
418 n = uMap->mapUnicode(str1->text[i], buf, sizeof(buf)); 430 n = uMap->mapUnicode(str1->text[i], buf, sizeof(buf));
419 s->append(buf, n); 431 s->append(buf, n);
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));
445 eolLen = 0; // make gcc happy 457 eolLen = 0; // make gcc happy
446 switch (globalParams->getTextEOL()) { 458 switch (globalParams->getTextEOL()) {
447 case eolUnix: 459 case eolUnix:
448 eolLen = uMap->mapUnicode(0x0a, eol, sizeof(eol)); 460 eolLen = uMap->mapUnicode(0x0a, eol, sizeof(eol));
449 break; 461 break;
450 case eolDOS: 462 case eolDOS:
451 eolLen = uMap->mapUnicode(0x0d, eol, sizeof(eol)); 463 eolLen = uMap->mapUnicode(0x0d, eol, sizeof(eol));
452 eolLen += uMap->mapUnicode(0x0a, eol + eolLen, sizeof(eol) - eolLen); 464 eolLen += uMap->mapUnicode(0x0a, eol + eolLen, sizeof(eol) - eolLen);
453 break; 465 break;
454 case eolMac: 466 case eolMac:
455 eolLen = uMap->mapUnicode(0x0d, eol, sizeof(eol)); 467 eolLen = uMap->mapUnicode(0x0d, eol, sizeof(eol));
456 break; 468 break;
457 } 469 }
458 eopLen = uMap->mapUnicode(0x0c, eop, sizeof(eop)); 470 eopLen = uMap->mapUnicode(0x0c, eop, sizeof(eop));
459 471
460 // build x-major list 472 // build x-major list
461 xyStrings = NULL; 473 xyStrings = NULL;
462 for (str1 = yxStrings; str1; str1 = str1->yxNext) { 474 for (str1 = yxStrings; str1; str1 = str1->yxNext) {
463 for (str2 = NULL, str3 = xyStrings; 475 for (str2 = NULL, str3 = xyStrings;
464 str3; 476 str3;
465 str2 = str3, str3 = str3->xyNext) { 477 str2 = str3, str3 = str3->xyNext) {
466 if (str1->xMin < str3->xMin || 478 if (str1->xMin < str3->xMin ||
467 (str1->xMin == str3->xMin && str1->yMin < str3->yMin)) { 479 (str1->xMin == str3->xMin && str1->yMin < str3->yMin)) {
468 break; 480 break;
469 } 481 }
470 } 482 }
471 if (str2) { 483 if (str2) {
472 str2->xyNext = str1; 484 str2->xyNext = str1;
473 } else { 485 } else {
474 xyStrings = str1; 486 xyStrings = str1;
475 } 487 }
476 str1->xyNext = str3; 488 str1->xyNext = str3;
477 } 489 }
478 490
479 // do column assignment 491 // do column assignment
480 for (str1 = xyStrings; str1; str1 = str1->xyNext) { 492 for (str1 = xyStrings; str1; str1 = str1->xyNext) {
481 col1 = 0; 493 col1 = 0;
482 for (str2 = xyStrings; str2 != str1; str2 = str2->xyNext) { 494 for (str2 = xyStrings; str2 != str1; str2 = str2->xyNext) {
483 if (str1->xMin >= str2->xMax) { 495 if (str1->xMin >= str2->xMax) {
484 col2 = str2->col + str2->len + 4; 496 col2 = str2->col + str2->len + 4;
485 if (col2 > col1) { 497 if (col2 > col1) {
486 col1 = col2; 498 col1 = col2;
487 } 499 }
488 } else if (str1->xMin > str2->xMin) { 500 } else if (str1->xMin > str2->xMin) {
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))
563 break; 575 break;
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) {
671 text->endString(); 698 text->endString();
672} 699}
673 700
674void TextOutputDev::drawChar(GfxState *state, fouble x, fouble y, 701void TextOutputDev::drawChar(GfxState *state, fouble x, fouble y,
675 fouble dx, fouble dy, 702 fouble dx, fouble dy,
676 fouble originX, fouble originY, 703 fouble originX, fouble originY,
677 CharCode c, Unicode *u, int uLen) { 704 CharCode c, Unicode *u, int uLen) {
678 text->addChar(state, x, y, dx, dy, u, uLen); 705 text->addChar(state, x, y, dx, dy, u, uLen);
679} 706}
680 707
681GBool TextOutputDev::findText(Unicode *s, int len, 708GBool TextOutputDev::findText(Unicode *s, int len,
682 GBool top, GBool bottom, 709 GBool top, GBool bottom,
683 fouble *xMin, fouble *yMin, 710 fouble *xMin, fouble *yMin,
684 fouble *xMax, fouble *yMax) { 711 fouble *xMax, fouble *yMax) {
685 return text->findText(s, len, top, bottom, xMin, yMin, xMax, yMax); 712 return text->findText(s, len, top, bottom, xMin, yMin, xMax, yMax);
686} 713}
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,189 +1,203 @@
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
37 // Add a character to the string. 41 // Add a character to the string.
38 void addChar(GfxState *state, fouble x, fouble y, 42 void addChar(GfxState *state, fouble x, fouble y,
39 fouble dx, fouble dy, Unicode u); 43 fouble dx, fouble dy, Unicode u);
40 44
41private: 45private:
42 46
43 fouble xMin, xMax; // bounding box x coordinates 47 fouble xMin, xMax; // bounding box x coordinates
44 fouble yMin, yMax; // bounding box y coordinates 48 fouble yMin, yMax; // bounding box y coordinates
45 int col; // starting column 49 int col; // starting column
46 Unicode *text; // the text 50 Unicode *text; // the text
47 fouble *xRight; // right-hand x coord of each char 51 fouble *xRight; // right-hand x coord of each char
48 int len; // length of text and xRight 52 int len; // length of text and xRight
49 int size; // size of text and xRight arrays 53 int size; // size of text and xRight arrays
50 TextString *yxNext; // next string in y-major order 54 TextString *yxNext; // next string in y-major order
51 TextString *xyNext; // next string in x-major order 55 TextString *xyNext; // next string in x-major order
52 56
53 friend class TextPage; 57 friend class TextPage;
54}; 58};
55 59
56//------------------------------------------------------------------------ 60//------------------------------------------------------------------------
57// TextPage 61// TextPage
58//------------------------------------------------------------------------ 62//------------------------------------------------------------------------
59 63
60class TextPage { 64class TextPage {
61public: 65public:
62 66
63 // Constructor. 67 // Constructor.
64 TextPage(GBool rawOrderA); 68 TextPage(GBool rawOrderA);
65 69
66 // Destructor. 70 // Destructor.
67 ~TextPage(); 71 ~TextPage();
68 72
69 // Update the current font. 73 // Update the current font.
70 void updateFont(GfxState *state); 74 void updateFont(GfxState *state);
71 75
72 // Begin a new string. 76 // Begin a new string.
73 void beginString(GfxState *state); 77 void beginString(GfxState *state);
74 78
75 // Add a character to the current string. 79 // Add a character to the current string.
76 void addChar(GfxState *state, fouble x, fouble y, 80 void addChar(GfxState *state, fouble x, fouble y,
77 fouble dx, fouble dy, Unicode *u, int uLen); 81 fouble dx, fouble dy, Unicode *u, int uLen);
78 82
79 // End the current string, sorting it into the list of strings. 83 // End the current string, sorting it into the list of strings.
80 void endString(); 84 void endString();
81 85
82 // Coalesce strings that look like parts of the same line. 86 // Coalesce strings that look like parts of the same line.
83 void coalesce(); 87 void coalesce();
84 88
85 // Find a string. If <top> is true, starts looking at top of page; 89 // Find a string. If <top> is true, starts looking at top of page;
86 // otherwise starts looking at <xMin>,<yMin>. If <bottom> is true, 90 // otherwise starts looking at <xMin>,<yMin>. If <bottom> is true,
87 // stops looking at bottom of page; otherwise stops looking at 91 // stops looking at bottom of page; otherwise stops looking at
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
113 TextString *xyStrings;// strings in x-major order 117 TextString *xyStrings;// strings in x-major order
114 TextString *yxCur1, *yxCur2;// cursors for yxStrings list 118 TextString *yxCur1, *yxCur2;// cursors for yxStrings list
115 119
116 int nest; // current nesting level (for Type 3 fonts) 120 int nest; // current nesting level (for Type 3 fonts)
117}; 121};
118 122
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
158 virtual void updateFont(GfxState *state); 170 virtual void updateFont(GfxState *state);
159 171
160 //----- text drawing 172 //----- text drawing
161 virtual void beginString(GfxState *state, GString *s); 173 virtual void beginString(GfxState *state, GString *s);
162 virtual void endString(GfxState *state); 174 virtual void endString(GfxState *state);
163 virtual void drawChar(GfxState *state, fouble x, fouble y, 175 virtual void drawChar(GfxState *state, fouble x, fouble y,
164 fouble dx, fouble dy, 176 fouble dx, fouble dy,
165 fouble originX, fouble originY, 177 fouble originX, fouble originY,
166 CharCode c, Unicode *u, int uLen); 178 CharCode c, Unicode *u, int uLen);
167 179
168 //----- special access 180 //----- special access
169 181
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,197 +1,197 @@
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"
18#include "GString.h" 18#include "GString.h"
19#include "GList.h" 19#include "GList.h"
20#include "Error.h" 20#include "Error.h"
21#include "GlobalParams.h" 21#include "GlobalParams.h"
22#include "UnicodeMap.h" 22#include "UnicodeMap.h"
23 23
24//------------------------------------------------------------------------ 24//------------------------------------------------------------------------
25 25
26#define maxExtCode 16 26#define maxExtCode 16
27 27
28struct UnicodeMapExt { 28struct UnicodeMapExt {
29 Unicode u; // Unicode char 29 Unicode u; // Unicode char
30 char code[maxExtCode]; 30 char code[maxExtCode];
31 Guint nBytes; 31 Guint nBytes;
32}; 32};
33 33
34//------------------------------------------------------------------------ 34//------------------------------------------------------------------------
35 35
36UnicodeMap *UnicodeMap::parse(GString *encodingNameA) { 36UnicodeMap *UnicodeMap::parse(GString *encodingNameA) {
37 FILE *f; 37 FILE *f;
38 UnicodeMap *map; 38 UnicodeMap *map;
39 UnicodeMapRange *range; 39 UnicodeMapRange *range;
40 UnicodeMapExt *eMap; 40 UnicodeMapExt *eMap;
41 int size, eMapsSize; 41 int size, eMapsSize;
42 char buf[256]; 42 char buf[256];
43 int line, nBytes, i, x; 43 int line, nBytes, i, x;
44 char *tok1, *tok2, *tok3; 44 char *tok1, *tok2, *tok3;
45 45
46 if (!(f = globalParams->getUnicodeMapFile(encodingNameA))) { 46 if (!(f = globalParams->getUnicodeMapFile(encodingNameA))) {
47 error(-1, "Couldn't find unicodeMap file for the '%s' encoding", 47 error(-1, "Couldn't find unicodeMap file for the '%s' encoding",
48 encodingNameA->getCString()); 48 encodingNameA->getCString());
49 return NULL; 49 return NULL;
50 } 50 }
51 51
52 map = new UnicodeMap(encodingNameA->copy()); 52 map = new UnicodeMap(encodingNameA->copy());
53 53
54 size = 8; 54 size = 8;
55 map->ranges = (UnicodeMapRange *)gmalloc(size * sizeof(UnicodeMapRange)); 55 map->ranges = (UnicodeMapRange *)gmalloc(size * sizeof(UnicodeMapRange));
56 eMapsSize = 0; 56 eMapsSize = 0;
57 57
58 line = 1; 58 line = 1;
59 while (getLine(buf, sizeof(buf), f)) { 59 while (getLine(buf, sizeof(buf), f)) {
60 if ((tok1 = strtok(buf, " \t\r\n")) && 60 if ((tok1 = strtok(buf, " \t\r\n")) &&
61 (tok2 = strtok(NULL, " \t\r\n"))) { 61 (tok2 = strtok(NULL, " \t\r\n"))) {
62 if (!(tok3 = strtok(NULL, " \t\r\n"))) { 62 if (!(tok3 = strtok(NULL, " \t\r\n"))) {
63 tok3 = tok2; 63 tok3 = tok2;
64 tok2 = tok1; 64 tok2 = tok1;
65 } 65 }
66 nBytes = strlen(tok3) / 2; 66 nBytes = strlen(tok3) / 2;
67 if (nBytes <= 4) { 67 if (nBytes <= 4) {
68 if (map->len == size) { 68 if (map->len == size) {
69 size *= 2; 69 size *= 2;
70 map->ranges = (UnicodeMapRange *) 70 map->ranges = (UnicodeMapRange *)
71 grealloc(map->ranges, size * sizeof(UnicodeMapRange)); 71 grealloc(map->ranges, size * sizeof(UnicodeMapRange));
72 } 72 }
73 range = &map->ranges[map->len]; 73 range = &map->ranges[map->len];
74 sscanf(tok1, "%x", &range->start); 74 sscanf(tok1, "%x", &range->start);
75 sscanf(tok2, "%x", &range->end); 75 sscanf(tok2, "%x", &range->end);
76 sscanf(tok3, "%x", &range->code); 76 sscanf(tok3, "%x", &range->code);
77 range->nBytes = nBytes; 77 range->nBytes = nBytes;
78 ++map->len; 78 ++map->len;
79 } else if (tok2 == tok1) { 79 } else if (tok2 == tok1) {
80 if (map->eMapsLen == eMapsSize) { 80 if (map->eMapsLen == eMapsSize) {
81 eMapsSize += 16; 81 eMapsSize += 16;
82 map->eMaps = (UnicodeMapExt *) 82 map->eMaps = (UnicodeMapExt *)
83 grealloc(map->eMaps, eMapsSize * sizeof(UnicodeMapExt)); 83 grealloc(map->eMaps, eMapsSize * sizeof(UnicodeMapExt));
84 } 84 }
85 eMap = &map->eMaps[map->eMapsLen]; 85 eMap = &map->eMaps[map->eMapsLen];
86 sscanf(tok1, "%x", &eMap->u); 86 sscanf(tok1, "%x", &eMap->u);
87 for (i = 0; i < nBytes; ++i) { 87 for (i = 0; i < nBytes; ++i) {
88 sscanf(tok3 + i*2, "%2x", &x); 88 sscanf(tok3 + i*2, "%2x", &x);
89 eMap->code[i] = (char)x; 89 eMap->code[i] = (char)x;
90 } 90 }
91 eMap->nBytes = nBytes; 91 eMap->nBytes = nBytes;
92 ++map->eMapsLen; 92 ++map->eMapsLen;
93 } else { 93 } else {
94 error(-1, "Bad line (%d) in unicodeMap file for the '%s' encoding", 94 error(-1, "Bad line (%d) in unicodeMap file for the '%s' encoding",
95 line, encodingNameA->getCString()); 95 line, encodingNameA->getCString());
96 } 96 }
97 } else { 97 } else {
98 error(-1, "Bad line (%d) in unicodeMap file for the '%s' encoding", 98 error(-1, "Bad line (%d) in unicodeMap file for the '%s' encoding",
99 line, encodingNameA->getCString()); 99 line, encodingNameA->getCString());
100 } 100 }
101 ++line; 101 ++line;
102 } 102 }
103 103
104 return map; 104 return map;
105} 105}
106 106
107UnicodeMap::UnicodeMap(GString *encodingNameA) { 107UnicodeMap::UnicodeMap(GString *encodingNameA) {
108 encodingName = encodingNameA; 108 encodingName = encodingNameA;
109 kind = unicodeMapUser; 109 kind = unicodeMapUser;
110 ranges = NULL; 110 ranges = NULL;
111 len = 0; 111 len = 0;
112 eMaps = NULL; 112 eMaps = NULL;
113 eMapsLen = 0; 113 eMapsLen = 0;
114 refCnt = 1; 114 refCnt = 1;
115} 115}
116 116
117UnicodeMap::UnicodeMap(char *encodingNameA, 117UnicodeMap::UnicodeMap(char *encodingNameA,
118 UnicodeMapRange *rangesA, int lenA) { 118 UnicodeMapRange *rangesA, int lenA) {
119 encodingName = new GString(encodingNameA); 119 encodingName = new GString(encodingNameA);
120 kind = unicodeMapResident; 120 kind = unicodeMapResident;
121 ranges = rangesA; 121 ranges = rangesA;
122 len = lenA; 122 len = lenA;
123 eMaps = NULL; 123 eMaps = NULL;
124 eMapsLen = 0; 124 eMapsLen = 0;
125 refCnt = 1; 125 refCnt = 1;
126} 126}
127 127
128UnicodeMap::UnicodeMap(char *encodingNameA, UnicodeMapFunc funcA) { 128UnicodeMap::UnicodeMap(char *encodingNameA, UnicodeMapFunc funcA) {
129 encodingName = new GString(encodingNameA); 129 encodingName = new GString(encodingNameA);
130 kind = unicodeMapFunc; 130 kind = unicodeMapFunc;
131 func = funcA; 131 func = funcA;
132 eMaps = NULL; 132 eMaps = NULL;
133 eMapsLen = 0; 133 eMapsLen = 0;
134 refCnt = 1; 134 refCnt = 1;
135} 135}
136 136
137UnicodeMap::~UnicodeMap() { 137UnicodeMap::~UnicodeMap() {
138 delete encodingName; 138 delete encodingName;
139 if (kind == unicodeMapUser && ranges) { 139 if (kind == unicodeMapUser && ranges) {
140 gfree(ranges); 140 gfree(ranges);
141 } 141 }
142 if (eMaps) { 142 if (eMaps) {
143 gfree(eMaps); 143 gfree(eMaps);
144 } 144 }
145} 145}
146 146
147void UnicodeMap::incRefCnt() { 147void UnicodeMap::incRefCnt() {
148 ++refCnt; 148 ++refCnt;
149} 149}
150 150
151void UnicodeMap::decRefCnt() { 151void UnicodeMap::decRefCnt() {
152 if (--refCnt == 0) { 152 if (--refCnt == 0) {
153 delete this; 153 delete this;
154 } 154 }
155} 155}
156 156
157GBool UnicodeMap::match(GString *encodingNameA) { 157GBool UnicodeMap::match(GString *encodingNameA) {
158 return !encodingName->cmp(encodingNameA); 158 return !encodingName->cmp(encodingNameA);
159} 159}
160 160
161int UnicodeMap::mapUnicode(Unicode u, char *buf, int bufSize) { 161int UnicodeMap::mapUnicode(Unicode u, char *buf, int bufSize) {
162 int a, b, m, n, i, j; 162 int a, b, m, n, i, j;
163 Guint code; 163 Guint code;
164 164
165 if (kind == unicodeMapFunc) { 165 if (kind == unicodeMapFunc) {
166 return (*func)(u, buf, bufSize); 166 return (*func)(u, buf, bufSize);
167 } 167 }
168 168
169 a = 0; 169 a = 0;
170 b = len; 170 b = len;
171 if (u < ranges[a].start) { 171 if (u < ranges[a].start) {
172 return 0; 172 return 0;
173 } 173 }
174 // invariant: ranges[a].start <= u < ranges[b].start 174 // invariant: ranges[a].start <= u < ranges[b].start
175 while (b - a > 1) { 175 while (b - a > 1) {
176 m = (a + b) / 2; 176 m = (a + b) / 2;
177 if (u >= ranges[m].start) { 177 if (u >= ranges[m].start) {
178 a = m; 178 a = m;
179 } else if (u < ranges[m].start) { 179 } else if (u < ranges[m].start) {
180 b = m; 180 b = m;
181 } 181 }
182 } 182 }
183 if (u <= ranges[a].end) { 183 if (u <= ranges[a].end) {
184 n = ranges[a].nBytes; 184 n = ranges[a].nBytes;
185 if (n > bufSize) { 185 if (n > bufSize) {
186 return 0; 186 return 0;
187 } 187 }
188 code = ranges[a].code + (u - ranges[a].start); 188 code = ranges[a].code + (u - ranges[a].start);
189 for (i = n - 1; i >= 0; --i) { 189 for (i = n - 1; i >= 0; --i) {
190 buf[i] = (char)(code & 0xff); 190 buf[i] = (char)(code & 0xff);
191 code >>= 8; 191 code >>= 8;
192 } 192 }
193 return n; 193 return n;
194 } 194 }
195 195
196 for (i = 0; i < eMapsLen; ++i) { 196 for (i = 0; i < eMapsLen; ++i) {
197 if (eMaps[i].u == u) { 197 if (eMaps[i].u == u) {
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,110 +1,110 @@
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"
20 20
21class GString; 21class GString;
22 22
23//------------------------------------------------------------------------ 23//------------------------------------------------------------------------
24 24
25enum UnicodeMapKind { 25enum UnicodeMapKind {
26 unicodeMapUser, // read from a file 26 unicodeMapUser, // read from a file
27 unicodeMapResident, // static list of ranges 27 unicodeMapResident, // static list of ranges
28 unicodeMapFunc // function pointer 28 unicodeMapFunc // function pointer
29}; 29};
30 30
31typedef int (*UnicodeMapFunc)(Unicode u, char *buf, int bufSize); 31typedef int (*UnicodeMapFunc)(Unicode u, char *buf, int bufSize);
32 32
33struct UnicodeMapRange { 33struct UnicodeMapRange {
34 Unicode start, end; // range of Unicode chars 34 Unicode start, end; // range of Unicode chars
35 Guint code, nBytes; // first output code 35 Guint code, nBytes; // first output code
36}; 36};
37 37
38struct UnicodeMapExt; 38struct UnicodeMapExt;
39 39
40//------------------------------------------------------------------------ 40//------------------------------------------------------------------------
41 41
42class UnicodeMap { 42class UnicodeMap {
43public: 43public:
44 44
45 // Create the UnicodeMap specified by <encodingName>. Sets the 45 // Create the UnicodeMap specified by <encodingName>. Sets the
46 // initial reference count to 1. Returns NULL on failure. 46 // initial reference count to 1. Returns NULL on failure.
47 static UnicodeMap *parse(GString *encodingNameA); 47 static UnicodeMap *parse(GString *encodingNameA);
48 48
49 // Create a resident UnicodeMap. 49 // Create a resident UnicodeMap.
50 UnicodeMap(char *encodingNameA, 50 UnicodeMap(char *encodingNameA,
51 UnicodeMapRange *rangesA, int lenA); 51 UnicodeMapRange *rangesA, int lenA);
52 52
53 // Create a resident UnicodeMap that uses a function instead of a 53 // Create a resident UnicodeMap that uses a function instead of a
54 // list of ranges. 54 // list of ranges.
55 UnicodeMap(char *encodingNameA, UnicodeMapFunc funcA); 55 UnicodeMap(char *encodingNameA, UnicodeMapFunc funcA);
56 56
57 ~UnicodeMap(); 57 ~UnicodeMap();
58 58
59 void incRefCnt(); 59 void incRefCnt();
60 void decRefCnt(); 60 void decRefCnt();
61 61
62 GString *getEncodingName() { return encodingName; } 62 GString *getEncodingName() { return encodingName; }
63 63
64 // Return true if this UnicodeMap matches the specified 64 // Return true if this UnicodeMap matches the specified
65 // <encodingNameA>. 65 // <encodingNameA>.
66 GBool match(GString *encodingNameA); 66 GBool match(GString *encodingNameA);
67 67
68 // Map Unicode to the target encoding. Fills in <buf> with the 68 // Map Unicode to the target encoding. Fills in <buf> with the
69 // output and returns the number of bytes used. Output will be 69 // output and returns the number of bytes used. Output will be
70 // truncated at <bufSize> bytes. No string terminator is written. 70 // truncated at <bufSize> bytes. No string terminator is written.
71 // Returns 0 if no mapping is found. 71 // Returns 0 if no mapping is found.
72 int mapUnicode(Unicode u, char *buf, int bufSize); 72 int mapUnicode(Unicode u, char *buf, int bufSize);
73 73
74private: 74private:
75 75
76 UnicodeMap(GString *encodingNameA); 76 UnicodeMap(GString *encodingNameA);
77 77
78 GString *encodingName; 78 GString *encodingName;
79 UnicodeMapKind kind; 79 UnicodeMapKind kind;
80 union { 80 union {
81 UnicodeMapRange *ranges;// (user, resident) 81 UnicodeMapRange *ranges;// (user, resident)
82 UnicodeMapFunc func;// (func) 82 UnicodeMapFunc func;// (func)
83 }; 83 };
84 int len; // (user, resident) 84 int len; // (user, resident)
85 UnicodeMapExt *eMaps; // (user) 85 UnicodeMapExt *eMaps; // (user)
86 int eMapsLen; // (user) 86 int eMapsLen; // (user)
87 int refCnt; 87 int refCnt;
88}; 88};
89 89
90//------------------------------------------------------------------------ 90//------------------------------------------------------------------------
91 91
92#define unicodeMapCacheSize 4 92#define unicodeMapCacheSize 4
93 93
94class UnicodeMapCache { 94class UnicodeMapCache {
95public: 95public:
96 96
97 UnicodeMapCache(); 97 UnicodeMapCache();
98 ~UnicodeMapCache(); 98 ~UnicodeMapCache();
99 99
100 // Get the UnicodeMap for <encodingName>. Increments its reference 100 // Get the UnicodeMap for <encodingName>. Increments its reference
101 // count; there will be one reference for the cache plus one for the 101 // count; there will be one reference for the cache plus one for the
102 // caller of this function. Returns NULL on failure. 102 // caller of this function. Returns NULL on failure.
103 UnicodeMap *getUnicodeMap(GString *encodingName); 103 UnicodeMap *getUnicodeMap(GString *encodingName);
104 104
105private: 105private:
106 106
107 UnicodeMap *cache[unicodeMapCacheSize]; 107 UnicodeMap *cache[unicodeMapCacheSize];
108}; 108};
109 109
110#endif 110#endif
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,303 +1,361 @@
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 },
28 { 0x02dc, 0x02dc, 0x7e, 1 }, 30 { 0x02dc, 0x02dc, 0x7e, 1 },
29 { 0x2013, 0x2013, 0xad, 1 }, 31 { 0x2013, 0x2013, 0xad, 1 },
30 { 0x2014, 0x2014, 0x2d2d, 2 }, 32 { 0x2014, 0x2014, 0x2d2d, 2 },
31 { 0x2018, 0x2018, 0x60, 1 }, 33 { 0x2018, 0x2018, 0x60, 1 },
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 },
56 { 0x0061, 0x007e, 0x61, 1 }, 75 { 0x0061, 0x007e, 0x61, 1 },
57 { 0x00a6, 0x00a6, 0x7c, 1 }, 76 { 0x00a6, 0x00a6, 0x7c, 1 },
58 { 0x00a9, 0x00a9, 0x286329, 3 }, 77 { 0x00a9, 0x00a9, 0x286329, 3 },
59 { 0x00ae, 0x00ae, 0x285229, 3 }, 78 { 0x00ae, 0x00ae, 0x285229, 3 },
60 { 0x00b7, 0x00b7, 0x2a, 1 }, 79 { 0x00b7, 0x00b7, 0x2a, 1 },
61 { 0x00bc, 0x00bc, 0x312f34, 3 }, 80 { 0x00bc, 0x00bc, 0x312f34, 3 },
62 { 0x00bd, 0x00bd, 0x312f32, 3 }, 81 { 0x00bd, 0x00bd, 0x312f32, 3 },
63 { 0x00be, 0x00be, 0x332f34, 3 }, 82 { 0x00be, 0x00be, 0x332f34, 3 },
64 { 0x00c0, 0x00c0, 0x41, 1 }, 83 { 0x00c0, 0x00c0, 0x41, 1 },
65 { 0x00c1, 0x00c1, 0x41, 1 }, 84 { 0x00c1, 0x00c1, 0x41, 1 },
66 { 0x00c2, 0x00c2, 0x41, 1 }, 85 { 0x00c2, 0x00c2, 0x41, 1 },
67 { 0x00c3, 0x00c3, 0x41, 1 }, 86 { 0x00c3, 0x00c3, 0x41, 1 },
68 { 0x00c4, 0x00c4, 0x41, 1 }, 87 { 0x00c4, 0x00c4, 0x41, 1 },
69 { 0x00c5, 0x00c5, 0x41, 1 }, 88 { 0x00c5, 0x00c5, 0x41, 1 },
70 { 0x00c6, 0x00c6, 0x4145, 2 }, 89 { 0x00c6, 0x00c6, 0x4145, 2 },
71 { 0x00c7, 0x00c7, 0x43, 1 }, 90 { 0x00c7, 0x00c7, 0x43, 1 },
72 { 0x00c8, 0x00c8, 0x45, 1 }, 91 { 0x00c8, 0x00c8, 0x45, 1 },
73 { 0x00c9, 0x00c9, 0x45, 1 }, 92 { 0x00c9, 0x00c9, 0x45, 1 },
74 { 0x00ca, 0x00ca, 0x45, 1 }, 93 { 0x00ca, 0x00ca, 0x45, 1 },
75 { 0x00cb, 0x00cb, 0x45, 1 }, 94 { 0x00cb, 0x00cb, 0x45, 1 },
76 { 0x00cc, 0x00cc, 0x49, 1 }, 95 { 0x00cc, 0x00cc, 0x49, 1 },
77 { 0x00cd, 0x00cd, 0x49, 1 }, 96 { 0x00cd, 0x00cd, 0x49, 1 },
78 { 0x00ce, 0x00ce, 0x49, 1 }, 97 { 0x00ce, 0x00ce, 0x49, 1 },
79 { 0x00cf, 0x00cf, 0x49, 1 }, 98 { 0x00cf, 0x00cf, 0x49, 1 },
80 { 0x00d1, 0x00d2, 0x4e, 1 }, 99 { 0x00d1, 0x00d2, 0x4e, 1 },
81 { 0x00d3, 0x00d3, 0x4f, 1 }, 100 { 0x00d3, 0x00d3, 0x4f, 1 },
82 { 0x00d4, 0x00d4, 0x4f, 1 }, 101 { 0x00d4, 0x00d4, 0x4f, 1 },
83 { 0x00d5, 0x00d5, 0x4f, 1 }, 102 { 0x00d5, 0x00d5, 0x4f, 1 },
84 { 0x00d6, 0x00d6, 0x4f, 1 }, 103 { 0x00d6, 0x00d6, 0x4f, 1 },
85 { 0x00d7, 0x00d7, 0x78, 1 }, 104 { 0x00d7, 0x00d7, 0x78, 1 },
86 { 0x00d8, 0x00d8, 0x4f, 1 }, 105 { 0x00d8, 0x00d8, 0x4f, 1 },
87 { 0x00d9, 0x00d9, 0x55, 1 }, 106 { 0x00d9, 0x00d9, 0x55, 1 },
88 { 0x00da, 0x00da, 0x55, 1 }, 107 { 0x00da, 0x00da, 0x55, 1 },
89 { 0x00db, 0x00db, 0x55, 1 }, 108 { 0x00db, 0x00db, 0x55, 1 },
90 { 0x00dc, 0x00dc, 0x55, 1 }, 109 { 0x00dc, 0x00dc, 0x55, 1 },
91 { 0x00dd, 0x00dd, 0x59, 1 }, 110 { 0x00dd, 0x00dd, 0x59, 1 },
92 { 0x00e0, 0x00e0, 0x61, 1 }, 111 { 0x00e0, 0x00e0, 0x61, 1 },
93 { 0x00e1, 0x00e1, 0x61, 1 }, 112 { 0x00e1, 0x00e1, 0x61, 1 },
94 { 0x00e2, 0x00e2, 0x61, 1 }, 113 { 0x00e2, 0x00e2, 0x61, 1 },
95 { 0x00e3, 0x00e3, 0x61, 1 }, 114 { 0x00e3, 0x00e3, 0x61, 1 },
96 { 0x00e4, 0x00e4, 0x61, 1 }, 115 { 0x00e4, 0x00e4, 0x61, 1 },
97 { 0x00e5, 0x00e5, 0x61, 1 }, 116 { 0x00e5, 0x00e5, 0x61, 1 },
98 { 0x00e6, 0x00e6, 0x6165, 2 }, 117 { 0x00e6, 0x00e6, 0x6165, 2 },
99 { 0x00e7, 0x00e7, 0x63, 1 }, 118 { 0x00e7, 0x00e7, 0x63, 1 },
100 { 0x00e8, 0x00e8, 0x65, 1 }, 119 { 0x00e8, 0x00e8, 0x65, 1 },
101 { 0x00e9, 0x00e9, 0x65, 1 }, 120 { 0x00e9, 0x00e9, 0x65, 1 },
102 { 0x00ea, 0x00ea, 0x65, 1 }, 121 { 0x00ea, 0x00ea, 0x65, 1 },
103 { 0x00eb, 0x00eb, 0x65, 1 }, 122 { 0x00eb, 0x00eb, 0x65, 1 },
104 { 0x00ec, 0x00ec, 0x69, 1 }, 123 { 0x00ec, 0x00ec, 0x69, 1 },
105 { 0x00ed, 0x00ed, 0x69, 1 }, 124 { 0x00ed, 0x00ed, 0x69, 1 },
106 { 0x00ee, 0x00ee, 0x69, 1 }, 125 { 0x00ee, 0x00ee, 0x69, 1 },
107 { 0x00ef, 0x00ef, 0x69, 1 }, 126 { 0x00ef, 0x00ef, 0x69, 1 },
108 { 0x00f1, 0x00f2, 0x6e, 1 }, 127 { 0x00f1, 0x00f2, 0x6e, 1 },
109 { 0x00f3, 0x00f3, 0x6f, 1 }, 128 { 0x00f3, 0x00f3, 0x6f, 1 },
110 { 0x00f4, 0x00f4, 0x6f, 1 }, 129 { 0x00f4, 0x00f4, 0x6f, 1 },
111 { 0x00f5, 0x00f5, 0x6f, 1 }, 130 { 0x00f5, 0x00f5, 0x6f, 1 },
112 { 0x00f6, 0x00f6, 0x6f, 1 }, 131 { 0x00f6, 0x00f6, 0x6f, 1 },
113 { 0x00f7, 0x00f7, 0x2f, 1 }, 132 { 0x00f7, 0x00f7, 0x2f, 1 },
114 { 0x00f8, 0x00f8, 0x6f, 1 }, 133 { 0x00f8, 0x00f8, 0x6f, 1 },
115 { 0x00f9, 0x00f9, 0x75, 1 }, 134 { 0x00f9, 0x00f9, 0x75, 1 },
116 { 0x00fa, 0x00fa, 0x75, 1 }, 135 { 0x00fa, 0x00fa, 0x75, 1 },
117 { 0x00fb, 0x00fb, 0x75, 1 }, 136 { 0x00fb, 0x00fb, 0x75, 1 },
118 { 0x00fc, 0x00fc, 0x75, 1 }, 137 { 0x00fc, 0x00fc, 0x75, 1 },
119 { 0x00fd, 0x00fd, 0x79, 1 }, 138 { 0x00fd, 0x00fd, 0x79, 1 },
120 { 0x00ff, 0x00ff, 0x79, 1 }, 139 { 0x00ff, 0x00ff, 0x79, 1 },
121 { 0x0131, 0x0131, 0x69, 1 }, 140 { 0x0131, 0x0131, 0x69, 1 },
122 { 0x0141, 0x0141, 0x4c, 1 }, 141 { 0x0141, 0x0141, 0x4c, 1 },
123 { 0x0152, 0x0152, 0x4f45, 2 }, 142 { 0x0152, 0x0152, 0x4f45, 2 },
124 { 0x0153, 0x0153, 0x6f65, 2 }, 143 { 0x0153, 0x0153, 0x6f65, 2 },
125 { 0x0160, 0x0160, 0x53, 1 }, 144 { 0x0160, 0x0160, 0x53, 1 },
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 },
150 { 0x0028, 0x0029, 0x28, 1 }, 208 { 0x0028, 0x0029, 0x28, 1 },
151 { 0x002b, 0x002c, 0x2b, 1 }, 209 { 0x002b, 0x002c, 0x2b, 1 },
152 { 0x002e, 0x003f, 0x2e, 1 }, 210 { 0x002e, 0x003f, 0x2e, 1 },
153 { 0x005b, 0x005b, 0x5b, 1 }, 211 { 0x005b, 0x005b, 0x5b, 1 },
154 { 0x005d, 0x005d, 0x5d, 1 }, 212 { 0x005d, 0x005d, 0x5d, 1 },
155 { 0x005f, 0x005f, 0x5f, 1 }, 213 { 0x005f, 0x005f, 0x5f, 1 },
156 { 0x007b, 0x007d, 0x7b, 1 }, 214 { 0x007b, 0x007d, 0x7b, 1 },
157 { 0x00ac, 0x00ac, 0xd8, 1 }, 215 { 0x00ac, 0x00ac, 0xd8, 1 },
158 { 0x00b0, 0x00b1, 0xb0, 1 }, 216 { 0x00b0, 0x00b1, 0xb0, 1 },
159 { 0x00b5, 0x00b5, 0x6d, 1 }, 217 { 0x00b5, 0x00b5, 0x6d, 1 },
160 { 0x00d7, 0x00d7, 0xb4, 1 }, 218 { 0x00d7, 0x00d7, 0xb4, 1 },
161 { 0x00f7, 0x00f7, 0xb8, 1 }, 219 { 0x00f7, 0x00f7, 0xb8, 1 },
162 { 0x0192, 0x0192, 0xa6, 1 }, 220 { 0x0192, 0x0192, 0xa6, 1 },
163 { 0x0391, 0x0392, 0x41, 1 }, 221 { 0x0391, 0x0392, 0x41, 1 },
164 { 0x0393, 0x0393, 0x47, 1 }, 222 { 0x0393, 0x0393, 0x47, 1 },
165 { 0x0395, 0x0395, 0x45, 1 }, 223 { 0x0395, 0x0395, 0x45, 1 },
166 { 0x0396, 0x0396, 0x5a, 1 }, 224 { 0x0396, 0x0396, 0x5a, 1 },
167 { 0x0397, 0x0397, 0x48, 1 }, 225 { 0x0397, 0x0397, 0x48, 1 },
168 { 0x0398, 0x0398, 0x51, 1 }, 226 { 0x0398, 0x0398, 0x51, 1 },
169 { 0x0399, 0x0399, 0x49, 1 }, 227 { 0x0399, 0x0399, 0x49, 1 },
170 { 0x039a, 0x039d, 0x4b, 1 }, 228 { 0x039a, 0x039d, 0x4b, 1 },
171 { 0x039e, 0x039e, 0x58, 1 }, 229 { 0x039e, 0x039e, 0x58, 1 },
172 { 0x039f, 0x03a0, 0x4f, 1 }, 230 { 0x039f, 0x03a0, 0x4f, 1 },
173 { 0x03a1, 0x03a1, 0x52, 1 }, 231 { 0x03a1, 0x03a1, 0x52, 1 },
174 { 0x03a3, 0x03a5, 0x53, 1 }, 232 { 0x03a3, 0x03a5, 0x53, 1 },
175 { 0x03a6, 0x03a6, 0x46, 1 }, 233 { 0x03a6, 0x03a6, 0x46, 1 },
176 { 0x03a7, 0x03a7, 0x43, 1 }, 234 { 0x03a7, 0x03a7, 0x43, 1 },
177 { 0x03a8, 0x03a8, 0x59, 1 }, 235 { 0x03a8, 0x03a8, 0x59, 1 },
178 { 0x03b1, 0x03b2, 0x61, 1 }, 236 { 0x03b1, 0x03b2, 0x61, 1 },
179 { 0x03b3, 0x03b3, 0x67, 1 }, 237 { 0x03b3, 0x03b3, 0x67, 1 },
180 { 0x03b4, 0x03b5, 0x64, 1 }, 238 { 0x03b4, 0x03b5, 0x64, 1 },
181 { 0x03b6, 0x03b6, 0x7a, 1 }, 239 { 0x03b6, 0x03b6, 0x7a, 1 },
182 { 0x03b7, 0x03b7, 0x68, 1 }, 240 { 0x03b7, 0x03b7, 0x68, 1 },
183 { 0x03b8, 0x03b8, 0x71, 1 }, 241 { 0x03b8, 0x03b8, 0x71, 1 },
184 { 0x03b9, 0x03b9, 0x69, 1 }, 242 { 0x03b9, 0x03b9, 0x69, 1 },
185 { 0x03ba, 0x03bb, 0x6b, 1 }, 243 { 0x03ba, 0x03bb, 0x6b, 1 },
186 { 0x03bd, 0x03bd, 0x6e, 1 }, 244 { 0x03bd, 0x03bd, 0x6e, 1 },
187 { 0x03be, 0x03be, 0x78, 1 }, 245 { 0x03be, 0x03be, 0x78, 1 },
188 { 0x03bf, 0x03c0, 0x6f, 1 }, 246 { 0x03bf, 0x03c0, 0x6f, 1 },
189 { 0x03c1, 0x03c1, 0x72, 1 }, 247 { 0x03c1, 0x03c1, 0x72, 1 },
190 { 0x03c2, 0x03c2, 0x56, 1 }, 248 { 0x03c2, 0x03c2, 0x56, 1 },
191 { 0x03c3, 0x03c5, 0x73, 1 }, 249 { 0x03c3, 0x03c5, 0x73, 1 },
192 { 0x03c6, 0x03c6, 0x66, 1 }, 250 { 0x03c6, 0x03c6, 0x66, 1 },
193 { 0x03c7, 0x03c7, 0x63, 1 }, 251 { 0x03c7, 0x03c7, 0x63, 1 },
194 { 0x03c8, 0x03c8, 0x79, 1 }, 252 { 0x03c8, 0x03c8, 0x79, 1 },
195 { 0x03c9, 0x03c9, 0x77, 1 }, 253 { 0x03c9, 0x03c9, 0x77, 1 },
196 { 0x03d1, 0x03d1, 0x4a, 1 }, 254 { 0x03d1, 0x03d1, 0x4a, 1 },
197 { 0x03d2, 0x03d2, 0xa1, 1 }, 255 { 0x03d2, 0x03d2, 0xa1, 1 },
198 { 0x03d5, 0x03d5, 0x6a, 1 }, 256 { 0x03d5, 0x03d5, 0x6a, 1 },
199 { 0x03d6, 0x03d6, 0x76, 1 }, 257 { 0x03d6, 0x03d6, 0x76, 1 },
200 { 0x2022, 0x2022, 0xb7, 1 }, 258 { 0x2022, 0x2022, 0xb7, 1 },
201 { 0x2026, 0x2026, 0xbc, 1 }, 259 { 0x2026, 0x2026, 0xbc, 1 },
202 { 0x2032, 0x2032, 0xa2, 1 }, 260 { 0x2032, 0x2032, 0xa2, 1 },
203 { 0x2033, 0x2033, 0xb2, 1 }, 261 { 0x2033, 0x2033, 0xb2, 1 },
204 { 0x2044, 0x2044, 0xa4, 1 }, 262 { 0x2044, 0x2044, 0xa4, 1 },
205 { 0x2111, 0x2111, 0xc1, 1 }, 263 { 0x2111, 0x2111, 0xc1, 1 },
206 { 0x2118, 0x2118, 0xc3, 1 }, 264 { 0x2118, 0x2118, 0xc3, 1 },
207 { 0x211c, 0x211c, 0xc2, 1 }, 265 { 0x211c, 0x211c, 0xc2, 1 },
208 { 0x2126, 0x2126, 0x57, 1 }, 266 { 0x2126, 0x2126, 0x57, 1 },
209 { 0x2135, 0x2135, 0xc0, 1 }, 267 { 0x2135, 0x2135, 0xc0, 1 },
210 { 0x2190, 0x2193, 0xac, 1 }, 268 { 0x2190, 0x2193, 0xac, 1 },
211 { 0x2194, 0x2194, 0xab, 1 }, 269 { 0x2194, 0x2194, 0xab, 1 },
212 { 0x21b5, 0x21b5, 0xbf, 1 }, 270 { 0x21b5, 0x21b5, 0xbf, 1 },
213 { 0x21d0, 0x21d3, 0xdc, 1 }, 271 { 0x21d0, 0x21d3, 0xdc, 1 },
214 { 0x21d4, 0x21d4, 0xdb, 1 }, 272 { 0x21d4, 0x21d4, 0xdb, 1 },
215 { 0x2200, 0x2200, 0x22, 1 }, 273 { 0x2200, 0x2200, 0x22, 1 },
216 { 0x2202, 0x2202, 0xb6, 1 }, 274 { 0x2202, 0x2202, 0xb6, 1 },
217 { 0x2203, 0x2203, 0x24, 1 }, 275 { 0x2203, 0x2203, 0x24, 1 },
218 { 0x2205, 0x2205, 0xc6, 1 }, 276 { 0x2205, 0x2205, 0xc6, 1 },
219 { 0x2206, 0x2206, 0x44, 1 }, 277 { 0x2206, 0x2206, 0x44, 1 },
220 { 0x2207, 0x2207, 0xd1, 1 }, 278 { 0x2207, 0x2207, 0xd1, 1 },
221 { 0x2208, 0x2209, 0xce, 1 }, 279 { 0x2208, 0x2209, 0xce, 1 },
222 { 0x220b, 0x220b, 0x27, 1 }, 280 { 0x220b, 0x220b, 0x27, 1 },
223 { 0x220f, 0x220f, 0xd5, 1 }, 281 { 0x220f, 0x220f, 0xd5, 1 },
224 { 0x2211, 0x2211, 0xe5, 1 }, 282 { 0x2211, 0x2211, 0xe5, 1 },
225 { 0x2212, 0x2212, 0x2d, 1 }, 283 { 0x2212, 0x2212, 0x2d, 1 },
226 { 0x2217, 0x2217, 0x2a, 1 }, 284 { 0x2217, 0x2217, 0x2a, 1 },
227 { 0x221a, 0x221a, 0xd6, 1 }, 285 { 0x221a, 0x221a, 0xd6, 1 },
228 { 0x221d, 0x221d, 0xb5, 1 }, 286 { 0x221d, 0x221d, 0xb5, 1 },
229 { 0x221e, 0x221e, 0xa5, 1 }, 287 { 0x221e, 0x221e, 0xa5, 1 },
230 { 0x2220, 0x2220, 0xd0, 1 }, 288 { 0x2220, 0x2220, 0xd0, 1 },
231 { 0x2227, 0x2228, 0xd9, 1 }, 289 { 0x2227, 0x2228, 0xd9, 1 },
232 { 0x2229, 0x222a, 0xc7, 1 }, 290 { 0x2229, 0x222a, 0xc7, 1 },
233 { 0x222b, 0x222b, 0xf2, 1 }, 291 { 0x222b, 0x222b, 0xf2, 1 },
234 { 0x2234, 0x2234, 0x5c, 1 }, 292 { 0x2234, 0x2234, 0x5c, 1 },
235 { 0x223c, 0x223c, 0x7e, 1 }, 293 { 0x223c, 0x223c, 0x7e, 1 },
236 { 0x2245, 0x2245, 0x40, 1 }, 294 { 0x2245, 0x2245, 0x40, 1 },
237 { 0x2248, 0x2248, 0xbb, 1 }, 295 { 0x2248, 0x2248, 0xbb, 1 },
238 { 0x2260, 0x2261, 0xb9, 1 }, 296 { 0x2260, 0x2261, 0xb9, 1 },
239 { 0x2264, 0x2264, 0xa3, 1 }, 297 { 0x2264, 0x2264, 0xa3, 1 },
240 { 0x2265, 0x2265, 0xb3, 1 }, 298 { 0x2265, 0x2265, 0xb3, 1 },
241 { 0x2282, 0x2282, 0xcc, 1 }, 299 { 0x2282, 0x2282, 0xcc, 1 },
242 { 0x2283, 0x2283, 0xc9, 1 }, 300 { 0x2283, 0x2283, 0xc9, 1 },
243 { 0x2284, 0x2284, 0xcb, 1 }, 301 { 0x2284, 0x2284, 0xcb, 1 },
244 { 0x2286, 0x2286, 0xcd, 1 }, 302 { 0x2286, 0x2286, 0xcd, 1 },
245 { 0x2287, 0x2287, 0xca, 1 }, 303 { 0x2287, 0x2287, 0xca, 1 },
246 { 0x2295, 0x2295, 0xc5, 1 }, 304 { 0x2295, 0x2295, 0xc5, 1 },
247 { 0x2297, 0x2297, 0xc4, 1 }, 305 { 0x2297, 0x2297, 0xc4, 1 },
248 { 0x22a5, 0x22a5, 0x5e, 1 }, 306 { 0x22a5, 0x22a5, 0x5e, 1 },
249 { 0x22c5, 0x22c5, 0xd7, 1 }, 307 { 0x22c5, 0x22c5, 0xd7, 1 },
250 { 0x2320, 0x2320, 0xf3, 1 }, 308 { 0x2320, 0x2320, 0xf3, 1 },
251 { 0x2321, 0x2321, 0xf5, 1 }, 309 { 0x2321, 0x2321, 0xf5, 1 },
252 { 0x2329, 0x2329, 0xe1, 1 }, 310 { 0x2329, 0x2329, 0xe1, 1 },
253 { 0x232a, 0x232a, 0xf1, 1 }, 311 { 0x232a, 0x232a, 0xf1, 1 },
254 { 0x25ca, 0x25ca, 0xe0, 1 }, 312 { 0x25ca, 0x25ca, 0xe0, 1 },
255 { 0x2660, 0x2660, 0xaa, 1 }, 313 { 0x2660, 0x2660, 0xaa, 1 },
256 { 0x2663, 0x2663, 0xa7, 1 }, 314 { 0x2663, 0x2663, 0xa7, 1 },
257 { 0x2665, 0x2665, 0xa9, 1 }, 315 { 0x2665, 0x2665, 0xa9, 1 },
258 { 0x2666, 0x2666, 0xa8, 1 }, 316 { 0x2666, 0x2666, 0xa8, 1 },
259 { 0xf6d9, 0xf6d9, 0xd3, 1 }, 317 { 0xf6d9, 0xf6d9, 0xd3, 1 },
260 { 0xf6da, 0xf6da, 0xd2, 1 }, 318 { 0xf6da, 0xf6da, 0xd2, 1 },
261 { 0xf6db, 0xf6db, 0xd4, 1 }, 319 { 0xf6db, 0xf6db, 0xd4, 1 },
262 { 0xf8e5, 0xf8e5, 0x60, 1 }, 320 { 0xf8e5, 0xf8e5, 0x60, 1 },
263 { 0xf8e6, 0xf8e7, 0xbd, 1 }, 321 { 0xf8e6, 0xf8e7, 0xbd, 1 },
264 { 0xf8e8, 0xf8ea, 0xe2, 1 }, 322 { 0xf8e8, 0xf8ea, 0xe2, 1 },
265 { 0xf8eb, 0xf8f4, 0xe6, 1 }, 323 { 0xf8eb, 0xf8f4, 0xe6, 1 },
266 { 0xf8f5, 0xf8f5, 0xf4, 1 }, 324 { 0xf8f5, 0xf8f5, 0xf4, 1 },
267 { 0xf8f6, 0xf8fe, 0xf6, 1 } 325 { 0xf8f6, 0xf8fe, 0xf6, 1 }
268}; 326};
269#define symbolUnicodeMapLen (sizeof(symbolUnicodeMapRanges) / sizeof(UnicodeMapRange)) 327#define symbolUnicodeMapLen (sizeof(symbolUnicodeMapRanges) / sizeof(UnicodeMapRange))
270 328
271static UnicodeMapRange zapfDingbatsUnicodeMapRanges[] = { 329static UnicodeMapRange zapfDingbatsUnicodeMapRanges[] = {
272 { 0x0020, 0x0020, 0x20, 1 }, 330 { 0x0020, 0x0020, 0x20, 1 },
273 { 0x2192, 0x2192, 0xd5, 1 }, 331 { 0x2192, 0x2192, 0xd5, 1 },
274 { 0x2194, 0x2195, 0xd6, 1 }, 332 { 0x2194, 0x2195, 0xd6, 1 },
275 { 0x2460, 0x2469, 0xac, 1 }, 333 { 0x2460, 0x2469, 0xac, 1 },
276 { 0x25a0, 0x25a0, 0x6e, 1 }, 334 { 0x25a0, 0x25a0, 0x6e, 1 },
277 { 0x25b2, 0x25b2, 0x73, 1 }, 335 { 0x25b2, 0x25b2, 0x73, 1 },
278 { 0x25bc, 0x25bc, 0x74, 1 }, 336 { 0x25bc, 0x25bc, 0x74, 1 },
279 { 0x25c6, 0x25c6, 0x75, 1 }, 337 { 0x25c6, 0x25c6, 0x75, 1 },
280 { 0x25cf, 0x25cf, 0x6c, 1 }, 338 { 0x25cf, 0x25cf, 0x6c, 1 },
281 { 0x25d7, 0x25d7, 0x77, 1 }, 339 { 0x25d7, 0x25d7, 0x77, 1 },
282 { 0x2605, 0x2605, 0x48, 1 }, 340 { 0x2605, 0x2605, 0x48, 1 },
283 { 0x260e, 0x260e, 0x25, 1 }, 341 { 0x260e, 0x260e, 0x25, 1 },
284 { 0x261b, 0x261b, 0x2a, 1 }, 342 { 0x261b, 0x261b, 0x2a, 1 },
285 { 0x261e, 0x261e, 0x2b, 1 }, 343 { 0x261e, 0x261e, 0x2b, 1 },
286 { 0x2660, 0x2660, 0xab, 1 }, 344 { 0x2660, 0x2660, 0xab, 1 },
287 { 0x2663, 0x2663, 0xa8, 1 }, 345 { 0x2663, 0x2663, 0xa8, 1 },
288 { 0x2665, 0x2665, 0xaa, 1 }, 346 { 0x2665, 0x2665, 0xaa, 1 },
289 { 0x2666, 0x2666, 0xa9, 1 }, 347 { 0x2666, 0x2666, 0xa9, 1 },
290 { 0x2701, 0x2704, 0x21, 1 }, 348 { 0x2701, 0x2704, 0x21, 1 },
291 { 0x2706, 0x2709, 0x26, 1 }, 349 { 0x2706, 0x2709, 0x26, 1 },
292 { 0x270c, 0x2727, 0x2c, 1 }, 350 { 0x270c, 0x2727, 0x2c, 1 },
293 { 0x2729, 0x274b, 0x49, 1 }, 351 { 0x2729, 0x274b, 0x49, 1 },
294 { 0x274d, 0x274d, 0x6d, 1 }, 352 { 0x274d, 0x274d, 0x6d, 1 },
295 { 0x274f, 0x2752, 0x6f, 1 }, 353 { 0x274f, 0x2752, 0x6f, 1 },
296 { 0x2756, 0x2756, 0x76, 1 }, 354 { 0x2756, 0x2756, 0x76, 1 },
297 { 0x2758, 0x275e, 0x78, 1 }, 355 { 0x2758, 0x275e, 0x78, 1 },
298 { 0x2761, 0x2767, 0xa1, 1 }, 356 { 0x2761, 0x2767, 0xa1, 1 },
299 { 0x2776, 0x2794, 0xb6, 1 }, 357 { 0x2776, 0x2794, 0xb6, 1 },
300 { 0x2798, 0x27af, 0xd8, 1 }, 358 { 0x2798, 0x27af, 0xd8, 1 },
301 { 0x27b1, 0x27be, 0xf1, 1 } 359 { 0x27b1, 0x27be, 0xf1, 1 }
302}; 360};
303#define zapfDingbatsUnicodeMapLen (sizeof(zapfDingbatsUnicodeMapRanges) / sizeof(UnicodeMapRange)) 361#define zapfDingbatsUnicodeMapLen (sizeof(zapfDingbatsUnicodeMapRanges) / sizeof(UnicodeMapRange))
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,641 +1,665 @@
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);
157 for (i = 0; i < 35; ++i) { 163 for (i = 0; i < 35; ++i) {
158 if ((c = str->getChar()) == EOF) 164 if ((c = str->getChar()) == EOF)
159 return 0; 165 return 0;
160 buf[i] = c; 166 buf[i] = c;
161 } 167 }
162 if (!strncmp(buf, "trailer", 7)) 168 if (!strncmp(buf, "trailer", 7))
163 break; 169 break;
164 p = buf; 170 p = buf;
165 while (isspace(*p)) ++p; 171 while (isspace(*p)) ++p;
166 while ('0' <= *p && *p <= '9') ++p; 172 while ('0' <= *p && *p <= '9') ++p;
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();
193 } else { 200 } else {
194 pos = 0; 201 pos = 0;
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)) ;
220 s[0] = (char)c; 227 s[0] = (char)c;
221 s[1] = (char)str->getChar(); 228 s[1] = (char)str->getChar();
222 s[2] = (char)str->getChar(); 229 s[2] = (char)str->getChar();
223 s[3] = (char)str->getChar(); 230 s[3] = (char)str->getChar();
224 if (!(s[0] == 'x' && s[1] == 'r' && s[2] == 'e' && s[3] == 'f')) { 231 if (!(s[0] == 'x' && s[1] == 'r' && s[2] == 'e' && s[3] == 'f')) {
225 goto err2; 232 goto err2;
226 } 233 }
227 234
228 // read xref 235 // read xref
229 while (1) { 236 while (1) {
230 while ((c = str->lookChar()) != EOF && isspace(c)) { 237 while ((c = str->lookChar()) != EOF && isspace(c)) {
231 str->getChar(); 238 str->getChar();
232 } 239 }
233 if (c == 't') { 240 if (c == 't') {
234 break; 241 break;
235 } 242 }
236 for (i = 0; (c = str->getChar()) != EOF && isdigit(c) && i < 20; ++i) { 243 for (i = 0; (c = str->getChar()) != EOF && isdigit(c) && i < 20; ++i) {
237 s[i] = (char)c; 244 s[i] = (char)c;
238 } 245 }
239 if (i == 0) { 246 if (i == 0) {
240 goto err2; 247 goto err2;
241 } 248 }
242 s[i] = '\0'; 249 s[i] = '\0';
243 first = atoi(s); 250 first = atoi(s);
244 while ((c = str->lookChar()) != EOF && isspace(c)) { 251 while ((c = str->lookChar()) != EOF && isspace(c)) {
245 str->getChar(); 252 str->getChar();
246 } 253 }
247 for (i = 0; (c = str->getChar()) != EOF && isdigit(c) && i < 20; ++i) { 254 for (i = 0; (c = str->getChar()) != EOF && isdigit(c) && i < 20; ++i) {
248 s[i] = (char)c; 255 s[i] = (char)c;
249 } 256 }
250 if (i == 0) { 257 if (i == 0) {
251 goto err2; 258 goto err2;
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 {
377 pos = 0; 386 pos = 0;
378 } 387 }
379 delete parser; 388 delete parser;
380 389
381 // look for object 390 // look for object
382 } else if (isdigit(*p)) { 391 } else if (isdigit(*p)) {
383 num = atoi(p); 392 num = atoi(p);
384 do { 393 do {
385 ++p; 394 ++p;
386 } while (*p && isdigit(*p)); 395 } while (*p && isdigit(*p));
387 if (isspace(*p)) { 396 if (isspace(*p)) {
388 do { 397 do {
389 ++p; 398 ++p;
390 } while (*p && isspace(*p)); 399 } while (*p && isspace(*p));
391 if (isdigit(*p)) { 400 if (isdigit(*p)) {
392 gen = atoi(p); 401 gen = atoi(p);
393 do { 402 do {
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
437#ifndef NO_DECRYPTION 447#ifndef NO_DECRYPTION
438GBool XRef::checkEncrypted(GString *ownerPassword, GString *userPassword) { 448GBool XRef::checkEncrypted(GString *ownerPassword, GString *userPassword) {
439 Object encrypt, filterObj, versionObj, revisionObj, lengthObj; 449 Object encrypt, filterObj, versionObj, revisionObj, lengthObj;
440 Object ownerKey, userKey, permissions, fileID, fileID1; 450 Object ownerKey, userKey, permissions, fileID, fileID1;
441 GBool encrypted1; 451 GBool encrypted1;
442 GBool ret; 452 GBool ret;
443 453
444 ret = gFalse; 454 ret = gFalse;
445 455
446 permFlags = defPermFlags; 456 permFlags = defPermFlags;
447 trailerDict.dictLookup("Encrypt", &encrypt); 457 trailerDict.dictLookup("Encrypt", &encrypt);
448 if ((encrypted1 = encrypt.isDict())) { 458 if ((encrypted1 = encrypt.isDict())) {
449 ret = gTrue; 459 ret = gTrue;
450 encrypt.dictLookup("Filter", &filterObj); 460 encrypt.dictLookup("Filter", &filterObj);
451 if (filterObj.isName("Standard")) { 461 if (filterObj.isName("Standard")) {
452 encrypt.dictLookup("V", &versionObj); 462 encrypt.dictLookup("V", &versionObj);
453 encrypt.dictLookup("R", &revisionObj); 463 encrypt.dictLookup("R", &revisionObj);
454 encrypt.dictLookup("Length", &lengthObj); 464 encrypt.dictLookup("Length", &lengthObj);
455 encrypt.dictLookup("O", &ownerKey); 465 encrypt.dictLookup("O", &ownerKey);
456 encrypt.dictLookup("U", &userKey); 466 encrypt.dictLookup("U", &userKey);
457 encrypt.dictLookup("P", &permissions); 467 encrypt.dictLookup("P", &permissions);
458 trailerDict.dictLookup("ID", &fileID); 468 trailerDict.dictLookup("ID", &fileID);
459 if (versionObj.isInt() && 469 if (versionObj.isInt() &&
460 revisionObj.isInt() && 470 revisionObj.isInt() &&
461 ownerKey.isString() && ownerKey.getString()->getLength() == 32 && 471 ownerKey.isString() && ownerKey.getString()->getLength() == 32 &&
462 userKey.isString() && userKey.getString()->getLength() == 32 && 472 userKey.isString() && userKey.getString()->getLength() == 32 &&
463 permissions.isInt() && 473 permissions.isInt() &&
464 fileID.isArray()) { 474 fileID.isArray()) {
465 encVersion = versionObj.getInt(); 475 encVersion = versionObj.getInt();
466 encRevision = revisionObj.getInt(); 476 encRevision = revisionObj.getInt();
467 if (lengthObj.isInt()) { 477 if (lengthObj.isInt()) {
468 keyLength = lengthObj.getInt() / 8; 478 keyLength = lengthObj.getInt() / 8;
469 } else { 479 } else {
470 keyLength = 5; 480 keyLength = 5;
471 } 481 }
472 permFlags = permissions.getInt(); 482 permFlags = permissions.getInt();
473 if (encVersion >= 1 && encVersion <= 2 && 483 if (encVersion >= 1 && encVersion <= 2 &&
474 encRevision >= 2 && encRevision <= 3) { 484 encRevision >= 2 && encRevision <= 3) {
475 fileID.arrayGet(0, &fileID1); 485 fileID.arrayGet(0, &fileID1);
476 if (fileID1.isString()) { 486 if (fileID1.isString()) {
477 if (Decrypt::makeFileKey(encVersion, encRevision, keyLength, 487 if (Decrypt::makeFileKey(encVersion, encRevision, keyLength,
478 ownerKey.getString(), userKey.getString(), 488 ownerKey.getString(), userKey.getString(),
479 permFlags, fileID1.getString(), 489 permFlags, fileID1.getString(),
480 ownerPassword, userPassword, fileKey, 490 ownerPassword, userPassword, fileKey,
481 &ownerPasswordOk)) { 491 &ownerPasswordOk)) {
482 if (ownerPassword && !ownerPasswordOk) { 492 if (ownerPassword && !ownerPasswordOk) {
483 error(-1, "Incorrect owner password"); 493 error(-1, "Incorrect owner password");
484 } 494 }
485 ret = gFalse; 495 ret = gFalse;
486 } else { 496 } else {
487 error(-1, "Incorrect password"); 497 error(-1, "Incorrect password");
488 } 498 }
489 } else { 499 } else {
490 error(-1, "Weird encryption info"); 500 error(-1, "Weird encryption info");
491 } 501 }
492 fileID1.free(); 502 fileID1.free();
493 } else { 503 } else {
494 error(-1, "Unsupported version/revision (%d/%d) of Standard security handler", 504 error(-1, "Unsupported version/revision (%d/%d) of Standard security handler",
495 encVersion, encRevision); 505 encVersion, encRevision);
496 } 506 }
497 } else { 507 } else {
498 error(-1, "Weird encryption info"); 508 error(-1, "Weird encryption info");
499 } 509 }
500 fileID.free(); 510 fileID.free();
501 permissions.free(); 511 permissions.free();
502 userKey.free(); 512 userKey.free();
503 ownerKey.free(); 513 ownerKey.free();
504 lengthObj.free(); 514 lengthObj.free();
505 revisionObj.free(); 515 revisionObj.free();
506 versionObj.free(); 516 versionObj.free();
507 } else { 517 } else {
508 error(-1, "Unknown security handler '%s'", 518 error(-1, "Unknown security handler '%s'",
509 filterObj.isName() ? filterObj.getName() : "???"); 519 filterObj.isName() ? filterObj.getName() : "???");
510 } 520 }
511 filterObj.free(); 521 filterObj.free();
512 } 522 }
513 encrypt.free(); 523 encrypt.free();
514 524
515 // this flag has to be set *after* we read the O/U/P strings 525 // this flag has to be set *after* we read the O/U/P strings
516 encrypted = encrypted1; 526 encrypted = encrypted1;
517 527
518 return ret; 528 return ret;
519} 529}
520#else 530#else
521GBool XRef::checkEncrypted(GString *ownerPassword, GString *userPassword) { 531GBool XRef::checkEncrypted(GString *ownerPassword, GString *userPassword) {
522 Object obj; 532 Object obj;
523 GBool encrypted; 533 GBool encrypted;
524 534
525 trailerDict.dictLookup("Encrypt", &obj); 535 trailerDict.dictLookup("Encrypt", &obj);
526 if ((encrypted = !obj.isNull())) { 536 if ((encrypted = !obj.isNull())) {
527 error(-1, "PDF file is encrypted and this version of the Xpdf tools"); 537 error(-1, "PDF file is encrypted and this version of the Xpdf tools");
528 error(-1, "was built without decryption support."); 538 error(-1, "was built without decryption support.");
529 } 539 }
530 obj.free(); 540 obj.free();
531 return encrypted; 541 return encrypted;
532} 542}
533#endif 543#endif
534 544
535GBool XRef::okToPrint(GBool ignoreOwnerPW) { 545GBool XRef::okToPrint(GBool ignoreOwnerPW) {
536#ifndef NO_DECRYPTION 546#ifndef NO_DECRYPTION
537 if ((ignoreOwnerPW || !ownerPasswordOk) && !(permFlags & permPrint)) { 547 if ((ignoreOwnerPW || !ownerPasswordOk) && !(permFlags & permPrint)) {
538 return gFalse; 548 return gFalse;
539 } 549 }
540#endif 550#endif
541 return gTrue; 551 return gTrue;
542} 552}
543 553
544GBool XRef::okToChange(GBool ignoreOwnerPW) { 554GBool XRef::okToChange(GBool ignoreOwnerPW) {
545#ifndef NO_DECRYPTION 555#ifndef NO_DECRYPTION
546 if ((ignoreOwnerPW || !ownerPasswordOk) && !(permFlags & permChange)) { 556 if ((ignoreOwnerPW || !ownerPasswordOk) && !(permFlags & permChange)) {
547 return gFalse; 557 return gFalse;
548 } 558 }
549#endif 559#endif
550 return gTrue; 560 return gTrue;
551} 561}
552 562
553GBool XRef::okToCopy(GBool ignoreOwnerPW) { 563GBool XRef::okToCopy(GBool ignoreOwnerPW) {
554#ifndef NO_DECRYPTION 564#ifndef NO_DECRYPTION
555 if ((ignoreOwnerPW || !ownerPasswordOk) && !(permFlags & permCopy)) { 565 if ((ignoreOwnerPW || !ownerPasswordOk) && !(permFlags & permCopy)) {
556 return gFalse; 566 return gFalse;
557 } 567 }
558#endif 568#endif
559 return gTrue; 569 return gTrue;
560} 570}
561 571
562GBool XRef::okToAddNotes(GBool ignoreOwnerPW) { 572GBool XRef::okToAddNotes(GBool ignoreOwnerPW) {
563#ifndef NO_DECRYPTION 573#ifndef NO_DECRYPTION
564 if ((ignoreOwnerPW || !ownerPasswordOk) && !(permFlags & permNotes)) { 574 if ((ignoreOwnerPW || !ownerPasswordOk) && !(permFlags & permNotes)) {
565 return gFalse; 575 return gFalse;
566 } 576 }
567#endif 577#endif
568 return gTrue; 578 return gTrue;
569} 579}
570 580
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
599 } else { 610 } else {
600 obj->initNull(); 611 obj->initNull();
601 } 612 }
602 obj1.free(); 613 obj1.free();
603 obj2.free(); 614 obj2.free();
604 obj3.free(); 615 obj3.free();
605 delete parser; 616 delete parser;
606 } else { 617 } else {
607 obj->initNull(); 618 obj->initNull();
608 } 619 }
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,111 +1,116 @@
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);
56 59
57 // Get catalog object. 60 // Get catalog object.
58 Object *getCatalog(Object *obj) { return fetch(rootNum, rootGen, obj); } 61 Object *getCatalog(Object *obj) { return fetch(rootNum, rootGen, obj); }
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