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 | ||
22 | class Object; | 22 | class 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 | ||
29 | class GString; | 29 | class GString; |
30 | class GList; | 30 | class GList; |
31 | struct GfxRGB; | 31 | struct GfxRGB; |
32 | class GfxFont; | 32 | class GfxFont; |
33 | class GfxSubpath; | 33 | class GfxSubpath; |
34 | class TextPage; | 34 | class TextPage; |
35 | class XOutputFontCache; | 35 | class XOutputFontCache; |
36 | class Link; | 36 | class Link; |
37 | class Catalog; | 37 | class Catalog; |
38 | class DisplayFontParam; | 38 | class DisplayFontParam; |
39 | class UnicodeMap; | 39 | class UnicodeMap; |
40 | class CharCodeToUnicode; | 40 | class CharCodeToUnicode; |
41 | 41 | ||
42 | 42 | ||
43 | class QPainter; | 43 | class QPainter; |
44 | class QPixmap; | 44 | class QPixmap; |
45 | class QPointArray; | 45 | class QPointArray; |
46 | 46 | ||
47 | 47 | ||
48 | typedef fouble fp_t; | 48 | typedef 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 | ||
64 | class QOutputDev : public QScrollView, public OutputDev { | 64 | class QOutputDev : public QScrollView, public OutputDev { |
65 | public: | 65 | public: |
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 | ||
154 | protected: | 161 | protected: |
155 | virtual void drawContents ( QPainter *p, int, int, int, int ); | 162 | virtual void drawContents ( QPainter *p, int, int, int, int ); |
156 | 163 | ||
157 | private: | 164 | private: |
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 | ||
2 | QPDF - a PDF viewer for the Qtopia environment | 2 | QPDF - a PDF viewer for the Qtopia environment |
3 | 3 | ||
4 | This tool is based on xpdf (currently 1.00). It uses the (mostly unmodified - | 4 | This tool is based on xpdf (currently 1.01). It uses the (mostly unmodified - |
5 | see below) xpdf PDF rendering engine. The Qtopia adaption was done with a new | 5 | see below) xpdf PDF rendering engine. The Qtopia adaption was done with a new |
6 | OutputDev which renders directly to a QPixmap via QPainter calls. | 6 | OutputDev which renders directly to a QPixmap via QPainter calls. |
7 | 7 | ||
8 | Changes in 20020406: | 8 | Changes in 20020406: |
9 | - Font substitution handling improved. | 9 | - Font substitution handling improved. |
10 | - Unknown characters are simply ignored now. | 10 | - Unknown characters are simply ignored now. |
11 | - Fullscreen view added. | 11 | - Fullscreen view added. |
12 | 12 | ||
13 | Changes in 20020407: | 13 | Changes 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 | ||
18 | Changes in 20020408: | 18 | Changes in 20020408: |
19 | - Progress indicator added | 19 | - Progress indicator added |
20 | - Problems with type 3 fonts (not fully supported by XPDF) solved | 20 | - Problems with type 3 fonts (not fully supported by XPDF) solved |
21 | - Heavy optimizations in the image rendering code | 21 | - Heavy optimizations in the image rendering code |
22 | 22 | ||
23 | Changed in 20020413: | 23 | Changes in 20020413: |
24 | - Fixed crash in find routine | 24 | - Fixed crash in find routine |
25 | - Stylus selection reworked | 25 | - Stylus selection reworked |
26 | - Cursor-key navigation added | 26 | - Cursor-key navigation added |
27 | - Various crashes related to recursive calling of XPDF fixed | 27 | - Various crashes related to recursive calling of XPDF fixed |
28 | 28 | ||
29 | Changes in 20020417: | ||
30 | - Fixed crash in XPDF regarding 0-length strings. | ||
31 | - Fast sqrt, rint and fabs functions added. | ||
32 | |||
33 | Changes in 20020524: | ||
34 | - Ported to xpdf 1.01 | ||
35 | |||
29 | 36 | ||
30 | Changes to xpdf: | 37 | Changes to xpdf: |
31 | - xpdf calculates nearly everything with doubles. Since ARMs are not equipped | 38 | - xpdf calculates nearly everything with doubles. Since ARMs are not equipped |
32 | with a FPU, all doubles have been replaced with a C++ class "fouble" (fixed | 39 | with a FPU, all doubles have been replaced with a C++ class "fouble" (fixed |
33 | double), which operates on 32bit integers with fixed point arithmetic. | 40 | double), which operates on 32bit integers with fixed point arithmetic. |
34 | This gave a speedup of up to 800% for image rendering. | 41 | This gave a speedup of up to 800% for image rendering. |
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 | ||
46 | ToDo: | 53 | ToDo: |
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 | ||
54 | Install: | 61 | Install: |
55 | - xpdf-1.00 | 62 | - Qpdf is now fully integrated into Opie. For compilation and installation |
56 | Get the tarball for xpdf, version 1.0, untar it and ./configure it. | 63 | instructions see http://opie.handhelds.org. |
57 | (No special flags are needed for ./configure - it simply has to run) | ||
58 | |||
59 | - qpdf | ||
60 | Make sure your QPEDIR / TMAKEPATH variables are correctly ! | ||
61 | |||
62 | cd into the xpdf directory (xpdf-1.00) and untar the qpdf tarball. This | ||
63 | should create a subdirectory qpdf. | ||
64 | cd into this directory and start the script "./setup-qpdf". This | ||
65 | incorporates the above mentioned patches into xpdf. | ||
66 | |||
67 | Now do a make. | ||
68 | |||
69 | Copy the files qpdf, qpdf_icon.png and qpdf.desktop to the appropriate | ||
70 | directories on your iPaq or: | ||
71 | If you want a ipk, just run ./mkipkg | ||
72 | 64 | ||
73 | - compress / uncompress | 65 | - compress / uncompress |
74 | If you run a normal familiar installation, it the standard gzip (I tested | 66 | If you run a normal familiar installation, the standard gzip (I tested |
75 | 1.2.4-33 ipkg) can handle the compression format used in PDF files, when | 67 | 1.2.4-33 ipkg) can handle the compression format used in PDF files, when |
76 | called as uncompress. The BusyBox version of gzip can _not_ handle this | 68 | called as uncompress. The BusyBox version of gzip can _not_ handle this |
77 | old format. | 69 | old format. |
78 | 70 | ||
79 | If you do not have a working uncompress installed on your iPaq, you can | 71 | If you do not have a working uncompress installed on your iPaq, you could |
80 | simply use the one in the contrib directory of the tarball (make uncompress | 72 | simply use the old compress package. |
81 | a link to compress). | 73 | (I could not find an official tarball for compress -- I used the SuSE |
82 | [I could not find an official tarball for compress -- this is the SuSE | 74 | version cross-compiled for ARM for myself, but I will make an ipk soon) |
83 | version cross-compiled for ARM] | 75 | |
84 | |||
85 | 76 | ||
86 | Have fun ;) | 77 | Have fun ;) |
87 | 78 | ||
88 | Robert (griebl@gmx.de) | 79 | Robert (griebl@gmx.de) |
89 | \ No newline at end of file | 80 | \ No newline at end of file |
diff --git a/noncore/unsupported/qpdf/UTF8.h b/noncore/unsupported/qpdf/UTF8.h index aacf663..95adecf 100644 --- a/noncore/unsupported/qpdf/UTF8.h +++ b/noncore/unsupported/qpdf/UTF8.h | |||
@@ -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 | ||
13 | static int mapUTF8 ( Unicode u, char *buf, int bufSize ) | 13 | static 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 | |||
26 | static int mapUCS2 ( Unicode u, char *buf, int bufSize) | ||
27 | { | ||
28 | if (u <= 0xffff) { | ||
29 | if (bufSize < 2) | ||
30 | return 0; | ||
31 | |||
32 | buf[0] = (char)((u >> 8) & 0xff); | ||
33 | buf[1] = (char)(u & 0xff); | ||
34 | return 2; | ||
35 | } | ||
36 | else | ||
37 | return 0; | ||
38 | } | ||
diff --git a/noncore/unsupported/qpdf/qpdf.cpp b/noncore/unsupported/qpdf/qpdf.cpp index 6c268ec..f338509 100644 --- a/noncore/unsupported/qpdf/qpdf.cpp +++ b/noncore/unsupported/qpdf/qpdf.cpp | |||
@@ -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 | ||
41 | int main ( int argc, char **argv ) | 47 | int main ( int argc, char **argv ) |
42 | { | 48 | { |
43 | QPEApplication app ( argc, argv ); | 49 | QPEApplication app ( argc, argv ); |
44 | 50 | ||
45 | // read config file | 51 | // read config file |
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 | ||
59 | QPdfDlg::QPdfDlg ( ) : QMainWindow ( ) | 65 | QPdfDlg::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 | ||
140 | QPdfDlg::~QPdfDlg ( ) | 151 | QPdfDlg::~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 | ||
147 | void QPdfDlg::resizeEvent ( QResizeEvent * ) | 158 | void 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 | ||
153 | void QPdfDlg::focusInEvent ( QFocusEvent * ) | 164 | void QPdfDlg::focusInEvent ( QFocusEvent * ) |
154 | { | 165 | { |
155 | if ( m_fullscreen ) | 166 | if ( m_fullscreen ) |
156 | setFullscreen ( true ); | 167 | setFullscreen ( true ); |
157 | } | 168 | } |
158 | 169 | ||
159 | void QPdfDlg::toggleFullscreen ( ) | 170 | void 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 | ||
168 | void QPdfDlg::setFullscreen ( bool b ) | 179 | void 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 | ||
192 | void QPdfDlg::setBusy ( bool b ) | 203 | void 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 | ||
202 | bool QPdfDlg::busy ( ) const | 213 | bool QPdfDlg::busy ( ) const |
203 | { | 214 | { |
204 | return m_busy; | 215 | return m_busy; |
205 | } | 216 | } |
206 | 217 | ||
207 | 218 | ||
208 | void QPdfDlg::updateCaption ( ) | 219 | void 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 | ||
220 | void QPdfDlg::setZoom ( int id ) | 231 | void 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 | ||
259 | void QPdfDlg::gotoPageDialog ( ) | 270 | void 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 | ||
9 | class QPEOutputDev; | 10 | class QPEOutputDev; |
10 | class PDFDoc; | 11 | class PDFDoc; |
11 | 12 | ||
12 | class DocLnk; | 13 | class DocLnk; |
13 | class FileSelector; | 14 | class FileSelector; |
15 | class OFileSelector; | ||
14 | class QWidgetStack; | 16 | class QWidgetStack; |
15 | class QLineEdit; | 17 | class QLineEdit; |
16 | 18 | ||
17 | 19 | ||
18 | class QPdfDlg : public QMainWindow { | 20 | class QPdfDlg : public QMainWindow { |
19 | Q_OBJECT | 21 | Q_OBJECT |
20 | 22 | ||
21 | public: | 23 | public: |
22 | QPdfDlg ( ); | 24 | QPdfDlg ( ); |
23 | virtual ~QPdfDlg ( ); | 25 | virtual ~QPdfDlg ( ); |
24 | 26 | ||
25 | public slots: | 27 | public 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 | ||
49 | private slots: | 51 | private 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 | ||
57 | protected: | 59 | protected: |
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 | ||
68 | private: | 70 | private: |
69 | QWidgetStack *m_stack; | 71 | QWidgetStack *m_stack; |
70 | QPEOutputDev *m_outdev; | 72 | QPEOutputDev *m_outdev; |
73 | |||
74 | #ifdef QPDF_QPE_ONLY | ||
71 | FileSelector *m_filesel; | 75 | FileSelector *m_filesel; |
76 | #else | ||
77 | OFileSelector *m_filesel; | ||
78 | #endif | ||
72 | 79 | ||
73 | QToolBar *m_tb_menu, *m_tb_tool, *m_tb_find; | 80 | QToolBar *m_tb_menu, *m_tb_tool, *m_tb_find; |
74 | QLineEdit *m_findedit; | 81 | QLineEdit *m_findedit; |
75 | QPopupMenu *m_pm_zoom; | 82 | QPopupMenu *m_pm_zoom; |
76 | 83 | ||
77 | QToolButton *m_to_find, *m_to_full; | 84 | QToolButton *m_to_find, *m_to_full; |
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 @@ | |||
1 | TEMPLATE = app | 1 | TEMPLATE = app |
2 | 2 | ||
3 | CONFIG *= qt embedded release warn_off | 3 | CONFIG *= qt embedded release warn_off |
4 | CONFIG -= warn_on | 4 | CONFIG -= warn_on |
5 | 5 | ||
6 | SOURCES = xpdf/Array.cc \ | 6 | SOURCES = 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 | ||
43 | HEADERS = QOutputDev.h \ | 44 | HEADERS = QOutputDev.h \ |
44 | QPEOutputDev.h \ | 45 | QPEOutputDev.h \ |
45 | qbusybar.h \ | 46 | qbusybar.h \ |
46 | qpdf.h | 47 | qpdf.h |
47 | 48 | ||
48 | INCLUDEPATH += . \ | 49 | INCLUDEPATH += . \ |
49 | .. \ | 50 | .. \ |
50 | xpdf \ | 51 | xpdf \ |
51 | $(OPIEDIR)/include \ | 52 | $(OPIEDIR)/include \ |
52 | ../goo \ | 53 | ../goo \ |
53 | goo | 54 | goo |
54 | 55 | ||
55 | LIBS += -L $(OPIEDIR)/lib -lqpe | 56 | LIBS += -L $(OPIEDIR)/lib -lqpe -lopie |
56 | 57 | ||
57 | DESTDIR = $(OPIEDIR)/bin | 58 | DESTDIR = $(OPIEDIR)/bin |
58 | TARGET = qpdf | 59 | TARGET = qpdf |
59 | 60 | ||
60 | TRANSLATIONS = ../../i18n/de/qpdf.ts | 61 | TRANSLATIONS = ../../i18n/de/qpdf.ts |
diff --git a/noncore/unsupported/qpdf/xpdf/FormWidget.cc b/noncore/unsupported/qpdf/xpdf/Annot.cc index 05c67a4..49ae50a 100644 --- a/noncore/unsupported/qpdf/xpdf/FormWidget.cc +++ b/noncore/unsupported/qpdf/xpdf/Annot.cc | |||
@@ -1,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 | ||
23 | FormWidget::FormWidget(XRef *xrefA, Dict *dict) { | 23 | Annot::Annot(XRef *xrefA, Dict *dict) { |
24 | Object apObj, asObj, obj1, obj2; | 24 | Object apObj, asObj, obj1, obj2; |
25 | fouble t; | 25 | fouble t; |
26 | 26 | ||
27 | ok = gFalse; | 27 | ok = gFalse; |
28 | xref = xrefA; | 28 | xref = xrefA; |
29 | 29 | ||
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 | ||
80 | FormWidget::~FormWidget() { | 80 | Annot::~Annot() { |
81 | appearance.free(); | 81 | appearance.free(); |
82 | } | 82 | } |
83 | 83 | ||
84 | void FormWidget::draw(Gfx *gfx) { | 84 | void Annot::draw(Gfx *gfx) { |
85 | Object obj; | 85 | Object obj; |
86 | 86 | ||
87 | if (appearance.fetch(xref, &obj)->isStream()) { | 87 | if (appearance.fetch(xref, &obj)->isStream()) { |
88 | gfx->doWidgetForm(&obj, xMin, yMin, xMax, yMax); | 88 | gfx->doAnnot(&obj, xMin, yMin, xMax, yMax); |
89 | } | 89 | } |
90 | obj.free(); | 90 | obj.free(); |
91 | } | 91 | } |
92 | 92 | ||
93 | //------------------------------------------------------------------------ | 93 | //------------------------------------------------------------------------ |
94 | // FormWidgets | 94 | // Annots |
95 | //------------------------------------------------------------------------ | 95 | //------------------------------------------------------------------------ |
96 | 96 | ||
97 | FormWidgets::FormWidgets(XRef *xref, Object *annots) { | 97 | Annots::Annots(XRef *xref, Object *annotsObj) { |
98 | FormWidget *widget; | 98 | Annot *annot; |
99 | Object obj1, obj2; | 99 | Object obj1, obj2; |
100 | int size; | 100 | int size; |
101 | int i; | 101 | int i; |
102 | 102 | ||
103 | widgets = NULL; | 103 | annots = NULL; |
104 | size = 0; | 104 | size = 0; |
105 | nWidgets = 0; | 105 | nAnnots = 0; |
106 | 106 | ||
107 | if (annots->isArray()) { | 107 | if (annotsObj->isArray()) { |
108 | for (i = 0; i < annots->arrayGetLength(); ++i) { | 108 | for (i = 0; i < annotsObj->arrayGetLength(); ++i) { |
109 | if (annots->arrayGet(i, &obj1)->isDict()) { | 109 | if (annotsObj->arrayGet(i, &obj1)->isDict()) { |
110 | obj1.dictLookup("Subtype", &obj2); | 110 | obj1.dictLookup("Subtype", &obj2); |
111 | if (obj2.isName("Widget") || | 111 | if (obj2.isName("Widget") || |
112 | obj2.isName("Stamp")) { | 112 | obj2.isName("Stamp")) { |
113 | widget = new FormWidget(xref, obj1.getDict()); | 113 | annot = new Annot(xref, obj1.getDict()); |
114 | if (widget->isOk()) { | 114 | if (annot->isOk()) { |
115 | if (nWidgets >= size) { | 115 | if (nAnnots >= size) { |
116 | size += 16; | 116 | size += 16; |
117 | widgets = (FormWidget **)grealloc(widgets, | 117 | annots = (Annot **)grealloc(annots, size * sizeof(Annot *)); |
118 | size * sizeof(FormWidget *)); | ||
119 | } | 118 | } |
120 | widgets[nWidgets++] = widget; | 119 | annots[nAnnots++] = annot; |
121 | } else { | 120 | } else { |
122 | delete widget; | 121 | delete annot; |
123 | } | 122 | } |
124 | } | 123 | } |
125 | obj2.free(); | 124 | obj2.free(); |
126 | } | 125 | } |
127 | obj1.free(); | 126 | obj1.free(); |
128 | } | 127 | } |
129 | } | 128 | } |
130 | } | 129 | } |
131 | 130 | ||
132 | FormWidgets::~FormWidgets() { | 131 | Annots::~Annots() { |
133 | int i; | 132 | int i; |
134 | 133 | ||
135 | for (i = 0; i < nWidgets; ++i) { | 134 | for (i = 0; i < nAnnots; ++i) { |
136 | delete widgets[i]; | 135 | delete annots[i]; |
137 | } | 136 | } |
138 | gfree(widgets); | 137 | gfree(annots); |
139 | } | 138 | } |
diff --git a/noncore/unsupported/qpdf/xpdf/FormWidget.h b/noncore/unsupported/qpdf/xpdf/Annot.h index 7f07889..0cc33dd 100644 --- a/noncore/unsupported/qpdf/xpdf/FormWidget.h +++ b/noncore/unsupported/qpdf/xpdf/Annot.h | |||
@@ -1,67 +1,69 @@ | |||
1 | //======================================================================== | 1 | //======================================================================== |
2 | // | 2 | // |
3 | // FormWidget.h | 3 | // Annot.h |
4 | // | 4 | // |
5 | // Copyright 2000 Derek B. Noonburg | 5 | // Copyright 2000-2002 Glyph & Cog, LLC |
6 | // | 6 | // |
7 | //======================================================================== | 7 | //======================================================================== |
8 | 8 | ||
9 | #ifndef FORMWIDGET_H | 9 | #ifndef ANNOT_H |
10 | #define FORMWIDGET_H | 10 | #define ANNOT_H |
11 | 11 | ||
12 | #ifdef __GNUC__ | 12 | #ifdef __GNUC__ |
13 | #pragma interface | 13 | #pragma interface |
14 | #endif | 14 | #endif |
15 | 15 | ||
16 | #include <aconf.h> | ||
17 | |||
16 | class XRef; | 18 | class XRef; |
17 | class Gfx; | 19 | class Gfx; |
18 | 20 | ||
19 | //------------------------------------------------------------------------ | 21 | //------------------------------------------------------------------------ |
20 | // FormWidget | 22 | // Annot |
21 | //------------------------------------------------------------------------ | 23 | //------------------------------------------------------------------------ |
22 | 24 | ||
23 | class FormWidget { | 25 | class Annot { |
24 | public: | 26 | public: |
25 | 27 | ||
26 | FormWidget(XRef *xrefA, Dict *dict); | 28 | Annot(XRef *xrefA, Dict *dict); |
27 | ~FormWidget(); | 29 | ~Annot(); |
28 | GBool isOk() { return ok; } | 30 | GBool isOk() { return ok; } |
29 | 31 | ||
30 | void draw(Gfx *gfx); | 32 | void draw(Gfx *gfx); |
31 | 33 | ||
32 | // Get appearance object. | 34 | // Get appearance object. |
33 | Object *getAppearance(Object *obj) { return appearance.fetch(xref, obj); } | 35 | Object *getAppearance(Object *obj) { return appearance.fetch(xref, obj); } |
34 | 36 | ||
35 | private: | 37 | private: |
36 | 38 | ||
37 | XRef *xref; // the xref table for this PDF file | 39 | XRef *xref; // the xref table for this PDF file |
38 | Object appearance; // a reference to the Form XObject stream | 40 | Object appearance; // a reference to the Form XObject stream |
39 | // for the normal appearance | 41 | // for the normal appearance |
40 | fouble xMin, yMin, // widget rectangle | 42 | fouble xMin, yMin, // annotation rectangle |
41 | xMax, yMax; | 43 | xMax, yMax; |
42 | GBool ok; | 44 | GBool ok; |
43 | }; | 45 | }; |
44 | 46 | ||
45 | //------------------------------------------------------------------------ | 47 | //------------------------------------------------------------------------ |
46 | // FormWidgets | 48 | // Annots |
47 | //------------------------------------------------------------------------ | 49 | //------------------------------------------------------------------------ |
48 | 50 | ||
49 | class FormWidgets { | 51 | class Annots { |
50 | public: | 52 | public: |
51 | 53 | ||
52 | // Extract widgets from array of annotations. | 54 | // Extract non-link annotations from array of annotations. |
53 | FormWidgets(XRef *xref, Object *annots); | 55 | Annots(XRef *xref, Object *annotsObj); |
54 | 56 | ||
55 | ~FormWidgets(); | 57 | ~Annots(); |
56 | 58 | ||
57 | // Iterate through list of widgets. | 59 | // Iterate through list of annotations. |
58 | int getNumWidgets() { return nWidgets; } | 60 | int getNumAnnots() { return nAnnots; } |
59 | FormWidget *getWidget(int i) { return widgets[i]; } | 61 | Annot *getAnnot(int i) { return annots[i]; } |
60 | 62 | ||
61 | private: | 63 | private: |
62 | 64 | ||
63 | FormWidget **widgets; | 65 | Annot **annots; |
64 | int nWidgets; | 66 | int nAnnots; |
65 | }; | 67 | }; |
66 | 68 | ||
67 | #endif | 69 | #endif |
diff --git a/noncore/unsupported/qpdf/xpdf/Array.cc b/noncore/unsupported/qpdf/xpdf/Array.cc index 5743fe6..fbdde49 100644 --- a/noncore/unsupported/qpdf/xpdf/Array.cc +++ b/noncore/unsupported/qpdf/xpdf/Array.cc | |||
@@ -1,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 | ||
23 | Array::Array(XRef *xrefA) { | 23 | Array::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 | ||
30 | Array::~Array() { | 30 | Array::~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 | ||
38 | void Array::add(Object *elem) { | 38 | void 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 | ||
47 | Object *Array::get(int i, Object *obj) { | 47 | Object *Array::get(int i, Object *obj) { |
48 | return elems[i].fetch(xref, obj); | 48 | return elems[i].fetch(xref, obj); |
49 | } | 49 | } |
50 | 50 | ||
51 | Object *Array::getNF(int i, Object *obj) { | 51 | Object *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 | ||
18 | class XRef; | 18 | class XRef; |
19 | 19 | ||
20 | //------------------------------------------------------------------------ | 20 | //------------------------------------------------------------------------ |
21 | // Array | 21 | // Array |
22 | //------------------------------------------------------------------------ | 22 | //------------------------------------------------------------------------ |
23 | 23 | ||
24 | class Array { | 24 | class Array { |
25 | public: | 25 | public: |
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 | ||
47 | private: | 47 | private: |
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 | ||
18 | struct BuiltinFont; | 18 | struct BuiltinFont; |
19 | class BuiltinFontWidths; | 19 | class BuiltinFontWidths; |
20 | 20 | ||
21 | //------------------------------------------------------------------------ | 21 | //------------------------------------------------------------------------ |
22 | 22 | ||
23 | struct BuiltinFont { | 23 | struct 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 | ||
34 | struct BuiltinFontWidth { | 34 | struct BuiltinFontWidth { |
35 | char *name; | 35 | char *name; |
36 | Gushort width; | 36 | Gushort width; |
37 | BuiltinFontWidth *next; | 37 | BuiltinFontWidth *next; |
38 | }; | 38 | }; |
39 | 39 | ||
40 | class BuiltinFontWidths { | 40 | class BuiltinFontWidths { |
41 | public: | 41 | public: |
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 | ||
47 | private: | 47 | private: |
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 | ||
14 | static BuiltinFontWidth courierWidthsTab[] = { | 14 | static 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 | ||
17 | extern BuiltinFont builtinFonts[nBuiltinFonts]; | 17 | extern BuiltinFont builtinFonts[nBuiltinFonts]; |
18 | extern BuiltinFont *builtinFontSubst[nBuiltinFontSubsts]; | 18 | extern BuiltinFont *builtinFontSubst[nBuiltinFontSubsts]; |
19 | 19 | ||
20 | extern void initBuiltinFontTables(); | 20 | extern void initBuiltinFontTables(); |
21 | extern void freeBuiltinFontTables(); | 21 | extern 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 | ||
27 | struct CMapVectorEntry { | 28 | struct 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 | ||
38 | static int getCharFromFile(void *data) { | ||
39 | return fgetc((FILE *)data); | ||
40 | } | ||
41 | |||
42 | //------------------------------------------------------------------------ | ||
43 | |||
37 | CMap *CMap::parse(CMapCache *cache, GString *collectionA, | 44 | CMap *CMap::parse(CMapCache *cache, GString *collectionA, |
38 | GString *cMapNameA) { | 45 | GString *cMapNameA) { |
39 | FILE *f; | 46 | FILE *f; |
40 | CMap *cmap; | 47 | CMap *cmap; |
41 | char buf[256]; | 48 | PSTokenizer *pst; |
42 | GBool inCodeSpace, inCIDRange; | 49 | char tok1[256], tok2[256], tok3[256]; |
43 | char *tok1, *tok2, *tok3; | 50 | int n1, n2, n3; |
44 | Guint start, end; | 51 | Guint start, end; |
45 | Guint n; | ||
46 | 52 | ||
47 | if (!(f = globalParams->findCMapFile(collectionA, cMapNameA))) { | 53 | if (!(f = globalParams->findCMapFile(collectionA, cMapNameA))) { |
48 | 54 | ||
49 | // Check for an identity CMap. | 55 | // Check for an identity CMap. |
50 | if (!cMapNameA->cmp("Identity") || !cMapNameA->cmp("Identity-H")) { | 56 | if (!cMapNameA->cmp("Identity") || !cMapNameA->cmp("Identity-H")) { |
51 | return new CMap(collectionA->copy(), cMapNameA->copy(), 0); | 57 | return new CMap(collectionA->copy(), cMapNameA->copy(), 0); |
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 | ||
114 | CMap::CMap(GString *collectionA, GString *cMapNameA) { | 134 | CMap::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 | ||
128 | CMap::CMap(GString *collectionA, GString *cMapNameA, int wModeA) { | 148 | CMap::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 | ||
136 | void CMap::useCMap(CMapCache *cache, char *useName) { | 156 | void 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 | ||
150 | void CMap::copyVector(CMapVectorEntry *dest, CMapVectorEntry *src) { | 170 | void 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 | ||
175 | void CMap::addCodeSpace(CMapVectorEntry *vec, Guint start, Guint end, | 195 | void 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 | ||
200 | void CMap::addCIDs(Guint start, Guint end, Guint nBytes, CID firstCID) { | 220 | void 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 | ||
228 | CMap::~CMap() { | 248 | CMap::~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 | ||
236 | void CMap::freeCMapVector(CMapVectorEntry *vec) { | 256 | void 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 | ||
247 | void CMap::incRefCnt() { | 267 | void CMap::incRefCnt() { |
248 | ++refCnt; | 268 | ++refCnt; |
249 | } | 269 | } |
250 | 270 | ||
251 | void CMap::decRefCnt() { | 271 | void CMap::decRefCnt() { |
252 | if (--refCnt == 0) { | 272 | if (--refCnt == 0) { |
253 | delete this; | 273 | delete this; |
254 | } | 274 | } |
255 | } | 275 | } |
256 | 276 | ||
257 | GBool CMap::match(GString *collectionA, GString *cMapNameA) { | 277 | GBool 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 | ||
261 | CID CMap::getCID(char *s, int len, int *nUsed) { | 281 | CID 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 | ||
290 | CMapCache::CMapCache() { | 310 | CMapCache::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 | ||
298 | CMapCache::~CMapCache() { | 318 | CMapCache::~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 | ||
19 | class GString; | 19 | class GString; |
20 | struct CMapVectorEntry; | 20 | struct CMapVectorEntry; |
21 | class CMapCache; | 21 | class CMapCache; |
22 | 22 | ||
23 | //------------------------------------------------------------------------ | 23 | //------------------------------------------------------------------------ |
24 | 24 | ||
25 | class CMap { | 25 | class CMap { |
26 | public: | 26 | public: |
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 | ||
53 | private: | 53 | private: |
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 | ||
76 | class CMapCache { | 76 | class CMapCache { |
77 | public: | 77 | public: |
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 | ||
88 | private: | 88 | private: |
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 | ||
29 | Catalog::Catalog(XRef *xrefA, GBool printCommands) { | 29 | Catalog::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 | ||
117 | Catalog::~Catalog() { | 117 | Catalog::~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 | ||
138 | GString *Catalog::readMetadata() { | 138 | GString *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 | ||
162 | int Catalog::readPageTree(Dict *pagesDict, PageAttrs *attrs, int start, | 162 | int 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 | ||
233 | int Catalog::findPage(int num, int gen) { | 233 | int 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 | ||
243 | LinkDest *Catalog::findDest(GString *name) { | 243 | LinkDest *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 | ||
283 | Object *Catalog::findDestInTree(Object *tree, GString *name, Object *obj) { | 283 | Object *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 | ||
16 | class XRef; | 16 | class XRef; |
17 | class Object; | 17 | class Object; |
18 | class Page; | 18 | class Page; |
19 | class PageAttrs; | 19 | class PageAttrs; |
20 | struct Ref; | 20 | struct Ref; |
21 | class LinkDest; | 21 | class LinkDest; |
22 | 22 | ||
23 | //------------------------------------------------------------------------ | 23 | //------------------------------------------------------------------------ |
24 | // Catalog | 24 | // Catalog |
25 | //------------------------------------------------------------------------ | 25 | //------------------------------------------------------------------------ |
26 | 26 | ||
27 | class Catalog { | 27 | class Catalog { |
28 | public: | 28 | public: |
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 | ||
66 | private: | 66 | private: |
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 | ||
27 | struct CharCodeToUnicodeString { | 28 | struct 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 | ||
36 | static int getCharFromString(void *data) { | ||
37 | char *p; | ||
38 | int c; | ||
39 | |||
40 | p = *(char **)data; | ||
41 | if (*p) { | ||
42 | c = *p++; | ||
43 | *(char **)data = p; | ||
44 | } else { | ||
45 | c = EOF; | ||
46 | } | ||
47 | return c; | ||
48 | } | ||
49 | |||
50 | static int getCharFromFile(void *data) { | ||
51 | return fgetc((FILE *)data); | ||
52 | } | ||
53 | |||
54 | //------------------------------------------------------------------------ | ||
55 | |||
35 | CharCodeToUnicode *CharCodeToUnicode::parseCIDToUnicode(GString *collectionA) { | 56 | CharCodeToUnicode *CharCodeToUnicode::parseCIDToUnicode(GString *collectionA) { |
36 | FILE *f; | 57 | FILE *f; |
37 | Unicode *mapA; | 58 | Unicode *mapA; |
38 | CharCode size, mapLenA; | 59 | CharCode size, mapLenA; |
39 | char buf[64]; | 60 | char buf[64]; |
40 | Unicode u; | 61 | Unicode u; |
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 | ||
74 | CharCodeToUnicode *CharCodeToUnicode::make8BitToUnicode(Unicode *toUnicode) { | 95 | CharCodeToUnicode *CharCodeToUnicode::make8BitToUnicode(Unicode *toUnicode) { |
75 | return new CharCodeToUnicode(NULL, toUnicode, 256, gTrue, NULL, 0); | 96 | return new CharCodeToUnicode(NULL, toUnicode, 256, gTrue, NULL, 0); |
76 | } | 97 | } |
77 | 98 | ||
78 | static char *getLineFromString(char *buf, int size, char **s) { | ||
79 | char c; | ||
80 | int i; | ||
81 | |||
82 | i = 0; | ||
83 | while (i < size - 1 && **s) { | ||
84 | buf[i++] = c = *(*s)++; | ||
85 | if (c == '\x0a') { | ||
86 | break; | ||
87 | } | ||
88 | if (c == '\x0d') { | ||
89 | if (**s == '\x0a' && i < size - 1) { | ||
90 | buf[i++] = '\x0a'; | ||
91 | ++*s; | ||
92 | } | ||
93 | break; | ||
94 | } | ||
95 | } | ||
96 | buf[i] = '\0'; | ||
97 | if (i == 0) { | ||
98 | return NULL; | ||
99 | } | ||
100 | return buf; | ||
101 | } | ||
102 | |||
103 | CharCodeToUnicode *CharCodeToUnicode::parseCMap(GString *buf, int nBits) { | 99 | CharCodeToUnicode *CharCodeToUnicode::parseCMap(GString *buf, int nBits) { |
104 | CharCodeToUnicode *ctu; | 100 | CharCodeToUnicode *ctu; |
105 | char *p; | 101 | char *p; |
106 | 102 | ||
107 | ctu = new CharCodeToUnicode(NULL); | 103 | ctu = new CharCodeToUnicode(NULL); |
108 | p = buf->getCString(); | 104 | p = buf->getCString(); |
109 | ctu->parseCMap1((char *(*)(char *, int, void *))&getLineFromString, | 105 | ctu->parseCMap1(&getCharFromString, &p, nBits); |
110 | &p, nBits); | ||
111 | return ctu; | 106 | return ctu; |
112 | } | 107 | } |
113 | 108 | ||
114 | void CharCodeToUnicode::parseCMap1(char *(*getLineFunc)(char *, int, void *), | 109 | void CharCodeToUnicode::parseCMap1(int (*getCharFunc)(void *), void *data, |
115 | void *data, int nBits) { | 110 | int nBits) { |
116 | char buf[256]; | 111 | PSTokenizer *pst; |
117 | GBool inBFChar, inBFRange; | 112 | char tok1[256], tok2[256], tok3[256]; |
118 | char *tok1, *tok2, *tok3; | ||
119 | int nDigits, n1, n2, n3; | 113 | int nDigits, n1, n2, n3; |
120 | CharCode oldLen, i; | 114 | CharCode oldLen, i; |
121 | CharCode code1, code2; | 115 | CharCode code1, code2; |
122 | Unicode u; | 116 | Unicode u; |
123 | char uHex[5]; | 117 | char uHex[5]; |
124 | int j; | 118 | int j; |
125 | GString *name; | 119 | GString *name; |
126 | FILE *f; | 120 | FILE *f; |
127 | 121 | ||
128 | nDigits = nBits / 4; | 122 | nDigits = nBits / 4; |
129 | inBFChar = inBFRange = gFalse; | 123 | pst = new PSTokenizer(getCharFunc, data); |
130 | while ((*getLineFunc)(buf, sizeof(buf), data)) { | 124 | pst->getToken(tok1, sizeof(tok1), &n1); |
131 | tok1 = strtok(buf, " \t\r\n"); | 125 | while (pst->getToken(tok2, sizeof(tok2), &n2)) { |
132 | if (!tok1 || tok1[0] == '%') { | 126 | if (!strcmp(tok2, "usecmap")) { |
133 | continue; | 127 | if (tok1[0] == '/') { |
134 | } | 128 | name = new GString(tok1 + 1); |
135 | tok2 = strtok(NULL, " \t\r\n"); | 129 | if ((f = globalParams->findToUnicodeFile(name))) { |
136 | tok3 = strtok(NULL, " \t\r\n"); | 130 | parseCMap1(&getCharFromFile, f, nBits); |
137 | if (inBFChar) { | 131 | fclose(f); |
138 | if (!strcmp(tok1, "endbfchar")) { | 132 | } else { |
139 | inBFChar = gFalse; | 133 | error(-1, "Couldn't find ToUnicode CMap file for '%s'", |
140 | } else if (tok2) { | 134 | name->getCString()); |
141 | n1 = strlen(tok1); | 135 | } |
142 | n2 = strlen(tok2); | 136 | delete name; |
137 | } | ||
138 | pst->getToken(tok1, sizeof(tok1), &n1); | ||
139 | } else if (!strcmp(tok2, "beginbfchar")) { | ||
140 | while (pst->getToken(tok1, sizeof(tok1), &n1)) { | ||
141 | if (!strcmp(tok1, "endbfchar")) { | ||
142 | break; | ||
143 | } | ||
144 | if (!pst->getToken(tok2, sizeof(tok2), &n2) || | ||
145 | !strcmp(tok2, "endbfchar")) { | ||
146 | error(-1, "Illegal entry in bfchar block in ToUnicode CMap"); | ||
147 | break; | ||
148 | } | ||
143 | if (!(n1 == 2 + nDigits && tok1[0] == '<' && tok1[n1 - 1] == '>' && | 149 | if (!(n1 == 2 + nDigits && tok1[0] == '<' && tok1[n1 - 1] == '>' && |
144 | tok2[0] == '<' && tok2[n2 - 1] == '>')) { | 150 | tok2[0] == '<' && tok2[n2 - 1] == '>')) { |
145 | error(-1, "Illegal line in bfchar block in ToUnicode CMap"); | 151 | error(-1, "Illegal entry in bfchar block in ToUnicode CMap"); |
146 | continue; | 152 | continue; |
147 | } | 153 | } |
148 | tok1[n1 - 1] = tok2[n2 - 1] = '\0'; | 154 | tok1[n1 - 1] = tok2[n2 - 1] = '\0'; |
149 | if (sscanf(tok1 + 1, "%x", &code1) != 1) { | 155 | if (sscanf(tok1 + 1, "%x", &code1) != 1) { |
150 | error(-1, "Illegal line in bfchar block in ToUnicode CMap"); | 156 | error(-1, "Illegal entry in bfchar block in ToUnicode CMap"); |
151 | continue; | 157 | continue; |
152 | } | 158 | } |
153 | if (code1 >= mapLen) { | 159 | if (code1 >= mapLen) { |
154 | oldLen = mapLen; | 160 | oldLen = mapLen; |
155 | mapLen = (code1 + 256) & ~255; | 161 | mapLen = (code1 + 256) & ~255; |
156 | map = (Unicode *)grealloc(map, mapLen * sizeof(Unicode)); | 162 | map = (Unicode *)grealloc(map, mapLen * sizeof(Unicode)); |
157 | for (i = oldLen; i < mapLen; ++i) { | 163 | for (i = oldLen; i < mapLen; ++i) { |
158 | map[i] = 0; | 164 | map[i] = 0; |
159 | } | 165 | } |
160 | } | 166 | } |
161 | if (n2 == 6) { | 167 | if (n2 == 6) { |
162 | if (sscanf(tok2 + 1, "%x", &u) != 1) { | 168 | if (sscanf(tok2 + 1, "%x", &u) != 1) { |
163 | error(-1, "Illegal line in bfchar block in ToUnicode CMap"); | 169 | error(-1, "Illegal entry in bfchar block in ToUnicode CMap"); |
164 | continue; | 170 | continue; |
165 | } | 171 | } |
166 | map[code1] = u; | 172 | map[code1] = u; |
167 | } else { | 173 | } else { |
168 | map[code1] = 0; | 174 | map[code1] = 0; |
169 | if (sMapLen == sMapSize) { | 175 | if (sMapLen == sMapSize) { |
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 | ||
267 | CharCodeToUnicode::CharCodeToUnicode(GString *collectionA) { | 263 | CharCodeToUnicode::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 | ||
281 | CharCodeToUnicode::CharCodeToUnicode(GString *collectionA, Unicode *mapA, | 277 | CharCodeToUnicode::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 | ||
298 | CharCodeToUnicode::~CharCodeToUnicode() { | 294 | CharCodeToUnicode::~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 | ||
308 | void CharCodeToUnicode::incRefCnt() { | 304 | void CharCodeToUnicode::incRefCnt() { |
309 | ++refCnt; | 305 | ++refCnt; |
310 | } | 306 | } |
311 | 307 | ||
312 | void CharCodeToUnicode::decRefCnt() { | 308 | void CharCodeToUnicode::decRefCnt() { |
313 | if (--refCnt == 0) { | 309 | if (--refCnt == 0) { |
314 | delete this; | 310 | delete this; |
315 | } | 311 | } |
316 | } | 312 | } |
317 | 313 | ||
318 | GBool CharCodeToUnicode::match(GString *collectionA) { | 314 | GBool CharCodeToUnicode::match(GString *collectionA) { |
319 | return collection && !collection->cmp(collectionA); | 315 | return collection && !collection->cmp(collectionA); |
320 | } | 316 | } |
321 | 317 | ||
322 | int CharCodeToUnicode::mapToUnicode(CharCode c, Unicode *u, int size) { | 318 | int 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 | ||
345 | CIDToUnicodeCache::CIDToUnicodeCache() { | 341 | CIDToUnicodeCache::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 | ||
353 | CIDToUnicodeCache::~CIDToUnicodeCache() { | 349 | CIDToUnicodeCache::~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 | ||
363 | CharCodeToUnicode *CIDToUnicodeCache::getCIDToUnicode(GString *collection) { | 359 | CharCodeToUnicode *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 | ||
20 | struct CharCodeToUnicodeString; | 20 | struct CharCodeToUnicodeString; |
21 | 21 | ||
22 | //------------------------------------------------------------------------ | 22 | //------------------------------------------------------------------------ |
23 | 23 | ||
24 | class CharCodeToUnicode { | 24 | class CharCodeToUnicode { |
25 | public: | 25 | public: |
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 | ||
51 | private: | 51 | private: |
52 | 52 | ||
53 | void parseCMap1(char *(*getLineFunc)(char *, int, void *), | 53 | void parseCMap1(int (*getCharFunc)(void *), void *data, int nBits); |
54 | void *data, int nBits); | ||
55 | CharCodeToUnicode(GString *collectionA); | 54 | CharCodeToUnicode(GString *collectionA); |
56 | CharCodeToUnicode(GString *collectionA, Unicode *mapA, | 55 | CharCodeToUnicode(GString *collectionA, Unicode *mapA, |
57 | CharCode mapLenA, GBool copyMap, | 56 | CharCode mapLenA, GBool copyMap, |
58 | CharCodeToUnicodeString *sMapA, int sMapLenA); | 57 | CharCodeToUnicodeString *sMapA, int sMapLenA); |
59 | 58 | ||
60 | GString *collection; | 59 | GString *collection; |
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 | ||
72 | class CIDToUnicodeCache { | 71 | class CIDToUnicodeCache { |
73 | public: | 72 | public: |
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 | ||
84 | private: | 83 | private: |
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. |
13 | typedef unsigned int Unicode; | 13 | typedef unsigned int Unicode; |
14 | 14 | ||
15 | // Character ID for CID character collections. | 15 | // Character ID for CID character collections. |
16 | typedef unsigned int CID; | 16 | typedef 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 |
22 | typedef unsigned int CharCode; | 22 | typedef 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 | ||
17 | static void rc4InitKey(Guchar *key, int keyLen, Guchar *state); | 17 | static void rc4InitKey(Guchar *key, int keyLen, Guchar *state); |
18 | static Guchar rc4DecryptByte(Guchar *state, Guchar *x, Guchar *y, Guchar c); | 18 | static Guchar rc4DecryptByte(Guchar *state, Guchar *x, Guchar *y, Guchar c); |
19 | static void md5(Guchar *msg, int msgLen, Guchar *digest); | 19 | static void md5(Guchar *msg, int msgLen, Guchar *digest); |
20 | 20 | ||
21 | static Guchar passwordPad[32] = { | 21 | static 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 | ||
32 | Decrypt::Decrypt(Guchar *fileKey, int keyLength, int objNum, int objGen) { | 32 | Decrypt::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 | ||
54 | void Decrypt::reset() { | 54 | void Decrypt::reset() { |
55 | x = y = 0; | 55 | x = y = 0; |
56 | rc4InitKey(objKey, objKeyLength, state); | 56 | rc4InitKey(objKey, objKeyLength, state); |
57 | } | 57 | } |
58 | 58 | ||
59 | Guchar Decrypt::decryptByte(Guchar c) { | 59 | Guchar Decrypt::decryptByte(Guchar c) { |
60 | return rc4DecryptByte(state, &x, &y, c); | 60 | return rc4DecryptByte(state, &x, &y, c); |
61 | } | 61 | } |
62 | 62 | ||
63 | GBool Decrypt::makeFileKey(int encVersion, int encRevision, int keyLength, | 63 | GBool 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 | ||
112 | GBool Decrypt::makeFileKey2(int encVersion, int encRevision, int keyLength, | 112 | GBool 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 | ||
186 | static void rc4InitKey(Guchar *key, int keyLen, Guchar *state) { | 186 | static 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 | ||
23 | class Decrypt { | 23 | class Decrypt { |
24 | public: | 24 | public: |
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 | ||
46 | private: | 46 | private: |
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 | ||
25 | Dict::Dict(XRef *xrefA) { | 25 | Dict::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 | ||
32 | Dict::~Dict() { | 32 | Dict::~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 | ||
42 | void Dict::add(char *key, Object *val) { | 42 | void 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 | ||
52 | inline DictEntry *Dict::find(char *key) { | 52 | inline 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 | ||
62 | GBool Dict::is(char *type) { | 62 | GBool 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 | ||
68 | Object *Dict::lookup(char *key, Object *obj) { | 68 | Object *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 | ||
74 | Object *Dict::lookupNF(char *key, Object *obj) { | 74 | Object *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 | ||
80 | char *Dict::getKey(int i) { | 80 | char *Dict::getKey(int i) { |
81 | return entries[i].key; | 81 | return entries[i].key; |
82 | } | 82 | } |
83 | 83 | ||
84 | Object *Dict::getVal(int i, Object *obj) { | 84 | Object *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 | ||
88 | Object *Dict::getValNF(int i, Object *obj) { | 88 | Object *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 | ||
22 | struct DictEntry { | 22 | struct DictEntry { |
23 | char *key; | 23 | char *key; |
24 | Object val; | 24 | Object val; |
25 | }; | 25 | }; |
26 | 26 | ||
27 | class Dict { | 27 | class Dict { |
28 | public: | 28 | public: |
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 | ||
64 | private: | 64 | private: |
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 | ||
9 | static struct { | 9 | static struct { |
10 | char *name; | 10 | char *name; |
11 | char *xlfd; | 11 | char *xlfd; |
12 | char *encoding; | 12 | char *encoding; |
13 | } displayFontTab[] = { | 13 | } displayFontTab[] = { |
14 | #if _NO_USE_FOR_QPE | 14 | #if 0 |
15 | {"Courier", "-*-courier-medium-r-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"}, | 15 | {"Courier", "-*-courier-medium-r-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"}, |
16 | {"Courier-Bold", "-*-courier-bold-r-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"}, | 16 | {"Courier-Bold", "-*-courier-bold-r-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"}, |
17 | {"Courier-BoldOblique", "-*-courier-bold-o-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"}, | 17 | {"Courier-BoldOblique", "-*-courier-bold-o-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"}, |
18 | {"Courier-Oblique", "-*-courier-medium-o-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"}, | 18 | {"Courier-Oblique", "-*-courier-medium-o-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"}, |
19 | {"Helvetica", "-*-helvetica-medium-r-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"}, | 19 | {"Helvetica", "-*-helvetica-medium-r-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"}, |
20 | {"Helvetica-Bold", "-*-helvetica-bold-r-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"}, | 20 | {"Helvetica-Bold", "-*-helvetica-bold-r-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"}, |
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 | ||
20 | void CDECL error(int pos, char *msg, ...) { | 20 | void 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 | ||
19 | extern void CDECL error(int pos, char *msg, ...); | 19 | extern 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 | ||
13 | char *macRomanEncoding[256] = { | 13 | char *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 | ||
12 | extern char *macRomanEncoding[]; | 12 | extern char *macRomanEncoding[]; |
13 | extern char *macExpertEncoding[]; | 13 | extern char *macExpertEncoding[]; |
14 | extern char *winAnsiEncoding[]; | 14 | extern char *winAnsiEncoding[]; |
15 | extern char *standardEncoding[]; | 15 | extern char *standardEncoding[]; |
16 | extern char *expertEncoding[]; | 16 | extern char *expertEncoding[]; |
17 | extern char *symbolEncoding[]; | 17 | extern char *symbolEncoding[]; |
18 | extern char *zapfDingbatsEncoding[]; | 18 | extern 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 | ||
29 | Function::Function() { | 29 | Function::Function() { |
30 | } | 30 | } |
31 | 31 | ||
32 | Function::~Function() { | 32 | Function::~Function() { |
33 | } | 33 | } |
34 | 34 | ||
35 | Function *Function::parse(Object *funcObj) { | 35 | Function *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 | ||
80 | GBool Function::init(Dict *dict) { | 80 | GBool 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 | ||
156 | IdentityFunction::IdentityFunction() { | 156 | IdentityFunction::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 | ||
170 | IdentityFunction::~IdentityFunction() { | 170 | IdentityFunction::~IdentityFunction() { |
171 | } | 171 | } |
172 | 172 | ||
173 | void IdentityFunction::transform(fouble *in, fouble *out) { | 173 | void 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 | ||
185 | SampledFunction::SampledFunction(Object *funcObj, Dict *dict) { | 185 | SampledFunction::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 | ||
337 | SampledFunction::~SampledFunction() { | 337 | SampledFunction::~SampledFunction() { |
338 | if (samples) { | 338 | if (samples) { |
339 | gfree(samples); | 339 | gfree(samples); |
340 | } | 340 | } |
341 | } | 341 | } |
342 | 342 | ||
343 | SampledFunction::SampledFunction(SampledFunction *func) { | 343 | SampledFunction::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 | ||
356 | void SampledFunction::transform(fouble *in, fouble *out) { | 356 | void 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 | ||
412 | ExponentialFunction::ExponentialFunction(Object *funcObj, Dict *dict) { | 412 | ExponentialFunction::ExponentialFunction(Object *funcObj, Dict *dict) { |
413 | Object obj1, obj2; | 413 | Object obj1, obj2; |
414 | GBool hasN; | 414 | GBool hasN; |
415 | int i; | 415 | int i; |
416 | 416 | ||
417 | ok = gFalse; | 417 | ok = gFalse; |
418 | hasN = gFalse; | ||
419 | 418 | ||
420 | //----- initialize the generic stuff | 419 | //----- initialize the generic stuff |
421 | if (!init(dict)) { | 420 | if (!init(dict)) { |
422 | goto err1; | 421 | goto err1; |
423 | } | 422 | } |
424 | if (m != 1) { | 423 | if (m != 1) { |
425 | error(-1, "Exponential function with more than one input"); | 424 | error(-1, "Exponential function with more than one input"); |
426 | goto err1; | 425 | goto err1; |
427 | } | 426 | } |
427 | hasN = hasRange; | ||
428 | 428 | ||
429 | //----- default values | 429 | //----- default values |
430 | for (i = 0; i < funcMaxOutputs; ++i) { | 430 | for (i = 0; i < funcMaxOutputs; ++i) { |
431 | c0[i] = 0; | 431 | c0[i] = 0; |
432 | c1[i] = 1; | 432 | c1[i] = 1; |
433 | } | 433 | } |
434 | 434 | ||
435 | //----- C0 | 435 | //----- C0 |
436 | if (dict->lookup("C0", &obj1)->isArray()) { | 436 | if (dict->lookup("C0", &obj1)->isArray()) { |
437 | if (!hasN) { | 437 | if (!hasN) { |
438 | n = obj1.arrayGetLength(); | 438 | n = obj1.arrayGetLength(); |
439 | hasN = gTrue; | ||
439 | } else if (obj1.arrayGetLength() != n) { | 440 | } else if (obj1.arrayGetLength() != n) { |
440 | error(-1, "Function's C0 array is wrong length"); | 441 | error(-1, "Function's C0 array is wrong length"); |
441 | goto err2; | 442 | goto err2; |
442 | } | 443 | } |
443 | for (i = 0; i < n; ++i) { | 444 | for (i = 0; i < n; ++i) { |
444 | obj1.arrayGet(i, &obj2); | 445 | obj1.arrayGet(i, &obj2); |
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 | ||
494 | ExponentialFunction::~ExponentialFunction() { | 503 | ExponentialFunction::~ExponentialFunction() { |
495 | } | 504 | } |
496 | 505 | ||
497 | ExponentialFunction::ExponentialFunction(ExponentialFunction *func) { | 506 | ExponentialFunction::ExponentialFunction(ExponentialFunction *func) { |
498 | memcpy(this, func, sizeof(ExponentialFunction)); | 507 | memcpy(this, func, sizeof(ExponentialFunction)); |
499 | } | 508 | } |
500 | 509 | ||
501 | void ExponentialFunction::transform(fouble *in, fouble *out) { | 510 | void 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 | ||
529 | StitchingFunction::StitchingFunction(Object *funcObj, Dict *dict) { | 538 | StitchingFunction::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 | ||
615 | StitchingFunction::StitchingFunction(StitchingFunction *func) { | 624 | StitchingFunction::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 | ||
626 | StitchingFunction::~StitchingFunction() { | 635 | StitchingFunction::~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 | ||
639 | void StitchingFunction::transform(fouble *in, fouble *out) { | 648 | void 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 | ||
664 | enum PSOp { | 673 | enum 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 | ||
19 | class Dict; | 19 | class Dict; |
20 | class Stream; | 20 | class Stream; |
21 | struct PSObject; | 21 | struct PSObject; |
22 | class PSStack; | 22 | class 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 | ||
31 | class Function { | 31 | class Function { |
32 | public: | 32 | public: |
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 | ||
55 | protected: | 55 | protected: |
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 | ||
69 | class IdentityFunction: public Function { | 69 | class IdentityFunction: public Function { |
70 | public: | 70 | public: |
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 | ||
78 | private: | 78 | private: |
79 | }; | 79 | }; |
80 | 80 | ||
81 | //------------------------------------------------------------------------ | 81 | //------------------------------------------------------------------------ |
82 | // SampledFunction | 82 | // SampledFunction |
83 | //------------------------------------------------------------------------ | 83 | //------------------------------------------------------------------------ |
84 | 84 | ||
85 | class SampledFunction: public Function { | 85 | class SampledFunction: public Function { |
86 | public: | 86 | public: |
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 | ||
94 | private: | 94 | private: |
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 | ||
112 | class ExponentialFunction: public Function { | 112 | class ExponentialFunction: public Function { |
113 | public: | 113 | public: |
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 | ||
121 | private: | 121 | private: |
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 | ||
135 | class StitchingFunction: public Function { | 135 | class StitchingFunction: public Function { |
136 | public: | 136 | public: |
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 | ||
144 | private: | 144 | private: |
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 | ||
159 | class PostScriptFunction: public Function { | 159 | class PostScriptFunction: public Function { |
160 | public: | 160 | public: |
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 | ||
168 | private: | 168 | private: |
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 | ||
47 | Operator Gfx::opTab[] = { | 58 | Operator 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 | ||
208 | GfxResources::GfxResources(XRef *xref, Dict *resDict, GfxResources *nextA) { | 219 | GfxResources::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 | ||
247 | GfxResources::~GfxResources() { | 258 | GfxResources::~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 | ||
258 | GfxFont *GfxResources::lookupFont(char *name) { | 269 | GfxFont *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 | ||
272 | GBool GfxResources::lookupXObject(char *name, Object *obj) { | 283 | GBool 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 | ||
286 | GBool GfxResources::lookupXObjectNF(char *name, Object *obj) { | 297 | GBool 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 | ||
300 | void GfxResources::lookupColorSpace(char *name, Object *obj) { | 311 | void 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 | ||
314 | GfxPattern *GfxResources::lookupPattern(char *name) { | 325 | GfxPattern *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 | ||
333 | GfxShading *GfxResources::lookupShading(char *name) { | 344 | GfxShading *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 | ||
352 | GBool GfxResources::lookupGState(char *name, Object *obj) { | 363 | GBool 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 | ||
371 | Gfx::Gfx(XRef *xrefA, OutputDev *outA, int pageNum, Dict *resDict, fouble dpi, | 382 | Gfx::Gfx(XRef *xrefA, OutputDev *outA, int pageNum, Dict *resDict, fouble dpi, |
372 | PDFRectangle *box, GBool crop, PDFRectangle *cropBox, int rotate, | 383 | PDFRectangle *box, GBool crop, PDFRectangle *cropBox, int rotate, |
373 | GBool printCommandsA) { | 384 | GBool printCommandsA) { |
374 | int i; | 385 | int i; |
375 | 386 | ||
376 | xref = xrefA; | 387 | xref = xrefA; |
388 | subPage = gFalse; | ||
377 | printCommands = printCommandsA; | 389 | printCommands = printCommandsA; |
378 | 390 | ||
379 | // start the resource stack | 391 | // start the resource stack |
380 | res = new GfxResources(xref, resDict, NULL); | 392 | res = new GfxResources(xref, resDict, NULL); |
381 | 393 | ||
382 | // initialize | 394 | // initialize |
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 | ||
408 | Gfx::~Gfx() { | 420 | Gfx::Gfx(XRef *xrefA, OutputDev *outA, Dict *resDict, |
409 | GfxResources *resPtr; | 421 | PDFRectangle *box, GBool crop, PDFRectangle *cropBox) { |
422 | int i; | ||
410 | 423 | ||
424 | xref = xrefA; | ||
425 | subPage = gTrue; | ||
426 | printCommands = gFalse; | ||
427 | |||
428 | // start the resource stack | ||
429 | res = new GfxResources(xref, resDict, NULL); | ||
430 | |||
431 | // initialize | ||
432 | out = outA; | ||
433 | state = new GfxState(72, box, 0, gFalse); | ||
434 | fontChanged = gFalse; | ||
435 | clip = clipNone; | ||
436 | ignoreUndef = 0; | ||
437 | for (i = 0; i < 6; ++i) { | ||
438 | baseMatrix[i] = state->getCTM()[i]; | ||
439 | } | ||
440 | |||
441 | // set crop box | ||
442 | if (crop) { | ||
443 | state->moveTo(cropBox->x1, cropBox->y1); | ||
444 | state->lineTo(cropBox->x2, cropBox->y1); | ||
445 | state->lineTo(cropBox->x2, cropBox->y2); | ||
446 | state->lineTo(cropBox->x1, cropBox->y2); | ||
447 | state->closePath(); | ||
448 | state->clip(); | ||
449 | out->clip(state); | ||
450 | state->clearPath(); | ||
451 | } | ||
452 | } | ||
453 | |||
454 | Gfx::~Gfx() { | ||
411 | while (state->hasSaves()) { | 455 | while (state->hasSaves()) { |
412 | state = state->restore(); | 456 | state = state->restore(); |
413 | out->restoreState(state); | 457 | out->restoreState(state); |
414 | } | 458 | } |
415 | out->endPage(); | 459 | if (!subPage) { |
460 | out->endPage(); | ||
461 | } | ||
416 | while (res) { | 462 | while (res) { |
417 | resPtr = res->getNext(); | 463 | popResources(); |
418 | delete res; | ||
419 | res = resPtr; | ||
420 | } | 464 | } |
421 | if (state) | 465 | if (state) { |
422 | delete state; | 466 | delete state; |
467 | } | ||
423 | } | 468 | } |
424 | 469 | ||
425 | void Gfx::display(Object *obj, GBool topLevel) { | 470 | void Gfx::display(Object *obj, GBool topLevel) { |
426 | Object obj2; | 471 | Object obj2; |
427 | int i; | 472 | int i; |
428 | 473 | ||
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 | ||
449 | void Gfx::go(GBool topLevel) { | 494 | void Gfx::go(GBool topLevel) { |
450 | Object obj; | 495 | Object obj; |
451 | Object args[maxArgs]; | 496 | Object args[maxArgs]; |
452 | int numCmds, numArgs; | 497 | int numArgs; |
453 | int i; | 498 | int i; |
454 | 499 | ||
455 | // scan a sequence of objects | 500 | // scan a sequence of objects |
456 | numCmds = 0; | 501 | updateLevel = 0; |
457 | numArgs = 0; | 502 | numArgs = 0; |
458 | parser->getObj(&obj); | 503 | parser->getObj(&obj); |
459 | while (!obj.isEOF()) { | 504 | while (!obj.isEOF()) { |
460 | 505 | ||
461 | // got a command - execute it | 506 | // got a command - execute it |
462 | if (obj.isCmd()) { | 507 | if (obj.isCmd()) { |
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 | ||
527 | void Gfx::execOp(Object *cmd, Object args[], int numArgs) { | 572 | void Gfx::execOp(Object *cmd, Object args[], int numArgs) { |
528 | Operator *op; | 573 | Operator *op; |
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 | ||
566 | Operator *Gfx::findOp(char *name) { | 611 | Operator *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 | ||
587 | GBool Gfx::checkArg(Object *arg, TchkType type) { | 632 | GBool 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 | ||
602 | int Gfx::getPos() { | 647 | int 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 | ||
610 | void Gfx::opSave(Object args[], int numArgs) { | 655 | void 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 | ||
615 | void Gfx::opRestore(Object args[], int numArgs) { | 660 | void 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 | ||
620 | void Gfx::opConcat(Object args[], int numArgs) { | 665 | void 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 | ||
630 | void Gfx::opSetDash(Object args[], int numArgs) { | 675 | void 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 | ||
652 | void Gfx::opSetFlat(Object args[], int numArgs) { | 697 | void 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 | ||
657 | void Gfx::opSetLineJoin(Object args[], int numArgs) { | 702 | void 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 | ||
662 | void Gfx::opSetLineCap(Object args[], int numArgs) { | 707 | void 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 | ||
667 | void Gfx::opSetMiterLimit(Object args[], int numArgs) { | 712 | void 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 | ||
672 | void Gfx::opSetLineWidth(Object args[], int numArgs) { | 717 | void 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 | ||
677 | void Gfx::opSetExtGState(Object args[], int numArgs) { | 722 | void 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 | ||
701 | void Gfx::opSetRenderingIntent(Object args[], int numArgs) { | 746 | void Gfx::opSetRenderingIntent(Object args[], int numArgs) { |
702 | } | 747 | } |
703 | 748 | ||
704 | //------------------------------------------------------------------------ | 749 | //------------------------------------------------------------------------ |
705 | // color operators | 750 | // color operators |
706 | //------------------------------------------------------------------------ | 751 | //------------------------------------------------------------------------ |
707 | 752 | ||
708 | void Gfx::opSetFillGray(Object args[], int numArgs) { | 753 | void 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 | ||
952 | void Gfx::opCurveTo1(Object args[], int numArgs) { | 997 | void 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 | ||
968 | void Gfx::opCurveTo2(Object args[], int numArgs) { | 1013 | void 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 | ||
984 | void Gfx::opRectangle(Object args[], int numArgs) { | 1029 | void 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 | ||
998 | void Gfx::opClosePath(Object args[], int numArgs) { | 1043 | void 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 | ||
1010 | void Gfx::opEndPath(Object args[], int numArgs) { | 1055 | void Gfx::opEndPath(Object args[], int numArgs) { |
1011 | doEndPath(); | 1056 | doEndPath(); |
1012 | } | 1057 | } |
1013 | 1058 | ||
1014 | void Gfx::opStroke(Object args[], int numArgs) { | 1059 | void 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 | ||
1024 | void Gfx::opCloseStroke(Object args[], int numArgs) { | 1069 | void 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 | ||
1036 | void Gfx::opFill(Object args[], int numArgs) { | 1081 | void 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 | ||
1051 | void Gfx::opEOFill(Object args[], int numArgs) { | 1096 | void 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 | ||
1066 | void Gfx::opFillStroke(Object args[], int numArgs) { | 1111 | void 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 | ||
1082 | void Gfx::opCloseFillStroke(Object args[], int numArgs) { | 1127 | void 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 | ||
1099 | void Gfx::opEOFillStroke(Object args[], int numArgs) { | 1144 | void 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 | ||
1115 | void Gfx::opCloseEOFillStroke(Object args[], int numArgs) { | 1160 | void 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 | ||
1132 | void Gfx::doPatternFill(GBool eoFill) { | 1177 | void 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 | ||
1301 | void Gfx::opShFill(Object args[], int numArgs) { | 1337 | void 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 | ||
1343 | void Gfx::doAxialShFill(GfxAxialShading *shading) { | 1382 | void Gfx::doAxialShFill(GfxAxialShading *shading) { |
1344 | fouble xMin, yMin, xMax, yMax; | 1383 | fouble xMin, yMin, xMax, yMax; |
1345 | fouble x0, y0, x1, y1; | 1384 | fouble x0, y0, x1, y1; |
1346 | fouble det; | ||
1347 | fouble *ctm; | ||
1348 | fouble ictm[6]; | ||
1349 | fouble dx, dy, mul; | 1385 | fouble dx, dy, mul; |
1350 | fouble tMin, tMax, t, tx, ty; | 1386 | fouble tMin, tMax, t, tx, ty; |
1351 | fouble s[4], sMin, sMax, tmp; | 1387 | fouble s[4], sMin, sMax, tmp; |
1352 | fouble ux0, uy0, ux1, uy1, vx0, vy0, vx1, vy1; | 1388 | fouble ux0, uy0, ux1, uy1, vx0, vy0, vx1, vy1; |
1353 | fouble t0, t1, tt; | 1389 | fouble t0, t1, tt; |
1354 | fouble ta[axialMaxSplits + 1]; | 1390 | fouble ta[axialMaxSplits + 1]; |
1355 | int next[axialMaxSplits + 1]; | 1391 | int next[axialMaxSplits + 1]; |
1356 | GfxColor color0, color1; | 1392 | GfxColor color0, color1; |
1357 | int nComps; | 1393 | int nComps; |
1358 | int i, j, k, kk; | 1394 | int i, j, k, kk; |
1359 | 1395 | ||
1360 | // get clip region bbox and transform to current user space | 1396 | // get the clip region bbox |
1361 | state->getClipBBox(&x0, &y0, &x1, &y1); | 1397 | state->getUserClipBBox(&xMin, &yMin, &xMax, &yMax); |
1362 | ctm = state->getCTM(); | ||
1363 | det = 1 / (ctm[0] * ctm[3] - ctm[1] * ctm[2]); | ||
1364 | ictm[0] = ctm[3] * det; | ||
1365 | ictm[1] = -ctm[1] * det; | ||
1366 | ictm[2] = -ctm[2] * det; | ||
1367 | ictm[3] = ctm[0] * det; | ||
1368 | ictm[4] = (ctm[2] * ctm[5] - ctm[3] * ctm[4]) * det; | ||
1369 | ictm[5] = (ctm[1] * ctm[4] - ctm[0] * ctm[5]) * det; | ||
1370 | xMin = xMax = x0 * ictm[0] + y0 * ictm[2] + ictm[4]; | ||
1371 | yMin = yMax = x0 * ictm[1] + y0 * ictm[3] + ictm[5]; | ||
1372 | tx = x0 * ictm[0] + y1 * ictm[2] + ictm[4]; | ||
1373 | ty = x0 * ictm[1] + y1 * ictm[3] + ictm[5]; | ||
1374 | if (tx < xMin) { | ||
1375 | xMin = tx; | ||
1376 | } else if (tx > xMax) { | ||
1377 | xMax = tx; | ||
1378 | } | ||
1379 | if (ty < yMin) { | ||
1380 | yMin = ty; | ||
1381 | } else if (ty > yMax) { | ||
1382 | yMax = ty; | ||
1383 | } | ||
1384 | tx = x1 * ictm[0] + y0 * ictm[2] + ictm[4]; | ||
1385 | ty = x1 * ictm[1] + y0 * ictm[3] + ictm[5]; | ||
1386 | if (tx < xMin) { | ||
1387 | xMin = tx; | ||
1388 | } else if (tx > xMax) { | ||
1389 | xMax = tx; | ||
1390 | } | ||
1391 | if (ty < yMin) { | ||
1392 | yMin = ty; | ||
1393 | } else if (ty > yMax) { | ||
1394 | yMax = ty; | ||
1395 | } | ||
1396 | tx = x1 * ictm[0] + y1 * ictm[2] + ictm[4]; | ||
1397 | ty = x1 * ictm[1] + y1 * ictm[3] + ictm[5]; | ||
1398 | if (tx < xMin) { | ||
1399 | xMin = tx; | ||
1400 | } else if (tx > xMax) { | ||
1401 | xMax = tx; | ||
1402 | } | ||
1403 | if (ty < yMin) { | ||
1404 | yMin = ty; | ||
1405 | } else if (ty > yMax) { | ||
1406 | yMax = ty; | ||
1407 | } | ||
1408 | 1398 | ||
1409 | // compute min and max t values, based on the four corners of the | 1399 | // compute min and max t values, based on the four corners of the |
1410 | // clip region bbox | 1400 | // clip region bbox |
1411 | shading->getCoords(&x0, &y0, &x1, &y1); | 1401 | shading->getCoords(&x0, &y0, &x1, &y1); |
1412 | dx = x1 - x0; | 1402 | dx = x1 - x0; |
1413 | dy = y1 - y0; | 1403 | dy = y1 - y0; |
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 | ||
1612 | void Gfx::doRadialShFill(GfxRadialShading *shading) { | ||
1613 | fouble sMin, sMax, xMin, yMin, xMax, yMax; | ||
1614 | fouble x0, y0, r0, x1, y1, r1, t0, t1; | ||
1615 | int nComps; | ||
1616 | GfxColor colorA, colorB; | ||
1617 | fouble xa, ya, xb, yb, ra, rb; | ||
1618 | fouble ta, tb, sa, sb; | ||
1619 | int ia, ib, k, n; | ||
1620 | fouble *ctm; | ||
1621 | fouble angle, t; | ||
1622 | |||
1623 | // get the shading info | ||
1624 | shading->getCoords(&x0, &y0, &r0, &x1, &y1, &r1); | ||
1625 | t0 = shading->getDomain0(); | ||
1626 | t1 = shading->getDomain1(); | ||
1627 | nComps = shading->getColorSpace()->getNComps(); | ||
1628 | |||
1629 | // compute the (possibly extended) s range | ||
1630 | sMin = 0; | ||
1631 | sMax = 1; | ||
1632 | if (shading->getExtend0()) { | ||
1633 | if (r0 < r1) { | ||
1634 | // extend the smaller end | ||
1635 | sMin = -r0 / (r1 - r0); | ||
1636 | } else { | ||
1637 | // extend the larger end | ||
1638 | //~ this computes the diagonal of the bounding box -- we should | ||
1639 | //~ really compute the intersection of the moving/expanding | ||
1640 | //~ circles with each of the four corners and look for the max | ||
1641 | //~ radius | ||
1642 | state->getUserClipBBox(&xMin, &yMin, &xMax, &yMax); | ||
1643 | sMin = (sqrt((xMax - xMin) * (xMax - xMin) + | ||
1644 | (yMax - yMin) * (yMax - yMin)) - r0) / (r1 - r0); | ||
1645 | if (sMin > 0) { | ||
1646 | sMin = 0; | ||
1647 | } else if (sMin < -20) { | ||
1648 | // sanity check | ||
1649 | sMin = -20; | ||
1650 | } | ||
1651 | } | ||
1652 | } | ||
1653 | if (shading->getExtend1()) { | ||
1654 | if (r1 < r0) { | ||
1655 | // extend the smaller end | ||
1656 | sMax = -r0 / (r1 - r0); | ||
1657 | } else if (r1 > r0) { | ||
1658 | // extend the larger end | ||
1659 | state->getUserClipBBox(&xMin, &yMin, &xMax, &yMax); | ||
1660 | sMax = (sqrt((xMax - xMin) * (xMax - xMin) + | ||
1661 | (yMax - yMin) * (yMax - yMin)) - r0) / (r1 - r0); | ||
1662 | if (sMax < 1) { | ||
1663 | sMin = 1; | ||
1664 | } else if (sMax > 20) { | ||
1665 | // sanity check | ||
1666 | sMax = 20; | ||
1667 | } | ||
1668 | } | ||
1669 | } | ||
1670 | |||
1671 | // compute the number of steps into which circles must be divided to | ||
1672 | // achieve a curve flatness of 0.1 pixel in device space for the | ||
1673 | // largest circle (note that "device space" is 72 dpi when generating | ||
1674 | // PostScript, hence the relatively small 0.1 pixel accuracy) | ||
1675 | ctm = state->getCTM(); | ||
1676 | t = fabs(ctm[0]); | ||
1677 | if (fabs(ctm[1]) > t) { | ||
1678 | t = fabs(ctm[1]); | ||
1679 | } | ||
1680 | if (fabs(ctm[2]) > t) { | ||
1681 | t = fabs(ctm[2]); | ||
1682 | } | ||
1683 | if (fabs(ctm[3]) > t) { | ||
1684 | t = fabs(ctm[3]); | ||
1685 | } | ||
1686 | if (r0 > r1) { | ||
1687 | t *= r0; | ||
1688 | } else { | ||
1689 | t *= r1; | ||
1690 | } | ||
1691 | if (t < 1) { | ||
1692 | n = 3; | ||
1693 | } else { | ||
1694 | n = (int)(M_PI / acos(1 - 0.1 / t)); | ||
1695 | if (n < 3) { | ||
1696 | n = 3; | ||
1697 | } else if (n > 200) { | ||
1698 | n = 200; | ||
1699 | } | ||
1700 | } | ||
1701 | |||
1702 | // Traverse the t axis and do the shading. | ||
1703 | // | ||
1704 | // This generates and fills a series of rings. Each ring is defined | ||
1705 | // by two circles: | ||
1706 | // sa, ta, xa, ya, ra, colorA | ||
1707 | // sb, tb, xb, yb, rb, colorB | ||
1708 | // | ||
1709 | // The s/t axis is divided into radialMaxSplits parts; these parts | ||
1710 | // are combined as much as possible while respecting the | ||
1711 | // radialColorDelta parameter. | ||
1712 | |||
1713 | // setup for the start circle | ||
1714 | ia = 0; | ||
1715 | sa = sMin; | ||
1716 | ta = t0 + sa * (t1 - t0); | ||
1717 | xa = x0 + sa * (x1 - x0); | ||
1718 | ya = y0 + sa * (y1 - y0); | ||
1719 | ra = r0 + sa * (r1 - r0); | ||
1720 | if (ta < t0) { | ||
1721 | shading->getColor(t0, &colorA); | ||
1722 | } else if (ta > t1) { | ||
1723 | shading->getColor(t1, &colorA); | ||
1724 | } else { | ||
1725 | shading->getColor(ta, &colorA); | ||
1726 | } | ||
1727 | |||
1728 | while (ia < radialMaxSplits) { | ||
1729 | |||
1730 | // go as far along the t axis (toward t1) as we can, such that the | ||
1731 | // color difference is within the tolerance (radialColorDelta) -- | ||
1732 | // this uses bisection (between the current value, t, and t1), | ||
1733 | // limited to radialMaxSplits points along the t axis | ||
1734 | ib = radialMaxSplits; | ||
1735 | sb = sMin + ((fouble)ib / (fouble)radialMaxSplits) * (sMax - sMin); | ||
1736 | tb = t0 + sb * (t1 - t0); | ||
1737 | if (tb < t0) { | ||
1738 | shading->getColor(t0, &colorB); | ||
1739 | } else if (tb > t1) { | ||
1740 | shading->getColor(t1, &colorB); | ||
1741 | } else { | ||
1742 | shading->getColor(tb, &colorB); | ||
1743 | } | ||
1744 | while (ib - ia > 1) { | ||
1745 | for (k = 0; k < nComps; ++k) { | ||
1746 | if (fabs(colorB.c[k] - colorA.c[k]) > radialColorDelta) { | ||
1747 | break; | ||
1748 | } | ||
1749 | } | ||
1750 | if (k == nComps) { | ||
1751 | break; | ||
1752 | } | ||
1753 | ib = (ia + ib) / 2; | ||
1754 | sb = sMin + ((fouble)ib / (fouble)radialMaxSplits) * (sMax - sMin); | ||
1755 | tb = t0 + sb * (t1 - t0); | ||
1756 | if (tb < t0) { | ||
1757 | shading->getColor(t0, &colorB); | ||
1758 | } else if (tb > t1) { | ||
1759 | shading->getColor(t1, &colorB); | ||
1760 | } else { | ||
1761 | shading->getColor(tb, &colorB); | ||
1762 | } | ||
1763 | } | ||
1764 | |||
1765 | // compute center and radius of the circle | ||
1766 | xb = x0 + sb * (x1 - x0); | ||
1767 | yb = y0 + sb * (y1 - y0); | ||
1768 | rb = r0 + sb * (r1 - r0); | ||
1769 | |||
1770 | // use the average of the colors at the two circles | ||
1771 | for (k = 0; k < nComps; ++k) { | ||
1772 | colorA.c[k] = 0.5 * (colorA.c[k] + colorB.c[k]); | ||
1773 | } | ||
1774 | state->setFillColor(&colorA); | ||
1775 | out->updateFillColor(state); | ||
1776 | |||
1777 | // construct path for first circle | ||
1778 | state->moveTo(xa + ra, ya); | ||
1779 | for (k = 1; k < n; ++k) { | ||
1780 | angle = ((fouble)k / (fouble)n) * 2 * M_PI; | ||
1781 | state->lineTo(xa + ra * cos(angle), ya + ra * sin(angle)); | ||
1782 | } | ||
1783 | state->closePath(); | ||
1784 | |||
1785 | // construct and append path for second circle | ||
1786 | state->moveTo(xb + rb, yb); | ||
1787 | for (k = 1; k < n; ++k) { | ||
1788 | angle = ((fouble)k / (fouble)n) * 2 * M_PI; | ||
1789 | state->lineTo(xb + rb * cos(angle), yb + rb * sin(angle)); | ||
1790 | } | ||
1791 | state->closePath(); | ||
1792 | |||
1793 | // fill the ring | ||
1794 | out->eoFill(state); | ||
1795 | state->clearPath(); | ||
1796 | |||
1797 | // step to the next value of t | ||
1798 | ia = ib; | ||
1799 | sa = sb; | ||
1800 | ta = tb; | ||
1801 | xa = xb; | ||
1802 | ya = yb; | ||
1803 | ra = rb; | ||
1804 | colorA = colorB; | ||
1805 | } | ||
1806 | } | ||
1807 | |||
1622 | void Gfx::doEndPath() { | 1808 | void Gfx::doEndPath() { |
1623 | if (state->isPath() && clip != clipNone) { | 1809 | if (state->isPath() && clip != clipNone) { |
1624 | state->clip(); | 1810 | state->clip(); |
1625 | if (clip == clipNormal) { | 1811 | if (clip == clipNormal) { |
1626 | out->clip(state); | 1812 | out->clip(state); |
1627 | } else { | 1813 | } else { |
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 | ||
1639 | void Gfx::opClip(Object args[], int numArgs) { | 1825 | void Gfx::opClip(Object args[], int numArgs) { |
1640 | clip = clipNormal; | 1826 | clip = clipNormal; |
1641 | } | 1827 | } |
1642 | 1828 | ||
1643 | void Gfx::opEOClip(Object args[], int numArgs) { | 1829 | void 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 | ||
1651 | void Gfx::opBeginText(Object args[], int numArgs) { | 1837 | void 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 | ||
1659 | void Gfx::opEndText(Object args[], int numArgs) { | 1845 | void Gfx::opEndText(Object args[], int numArgs) { |
1660 | } | 1846 | } |
1661 | 1847 | ||
1662 | //------------------------------------------------------------------------ | 1848 | //------------------------------------------------------------------------ |
1663 | // text state operators | 1849 | // text state operators |
1664 | //------------------------------------------------------------------------ | 1850 | //------------------------------------------------------------------------ |
1665 | 1851 | ||
1666 | void Gfx::opSetCharSpacing(Object args[], int numArgs) { | 1852 | void 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 | ||
1671 | void Gfx::opSetFont(Object args[], int numArgs) { | 1857 | void 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 | ||
1688 | void Gfx::opSetTextLeading(Object args[], int numArgs) { | 1874 | void Gfx::opSetTextLeading(Object args[], int numArgs) { |
1689 | state->setLeading(args[0].getNum()); | 1875 | state->setLeading(args[0].getNum()); |
1690 | } | 1876 | } |
1691 | 1877 | ||
1692 | void Gfx::opSetTextRender(Object args[], int numArgs) { | 1878 | void 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 | ||
1697 | void Gfx::opSetTextRise(Object args[], int numArgs) { | 1883 | void 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 | ||
1702 | void Gfx::opSetWordSpacing(Object args[], int numArgs) { | 1888 | void 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 | ||
1707 | void Gfx::opSetHorizScaling(Object args[], int numArgs) { | 1893 | void 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 | ||
1717 | void Gfx::opTextMove(Object args[], int numArgs) { | 1903 | void 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 | ||
1726 | void Gfx::opTextMoveSet(Object args[], int numArgs) { | 1912 | void 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 | ||
1737 | void Gfx::opSetTextMatrix(Object args[], int numArgs) { | 1923 | void 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 | ||
1747 | void Gfx::opTextNextLine(Object args[], int numArgs) { | 1933 | void 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 | ||
1760 | void Gfx::opShowText(Object args[], int numArgs) { | 1946 | void 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 | ||
1768 | void Gfx::opMoveShowText(Object args[], int numArgs) { | 1954 | void 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 | ||
1782 | void Gfx::opMoveSetShowText(Object args[], int numArgs) { | 1968 | void 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 | ||
1800 | void Gfx::opShowSpaceText(Object args[], int numArgs) { | 1986 | void Gfx::opShowSpaceText(Object args[], int numArgs) { |
1801 | Array *a; | 1987 | Array *a; |
1802 | Object obj; | 1988 | Object obj; |
1989 | int wMode; | ||
1803 | int i; | 1990 | int i; |
1804 | 1991 | ||
1805 | if (!state->getFont()) { | 1992 | if (!state->getFont()) { |
1806 | error(getPos(), "No font in show/space"); | 1993 | error(getPos(), "No font in show/space"); |
1807 | return; | 1994 | return; |
1808 | } | 1995 | } |
1996 | wMode = state->getFont()->getWMode(); | ||
1809 | a = args[0].getArray(); | 1997 | a = args[0].getArray(); |
1810 | for (i = 0; i < a->getLength(); ++i) { | 1998 | for (i = 0; i < a->getLength(); ++i) { |
1811 | a->get(i, &obj); | 1999 | a->get(i, &obj); |
1812 | if (obj.isNum()) { | 2000 | if (obj.isNum()) { |
1813 | state->textShift(-obj.getNum() * 0.001 * state->getFontSize()); | 2001 | if (wMode) { |
2002 | state->textShift(0, -obj.getNum() * 0.001 * state->getFontSize()); | ||
2003 | } else { | ||
2004 | state->textShift(-obj.getNum() * 0.001 * state->getFontSize(), 0); | ||
2005 | } | ||
1814 | out->updateTextShift(state, obj.getNum()); | 2006 | out->updateTextShift(state, obj.getNum()); |
1815 | } else if (obj.isString()) { | 2007 | } else if (obj.isString()) { |
1816 | doShowText(obj.getString()); | 2008 | doShowText(obj.getString()); |
1817 | } else { | 2009 | } else { |
1818 | error(getPos(), "Element of show/space array must be number or string"); | 2010 | error(getPos(), "Element of show/space array must be number or string"); |
1819 | } | 2011 | } |
1820 | obj.free(); | 2012 | obj.free(); |
1821 | } | 2013 | } |
1822 | } | 2014 | } |
1823 | 2015 | ||
1824 | void Gfx::doShowText(GString *s) { | 2016 | void Gfx::doShowText(GString *s) { |
1825 | GfxFont *font; | 2017 | GfxFont *font; |
2018 | int wMode; | ||
1826 | fouble riseX, riseY; | 2019 | fouble riseX, riseY; |
1827 | CharCode code; | 2020 | CharCode code; |
1828 | Unicode u[8]; | 2021 | Unicode u[8]; |
1829 | fouble dx, dy, dx2, dy2, tdx, tdy; | 2022 | fouble x, y, dx, dy, dx2, dy2, curX, curY, tdx, tdy; |
1830 | fouble originX, originY, tOriginX, tOriginY; | 2023 | fouble originX, originY, tOriginX, tOriginY; |
2024 | fouble oldCTM[6], newCTM[6]; | ||
2025 | fouble *mat; | ||
2026 | Object charProc; | ||
2027 | Dict *resDict; | ||
2028 | Parser *oldParser; | ||
1831 | char *p; | 2029 | char *p; |
1832 | int len, n, uLen, nChars, nSpaces; | 2030 | int len, n, uLen, nChars, nSpaces, i; |
1833 | 2031 | ||
1834 | if (fontChanged) { | 2032 | if (fontChanged) { |
1835 | out->updateFont(state); | 2033 | out->updateFont(state); |
1836 | fontChanged = gFalse; | 2034 | fontChanged = gFalse; |
1837 | } | 2035 | } |
1838 | font = state->getFont(); | 2036 | font = state->getFont(); |
2037 | wMode = font->getWMode(); | ||
1839 | 2038 | ||
1840 | #if 0 //~type3 | 2039 | if (out->useDrawChar()) { |
1841 | fouble x, y; | ||
1842 | fouble oldCTM[6], newCTM[6]; | ||
1843 | fouble *mat; | ||
1844 | Object charProc; | ||
1845 | Parser *oldParser; | ||
1846 | int i; | ||
1847 | |||
1848 | //~ also check out->renderType3() | ||
1849 | if (font->getType() == fontType3) { | ||
1850 | out->beginString(state, s); | 2040 | out->beginString(state, s); |
2041 | } | ||
2042 | |||
2043 | // handle a Type 3 char | ||
2044 | if (font->getType() == fontType3 && out->interpretType3Chars()) { | ||
1851 | mat = state->getCTM(); | 2045 | mat = state->getCTM(); |
1852 | for (i = 0; i < 6; ++i) { | 2046 | for (i = 0; i < 6; ++i) { |
1853 | oldCTM[i] = mat[i]; | 2047 | oldCTM[i] = mat[i]; |
1854 | } | 2048 | } |
1855 | mat = state->getTextMat(); | 2049 | mat = state->getTextMat(); |
1856 | newCTM[0] = mat[0] * oldCTM[0] + mat[1] * oldCTM[2]; | 2050 | newCTM[0] = mat[0] * oldCTM[0] + mat[1] * oldCTM[2]; |
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 | ||
1969 | void Gfx::opXObject(Object args[], int numArgs) { | 2192 | void Gfx::opXObject(Object args[], int numArgs) { |
1970 | Object obj1, obj2, refObj; | 2193 | Object obj1, obj2, obj3, refObj; |
1971 | #if OPI_SUPPORT | 2194 | #if OPI_SUPPORT |
1972 | Object opiDict; | 2195 | Object opiDict; |
1973 | #endif | 2196 | #endif |
1974 | 2197 | ||
1975 | if (!res->lookupXObject(args[0].getName(), &obj1)) { | 2198 | if (!res->lookupXObject(args[0].getName(), &obj1)) { |
1976 | return; | 2199 | return; |
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 | ||
2011 | void Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) { | 2238 | void 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 | ||
2159 | void Gfx::doForm(Object *str) { | 2391 | void 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 | ||
2218 | void Gfx::doWidgetForm(Object *str, fouble xMin, fouble yMin, | 2450 | void Gfx::doAnnot(Object *str, fouble xMin, fouble yMin, |
2219 | fouble xMax, fouble yMax) { | 2451 | fouble xMax, fouble yMax) { |
2220 | Dict *dict, *resDict; | 2452 | Dict *dict, *resDict; |
2221 | Object matrixObj, bboxObj, resObj; | 2453 | Object matrixObj, bboxObj, resObj; |
2222 | Object obj1; | 2454 | Object obj1; |
2223 | fouble m[6], bbox[6]; | 2455 | fouble m[6], bbox[6], ictm[6]; |
2224 | fouble sx, sy; | 2456 | fouble *ctm; |
2457 | fouble formX0, formY0, formX1, formY1; | ||
2458 | fouble annotX0, annotY0, annotX1, annotY1; | ||
2459 | fouble det, x, y, sx, sy; | ||
2225 | int i; | 2460 | int i; |
2226 | 2461 | ||
2227 | // get stream dict | 2462 | // get stream dict |
2228 | dict = str->streamGetDict(); | 2463 | dict = str->streamGetDict(); |
2229 | 2464 | ||
2230 | // get bounding box | 2465 | // get the form bounding box |
2231 | dict->lookup("BBox", &bboxObj); | 2466 | dict->lookup("BBox", &bboxObj); |
2232 | if (!bboxObj.isArray()) { | 2467 | if (!bboxObj.isArray()) { |
2233 | bboxObj.free(); | 2468 | bboxObj.free(); |
2234 | error(getPos(), "Bad form bounding box"); | 2469 | error(getPos(), "Bad form bounding box"); |
2235 | return; | 2470 | return; |
2236 | } | 2471 | } |
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 | ||
2281 | void Gfx::doForm1(Object *str, Dict *resDict, fouble *matrix, fouble *bbox) { | 2564 | void Gfx::doForm1(Object *str, Dict *resDict, fouble *matrix, fouble *bbox) { |
2282 | Parser *oldParser; | 2565 | Parser *oldParser; |
2283 | fouble oldBaseMatrix[6]; | 2566 | fouble oldBaseMatrix[6]; |
2284 | GfxResources *resPtr; | ||
2285 | int i; | 2567 | int i; |
2286 | 2568 | ||
2287 | // push new resources on stack | 2569 | // push new resources on stack |
2288 | res = new GfxResources(xref, resDict, res); | 2570 | pushResources(resDict); |
2289 | 2571 | ||
2290 | // save current graphics state | 2572 | // save current graphics state |
2291 | out->saveState(state); | 2573 | out->saveState(state); |
2292 | state = state->save(); | 2574 | state = state->save(); |
2293 | 2575 | ||
2294 | // save current parser | 2576 | // save current parser |
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 | |||
2622 | void Gfx::pushResources(Dict *resDict) { | ||
2623 | res = new GfxResources(xref, resDict, res); | ||
2624 | } | ||
2625 | |||
2626 | void Gfx::popResources() { | ||
2627 | GfxResources *resPtr; | ||
2628 | |||
2335 | resPtr = res->getNext(); | 2629 | resPtr = res->getNext(); |
2336 | delete res; | 2630 | delete res; |
2337 | res = resPtr; | 2631 | res = resPtr; |
2338 | |||
2339 | return; | ||
2340 | } | 2632 | } |
2341 | 2633 | ||
2342 | //------------------------------------------------------------------------ | 2634 | //------------------------------------------------------------------------ |
2343 | // in-line image operators | 2635 | // in-line image operators |
2344 | //------------------------------------------------------------------------ | 2636 | //------------------------------------------------------------------------ |
2345 | 2637 | ||
2346 | void Gfx::opBeginImage(Object args[], int numArgs) { | 2638 | void 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 | ||
2368 | Stream *Gfx::buildImageStream() { | 2660 | Stream *Gfx::buildImageStream() { |
2369 | Object dict; | 2661 | Object dict; |
2370 | Object obj; | 2662 | Object obj; |
2371 | char *key; | 2663 | char *key; |
2372 | Stream *str; | 2664 | Stream *str; |
2373 | 2665 | ||
2374 | // build dictionary | 2666 | // build dictionary |
2375 | dict.initDict(xref); | 2667 | dict.initDict(xref); |
2376 | parser->getObj(&obj); | 2668 | parser->getObj(&obj); |
2377 | while (!obj.isCmd("ID") && !obj.isEOF()) { | 2669 | while (!obj.isCmd("ID") && !obj.isEOF()) { |
2378 | if (!obj.isName()) { | 2670 | if (!obj.isName()) { |
2379 | error(getPos(), "Inline image dictionary key must be a name object"); | 2671 | error(getPos(), "Inline image dictionary key must be a name object"); |
2380 | obj.free(); | 2672 | obj.free(); |
2381 | parser->getObj(&obj); | ||
2382 | } else { | 2673 | } else { |
2383 | key = copyString(obj.getName()); | 2674 | key = copyString(obj.getName()); |
2384 | obj.free(); | 2675 | obj.free(); |
2385 | parser->getObj(&obj); | 2676 | parser->getObj(&obj); |
2386 | if (obj.isEOF() || obj.isError()) | 2677 | if (obj.isEOF() || obj.isError()) { |
2678 | gfree(key); | ||
2387 | break; | 2679 | break; |
2680 | } | ||
2388 | dict.dictAdd(key, &obj); | 2681 | dict.dictAdd(key, &obj); |
2389 | } | 2682 | } |
2390 | parser->getObj(&obj); | 2683 | parser->getObj(&obj); |
2391 | } | 2684 | } |
2392 | if (obj.isEOF()) | 2685 | if (obj.isEOF()) { |
2393 | error(getPos(), "End of file in inline image"); | 2686 | error(getPos(), "End of file in inline image"); |
2687 | obj.free(); | ||
2688 | dict.free(); | ||
2689 | return NULL; | ||
2690 | } | ||
2394 | obj.free(); | 2691 | obj.free(); |
2395 | 2692 | ||
2396 | // make stream | 2693 | // make stream |
2397 | str = new EmbedStream(parser->getStream(), &dict); | 2694 | str = new EmbedStream(parser->getStream(), &dict); |
2398 | str = str->addFilters(&dict); | 2695 | str = str->addFilters(&dict); |
2399 | 2696 | ||
2400 | return str; | 2697 | return str; |
2401 | } | 2698 | } |
2402 | 2699 | ||
2403 | void Gfx::opImageData(Object args[], int numArgs) { | 2700 | void Gfx::opImageData(Object args[], int numArgs) { |
2404 | error(getPos(), "Internal: got 'ID' operator"); | 2701 | error(getPos(), "Internal: got 'ID' operator"); |
2405 | } | 2702 | } |
2406 | 2703 | ||
2407 | void Gfx::opEndImage(Object args[], int numArgs) { | 2704 | void 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 | ||
2415 | void Gfx::opSetCharWidth(Object args[], int numArgs) { | 2712 | void Gfx::opSetCharWidth(Object args[], int numArgs) { |
2416 | error(getPos(), "Encountered 'd0' operator in content stream"); | 2713 | out->type3D0(state, args[0].getNum(), args[1].getNum()); |
2417 | } | 2714 | } |
2418 | 2715 | ||
2419 | void Gfx::opSetCacheDevice(Object args[], int numArgs) { | 2716 | void Gfx::opSetCacheDevice(Object args[], int numArgs) { |
2420 | error(getPos(), "Encountered 'd1' operator in content stream"); | 2717 | out->type3D1(state, args[0].getNum(), args[1].getNum(), |
2718 | args[2].getNum(), args[3].getNum(), | ||
2719 | args[4].getNum(), args[5].getNum()); | ||
2421 | } | 2720 | } |
2422 | 2721 | ||
2423 | //------------------------------------------------------------------------ | 2722 | //------------------------------------------------------------------------ |
2424 | // compatibility operators | 2723 | // compatibility operators |
2425 | //------------------------------------------------------------------------ | 2724 | //------------------------------------------------------------------------ |
2426 | 2725 | ||
2427 | void Gfx::opBeginIgnoreUndef(Object args[], int numArgs) { | 2726 | void Gfx::opBeginIgnoreUndef(Object args[], int numArgs) { |
2428 | ++ignoreUndef; | 2727 | ++ignoreUndef; |
2429 | } | 2728 | } |
2430 | 2729 | ||
2431 | void Gfx::opEndIgnoreUndef(Object args[], int numArgs) { | 2730 | void 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 | ||
2440 | void Gfx::opBeginMarkedContent(Object args[], int numArgs) { | 2739 | void 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 | ||
2450 | void Gfx::opEndMarkedContent(Object args[], int numArgs) { | 2749 | void Gfx::opEndMarkedContent(Object args[], int numArgs) { |
2451 | } | 2750 | } |
2452 | 2751 | ||
2453 | void Gfx::opMarkPoint(Object args[], int numArgs) { | 2752 | void 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 | ||
18 | class GString; | 18 | class GString; |
19 | class XRef; | 19 | class XRef; |
20 | class Array; | 20 | class Array; |
21 | class Stream; | 21 | class Stream; |
22 | class Parser; | 22 | class Parser; |
23 | class Dict; | 23 | class Dict; |
24 | class OutputDev; | 24 | class OutputDev; |
25 | class GfxFontDict; | 25 | class GfxFontDict; |
26 | class GfxFont; | 26 | class GfxFont; |
27 | class GfxPattern; | 27 | class GfxPattern; |
28 | class GfxShading; | 28 | class GfxShading; |
29 | class GfxAxialShading; | 29 | class GfxAxialShading; |
30 | class GfxRadialShading; | ||
30 | class GfxState; | 31 | class GfxState; |
31 | class Gfx; | 32 | class Gfx; |
32 | struct PDFRectangle; | 33 | struct PDFRectangle; |
33 | 34 | ||
34 | //------------------------------------------------------------------------ | 35 | //------------------------------------------------------------------------ |
35 | // Gfx | 36 | // Gfx |
36 | //------------------------------------------------------------------------ | 37 | //------------------------------------------------------------------------ |
37 | 38 | ||
38 | enum GfxClipType { | 39 | enum GfxClipType { |
39 | clipNone, | 40 | clipNone, |
40 | clipNormal, | 41 | clipNormal, |
41 | clipEO | 42 | clipEO |
42 | }; | 43 | }; |
43 | 44 | ||
44 | enum TchkType { | 45 | enum 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 | ||
58 | struct Operator { | 59 | struct 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 | ||
65 | class GfxResources { | 66 | class GfxResources { |
66 | public: | 67 | public: |
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 | ||
81 | private: | 82 | private: |
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 | ||
92 | class Gfx { | 93 | class Gfx { |
93 | public: | 94 | public: |
94 | 95 | ||
95 | // Constructor for regular output. | 96 | // Constructor for regular output. |
96 | Gfx(XRef *xrefA, OutputDev *outA, int pageNum, Dict *resDict, fouble dpi, | 97 | Gfx(XRef *xrefA, OutputDev *outA, int pageNum, Dict *resDict, fouble dpi, |
97 | PDFRectangle *box, GBool crop, PDFRectangle *cropBox, int rotate, | 98 | PDFRectangle *box, GBool crop, PDFRectangle *cropBox, int rotate, |
98 | GBool printCommandsA); | 99 | GBool printCommandsA); |
99 | 100 | ||
100 | // Destructor. | 101 | // Constructor for a sub-page object. |
102 | Gfx(XRef *xrefA, OutputDev *outA, Dict *resDict, | ||
103 | PDFRectangle *box, GBool crop, PDFRectangle *cropBox); | ||
104 | |||
101 | ~Gfx(); | 105 | ~Gfx(); |
102 | 106 | ||
103 | // Interpret a stream or array of streams. | 107 | // Interpret a stream or array of streams. |
104 | void display(Object *obj, GBool topLevel = gTrue); | 108 | void display(Object *obj, GBool topLevel = gTrue); |
105 | 109 | ||
106 | void doWidgetForm(Object *str, fouble xMin, fouble yMin, | 110 | // Display an annotation, given its appearance (a Form XObject) and |
107 | fouble xMax, fouble yMax); | 111 | // bounding box (in default user space). |
112 | void doAnnot(Object *str, fouble xMin, fouble yMin, | ||
113 | fouble xMax, fouble yMax); | ||
114 | |||
115 | void pushResources(Dict *resDict); | ||
116 | void popResources(); | ||
108 | 117 | ||
109 | private: | 118 | private: |
110 | 119 | ||
111 | XRef *xref; // the xref table for this PDF file | 120 | XRef *xref; // the xref table for this PDF file |
112 | OutputDev *out; // output device | 121 | OutputDev *out; // output device |
122 | GBool subPage; // is this a sub-page object? | ||
113 | GBool printCommands; // print the drawing commands (for debugging) | 123 | GBool printCommands; // print the drawing commands (for debugging) |
114 | GfxResources *res; // resource stack | 124 | GfxResources *res; // resource stack |
125 | int updateLevel; | ||
115 | 126 | ||
116 | GfxState *state; // current graphics state | 127 | GfxState *state; // current graphics state |
117 | GBool fontChanged; // set if font or text matrix has changed | 128 | GBool fontChanged; // set if font or text matrix has changed |
118 | GfxClipType clip; // do a clip? | 129 | GfxClipType clip; // do a clip? |
119 | int ignoreUndef; // current BX/EX nesting level | 130 | int ignoreUndef; // current BX/EX nesting level |
120 | fouble baseMatrix[6]; // default matrix for most recent | 131 | fouble baseMatrix[6]; // default matrix for most recent |
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 | ||
32 | struct StdFontMapEntry { | 32 | struct StdFontMapEntry { |
33 | char *altName; | 33 | char *altName; |
34 | char *properName; | 34 | char *properName; |
35 | }; | 35 | }; |
36 | 36 | ||
37 | static StdFontMapEntry stdFontMap[] = { | 37 | static 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 | ||
89 | GfxFont *GfxFont::makeFont(XRef *xref, char *tagA, Ref idA, Dict *fontDict) { | 89 | GfxFont *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 | ||
125 | GfxFont::GfxFont(char *tagA, Ref idA, GString *nameA) { | 125 | GfxFont::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 | ||
134 | GfxFont::~GfxFont() { | 134 | GfxFont::~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 | ||
147 | void GfxFont::readFontDescriptor(XRef *xref, Dict *fontDict) { | 147 | void 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 | ||
276 | CharCodeToUnicode *GfxFont::readToUnicodeCMap(Dict *fontDict, int nBits) { | 276 | CharCodeToUnicode *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 | ||
298 | void GfxFont::findExtFontFile() { | 298 | void 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 | ||
308 | char *GfxFont::readExtFontFile(int *len) { | 308 | char *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 | ||
327 | char *GfxFont::readEmbFontFile(XRef *xref, int *len) { | 327 | char *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 | ||
368 | Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA, | 368 | Gfx8BitFont::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 | ||
743 | Gfx8BitFont::~Gfx8BitFont() { | 768 | Gfx8BitFont::~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 | ||
757 | int Gfx8BitFont::getNextChar(char *s, int len, CharCode *code, | 785 | int Gfx8BitFont::getNextChar(char *s, int len, CharCode *code, |
758 | Unicode *u, int uSize, int *uLen, | 786 | Unicode *u, int uSize, int *uLen, |
759 | fouble *dx, fouble *dy, fouble *ox, fouble *oy) { | 787 | fouble *dx, fouble *dy, fouble *ox, fouble *oy) { |
760 | CharCode c; | 788 | CharCode c; |
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 | ||
769 | CharCodeToUnicode *Gfx8BitFont::getToUnicode() { | 797 | CharCodeToUnicode *Gfx8BitFont::getToUnicode() { |
770 | ctu->incRefCnt(); | 798 | ctu->incRefCnt(); |
771 | return ctu; | 799 | return ctu; |
772 | } | 800 | } |
773 | 801 | ||
802 | Dict *Gfx8BitFont::getCharProcs() { | ||
803 | return charProcs.isDict() ? charProcs.getDict() : (Dict *)NULL; | ||
804 | } | ||
805 | |||
774 | Object *Gfx8BitFont::getCharProc(int code, Object *proc) { | 806 | Object *Gfx8BitFont::getCharProc(int code, Object *proc) { |
775 | if (charProcs.isDict()) { | 807 | if (charProcs.isDict()) { |
776 | charProcs.dictLookup(enc[code], proc); | 808 | charProcs.dictLookup(enc[code], proc); |
777 | } else { | 809 | } else { |
778 | proc->initNull(); | 810 | proc->initNull(); |
779 | } | 811 | } |
780 | return proc; | 812 | return proc; |
781 | } | 813 | } |
782 | 814 | ||
815 | Dict *Gfx8BitFont::getResources() { | ||
816 | return resources.isDict() ? resources.getDict() : (Dict *)NULL; | ||
817 | } | ||
818 | |||
783 | //------------------------------------------------------------------------ | 819 | //------------------------------------------------------------------------ |
784 | // GfxCIDFont | 820 | // GfxCIDFont |
785 | //------------------------------------------------------------------------ | 821 | //------------------------------------------------------------------------ |
786 | 822 | ||
787 | static int cmpWidthExcep(const void *w1, const void *w2) { | 823 | static int cmpWidthExcep(const void *w1, const void *w2) { |
788 | return ((GfxFontCIDWidthExcep *)w1)->first - | 824 | return ((GfxFontCIDWidthExcep *)w1)->first - |
789 | ((GfxFontCIDWidthExcep *)w2)->first; | 825 | ((GfxFontCIDWidthExcep *)w2)->first; |
790 | } | 826 | } |
791 | 827 | ||
792 | static int cmpWidthExcepV(const void *w1, const void *w2) { | 828 | static 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 | ||
797 | GfxCIDFont::GfxCIDFont(XRef *xref, char *tagA, Ref idA, GString *nameA, | 833 | GfxCIDFont::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 | ||
1099 | GfxCIDFont::~GfxCIDFont() { | 1135 | GfxCIDFont::~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 | ||
1113 | int GfxCIDFont::getNextChar(char *s, int len, CharCode *code, | 1149 | int 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 | ||
1225 | int GfxCIDFont::getWMode() { | ||
1226 | return cMap ? cMap->getWMode() : 0; | ||
1227 | } | ||
1228 | |||
1189 | CharCodeToUnicode *GfxCIDFont::getToUnicode() { | 1229 | CharCodeToUnicode *GfxCIDFont::getToUnicode() { |
1190 | ctu->incRefCnt(); | 1230 | ctu->incRefCnt(); |
1191 | return ctu; | 1231 | return ctu; |
1192 | } | 1232 | } |
1193 | 1233 | ||
1194 | GString *GfxCIDFont::getCollection() { | 1234 | GString *GfxCIDFont::getCollection() { |
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 | ||
1202 | GfxFontDict::GfxFontDict(XRef *xref, Dict *fontDict) { | 1242 | GfxFontDict::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 | ||
1227 | GfxFontDict::~GfxFontDict() { | 1267 | GfxFontDict::~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 | ||
1238 | GfxFont *GfxFontDict::lookup(char *tag) { | 1278 | GfxFont *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 | ||
21 | class Dict; | 21 | class Dict; |
22 | class CMap; | 22 | class CMap; |
23 | class CharCodeToUnicode; | 23 | class CharCodeToUnicode; |
24 | struct GfxFontCIDWidths; | 24 | struct GfxFontCIDWidths; |
25 | 25 | ||
26 | //------------------------------------------------------------------------ | 26 | //------------------------------------------------------------------------ |
27 | // GfxFontType | 27 | // GfxFontType |
28 | //------------------------------------------------------------------------ | 28 | //------------------------------------------------------------------------ |
29 | 29 | ||
30 | enum GfxFontType { | 30 | enum 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 | ||
47 | struct GfxFontCIDWidthExcep { | 47 | struct 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 | ||
53 | struct GfxFontCIDWidthExcepV { | 53 | struct 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 | ||
60 | struct GfxFontCIDWidths { | 60 | struct 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 | ||
81 | class GfxFont { | 81 | class GfxFont { |
82 | public: | 82 | public: |
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 | ||
154 | protected: | 156 | protected: |
155 | 157 | ||
156 | void readFontDescriptor(XRef *xref, Dict *fontDict); | 158 | void readFontDescriptor(XRef *xref, Dict *fontDict); |
157 | CharCodeToUnicode *readToUnicodeCMap(Dict *fontDict, int nBits); | 159 | CharCodeToUnicode *readToUnicodeCMap(Dict *fontDict, int nBits); |
158 | void GfxFont::findExtFontFile(); | 160 | void findExtFontFile(); |
159 | 161 | ||
160 | GString *tag; // PDF font tag | 162 | GString *tag; // PDF font tag |
161 | Ref id; // reference (used as unique ID) | 163 | Ref id; // reference (used as unique ID) |
162 | GString *name; // font name | 164 | GString *name; // font name |
163 | GfxFontType type; // type of font | 165 | GfxFontType type; // type of font |
164 | int flags; // font descriptor flags | 166 | int flags; // font descriptor flags |
165 | GString *embFontName; // name of embedded font | 167 | GString *embFontName; // name of embedded font |
166 | Ref embFontID; // ref to embedded font file stream | 168 | Ref embFontID; // ref to embedded font file stream |
167 | GString *extFontFile; // external font file name | 169 | GString *extFontFile; // external font file name |
168 | fouble fontMat[6]; // font matrix (Type 3 only) | 170 | fouble fontMat[6]; // font matrix (Type 3 only) |
169 | fouble fontBBox[4]; // font bounding box | 171 | fouble fontBBox[4]; // font bounding box (Type 3 only) |
170 | fouble missingWidth; // "default" width | 172 | fouble missingWidth; // "default" width |
171 | fouble ascent; // max height above baseline | 173 | fouble ascent; // max height above baseline |
172 | fouble descent; // max depth below baseline | 174 | fouble descent; // max depth below baseline |
173 | GBool ok; | 175 | GBool ok; |
174 | }; | 176 | }; |
175 | 177 | ||
176 | //------------------------------------------------------------------------ | 178 | //------------------------------------------------------------------------ |
177 | // Gfx8BitFont | 179 | // Gfx8BitFont |
178 | //------------------------------------------------------------------------ | 180 | //------------------------------------------------------------------------ |
179 | 181 | ||
180 | class Gfx8BitFont: public GfxFont { | 182 | class Gfx8BitFont: public GfxFont { |
181 | public: | 183 | public: |
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 | |||
210 | private: | 218 | private: |
211 | 219 | ||
212 | char *enc[256]; // char code --> char name | 220 | char *enc[256]; // char code --> char name |
213 | char encFree[256]; // boolean for each char name: if set, | 221 | char encFree[256]; // boolean for each char name: if set, |
214 | // the string is malloc'ed | 222 | // the string is malloc'ed |
215 | CharCodeToUnicode *ctu;// char code --> Unicode | 223 | CharCodeToUnicode *ctu;// char code --> Unicode |
216 | GBool hasEncoding; | 224 | GBool hasEncoding; |
217 | fouble widths[256]; // character widths | 225 | fouble widths[256]; // character widths |
218 | Object charProcs; // Type3 CharProcs dictionary | 226 | Object charProcs; // Type 3 CharProcs dictionary |
227 | Object resources; // Type 3 Resources dictionary | ||
219 | }; | 228 | }; |
220 | 229 | ||
221 | //------------------------------------------------------------------------ | 230 | //------------------------------------------------------------------------ |
222 | // GfxCIDFont | 231 | // GfxCIDFont |
223 | //------------------------------------------------------------------------ | 232 | //------------------------------------------------------------------------ |
224 | 233 | ||
225 | class GfxCIDFont: public GfxFont { | 234 | class GfxCIDFont: public GfxFont { |
226 | public: | 235 | public: |
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 | ||
250 | private: | 262 | private: |
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 | ||
264 | class GfxFontDict { | 276 | class GfxFontDict { |
265 | public: | 277 | public: |
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 | ||
280 | private: | 292 | private: |
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 | ||
26 | static inline fouble clip01(fouble x) { | 26 | static 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 | ||
34 | GfxColorSpace::GfxColorSpace() { | 34 | GfxColorSpace::GfxColorSpace() { |
35 | } | 35 | } |
36 | 36 | ||
37 | GfxColorSpace::~GfxColorSpace() { | 37 | GfxColorSpace::~GfxColorSpace() { |
38 | } | 38 | } |
39 | 39 | ||
40 | GfxColorSpace *GfxColorSpace::parse(Object *csObj) { | 40 | GfxColorSpace *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 | ||
91 | void GfxColorSpace::getDefaultRanges(fouble *decodeLow, fouble *decodeRange, | 91 | void 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 | ||
105 | GfxDeviceGrayColorSpace::GfxDeviceGrayColorSpace() { | 105 | GfxDeviceGrayColorSpace::GfxDeviceGrayColorSpace() { |
106 | } | 106 | } |
107 | 107 | ||
108 | GfxDeviceGrayColorSpace::~GfxDeviceGrayColorSpace() { | 108 | GfxDeviceGrayColorSpace::~GfxDeviceGrayColorSpace() { |
109 | } | 109 | } |
110 | 110 | ||
111 | GfxColorSpace *GfxDeviceGrayColorSpace::copy() { | 111 | GfxColorSpace *GfxDeviceGrayColorSpace::copy() { |
112 | return new GfxDeviceGrayColorSpace(); | 112 | return new GfxDeviceGrayColorSpace(); |
113 | } | 113 | } |
114 | 114 | ||
115 | void GfxDeviceGrayColorSpace::getGray(GfxColor *color, fouble *gray) { | 115 | void GfxDeviceGrayColorSpace::getGray(GfxColor *color, fouble *gray) { |
116 | *gray = clip01(color->c[0]); | 116 | *gray = clip01(color->c[0]); |
117 | } | 117 | } |
118 | 118 | ||
119 | void GfxDeviceGrayColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) { | 119 | void 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 | ||
123 | void GfxDeviceGrayColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) { | 123 | void 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 | ||
132 | GfxCalGrayColorSpace::GfxCalGrayColorSpace() { | 132 | GfxCalGrayColorSpace::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 | ||
138 | GfxCalGrayColorSpace::~GfxCalGrayColorSpace() { | 138 | GfxCalGrayColorSpace::~GfxCalGrayColorSpace() { |
139 | } | 139 | } |
140 | 140 | ||
141 | GfxColorSpace *GfxCalGrayColorSpace::copy() { | 141 | GfxColorSpace *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 | ||
155 | GfxColorSpace *GfxCalGrayColorSpace::parse(Array *arr) { | 155 | GfxColorSpace *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 | ||
220 | GfxDeviceRGBColorSpace::~GfxDeviceRGBColorSpace() { | 220 | GfxDeviceRGBColorSpace::~GfxDeviceRGBColorSpace() { |
221 | } | 221 | } |
222 | 222 | ||
223 | GfxColorSpace *GfxDeviceRGBColorSpace::copy() { | 223 | GfxColorSpace *GfxDeviceRGBColorSpace::copy() { |
224 | return new GfxDeviceRGBColorSpace(); | 224 | return new GfxDeviceRGBColorSpace(); |
225 | } | 225 | } |
226 | 226 | ||
227 | void GfxDeviceRGBColorSpace::getGray(GfxColor *color, fouble *gray) { | 227 | void 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 | ||
233 | void GfxDeviceRGBColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) { | 233 | void 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 | ||
239 | void GfxDeviceRGBColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) { | 239 | void 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 | ||
262 | GfxCalRGBColorSpace::GfxCalRGBColorSpace() { | 262 | GfxCalRGBColorSpace::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 | ||
271 | GfxCalRGBColorSpace::~GfxCalRGBColorSpace() { | 271 | GfxCalRGBColorSpace::~GfxCalRGBColorSpace() { |
272 | } | 272 | } |
273 | 273 | ||
274 | GfxColorSpace *GfxCalRGBColorSpace::copy() { | 274 | GfxColorSpace *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 | ||
294 | GfxColorSpace *GfxCalRGBColorSpace::parse(Array *arr) { | 294 | GfxColorSpace *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 | ||
358 | void GfxCalRGBColorSpace::getGray(GfxColor *color, fouble *gray) { | 358 | void 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 | ||
364 | void GfxCalRGBColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) { | 364 | void 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 | ||
370 | void GfxCalRGBColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) { | 370 | void 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 | ||
393 | GfxDeviceCMYKColorSpace::GfxDeviceCMYKColorSpace() { | 393 | GfxDeviceCMYKColorSpace::GfxDeviceCMYKColorSpace() { |
394 | } | 394 | } |
395 | 395 | ||
396 | GfxDeviceCMYKColorSpace::~GfxDeviceCMYKColorSpace() { | 396 | GfxDeviceCMYKColorSpace::~GfxDeviceCMYKColorSpace() { |
397 | } | 397 | } |
398 | 398 | ||
399 | GfxColorSpace *GfxDeviceCMYKColorSpace::copy() { | 399 | GfxColorSpace *GfxDeviceCMYKColorSpace::copy() { |
400 | return new GfxDeviceCMYKColorSpace(); | 400 | return new GfxDeviceCMYKColorSpace(); |
401 | } | 401 | } |
402 | 402 | ||
403 | void GfxDeviceCMYKColorSpace::getGray(GfxColor *color, fouble *gray) { | 403 | void 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 | ||
410 | void GfxDeviceCMYKColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) { | 410 | void GfxDeviceCMYKColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) { |
411 | rgb->r = clip01(1 - (color->c[0] + color->c[3])); | 411 | fouble c, m, y, aw, ac, am, ay, ar, ag, ab; |
412 | rgb->g = clip01(1 - (color->c[1] + color->c[3])); | 412 | |
413 | rgb->b = clip01(1 - (color->c[2] + color->c[3])); | 413 | c = clip01(color->c[0] + color->c[3]); |
414 | m = clip01(color->c[1] + color->c[3]); | ||
415 | y = clip01(color->c[2] + color->c[3]); | ||
416 | aw = (1-c) * (1-m) * (1-y); | ||
417 | ac = c * (1-m) * (1-y); | ||
418 | am = (1-c) * m * (1-y); | ||
419 | ay = (1-c) * (1-m) * y; | ||
420 | ar = (1-c) * m * y; | ||
421 | ag = c * (1-m) * y; | ||
422 | ab = c * m * (1-y); | ||
423 | rgb->r = clip01(aw + 0.9137*am + 0.9961*ay + 0.9882*ar); | ||
424 | rgb->g = clip01(aw + 0.6196*ac + ay + 0.5176*ag); | ||
425 | rgb->b = clip01(aw + 0.7804*ac + 0.5412*am + 0.0667*ar + 0.2118*ag + | ||
426 | 0.4863*ab); | ||
414 | } | 427 | } |
415 | 428 | ||
416 | void GfxDeviceCMYKColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) { | 429 | void GfxDeviceCMYKColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) { |
417 | cmyk->c = clip01(color->c[0]); | 430 | cmyk->c = clip01(color->c[0]); |
418 | cmyk->m = clip01(color->c[1]); | 431 | cmyk->m = clip01(color->c[1]); |
419 | cmyk->y = clip01(color->c[2]); | 432 | cmyk->y = clip01(color->c[2]); |
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. |
429 | static fouble xyzrgb[3][3] = { | 442 | static 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 | ||
435 | GfxLabColorSpace::GfxLabColorSpace() { | 448 | GfxLabColorSpace::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 | ||
442 | GfxLabColorSpace::~GfxLabColorSpace() { | 455 | GfxLabColorSpace::~GfxLabColorSpace() { |
443 | } | 456 | } |
444 | 457 | ||
445 | GfxColorSpace *GfxLabColorSpace::copy() { | 458 | GfxColorSpace *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 | ||
465 | GfxColorSpace *GfxLabColorSpace::parse(Array *arr) { | 478 | GfxColorSpace *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 | ||
533 | void GfxLabColorSpace::getGray(GfxColor *color, fouble *gray) { | 546 | void 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 | ||
542 | void GfxLabColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) { | 555 | void 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 | ||
579 | void GfxLabColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) { | 592 | void 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 | ||
600 | void GfxLabColorSpace::getDefaultRanges(fouble *decodeLow, fouble *decodeRange, | 613 | void 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 | ||
1080 | GfxColorSpace *GfxPatternColorSpace::copy() { | 1093 | GfxColorSpace *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 | ||
1085 | GfxColorSpace *GfxPatternColorSpace::parse(Array *arr) { | 1098 | GfxColorSpace *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 | ||
1108 | void GfxPatternColorSpace::getGray(GfxColor *color, fouble *gray) { | 1121 | void GfxPatternColorSpace::getGray(GfxColor *color, fouble *gray) { |
1109 | *gray = 0; | 1122 | *gray = 0; |
1110 | } | 1123 | } |
1111 | 1124 | ||
1112 | void GfxPatternColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) { | 1125 | void 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 | ||
1116 | void GfxPatternColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) { | 1129 | void 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 | ||
1125 | GfxPattern::GfxPattern(int typeA) { | 1138 | GfxPattern::GfxPattern(int typeA) { |
1126 | type = typeA; | 1139 | type = typeA; |
1127 | } | 1140 | } |
1128 | 1141 | ||
1129 | GfxPattern::~GfxPattern() { | 1142 | GfxPattern::~GfxPattern() { |
1130 | } | 1143 | } |
1131 | 1144 | ||
1132 | GfxPattern *GfxPattern::parse(Object *obj) { | 1145 | GfxPattern *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 | ||
1153 | GfxTilingPattern::GfxTilingPattern(Dict *streamDict, Object *stream): | 1166 | GfxTilingPattern::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 | ||
1222 | GfxTilingPattern::~GfxTilingPattern() { | 1235 | GfxTilingPattern::~GfxTilingPattern() { |
1223 | resDict.free(); | 1236 | resDict.free(); |
1224 | contentStream.free(); | 1237 | contentStream.free(); |
1225 | } | 1238 | } |
1226 | 1239 | ||
1227 | GfxPattern *GfxTilingPattern::copy() { | 1240 | GfxPattern *GfxTilingPattern::copy() { |
1228 | return new GfxTilingPattern(this); | 1241 | return new GfxTilingPattern(this); |
1229 | } | 1242 | } |
1230 | 1243 | ||
1231 | GfxTilingPattern::GfxTilingPattern(GfxTilingPattern *pat): | 1244 | GfxTilingPattern::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 | ||
1243 | GfxShading::GfxShading() { | 1256 | GfxShading::GfxShading() { |
1244 | } | 1257 | } |
1245 | 1258 | ||
1246 | GfxShading::~GfxShading() { | 1259 | GfxShading::~GfxShading() { |
1247 | delete colorSpace; | 1260 | delete colorSpace; |
1248 | } | 1261 | } |
1249 | 1262 | ||
1250 | GfxShading *GfxShading::parse(Object *obj) { | 1263 | GfxShading *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 | ||
1347 | GfxAxialShading::GfxAxialShading(fouble x0A, fouble y0A, | 1366 | GfxAxialShading::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 | ||
1368 | GfxAxialShading::~GfxAxialShading() { | 1387 | GfxAxialShading::~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 | ||
1376 | GfxAxialShading *GfxAxialShading::parse(Dict *dict) { | 1395 | GfxAxialShading *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 | ||
1451 | void GfxAxialShading::getColor(fouble t, GfxColor *color) { | 1470 | void 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 | |||
1482 | GfxRadialShading::GfxRadialShading(fouble x0A, fouble y0A, fouble r0A, | ||
1483 | fouble x1A, fouble y1A, fouble r1A, | ||
1484 | fouble t0A, fouble t1A, | ||
1485 | Function **funcsA, int nFuncsA, | ||
1486 | GBool extend0A, GBool extend1A) { | ||
1487 | int i; | ||
1488 | |||
1489 | x0 = x0A; | ||
1490 | y0 = y0A; | ||
1491 | r0 = r0A; | ||
1492 | x1 = x1A; | ||
1493 | y1 = y1A; | ||
1494 | r1 = r1A; | ||
1495 | t0 = t0A; | ||
1496 | t1 = t1A; | ||
1497 | nFuncs = nFuncsA; | ||
1498 | for (i = 0; i < nFuncs; ++i) { | ||
1499 | funcs[i] = funcsA[i]; | ||
1500 | } | ||
1501 | extend0 = extend0A; | ||
1502 | extend1 = extend1A; | ||
1503 | } | ||
1504 | |||
1505 | GfxRadialShading::~GfxRadialShading() { | ||
1506 | int i; | ||
1507 | |||
1508 | for (i = 0; i < nFuncs; ++i) { | ||
1509 | delete funcs[i]; | ||
1510 | } | ||
1511 | } | ||
1512 | |||
1513 | GfxRadialShading *GfxRadialShading::parse(Dict *dict) { | ||
1514 | fouble x0A, y0A, r0A, x1A, y1A, r1A; | ||
1515 | fouble t0A, t1A; | ||
1516 | Function *funcsA[gfxColorMaxComps]; | ||
1517 | int nFuncsA; | ||
1518 | GBool extend0A, extend1A; | ||
1519 | Object obj1, obj2; | ||
1520 | int i; | ||
1521 | |||
1522 | x0A = y0A = r0A = x1A = y1A = r1A = 0; | ||
1523 | if (dict->lookup("Coords", &obj1)->isArray() && | ||
1524 | obj1.arrayGetLength() == 6) { | ||
1525 | x0A = obj1.arrayGet(0, &obj2)->getNum(); | ||
1526 | obj2.free(); | ||
1527 | y0A = obj1.arrayGet(1, &obj2)->getNum(); | ||
1528 | obj2.free(); | ||
1529 | r0A = obj1.arrayGet(2, &obj2)->getNum(); | ||
1530 | obj2.free(); | ||
1531 | x1A = obj1.arrayGet(3, &obj2)->getNum(); | ||
1532 | obj2.free(); | ||
1533 | y1A = obj1.arrayGet(4, &obj2)->getNum(); | ||
1534 | obj2.free(); | ||
1535 | r1A = obj1.arrayGet(5, &obj2)->getNum(); | ||
1536 | obj2.free(); | ||
1537 | } else { | ||
1538 | error(-1, "Missing or invalid Coords in shading dictionary"); | ||
1539 | goto err1; | ||
1540 | } | ||
1541 | obj1.free(); | ||
1542 | |||
1543 | t0A = 0; | ||
1544 | t1A = 1; | ||
1545 | if (dict->lookup("Domain", &obj1)->isArray() && | ||
1546 | obj1.arrayGetLength() == 2) { | ||
1547 | t0A = obj1.arrayGet(0, &obj2)->getNum(); | ||
1548 | obj2.free(); | ||
1549 | t1A = obj1.arrayGet(1, &obj2)->getNum(); | ||
1550 | obj2.free(); | ||
1551 | } | ||
1552 | obj1.free(); | ||
1553 | |||
1554 | dict->lookup("Function", &obj1); | ||
1555 | if (obj1.isArray()) { | ||
1556 | nFuncsA = obj1.arrayGetLength(); | ||
1557 | for (i = 0; i < nFuncsA; ++i) { | ||
1558 | obj1.arrayGet(i, &obj2); | ||
1559 | if (!(funcsA[i] = Function::parse(&obj2))) { | ||
1560 | obj1.free(); | ||
1561 | obj2.free(); | ||
1562 | goto err1; | ||
1563 | } | ||
1564 | obj2.free(); | ||
1565 | } | ||
1566 | } else { | ||
1567 | nFuncsA = 1; | ||
1568 | if (!(funcsA[0] = Function::parse(&obj1))) { | ||
1569 | obj1.free(); | ||
1570 | goto err1; | ||
1571 | } | ||
1572 | } | ||
1573 | obj1.free(); | ||
1574 | |||
1575 | extend0A = extend1A = gFalse; | ||
1576 | if (dict->lookup("Extend", &obj1)->isArray() && | ||
1577 | obj1.arrayGetLength() == 2) { | ||
1578 | extend0A = obj1.arrayGet(0, &obj2)->getBool(); | ||
1579 | obj2.free(); | ||
1580 | extend1A = obj1.arrayGet(1, &obj2)->getBool(); | ||
1581 | obj2.free(); | ||
1582 | } | ||
1583 | obj1.free(); | ||
1584 | |||
1585 | return new GfxRadialShading(x0A, y0A, r0A, x1A, y1A, r1A, t0A, t1A, | ||
1586 | funcsA, nFuncsA, extend0A, extend1A); | ||
1587 | |||
1588 | err1: | ||
1589 | return NULL; | ||
1590 | } | ||
1591 | |||
1592 | void GfxRadialShading::getColor(fouble t, GfxColor *color) { | ||
1593 | int i; | ||
1594 | |||
1595 | for (i = 0; i < nFuncs; ++i) { | ||
1596 | funcs[i]->transform(&t, &color->c[i]); | ||
1597 | } | ||
1598 | } | ||
1599 | |||
1600 | //------------------------------------------------------------------------ | ||
1460 | // GfxImageColorMap | 1601 | // GfxImageColorMap |
1461 | //------------------------------------------------------------------------ | 1602 | //------------------------------------------------------------------------ |
1462 | 1603 | ||
1463 | GfxImageColorMap::GfxImageColorMap(int bitsA, Object *decode, | 1604 | GfxImageColorMap::GfxImageColorMap(int bitsA, Object *decode, |
1464 | GfxColorSpace *colorSpaceA) { | 1605 | GfxColorSpace *colorSpaceA) { |
1465 | GfxIndexedColorSpace *indexedCS; | 1606 | GfxIndexedColorSpace *indexedCS; |
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 | ||
1565 | GfxImageColorMap::~GfxImageColorMap() { | 1706 | GfxImageColorMap::~GfxImageColorMap() { |
1566 | delete colorSpace; | 1707 | delete colorSpace; |
1567 | gfree(lookup); | 1708 | gfree(lookup); |
1568 | } | 1709 | } |
1569 | 1710 | ||
1570 | void GfxImageColorMap::getGray(Guchar *x, fouble *gray) { | 1711 | void 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 | ||
1589 | void GfxImageColorMap::getRGB(Guchar *x, GfxRGB *rgb) { | 1730 | void 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 | ||
1608 | void GfxImageColorMap::getCMYK(Guchar *x, GfxCMYK *cmyk) { | 1749 | void 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 | ||
1631 | GfxSubpath::GfxSubpath(fouble x1, fouble y1) { | 1772 | GfxSubpath::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 | ||
1643 | GfxSubpath::~GfxSubpath() { | 1784 | GfxSubpath::~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(). |
1650 | GfxSubpath::GfxSubpath(GfxSubpath *subpath) { | 1791 | GfxSubpath::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 | ||
1732 | void GfxPath::moveTo(fouble x, fouble y) { | 1873 | void 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 | ||
1738 | void GfxPath::lineTo(fouble x, fouble y) { | 1879 | void 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 | ||
1752 | void GfxPath::curveTo(fouble x1, fouble y1, fouble x2, fouble y2, | 1893 | void 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 | ||
1767 | void GfxPath::close() { | 1908 | void 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 | ||
1787 | GfxState::GfxState(fouble dpi, PDFRectangle *pageBox, int rotate, | 1928 | GfxState::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 | ||
1876 | GfxState::~GfxState() { | 2017 | GfxState::~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(); |
1900 | GfxState::GfxState(GfxState *state) { | 2041 | GfxState::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 | ||
2062 | void GfxState::getUserClipBBox(fouble *xMin, fouble *yMin, | ||
2063 | fouble *xMax, fouble *yMax) { | ||
2064 | fouble ictm[6]; | ||
2065 | fouble xMin1, yMin1, xMax1, yMax1, det, tx, ty; | ||
2066 | |||
2067 | // invert the CTM | ||
2068 | det = 1 / (ctm[0] * ctm[3] - ctm[1] * ctm[2]); | ||
2069 | ictm[0] = ctm[3] * det; | ||
2070 | ictm[1] = -ctm[1] * det; | ||
2071 | ictm[2] = -ctm[2] * det; | ||
2072 | ictm[3] = ctm[0] * det; | ||
2073 | ictm[4] = (ctm[2] * ctm[5] - ctm[3] * ctm[4]) * det; | ||
2074 | ictm[5] = (ctm[1] * ctm[4] - ctm[0] * ctm[5]) * det; | ||
2075 | |||
2076 | // transform all four corners of the clip bbox; find the min and max | ||
2077 | // x and y values | ||
2078 | xMin1 = xMax1 = clipXMin * ictm[0] + clipYMin * ictm[2] + ictm[4]; | ||
2079 | yMin1 = yMax1 = clipXMin * ictm[1] + clipYMin * ictm[3] + ictm[5]; | ||
2080 | tx = clipXMin * ictm[0] + clipYMax * ictm[2] + ictm[4]; | ||
2081 | ty = clipXMin * ictm[1] + clipYMax * ictm[3] + ictm[5]; | ||
2082 | if (tx < xMin1) { | ||
2083 | xMin1 = tx; | ||
2084 | } else if (tx > xMax1) { | ||
2085 | xMax1 = tx; | ||
2086 | } | ||
2087 | if (ty < yMin1) { | ||
2088 | yMin1 = ty; | ||
2089 | } else if (ty > yMax1) { | ||
2090 | yMax1 = ty; | ||
2091 | } | ||
2092 | tx = clipXMax * ictm[0] + clipYMin * ictm[2] + ictm[4]; | ||
2093 | ty = clipXMax * ictm[1] + clipYMin * ictm[3] + ictm[5]; | ||
2094 | if (tx < xMin1) { | ||
2095 | xMin1 = tx; | ||
2096 | } else if (tx > xMax1) { | ||
2097 | xMax1 = tx; | ||
2098 | } | ||
2099 | if (ty < yMin1) { | ||
2100 | yMin1 = ty; | ||
2101 | } else if (ty > yMax1) { | ||
2102 | yMax1 = ty; | ||
2103 | } | ||
2104 | tx = clipXMax * ictm[0] + clipYMax * ictm[2] + ictm[4]; | ||
2105 | ty = clipXMax * ictm[1] + clipYMax * ictm[3] + ictm[5]; | ||
2106 | if (tx < xMin1) { | ||
2107 | xMin1 = tx; | ||
2108 | } else if (tx > xMax1) { | ||
2109 | xMax1 = tx; | ||
2110 | } | ||
2111 | if (ty < yMin1) { | ||
2112 | yMin1 = ty; | ||
2113 | } else if (ty > yMax1) { | ||
2114 | yMax1 = ty; | ||
2115 | } | ||
2116 | |||
2117 | *xMin = xMin1; | ||
2118 | *yMin = yMin1; | ||
2119 | *xMax = xMax1; | ||
2120 | *yMax = yMax1; | ||
2121 | } | ||
2122 | |||
1921 | fouble GfxState::transformWidth(fouble w) { | 2123 | fouble GfxState::transformWidth(fouble w) { |
1922 | fouble x, y; | 2124 | fouble x, y; |
1923 | 2125 | ||
1924 | x = ctm[0] + ctm[2]; | 2126 | x = ctm[0] + ctm[2]; |
1925 | y = ctm[1] + ctm[3]; | 2127 | y = ctm[1] + ctm[3]; |
1926 | return w * sqrt(0.5 * (x * x + y * y)); | 2128 | return w * sqrt(0.5 * (x * x + y * y)); |
1927 | } | 2129 | } |
1928 | 2130 | ||
1929 | fouble GfxState::getTransformedFontSize() { | 2131 | fouble 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 | ||
1939 | void GfxState::getFontTransMat(fouble *m11, fouble *m12, | 2141 | void 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 | ||
1947 | void GfxState::setCTM(fouble a, fouble b, fouble c, | 2149 | void GfxState::setCTM(fouble a, fouble b, fouble c, |
1948 | fouble d, fouble e, fouble f) { | 2150 | fouble d, fouble e, fouble f) { |
2151 | int i; | ||
2152 | |||
1949 | ctm[0] = a; | 2153 | ctm[0] = a; |
1950 | ctm[1] = b; | 2154 | ctm[1] = b; |
1951 | ctm[2] = c; | 2155 | ctm[2] = c; |
1952 | ctm[3] = d; | 2156 | ctm[3] = d; |
1953 | ctm[4] = e; | 2157 | ctm[4] = e; |
1954 | ctm[5] = f; | 2158 | ctm[5] = f; |
2159 | |||
2160 | // avoid FP exceptions on badly messed up PDF files | ||
2161 | for (i = 0; i < 6; ++i) { | ||
2162 | if (ctm[i] > fouble(1e3)) { | ||
2163 | ctm[i] = fouble(1e3); | ||
2164 | } else if (ctm[i] < -fouble(1e3)) { | ||
2165 | ctm[i] = -fouble(1e3); | ||
2166 | } | ||
2167 | } | ||
1955 | } | 2168 | } |
1956 | 2169 | ||
1957 | void GfxState::concatCTM(fouble a, fouble b, fouble c, | 2170 | void GfxState::concatCTM(fouble a, fouble b, fouble c, |
1958 | fouble d, fouble e, fouble f) { | 2171 | fouble d, fouble e, fouble f) { |
1959 | fouble a1 = ctm[0]; | 2172 | fouble a1 = ctm[0]; |
1960 | fouble b1 = ctm[1]; | 2173 | fouble b1 = ctm[1]; |
1961 | fouble c1 = ctm[2]; | 2174 | fouble c1 = ctm[2]; |
1962 | fouble d1 = ctm[3]; | 2175 | fouble d1 = ctm[3]; |
2176 | int i; | ||
1963 | 2177 | ||
1964 | ctm[0] = a * a1 + b * c1; | 2178 | ctm[0] = a * a1 + b * c1; |
1965 | ctm[1] = a * b1 + b * d1; | 2179 | ctm[1] = a * b1 + b * d1; |
1966 | ctm[2] = c * a1 + d * c1; | 2180 | ctm[2] = c * a1 + d * c1; |
1967 | ctm[3] = c * b1 + d * d1; | 2181 | ctm[3] = c * b1 + d * d1; |
1968 | ctm[4] = e * a1 + f * c1 + ctm[4]; | 2182 | ctm[4] = e * a1 + f * c1 + ctm[4]; |
1969 | ctm[5] = e * b1 + f * d1 + ctm[5]; | 2183 | ctm[5] = e * b1 + f * d1 + ctm[5]; |
2184 | |||
2185 | // avoid FP exceptions on badly messed up PDF files | ||
2186 | for (i = 0; i < 6; ++i) { | ||
2187 | if (ctm[i] > fouble(1e3)) { | ||
2188 | ctm[i] = fouble(1e3); | ||
2189 | } else if (ctm[i] < -fouble(1e3)) { | ||
2190 | ctm[i] = -fouble(1e3); | ||
2191 | } | ||
2192 | } | ||
1970 | } | 2193 | } |
1971 | 2194 | ||
1972 | void GfxState::setFillColorSpace(GfxColorSpace *colorSpace) { | 2195 | void GfxState::setFillColorSpace(GfxColorSpace *colorSpace) { |
1973 | if (fillColorSpace) { | 2196 | if (fillColorSpace) { |
1974 | delete fillColorSpace; | 2197 | delete fillColorSpace; |
1975 | } | 2198 | } |
1976 | fillColorSpace = colorSpace; | 2199 | fillColorSpace = colorSpace; |
1977 | } | 2200 | } |
1978 | 2201 | ||
1979 | void GfxState::setStrokeColorSpace(GfxColorSpace *colorSpace) { | 2202 | void 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 | ||
1986 | void GfxState::setFillPattern(GfxPattern *pattern) { | 2209 | void 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 | ||
1993 | void GfxState::setStrokePattern(GfxPattern *pattern) { | 2216 | void 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 | ||
2000 | void GfxState::setLineDash(fouble *dash, int length, fouble start) { | 2223 | void 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 | ||
2008 | void GfxState::clearPath() { | 2231 | void GfxState::clearPath() { |
2009 | delete path; | 2232 | delete path; |
2010 | path = new GfxPath(); | 2233 | path = new GfxPath(); |
2011 | } | 2234 | } |
2012 | 2235 | ||
2013 | void GfxState::clip() { | 2236 | void 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 | ||
2054 | void GfxState::textShift(fouble tx) { | 2277 | void GfxState::textShift(fouble tx, fouble ty) { |
2055 | fouble dx, dy; | 2278 | fouble dx, dy; |
2056 | 2279 | ||
2057 | textTransformDelta(tx, 0, &dx, &dy); | 2280 | textTransformDelta(tx, ty, &dx, &dy); |
2058 | curX += dx; | 2281 | curX += dx; |
2059 | curY += dy; | 2282 | curY += dy; |
2060 | } | 2283 | } |
2061 | 2284 | ||
2062 | void GfxState::shift(fouble dx, fouble dy) { | 2285 | void GfxState::shift(fouble dx, fouble dy) { |
2063 | curX += dx; | 2286 | curX += dx; |
2064 | curY += dy; | 2287 | curY += dy; |
2065 | } | 2288 | } |
2066 | 2289 | ||
2067 | GfxState *GfxState::save() { | 2290 | GfxState *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 | ||
2075 | GfxState *GfxState::restore() { | 2298 | GfxState *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 | ||
20 | class Array; | 20 | class Array; |
21 | class GfxFont; | 21 | class GfxFont; |
22 | struct PDFRectangle; | 22 | struct PDFRectangle; |
23 | 23 | ||
24 | //------------------------------------------------------------------------ | 24 | //------------------------------------------------------------------------ |
25 | // GfxColor | 25 | // GfxColor |
26 | //------------------------------------------------------------------------ | 26 | //------------------------------------------------------------------------ |
27 | 27 | ||
28 | #define gfxColorMaxComps funcMaxOutputs | 28 | #define gfxColorMaxComps funcMaxOutputs |
29 | 29 | ||
30 | struct GfxColor { | 30 | struct GfxColor { |
31 | fouble c[gfxColorMaxComps]; | 31 | fouble c[gfxColorMaxComps]; |
32 | }; | 32 | }; |
33 | 33 | ||
34 | //------------------------------------------------------------------------ | 34 | //------------------------------------------------------------------------ |
35 | // GfxRGB | 35 | // GfxRGB |
36 | //------------------------------------------------------------------------ | 36 | //------------------------------------------------------------------------ |
37 | 37 | ||
38 | struct GfxRGB { | 38 | struct 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 | ||
46 | struct GfxCMYK { | 46 | struct 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 | ||
54 | enum GfxColorSpaceMode { | 54 | enum 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 | ||
68 | class GfxColorSpace { | 68 | class GfxColorSpace { |
69 | public: | 69 | public: |
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 | ||
92 | private: | 92 | private: |
93 | }; | 93 | }; |
94 | 94 | ||
95 | //------------------------------------------------------------------------ | 95 | //------------------------------------------------------------------------ |
96 | // GfxDeviceGrayColorSpace | 96 | // GfxDeviceGrayColorSpace |
97 | //------------------------------------------------------------------------ | 97 | //------------------------------------------------------------------------ |
98 | 98 | ||
99 | class GfxDeviceGrayColorSpace: public GfxColorSpace { | 99 | class GfxDeviceGrayColorSpace: public GfxColorSpace { |
100 | public: | 100 | public: |
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 | ||
113 | private: | 113 | private: |
114 | }; | 114 | }; |
115 | 115 | ||
116 | //------------------------------------------------------------------------ | 116 | //------------------------------------------------------------------------ |
117 | // GfxCalGrayColorSpace | 117 | // GfxCalGrayColorSpace |
118 | //------------------------------------------------------------------------ | 118 | //------------------------------------------------------------------------ |
119 | 119 | ||
120 | class GfxCalGrayColorSpace: public GfxColorSpace { | 120 | class GfxCalGrayColorSpace: public GfxColorSpace { |
121 | public: | 121 | public: |
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 | ||
146 | private: | 146 | private: |
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 | ||
157 | class GfxDeviceRGBColorSpace: public GfxColorSpace { | 157 | class GfxDeviceRGBColorSpace: public GfxColorSpace { |
158 | public: | 158 | public: |
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 | ||
171 | private: | 171 | private: |
172 | }; | 172 | }; |
173 | 173 | ||
174 | //------------------------------------------------------------------------ | 174 | //------------------------------------------------------------------------ |
175 | // GfxCalRGBColorSpace | 175 | // GfxCalRGBColorSpace |
176 | //------------------------------------------------------------------------ | 176 | //------------------------------------------------------------------------ |
177 | 177 | ||
178 | class GfxCalRGBColorSpace: public GfxColorSpace { | 178 | class GfxCalRGBColorSpace: public GfxColorSpace { |
179 | public: | 179 | public: |
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 | ||
380 | private: | 380 | private: |
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 | ||
391 | class GfxDeviceNColorSpace: public GfxColorSpace { | 391 | class GfxDeviceNColorSpace: public GfxColorSpace { |
392 | public: | 392 | public: |
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 | ||
411 | private: | 411 | private: |
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 | ||
425 | class GfxPatternColorSpace: public GfxColorSpace { | 425 | class GfxPatternColorSpace: public GfxColorSpace { |
426 | public: | 426 | public: |
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 | ||
445 | private: | 445 | private: |
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 | ||
455 | class GfxPattern { | 455 | class GfxPattern { |
456 | public: | 456 | public: |
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 | ||
467 | private: | 467 | private: |
468 | 468 | ||
469 | int type; | 469 | int type; |
470 | }; | 470 | }; |
471 | 471 | ||
472 | //------------------------------------------------------------------------ | 472 | //------------------------------------------------------------------------ |
473 | // GfxTilingPattern | 473 | // GfxTilingPattern |
474 | //------------------------------------------------------------------------ | 474 | //------------------------------------------------------------------------ |
475 | 475 | ||
476 | class GfxTilingPattern: public GfxPattern { | 476 | class GfxTilingPattern: public GfxPattern { |
477 | public: | 477 | public: |
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 | ||
494 | private: | 494 | private: |
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 | ||
511 | class GfxShading { | 511 | class GfxShading { |
512 | public: | 512 | public: |
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 | ||
527 | private: | 527 | private: |
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 | ||
541 | class GfxAxialShading: public GfxShading { | 541 | class GfxAxialShading: public GfxShading { |
542 | public: | 542 | public: |
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 | ||
561 | private: | 561 | private: |
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 | |||
574 | class GfxRadialShading: public GfxShading { | ||
575 | public: | ||
576 | |||
577 | GfxRadialShading(fouble x0A, fouble y0A, fouble r0A, | ||
578 | fouble x1A, fouble y1A, fouble r1A, | ||
579 | fouble t0A, fouble t1A, | ||
580 | Function **funcsA, int nFuncsA, | ||
581 | GBool extend0A, GBool extend1A); | ||
582 | virtual ~GfxRadialShading(); | ||
583 | |||
584 | static GfxRadialShading *parse(Dict *dict); | ||
585 | |||
586 | void getCoords(fouble *x0A, fouble *y0A, fouble *r0A, | ||
587 | fouble *x1A, fouble *y1A, fouble *r1A) | ||
588 | { *x0A = x0; *y0A = y0; *r0A = r0; *x1A = x1; *y1A = y1; *r1A = r1; } | ||
589 | fouble getDomain0() { return t0; } | ||
590 | fouble getDomain1() { return t1; } | ||
591 | void getColor(fouble t, GfxColor *color); | ||
592 | GBool getExtend0() { return extend0; } | ||
593 | GBool getExtend1() { return extend1; } | ||
594 | |||
595 | private: | ||
596 | |||
597 | fouble x0, y0, r0, x1, y1, r1; | ||
598 | fouble t0, t1; | ||
599 | Function *funcs[gfxColorMaxComps]; | ||
600 | int nFuncs; | ||
601 | GBool extend0, extend1; | ||
602 | }; | ||
603 | |||
604 | //------------------------------------------------------------------------ | ||
571 | // GfxImageColorMap | 605 | // GfxImageColorMap |
572 | //------------------------------------------------------------------------ | 606 | //------------------------------------------------------------------------ |
573 | 607 | ||
574 | class GfxImageColorMap { | 608 | class GfxImageColorMap { |
575 | public: | 609 | public: |
576 | 610 | ||
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 | ||
602 | private: | 636 | private: |
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 | ||
621 | class GfxSubpath { | 655 | class GfxSubpath { |
622 | public: | 656 | public: |
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 | ||
654 | private: | 688 | private: |
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 | ||
666 | class GfxPath { | 700 | class GfxPath { |
667 | public: | 701 | public: |
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 | ||
706 | private: | 740 | private: |
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 | ||
722 | class GfxState { | 756 | class GfxState { |
723 | public: | 757 | public: |
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 | ||
876 | private: | 911 | private: |
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 | ||
40 | GlobalParams *globalParams = NULL; | 40 | GlobalParams *globalParams = NULL; |
41 | 41 | ||
42 | //------------------------------------------------------------------------ | 42 | //------------------------------------------------------------------------ |
43 | // DisplayFontParam | 43 | // DisplayFontParam |
44 | //------------------------------------------------------------------------ | 44 | //------------------------------------------------------------------------ |
45 | 45 | ||
46 | DisplayFontParam::DisplayFontParam(GString *nameA, | 46 | DisplayFontParam::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 | ||
64 | DisplayFontParam::DisplayFontParam(char *nameA, char *xlfdA, char *encodingA) { | 64 | DisplayFontParam::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 | ||
71 | DisplayFontParam::~DisplayFontParam() { | 71 | DisplayFontParam::~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 | ||
99 | PSFontParam::PSFontParam(GString *pdfFontNameA, GString *psFontNameA) { | 99 | PSFontParam::PSFontParam(GString *pdfFontNameA, int wModeA, |
100 | GString *psFontNameA, GString *encodingA) { | ||
100 | pdfFontName = pdfFontNameA; | 101 | pdfFontName = pdfFontNameA; |
102 | wMode = wModeA; | ||
101 | psFontName = psFontNameA; | 103 | psFontName = psFontNameA; |
104 | encoding = encodingA; | ||
102 | } | 105 | } |
103 | 106 | ||
104 | PSFontParam::~PSFontParam() { | 107 | PSFontParam::~PSFontParam() { |
105 | delete pdfFontName; | 108 | delete pdfFontName; |
106 | delete psFontName; | 109 | delete psFontName; |
110 | if (encoding) { | ||
111 | delete encoding; | ||
112 | } | ||
107 | } | 113 | } |
108 | 114 | ||
109 | //------------------------------------------------------------------------ | 115 | //------------------------------------------------------------------------ |
110 | // parsing | 116 | // parsing |
111 | //------------------------------------------------------------------------ | 117 | //------------------------------------------------------------------------ |
112 | 118 | ||
113 | GlobalParams::GlobalParams(char *cfgFileName) { | 119 | GlobalParams::GlobalParams(char *cfgFileName) { |
114 | UnicodeMap *map; | 120 | UnicodeMap *map; |
115 | DisplayFontParam *dfp; | 121 | DisplayFontParam *dfp; |
116 | GString *fileName; | 122 | GString *fileName; |
117 | FILE *f; | 123 | FILE *f; |
118 | char buf[512]; | ||
119 | int line; | ||
120 | GList *tokens; | ||
121 | GString *cmd; | ||
122 | char *p1, *p2; | ||
123 | int i; | 124 | int i; |
124 | 125 | ||
125 | initBuiltinFontTables(); | 126 | initBuiltinFontTables(); |
126 | 127 | ||
128 | // scan the encoding in reverse because we want the lowest-numbered | ||
129 | // index for each char name ('space' is encoded twice) | ||
127 | macRomanReverseMap = new NameToCharCode(); | 130 | macRomanReverseMap = new NameToCharCode(); |
128 | for (i = 0; i < 256; ++i) { | 131 | for (i = 255; i >= 0; --i) { |
129 | if (macRomanEncoding[i]) { | 132 | if (macRomanEncoding[i]) { |
130 | macRomanReverseMap->add(macRomanEncoding[i], (CharCode)i); | 133 | macRomanReverseMap->add(macRomanEncoding[i], (CharCode)i); |
131 | } | 134 | } |
132 | } | 135 | } |
133 | 136 | ||
134 | nameToUnicode = new NameToCharCode(); | 137 | nameToUnicode = new NameToCharCode(); |
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; | 255 | void GlobalParams::parseFile(GString *fileName, FILE *f) { |
243 | while (*p1) { | 256 | int line; |
244 | for (; *p1 && isspace(*p1); ++p1) ; | 257 | GList *tokens; |
245 | if (!*p1) { | 258 | GString *cmd, *incFile; |
246 | break; | 259 | char *p1, *p2; |
247 | } | 260 | char buf[512]; |
248 | if (*p1 == '"' || *p1 == '\'') { | 261 | FILE *f2; |
249 | for (p2 = p1 + 1; *p2 && *p2 != *p1; ++p2) ; | 262 | |
250 | ++p1; | 263 | line = 1; |
251 | } else { | 264 | while (fgets(buf, sizeof(buf) - 1, f)) { |
252 | for (p2 = p1 + 1; *p2 && !isspace(*p2); ++p2) ; | 265 | |
253 | } | 266 | // break the line into tokens |
254 | tokens->append(new GString(p1, p2 - p1)); | 267 | tokens = new GList(); |
255 | p1 = p2 + 1; | 268 | p1 = buf; |
269 | while (*p1) { | ||
270 | for (; *p1 && isspace(*p1); ++p1) ; | ||
271 | if (!*p1) { | ||
272 | break; | ||
273 | } | ||
274 | if (*p1 == '"' || *p1 == '\'') { | ||
275 | for (p2 = p1 + 1; *p2 && *p2 != *p1; ++p2) ; | ||
276 | ++p1; | ||
277 | } else { | ||
278 | for (p2 = p1 + 1; *p2 && !isspace(*p2); ++p2) ; | ||
256 | } | 279 | } |
280 | tokens->append(new GString(p1, p2 - p1)); | ||
281 | p1 = p2 + 1; | ||
282 | } | ||
257 | 283 | ||
258 | if (tokens->getLength() > 0 && | 284 | if (tokens->getLength() > 0 && |
259 | ((GString *)tokens->get(0))->getChar(0) != '#') { | 285 | ((GString *)tokens->get(0))->getChar(0) != '#') { |
260 | cmd = (GString *)tokens->get(0); | 286 | cmd = (GString *)tokens->get(0); |
261 | if (!cmd->cmp("nameToUnicode")) { | 287 | if (!cmd->cmp("include")) { |
262 | parseNameToUnicode(tokens, fileName, line); | 288 | if (tokens->getLength() == 2) { |
263 | } else if (!cmd->cmp("cidToUnicode")) { | 289 | incFile = (GString *)tokens->get(1); |
264 | parseCIDToUnicode(tokens, fileName, line); | 290 | if ((f2 = fopen(incFile->getCString(), "r"))) { |
265 | } else if (!cmd->cmp("unicodeMap")) { | 291 | parseFile(incFile, f2); |
266 | parseUnicodeMap(tokens, fileName, line); | 292 | fclose(f2); |
267 | } else if (!cmd->cmp("cMapDir")) { | 293 | } else { |
268 | parseCMapDir(tokens, fileName, line); | 294 | error(-1, "Couldn't find included config file: '%s' (%s:%d)", |
269 | } else if (!cmd->cmp("toUnicodeDir")) { | 295 | incFile->getCString(), fileName->getCString(), line); |
270 | parseToUnicodeDir(tokens, fileName, line); | 296 | } |
271 | } else if (!cmd->cmp("displayFontX")) { | ||
272 | parseDisplayFont(tokens, gFalse, displayFontX, fileName, line); | ||
273 | } else if (!cmd->cmp("displayFontT1")) { | ||
274 | parseDisplayFont(tokens, gFalse, displayFontT1, fileName, line); | ||
275 | } else if (!cmd->cmp("displayFontTT")) { | ||
276 | parseDisplayFont(tokens, gFalse, displayFontTT, fileName, line); | ||
277 | } else if (!cmd->cmp("displayCIDFontX")) { | ||
278 | parseDisplayFont(tokens, gTrue, displayFontX, fileName, line); | ||
279 | } else if (!cmd->cmp("psFile")) { | ||
280 | parsePSFile(tokens, fileName, line); | ||
281 | } else if (!cmd->cmp("psFont")) { | ||
282 | parsePSFont(tokens, fileName, line); | ||
283 | } else if (!cmd->cmp("psPaperSize")) { | ||
284 | parsePSPaperSize(tokens, fileName, line); | ||
285 | } else if (!cmd->cmp("psDuplex")) { | ||
286 | parseYesNo("psDuplex", &psDuplex, tokens, fileName, line); | ||
287 | } else if (!cmd->cmp("psLevel")) { | ||
288 | parsePSLevel(tokens, fileName, line); | ||
289 | } else if (!cmd->cmp("psEmbedType1")) { | ||
290 | parseYesNo("psEmbedType1", &psEmbedType1, tokens, fileName, line); | ||
291 | } else if (!cmd->cmp("psEmbedTrueType")) { | ||
292 | parseYesNo("psEmbedTrueType", &psEmbedTrueType, | ||
293 | tokens, fileName, line); | ||
294 | } else if (!cmd->cmp("psOPI")) { | ||
295 | parseYesNo("psOPI", &psOPI, tokens, fileName, line); | ||
296 | } else if (!cmd->cmp("textEncoding")) { | ||
297 | parseTextEncoding(tokens, fileName, line); | ||
298 | } else if (!cmd->cmp("textEOL")) { | ||
299 | parseTextEOL(tokens, fileName, line); | ||
300 | } else if (!cmd->cmp("fontDir")) { | ||
301 | parseFontDir(tokens, fileName, line); | ||
302 | } else if (!cmd->cmp("t1libControl")) { | ||
303 | parseFontRastControl("t1libControl", &t1libControl, | ||
304 | tokens, fileName, line); | ||
305 | } else if (!cmd->cmp("freetypeControl")) { | ||
306 | parseFontRastControl("freetypeControl", &freetypeControl, | ||
307 | tokens, fileName, line); | ||
308 | } else if (!cmd->cmp("urlCommand")) { | ||
309 | parseURLCommand(tokens, fileName, line); | ||
310 | } else if (!cmd->cmp("mapNumericCharNames")) { | ||
311 | parseYesNo("mapNumericCharNames", &mapNumericCharNames, | ||
312 | tokens, fileName, line); | ||
313 | } else if (!cmd->cmp("errQuiet")) { | ||
314 | parseYesNo("errQuiet", &errQuiet, tokens, fileName, line); | ||
315 | } else if (!cmd->cmp("fontpath") || !cmd->cmp("fontmap")) { | ||
316 | error(-1, "Unknown config file command"); | ||
317 | error(-1, "-- the config file format has changed since Xpdf 0.9x"); | ||
318 | } else { | 297 | } else { |
319 | error(-1, "Unknown config file command '%s' (%s:%d)", | 298 | error(-1, "Bad 'include' config file command (%s:%d)", |
320 | cmd->getCString(), fileName->getCString(), line); | 299 | fileName->getCString(), line); |
321 | } | 300 | } |
301 | } else if (!cmd->cmp("nameToUnicode")) { | ||
302 | parseNameToUnicode(tokens, fileName, line); | ||
303 | } else if (!cmd->cmp("cidToUnicode")) { | ||
304 | parseCIDToUnicode(tokens, fileName, line); | ||
305 | } else if (!cmd->cmp("unicodeMap")) { | ||
306 | parseUnicodeMap(tokens, fileName, line); | ||
307 | } else if (!cmd->cmp("cMapDir")) { | ||
308 | parseCMapDir(tokens, fileName, line); | ||
309 | } else if (!cmd->cmp("toUnicodeDir")) { | ||
310 | parseToUnicodeDir(tokens, fileName, line); | ||
311 | } else if (!cmd->cmp("displayFontX")) { | ||
312 | parseDisplayFont(tokens, displayFonts, displayFontX, fileName, line); | ||
313 | } else if (!cmd->cmp("displayFontT1")) { | ||
314 | parseDisplayFont(tokens, displayFonts, displayFontT1, fileName, line); | ||
315 | } else if (!cmd->cmp("displayFontTT")) { | ||
316 | parseDisplayFont(tokens, displayFonts, displayFontTT, fileName, line); | ||
317 | } else if (!cmd->cmp("displayCIDFontX")) { | ||
318 | parseDisplayFont(tokens, displayCIDFonts, | ||
319 | displayFontX, fileName, line); | ||
320 | } else if (!cmd->cmp("displayNamedCIDFontX")) { | ||
321 | parseDisplayFont(tokens, displayNamedCIDFonts, | ||
322 | displayFontX, fileName, line); | ||
323 | } else if (!cmd->cmp("psFile")) { | ||
324 | parsePSFile(tokens, fileName, line); | ||
325 | } else if (!cmd->cmp("psFont")) { | ||
326 | parsePSFont(tokens, fileName, line); | ||
327 | } else if (!cmd->cmp("psNamedFont16")) { | ||
328 | parsePSFont16("psNamedFont16", psNamedFonts16, | ||
329 | tokens, fileName, line); | ||
330 | } else if (!cmd->cmp("psFont16")) { | ||
331 | parsePSFont16("psFont16", psFonts16, tokens, fileName, line); | ||
332 | } else if (!cmd->cmp("psPaperSize")) { | ||
333 | parsePSPaperSize(tokens, fileName, line); | ||
334 | } else if (!cmd->cmp("psDuplex")) { | ||
335 | parseYesNo("psDuplex", &psDuplex, tokens, fileName, line); | ||
336 | } else if (!cmd->cmp("psLevel")) { | ||
337 | parsePSLevel(tokens, fileName, line); | ||
338 | } else if (!cmd->cmp("psEmbedType1Fonts")) { | ||
339 | parseYesNo("psEmbedType1", &psEmbedType1, tokens, fileName, line); | ||
340 | } else if (!cmd->cmp("psEmbedTrueTypeFonts")) { | ||
341 | parseYesNo("psEmbedTrueType", &psEmbedTrueType, | ||
342 | tokens, fileName, line); | ||
343 | } else if (!cmd->cmp("psEmbedCIDPostScriptFonts")) { | ||
344 | parseYesNo("psEmbedCIDPostScript", &psEmbedCIDPostScript, | ||
345 | tokens, fileName, line); | ||
346 | } else if (!cmd->cmp("psEmbedCIDTrueTypeFonts")) { | ||
347 | parseYesNo("psEmbedCIDTrueType", &psEmbedCIDTrueType, | ||
348 | tokens, fileName, line); | ||
349 | } else if (!cmd->cmp("psOPI")) { | ||
350 | parseYesNo("psOPI", &psOPI, tokens, fileName, line); | ||
351 | } else if (!cmd->cmp("psASCIIHex")) { | ||
352 | parseYesNo("psASCIIHex", &psASCIIHex, tokens, fileName, line); | ||
353 | } else if (!cmd->cmp("textEncoding")) { | ||
354 | parseTextEncoding(tokens, fileName, line); | ||
355 | } else if (!cmd->cmp("textEOL")) { | ||
356 | parseTextEOL(tokens, fileName, line); | ||
357 | } else if (!cmd->cmp("fontDir")) { | ||
358 | parseFontDir(tokens, fileName, line); | ||
359 | } else if (!cmd->cmp("initialZoom")) { | ||
360 | parseInitialZoom(tokens, fileName, line); | ||
361 | } else if (!cmd->cmp("t1libControl")) { | ||
362 | parseFontRastControl("t1libControl", &t1libControl, | ||
363 | tokens, fileName, line); | ||
364 | } else if (!cmd->cmp("freetypeControl")) { | ||
365 | parseFontRastControl("freetypeControl", &freetypeControl, | ||
366 | tokens, fileName, line); | ||
367 | } else if (!cmd->cmp("urlCommand")) { | ||
368 | parseURLCommand(tokens, fileName, line); | ||
369 | } else if (!cmd->cmp("mapNumericCharNames")) { | ||
370 | parseYesNo("mapNumericCharNames", &mapNumericCharNames, | ||
371 | tokens, fileName, line); | ||
372 | } else if (!cmd->cmp("errQuiet")) { | ||
373 | parseYesNo("errQuiet", &errQuiet, tokens, fileName, line); | ||
374 | } else if (!cmd->cmp("fontpath") || !cmd->cmp("fontmap")) { | ||
375 | error(-1, "Unknown config file command"); | ||
376 | error(-1, "-- the config file format has changed since Xpdf 0.9x"); | ||
377 | } else { | ||
378 | error(-1, "Unknown config file command '%s' (%s:%d)", | ||
379 | cmd->getCString(), fileName->getCString(), line); | ||
322 | } | 380 | } |
323 | |||
324 | deleteGList(tokens, GString); | ||
325 | ++line; | ||
326 | } | 381 | } |
327 | 382 | ||
328 | delete fileName; | 383 | deleteGList(tokens, GString); |
384 | ++line; | ||
329 | } | 385 | } |
330 | } | 386 | } |
331 | 387 | ||
332 | void GlobalParams::parseNameToUnicode(GList *tokens, GString *fileName, | 388 | void GlobalParams::parseNameToUnicode(GList *tokens, GString *fileName, |
333 | int line) { | 389 | int line) { |
334 | GString *name; | 390 | GString *name; |
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 | ||
367 | void GlobalParams::parseCIDToUnicode(GList *tokens, GString *fileName, | 423 | void 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 | ||
384 | void GlobalParams::parseUnicodeMap(GList *tokens, GString *fileName, | 440 | void 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 | ||
401 | void GlobalParams::parseCMapDir(GList *tokens, GString *fileName, int line) { | 457 | void 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 | ||
419 | void GlobalParams::parseToUnicodeDir(GList *tokens, GString *fileName, | 475 | void 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 | ||
429 | void GlobalParams::parseDisplayFont(GList *tokens, GBool isCID, | 485 | void GlobalParams::parseDisplayFont(GList *tokens, GHash *fontHash, |
430 | DisplayFontParamKind kind, | 486 | DisplayFontParamKind kind, |
431 | GString *fileName, int line) { | 487 | GString *fileName, int line) { |
432 | DisplayFontParam *param, *old; | 488 | DisplayFontParam *param, *old; |
433 | 489 | ||
434 | if (tokens->getLength() < 2) { | 490 | if (tokens->getLength() < 2) { |
435 | goto err1; | 491 | goto err1; |
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 | ||
481 | void GlobalParams::parsePSPaperSize(GList *tokens, GString *fileName, | 530 | void GlobalParams::parsePSPaperSize(GList *tokens, GString *fileName, |
482 | int line) { | 531 | int line) { |
483 | GString *tok; | 532 | GString *tok; |
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 | ||
502 | void GlobalParams::parsePSLevel(GList *tokens, GString *fileName, int line) { | 551 | void 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 | ||
525 | void GlobalParams::parsePSFile(GList *tokens, GString *fileName, int line) { | 578 | void 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 | ||
537 | void GlobalParams::parsePSFont(GList *tokens, GString *fileName, int line) { | 590 | void 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 | ||
603 | void GlobalParams::parsePSFont16(char *cmdName, GList *fontList, | ||
604 | GList *tokens, GString *fileName, int line) { | ||
605 | PSFontParam *param; | ||
606 | int wMode; | ||
607 | GString *tok; | ||
608 | |||
609 | if (tokens->getLength() != 5) { | ||
610 | error(-1, "Bad '%s' config file command (%s:%d)", | ||
611 | cmdName, fileName->getCString(), line); | ||
612 | return; | ||
613 | } | ||
614 | tok = (GString *)tokens->get(2); | ||
615 | if (!tok->cmp("H")) { | ||
616 | wMode = 0; | ||
617 | } else if (!tok->cmp("V")) { | ||
618 | wMode = 1; | ||
619 | } else { | ||
620 | error(-1, "Bad '%s' config file command (%s:%d)", | ||
621 | cmdName, fileName->getCString(), line); | ||
622 | return; | ||
623 | } | ||
624 | param = new PSFontParam(((GString *)tokens->get(1))->copy(), | ||
625 | wMode, | ||
626 | ((GString *)tokens->get(3))->copy(), | ||
627 | ((GString *)tokens->get(4))->copy()); | ||
628 | fontList->append(param); | ||
629 | } | ||
630 | |||
550 | void GlobalParams::parseTextEncoding(GList *tokens, GString *fileName, | 631 | void GlobalParams::parseTextEncoding(GList *tokens, GString *fileName, |
551 | int line) { | 632 | int line) { |
552 | if (tokens->getLength() != 2) { | 633 | if (tokens->getLength() != 2) { |
553 | error(-1, "Bad 'textEncoding' config file command (%s:%d)", | 634 | error(-1, "Bad 'textEncoding' config file command (%s:%d)", |
554 | fileName->getCString(), line); | 635 | fileName->getCString(), line); |
555 | return; | 636 | return; |
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 | ||
561 | void GlobalParams::parseTextEOL(GList *tokens, GString *fileName, int line) { | 642 | void 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 | ||
582 | void GlobalParams::parseFontDir(GList *tokens, GString *fileName, int line) { | 663 | void 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 | ||
591 | void GlobalParams::parseURLCommand(GList *tokens, GString *fileName, | 672 | void GlobalParams::parseInitialZoom(GList *tokens, |
592 | int line) { | 673 | GString *fileName, int line) { |
593 | if (tokens->getLength() != 2) { | 674 | if (tokens->getLength() != 2) { |
594 | error(-1, "Bad 'urlCommand' config file command (%s:%d)", | 675 | error(-1, "Bad 'initialZoom' config file command (%s:%d)", |
595 | fileName->getCString(), line); | 676 | fileName->getCString(), line); |
596 | return; | 677 | return; |
597 | } | 678 | } |
598 | if (urlCommand) { | 679 | delete initialZoom; |
599 | delete urlCommand; | 680 | initialZoom = ((GString *)tokens->get(1))->copy(); |
600 | } | ||
601 | urlCommand = ((GString *)tokens->get(1))->copy(); | ||
602 | } | 681 | } |
603 | 682 | ||
604 | void GlobalParams::parseFontRastControl(char *cmdName, FontRastControl *val, | 683 | void GlobalParams::parseFontRastControl(char *cmdName, FontRastControl *val, |
605 | GList *tokens, GString *fileName, | 684 | GList *tokens, GString *fileName, |
606 | int line) { | 685 | int line) { |
607 | GString *tok; | 686 | GString *tok; |
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 | ||
700 | void GlobalParams::parseURLCommand(GList *tokens, GString *fileName, | ||
701 | int line) { | ||
702 | if (tokens->getLength() != 2) { | ||
703 | error(-1, "Bad 'urlCommand' config file command (%s:%d)", | ||
704 | fileName->getCString(), line); | ||
705 | return; | ||
706 | } | ||
707 | if (urlCommand) { | ||
708 | delete urlCommand; | ||
709 | } | ||
710 | urlCommand = ((GString *)tokens->get(1))->copy(); | ||
711 | } | ||
712 | |||
621 | void GlobalParams::parseYesNo(char *cmdName, GBool *flag, | 713 | void GlobalParams::parseYesNo(char *cmdName, GBool *flag, |
622 | GList *tokens, GString *fileName, int line) { | 714 | GList *tokens, GString *fileName, int line) { |
623 | GString *tok; | 715 | GString *tok; |
624 | 716 | ||
625 | if (tokens->getLength() != 2) { | 717 | if (tokens->getLength() != 2) { |
626 | error(-1, "Bad '%s' config file command (%s:%d)", | 718 | error(-1, "Bad '%s' config file command (%s:%d)", |
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 | ||
641 | GlobalParams::~GlobalParams() { | 733 | GlobalParams::~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 | ||
682 | CharCode GlobalParams::getMacRomanCharCode(char *charName) { | 778 | CharCode GlobalParams::getMacRomanCharCode(char *charName) { |
683 | return macRomanReverseMap->lookup(charName); | 779 | return macRomanReverseMap->lookup(charName); |
684 | } | 780 | } |
685 | 781 | ||
686 | Unicode GlobalParams::mapNameToUnicode(char *charName) { | 782 | Unicode GlobalParams::mapNameToUnicode(char *charName) { |
687 | return nameToUnicode->lookup(charName); | 783 | return nameToUnicode->lookup(charName); |
688 | } | 784 | } |
689 | 785 | ||
690 | FILE *GlobalParams::getCIDToUnicodeFile(GString *collection) { | 786 | FILE *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 | ||
699 | UnicodeMap *GlobalParams::getResidentUnicodeMap(GString *encodingName) { | 795 | UnicodeMap *GlobalParams::getResidentUnicodeMap(GString *encodingName) { |
700 | return (UnicodeMap *)residentUnicodeMaps->lookup(encodingName); | 796 | return (UnicodeMap *)residentUnicodeMaps->lookup(encodingName); |
701 | } | 797 | } |
702 | 798 | ||
703 | FILE *GlobalParams::getUnicodeMapFile(GString *encodingName) { | 799 | FILE *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 | ||
712 | FILE *GlobalParams::findCMapFile(GString *collection, GString *cMapName) { | 808 | FILE *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 | ||
734 | FILE *GlobalParams::findToUnicodeFile(GString *name) { | 830 | FILE *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 | ||
751 | DisplayFontParam *GlobalParams::getDisplayFont(GString *fontName) { | 847 | DisplayFontParam *GlobalParams::getDisplayFont(GString *fontName) { |
752 | return (DisplayFontParam *)displayFonts->lookup(fontName); | 848 | return (DisplayFontParam *)displayFonts->lookup(fontName); |
753 | } | 849 | } |
754 | 850 | ||
755 | DisplayFontParam *GlobalParams::getDisplayCIDFont(GString *collection) { | 851 | DisplayFontParam *GlobalParams::getDisplayCIDFont(GString *fontName, |
756 | return (DisplayFontParam *)displayCIDFonts->lookup(collection); | 852 | GString *collection) { |
853 | DisplayFontParam *dfp; | ||
854 | |||
855 | if (!fontName || | ||
856 | !(dfp = (DisplayFontParam *)displayNamedCIDFonts->lookup(fontName))) { | ||
857 | dfp = (DisplayFontParam *)displayCIDFonts->lookup(collection); | ||
858 | } | ||
859 | return dfp; | ||
757 | } | 860 | } |
758 | 861 | ||
759 | PSFontParam *GlobalParams::getPSFont(GString *fontName) { | 862 | PSFontParam *GlobalParams::getPSFont(GString *fontName) { |
760 | return (PSFontParam *)psFonts->lookup(fontName); | 863 | return (PSFontParam *)psFonts->lookup(fontName); |
761 | } | 864 | } |
762 | 865 | ||
866 | PSFontParam *GlobalParams::getPSFont16(GString *fontName, | ||
867 | GString *collection, int wMode) { | ||
868 | PSFontParam *p; | ||
869 | int i; | ||
870 | |||
871 | p = NULL; | ||
872 | if (fontName) { | ||
873 | for (i = 0; i < psNamedFonts16->getLength(); ++i) { | ||
874 | p = (PSFontParam *)psNamedFonts16->get(i); | ||
875 | if (!p->pdfFontName->cmp(fontName) && | ||
876 | p->wMode == wMode) { | ||
877 | break; | ||
878 | } | ||
879 | p = NULL; | ||
880 | } | ||
881 | } | ||
882 | if (!p && collection) { | ||
883 | for (i = 0; i < psFonts16->getLength(); ++i) { | ||
884 | p = (PSFontParam *)psFonts16->get(i); | ||
885 | if (!p->pdfFontName->cmp(collection) && | ||
886 | p->wMode == wMode) { | ||
887 | break; | ||
888 | } | ||
889 | p = NULL; | ||
890 | } | ||
891 | } | ||
892 | return p; | ||
893 | } | ||
894 | |||
763 | GString *GlobalParams::findFontFile(GString *fontName, | 895 | GString *GlobalParams::findFontFile(GString *fontName, |
764 | char *ext1, char *ext2) { | 896 | char *ext1, char *ext2) { |
765 | GString *dir, *fileName; | 897 | GString *dir, *fileName; |
766 | FILE *f; | 898 | FILE *f; |
767 | int i; | 899 | int i; |
768 | 900 | ||
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 | ||
793 | CharCodeToUnicode *GlobalParams::getCIDToUnicode(GString *collection) { | 925 | CharCodeToUnicode *GlobalParams::getCIDToUnicode(GString *collection) { |
794 | return cidToUnicodeCache->getCIDToUnicode(collection); | 926 | return cidToUnicodeCache->getCIDToUnicode(collection); |
795 | } | 927 | } |
796 | 928 | ||
797 | UnicodeMap *GlobalParams::getUnicodeMap(GString *encodingName) { | 929 | UnicodeMap *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 | ||
807 | CMap *GlobalParams::getCMap(GString *collection, GString *cMapName) { | 939 | CMap *GlobalParams::getCMap(GString *collection, GString *cMapName) { |
808 | return cMapCache->getCMap(collection, cMapName); | 940 | return cMapCache->getCMap(collection, cMapName); |
809 | } | 941 | } |
810 | 942 | ||
811 | UnicodeMap *GlobalParams::getTextEncoding() { | 943 | UnicodeMap *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 | ||
819 | void GlobalParams::setPSFile(char *file) { | 951 | void 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 | ||
826 | GBool GlobalParams::setPSPaperSize(char *size) { | 958 | GBool 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 | ||
845 | void GlobalParams::setPSPaperWidth(int width) { | 977 | void GlobalParams::setPSPaperWidth(int width) { |
846 | psPaperWidth = width; | 978 | psPaperWidth = width; |
847 | } | 979 | } |
848 | 980 | ||
849 | void GlobalParams::setPSPaperHeight(int height) { | 981 | void GlobalParams::setPSPaperHeight(int height) { |
850 | psPaperHeight = height; | 982 | psPaperHeight = height; |
851 | } | 983 | } |
852 | 984 | ||
853 | void GlobalParams::setPSDuplex(GBool duplex) { | 985 | void GlobalParams::setPSDuplex(GBool duplex) { |
854 | psDuplex = duplex; | 986 | psDuplex = duplex; |
855 | } | 987 | } |
856 | 988 | ||
857 | void GlobalParams::setPSLevel(PSLevel level) { | 989 | void GlobalParams::setPSLevel(PSLevel level) { |
858 | psLevel = level; | 990 | psLevel = level; |
859 | } | 991 | } |
860 | 992 | ||
861 | void GlobalParams::setPSEmbedType1(GBool embed) { | 993 | void GlobalParams::setPSEmbedType1(GBool embed) { |
862 | psEmbedType1 = embed; | 994 | psEmbedType1 = embed; |
863 | } | 995 | } |
864 | 996 | ||
865 | void GlobalParams::setPSEmbedTrueType(GBool embed) { | 997 | void GlobalParams::setPSEmbedTrueType(GBool embed) { |
866 | psEmbedTrueType = embed; | 998 | psEmbedTrueType = embed; |
867 | } | 999 | } |
868 | 1000 | ||
1001 | void GlobalParams::setPSEmbedCIDPostScript(GBool embed) { | ||
1002 | psEmbedCIDPostScript = embed; | ||
1003 | } | ||
1004 | |||
1005 | void GlobalParams::setPSEmbedCIDTrueType(GBool embed) { | ||
1006 | psEmbedCIDTrueType = embed; | ||
1007 | } | ||
1008 | |||
869 | void GlobalParams::setPSOPI(GBool opi) { | 1009 | void GlobalParams::setPSOPI(GBool opi) { |
870 | psOPI = opi; | 1010 | psOPI = opi; |
871 | } | 1011 | } |
872 | 1012 | ||
1013 | void GlobalParams::setPSASCIIHex(GBool hex) { | ||
1014 | psASCIIHex = hex; | ||
1015 | } | ||
1016 | |||
873 | void GlobalParams::setTextEncoding(char *encodingName) { | 1017 | void GlobalParams::setTextEncoding(char *encodingName) { |
874 | delete textEncoding; | 1018 | delete textEncoding; |
875 | textEncoding = new GString(encodingName); | 1019 | textEncoding = new GString(encodingName); |
876 | } | 1020 | } |
877 | 1021 | ||
878 | GBool GlobalParams::setTextEOL(char *s) { | 1022 | GBool GlobalParams::setTextEOL(char *s) { |
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 | ||
1035 | void GlobalParams::setInitialZoom(char *s) { | ||
1036 | delete initialZoom; | ||
1037 | initialZoom = new GString(s); | ||
1038 | } | ||
1039 | |||
891 | GBool GlobalParams::setT1libControl(char *s) { | 1040 | GBool GlobalParams::setT1libControl(char *s) { |
892 | return setFontRastControl(&t1libControl, s); | 1041 | return setFontRastControl(&t1libControl, s); |
893 | } | 1042 | } |
894 | 1043 | ||
895 | GBool GlobalParams::setFreeTypeControl(char *s) { | 1044 | GBool GlobalParams::setFreeTypeControl(char *s) { |
896 | return setFontRastControl(&freetypeControl, s); | 1045 | return setFontRastControl(&freetypeControl, s); |
897 | } | 1046 | } |
898 | 1047 | ||
899 | GBool GlobalParams::setFontRastControl(FontRastControl *val, char *s) { | 1048 | GBool 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 | ||
914 | void GlobalParams::setErrQuiet(GBool errQuietA) { | 1063 | void 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 | ||
20 | class GString; | 20 | class GString; |
21 | class GList; | 21 | class GList; |
22 | class GHash; | 22 | class GHash; |
23 | class NameToCharCode; | 23 | class NameToCharCode; |
24 | class CharCodeToUnicode; | 24 | class CharCodeToUnicode; |
25 | class CIDToUnicodeCache; | 25 | class CIDToUnicodeCache; |
26 | class UnicodeMap; | 26 | class UnicodeMap; |
27 | class UnicodeMapCache; | 27 | class UnicodeMapCache; |
28 | class CMap; | 28 | class CMap; |
29 | class CMapCache; | 29 | class CMapCache; |
30 | class GlobalParams; | 30 | class GlobalParams; |
31 | 31 | ||
32 | //------------------------------------------------------------------------ | 32 | //------------------------------------------------------------------------ |
33 | 33 | ||
34 | // The global parameters object. | 34 | // The global parameters object. |
35 | extern GlobalParams *globalParams; | 35 | extern GlobalParams *globalParams; |
36 | 36 | ||
37 | //------------------------------------------------------------------------ | 37 | //------------------------------------------------------------------------ |
38 | 38 | ||
39 | enum DisplayFontParamKind { | 39 | enum DisplayFontParamKind { |
40 | displayFontX, | 40 | displayFontX, |
41 | displayFontT1, | 41 | displayFontT1, |
42 | displayFontTT | 42 | displayFontTT |
43 | }; | 43 | }; |
44 | 44 | ||
45 | class DisplayFontParam { | 45 | class DisplayFontParam { |
46 | public: | 46 | public: |
47 | 47 | ||
48 | GString *name; // font name for 8-bit fonts; | 48 | GString *name; // font name for 8-bit fonts and named |
49 | // collection name for CID fonts | 49 | // CID fonts; collection name for |
50 | // generic CID fonts | ||
50 | DisplayFontParamKind kind; | 51 | DisplayFontParamKind kind; |
51 | union { | 52 | union { |
52 | struct { | 53 | struct { |
53 | GString *xlfd; | 54 | GString *xlfd; |
54 | GString *encoding; | 55 | GString *encoding; |
55 | } x; | 56 | } x; |
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. |
70 | enum FontRastControl { | 71 | enum 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 | ||
79 | class PSFontParam { | 80 | class PSFontParam { |
80 | public: | 81 | public: |
81 | 82 | ||
82 | GString *pdfFontName; | 83 | GString *pdfFontName; // PDF font name for 8-bit fonts and |
83 | GString *psFontName; | 84 | // named 16-bit fonts; char collection |
85 | // name for generic 16-bit fonts | ||
86 | int wMode; // writing mode (0=horiz, 1=vert) for | ||
87 | // 16-bit fonts | ||
88 | GString *psFontName; // PostScript font name | ||
89 | GString *encoding; // encoding, for 16-bit fonts only | ||
84 | 90 | ||
85 | PSFontParam(GString *pdfFontNameA, GString *psFontNameA); | 91 | PSFontParam(GString *pdfFontNameA, int wModeA, |
92 | GString *psFontNameA, GString *encodingA); | ||
86 | ~PSFontParam(); | 93 | ~PSFontParam(); |
87 | }; | 94 | }; |
88 | 95 | ||
89 | //------------------------------------------------------------------------ | 96 | //------------------------------------------------------------------------ |
90 | 97 | ||
91 | enum PSLevel { | 98 | enum PSLevel { |
92 | psLevel1, | 99 | psLevel1, |
93 | psLevel1Sep, | 100 | psLevel1Sep, |
94 | psLevel2, | 101 | psLevel2, |
95 | psLevel2Sep | 102 | psLevel2Sep, |
103 | psLevel3, | ||
104 | psLevel3Sep | ||
96 | }; | 105 | }; |
97 | 106 | ||
98 | //------------------------------------------------------------------------ | 107 | //------------------------------------------------------------------------ |
99 | 108 | ||
100 | enum EndOfLineKind { | 109 | enum EndOfLineKind { |
101 | eolUnix, // LF | 110 | eolUnix, // LF |
102 | eolDOS, // CR+LF | 111 | eolDOS, // CR+LF |
103 | eolMac // CR | 112 | eolMac // CR |
104 | }; | 113 | }; |
105 | 114 | ||
106 | //------------------------------------------------------------------------ | 115 | //------------------------------------------------------------------------ |
107 | 116 | ||
108 | class GlobalParams { | 117 | class GlobalParams { |
109 | public: | 118 | public: |
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 | ||
169 | private: | 187 | private: |
170 | 188 | ||
189 | void parseFile(GString *fileName, FILE *f); | ||
171 | void parseNameToUnicode(GList *tokens, GString *fileName, int line); | 190 | void parseNameToUnicode(GList *tokens, GString *fileName, int line); |
172 | void parseCIDToUnicode(GList *tokens, GString *fileName, int line); | 191 | void parseCIDToUnicode(GList *tokens, GString *fileName, int line); |
173 | void parseUnicodeMap(GList *tokens, GString *fileName, int line); | 192 | void parseUnicodeMap(GList *tokens, GString *fileName, int line); |
174 | void parseCMapDir(GList *tokens, GString *fileName, int line); | 193 | void parseCMapDir(GList *tokens, GString *fileName, int line); |
175 | void parseToUnicodeDir(GList *tokens, GString *fileName, int line); | 194 | void parseToUnicodeDir(GList *tokens, GString *fileName, int line); |
176 | void parseDisplayFont(GList *tokens, GBool isCID, DisplayFontParamKind kind, | 195 | void parseDisplayFont(GList *tokens, GHash *fontHash, |
196 | DisplayFontParamKind kind, | ||
177 | GString *fileName, int line); | 197 | GString *fileName, int line); |
178 | void parsePSFile(GList *tokens, GString *fileName, int line); | 198 | void parsePSFile(GList *tokens, GString *fileName, int line); |
179 | void parsePSPaperSize(GList *tokens, GString *fileName, int line); | 199 | void parsePSPaperSize(GList *tokens, GString *fileName, int line); |
180 | void parsePSLevel(GList *tokens, GString *fileName, int line); | 200 | void parsePSLevel(GList *tokens, GString *fileName, int line); |
181 | void parsePSFont(GList *tokens, GString *fileName, int line); | 201 | void parsePSFont(GList *tokens, GString *fileName, int line); |
202 | void parsePSFont16(char *cmdName, GList *fontList, | ||
203 | GList *tokens, GString *fileName, int line); | ||
182 | void parseTextEncoding(GList *tokens, GString *fileName, int line); | 204 | void parseTextEncoding(GList *tokens, GString *fileName, int line); |
183 | void parseTextEOL(GList *tokens, GString *fileName, int line); | 205 | void parseTextEOL(GList *tokens, GString *fileName, int line); |
184 | void parseFontDir(GList *tokens, GString *fileName, int line); | 206 | void parseFontDir(GList *tokens, GString *fileName, int line); |
207 | void parseInitialZoom(GList *tokens, GString *fileName, int line); | ||
185 | void parseFontRastControl(char *cmdName, FontRastControl *val, | 208 | void parseFontRastControl(char *cmdName, FontRastControl *val, |
186 | GList *tokens, GString *fileName, int line); | 209 | GList *tokens, GString *fileName, int line); |
187 | void parseURLCommand(GList *tokens, GString *fileName, int line); | 210 | void parseURLCommand(GList *tokens, GString *fileName, int line); |
188 | void parseYesNo(char *cmdName, GBool *flag, | 211 | void parseYesNo(char *cmdName, GBool *flag, |
189 | GList *tokens, GString *fileName, int line); | 212 | GList *tokens, GString *fileName, int line); |
190 | GBool setFontRastControl(FontRastControl *val, char *s); | 213 | GBool setFontRastControl(FontRastControl *val, char *s); |
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. |
25 | static char specialChars[256] = { | 25 | static 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 | ||
48 | Lexer::Lexer(XRef *xref, Stream *str) { | 48 | Lexer::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 | ||
59 | Lexer::Lexer(XRef *xref, Object *obj) { | 59 | Lexer::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 | ||
77 | Lexer::~Lexer() { | 77 | Lexer::~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 | ||
87 | int Lexer::getChar() { | 87 | int 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 | ||
103 | int Lexer::lookChar() { | 103 | int 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 | ||
110 | Object *Lexer::getObj(Object *obj) { | 110 | Object *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 | ||
19 | class XRef; | 19 | class 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 | ||
27 | class Lexer { | 27 | class Lexer { |
28 | public: | 28 | public: |
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 | ||
62 | private: | 63 | private: |
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 | ||
26 | static GString *getFileSpecName(Object *fileSpecObj); | 26 | static GString *getFileSpecName(Object *fileSpecObj); |
27 | 27 | ||
28 | //------------------------------------------------------------------------ | 28 | //------------------------------------------------------------------------ |
29 | // LinkDest | 29 | // LinkDest |
30 | //------------------------------------------------------------------------ | 30 | //------------------------------------------------------------------------ |
31 | 31 | ||
32 | LinkDest::LinkDest(Array *a, GBool pageIsRefA) { | 32 | LinkDest::LinkDest(Array *a) { |
33 | Object obj1, obj2; | 33 | Object obj1, obj2; |
34 | 34 | ||
35 | // initialize fields | 35 | // initialize fields |
36 | pageIsRef = pageIsRefA; | ||
37 | left = bottom = right = top = zoom = 0; | 36 | left = bottom = right = top = zoom = 0; |
38 | ok = gFalse; | 37 | ok = gFalse; |
39 | 38 | ||
40 | // get page | 39 | // get page |
41 | if (pageIsRef) { | 40 | a->getNF(0, &obj1); |
42 | if (!a->getNF(0, &obj1)->isRef()) { | 41 | if (obj1.isInt()) { |
43 | error(-1, "Bad annotation destination"); | 42 | pageNum = obj1.getInt() + 1; |
44 | goto err2; | 43 | pageIsRef = gFalse; |
45 | } | 44 | } else if (obj1.isRef()) { |
46 | pageRef.num = obj1.getRefNum(); | 45 | pageRef.num = obj1.getRefNum(); |
47 | pageRef.gen = obj1.getRefGen(); | 46 | pageRef.gen = obj1.getRefGen(); |
48 | obj1.free(); | 47 | pageIsRef = gTrue; |
49 | } else { | 48 | } else { |
50 | if (!a->get(0, &obj1)->isInt()) { | 49 | error(-1, "Bad annotation destination"); |
51 | error(-1, "Bad annotation destination"); | 50 | goto err2; |
52 | goto err2; | ||
53 | } | ||
54 | pageNum = obj1.getInt() + 1; | ||
55 | obj1.free(); | ||
56 | } | 51 | } |
52 | obj1.free(); | ||
57 | 53 | ||
58 | // get destination type | 54 | // get destination type |
59 | a->get(1, &obj1); | 55 | a->get(1, &obj1); |
60 | 56 | ||
61 | // XYZ link | 57 | // XYZ link |
62 | if (obj1.isName("XYZ")) { | 58 | if (obj1.isName("XYZ")) { |
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 | ||
190 | LinkDest::LinkDest(LinkDest *dest) { | 186 | LinkDest::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 | ||
212 | LinkGoTo::LinkGoTo(Object *destObj) { | 208 | LinkGoTo::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 | ||
236 | LinkGoTo::~LinkGoTo() { | 232 | LinkGoTo::~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 | ||
247 | LinkGoToR::LinkGoToR(Object *fileSpecObj, Object *destObj) { | 243 | LinkGoToR::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 | ||
274 | LinkGoToR::~LinkGoToR() { | 270 | LinkGoToR::~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 | ||
288 | LinkLaunch::LinkLaunch(Object *actionObj) { | 284 | LinkLaunch::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 | ||
316 | LinkLaunch::~LinkLaunch() { | 312 | LinkLaunch::~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 | ||
327 | LinkURI::LinkURI(Object *uriObj, GString *baseURI) { | 323 | LinkURI::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 | ||
362 | LinkURI::~LinkURI() { | 358 | LinkURI::~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 | ||
371 | LinkNamed::LinkNamed(Object *nameObj) { | 367 | LinkNamed::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 | ||
378 | LinkNamed::~LinkNamed() { | 374 | LinkNamed::~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 | ||
388 | LinkUnknown::LinkUnknown(char *actionA) { | 384 | LinkUnknown::LinkUnknown(char *actionA) { |
389 | action = new GString(actionA); | 385 | action = new GString(actionA); |
390 | } | 386 | } |
391 | 387 | ||
392 | LinkUnknown::~LinkUnknown() { | 388 | LinkUnknown::~LinkUnknown() { |
393 | delete action; | 389 | delete action; |
394 | } | 390 | } |
395 | 391 | ||
396 | //------------------------------------------------------------------------ | 392 | //------------------------------------------------------------------------ |
397 | // Link | 393 | // Link |
398 | //------------------------------------------------------------------------ | 394 | //------------------------------------------------------------------------ |
399 | 395 | ||
400 | Link::Link(Dict *dict, GString *baseURI) { | 396 | Link::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 | ||
533 | Link::~Link() { | 529 | Link::~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 | ||
542 | Links::Links(Object *annots, GString *baseURI) { | 538 | Links::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 | ||
574 | Links::~Links() { | 570 | Links::~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 | ||
582 | LinkAction *Links::find(fouble x, fouble y) { | 578 | LinkAction *Links::find(fouble x, fouble y) { |
583 | int i; | 579 | int i; |
584 | 580 | ||
585 | for (i = 0; i < numLinks; ++i) { | 581 | for (i = numLinks - 1; i >= 0; --i) { |
586 | if (links[i]->inRect(x, y)) { | 582 | if (links[i]->inRect(x, y)) { |
587 | return links[i]->getAction(); | 583 | return links[i]->getAction(); |
588 | } | 584 | } |
589 | } | 585 | } |
590 | return NULL; | 586 | return NULL; |
591 | } | 587 | } |
592 | 588 | ||
593 | GBool Links::onLink(fouble x, fouble y) { | 589 | GBool 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). |
606 | static GString *getFileSpecName(Object *fileSpecObj) { | 602 | static 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 | ||
18 | class GString; | 18 | class GString; |
19 | class Array; | 19 | class Array; |
20 | class Dict; | 20 | class Dict; |
21 | 21 | ||
22 | //------------------------------------------------------------------------ | 22 | //------------------------------------------------------------------------ |
23 | // LinkAction | 23 | // LinkAction |
24 | //------------------------------------------------------------------------ | 24 | //------------------------------------------------------------------------ |
25 | 25 | ||
26 | enum LinkActionKind { | 26 | enum 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 | ||
35 | class LinkAction { | 35 | class LinkAction { |
36 | public: | 36 | public: |
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 | ||
52 | enum LinkDestKind { | 52 | enum 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 | ||
63 | class LinkDest { | 63 | class LinkDest { |
64 | public: | 64 | public: |
65 | 65 | ||
66 | // Build a LinkDest from the array. If <pageIsRef> is true, the | 66 | // Build a LinkDest from the array. |
67 | // page is specified by an object reference; otherwise the page is | 67 | LinkDest(Array *a); |
68 | // specified by a (zero-relative) page number. | ||
69 | LinkDest(Array *a, GBool pageIsRef1); | ||
70 | 68 | ||
71 | // Copy a LinkDest. | 69 | // Copy a LinkDest. |
72 | LinkDest *copy() { return new LinkDest(this); } | 70 | LinkDest *copy() { return new LinkDest(this); } |
73 | 71 | ||
74 | // Was the LinkDest created successfully? | 72 | // Was the LinkDest created successfully? |
75 | GBool isOk() { return ok; } | 73 | GBool isOk() { return ok; } |
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 | ||
91 | private: | 89 | private: |
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 | ||
113 | class LinkGoTo: public LinkAction { | 111 | class LinkGoTo: public LinkAction { |
114 | public: | 112 | public: |
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 | ||
130 | private: | 128 | private: |
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 | ||
142 | class LinkGoToR: public LinkAction { | 140 | class LinkGoToR: public LinkAction { |
143 | public: | 141 | public: |
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 | ||
161 | private: | 159 | private: |
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 | ||
174 | class LinkLaunch: public LinkAction { | 172 | class LinkLaunch: public LinkAction { |
175 | public: | 173 | public: |
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 | ||
191 | private: | 189 | private: |
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 | ||
201 | class LinkURI: public LinkAction { | 199 | class LinkURI: public LinkAction { |
202 | public: | 200 | public: |
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 | ||
217 | private: | 215 | private: |
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 | ||
226 | class LinkNamed: public LinkAction { | 224 | class LinkNamed: public LinkAction { |
227 | public: | 225 | public: |
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 | ||
239 | private: | 237 | private: |
240 | 238 | ||
241 | GString *name; | 239 | GString *name; |
242 | }; | 240 | }; |
243 | 241 | ||
244 | //------------------------------------------------------------------------ | 242 | //------------------------------------------------------------------------ |
245 | // LinkUnknown | 243 | // LinkUnknown |
246 | //------------------------------------------------------------------------ | 244 | //------------------------------------------------------------------------ |
247 | 245 | ||
248 | class LinkUnknown: public LinkAction { | 246 | class LinkUnknown: public LinkAction { |
249 | public: | 247 | public: |
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 | ||
20 | struct NameToCharCodeEntry { | 20 | struct NameToCharCodeEntry { |
21 | char *name; | 21 | char *name; |
22 | CharCode c; | 22 | CharCode c; |
23 | }; | 23 | }; |
24 | 24 | ||
25 | //------------------------------------------------------------------------ | 25 | //------------------------------------------------------------------------ |
26 | 26 | ||
27 | NameToCharCode::NameToCharCode() { | 27 | NameToCharCode::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 | ||
38 | NameToCharCode::~NameToCharCode() { | 38 | NameToCharCode::~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 | ||
49 | void NameToCharCode::add(char *name, CharCode c) { | 49 | void 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 | ||
91 | CharCode NameToCharCode::lookup(char *name) { | 91 | CharCode 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 | ||
106 | int NameToCharCode::hash(char *name) { | 106 | int 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 | ||
18 | struct NameToCharCodeEntry; | 18 | struct NameToCharCodeEntry; |
19 | 19 | ||
20 | //------------------------------------------------------------------------ | 20 | //------------------------------------------------------------------------ |
21 | 21 | ||
22 | class NameToCharCode { | 22 | class NameToCharCode { |
23 | public: | 23 | public: |
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 | ||
31 | private: | 31 | private: |
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 | ||
9 | static struct { | 9 | static 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 | ||
26 | char *objTypeNames[numObjTypes] = { | 26 | char *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 |
44 | int Object::numAlloc[numObjTypes] = | 44 | int 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 | ||
48 | Object *Object::initArray(XRef *xref) { | 48 | Object *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 | ||
54 | Object *Object::initDict(XRef *xref) { | 54 | Object *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 | ||
60 | Object *Object::initStream(Stream *streamA) { | 60 | Object *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 | ||
66 | Object *Object::copy(Object *obj) { | 66 | Object *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 | ||
96 | Object *Object::fetch(XRef *xref, Object *obj) { | 96 | Object *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 | ||
101 | void Object::free() { | 101 | void 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 | ||
136 | char *Object::getTypeName() { | 136 | char *Object::getTypeName() { |
137 | return objTypeNames[type]; | 137 | return objTypeNames[type]; |
138 | } | 138 | } |
139 | 139 | ||
140 | void Object::print(FILE *f) { | 140 | void 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 | ||
22 | class XRef; | 22 | class XRef; |
23 | class Array; | 23 | class Array; |
24 | class Dict; | 24 | class Dict; |
25 | class Stream; | 25 | class Stream; |
26 | 26 | ||
27 | //------------------------------------------------------------------------ | 27 | //------------------------------------------------------------------------ |
28 | // Ref | 28 | // Ref |
29 | //------------------------------------------------------------------------ | 29 | //------------------------------------------------------------------------ |
30 | 30 | ||
31 | struct Ref { | 31 | struct 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 | ||
40 | enum ObjType { | 40 | enum 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 | ||
74 | class Object { | 74 | class Object { |
75 | public: | 75 | public: |
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 | ||
190 | private: | 190 | private: |
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 | ||
218 | inline int Object::arrayGetLength() | 218 | inline int Object::arrayGetLength() |
219 | { return array->getLength(); } | 219 | { return array->getLength(); } |
220 | 220 | ||
221 | inline void Object::arrayAdd(Object *elem) | 221 | inline void Object::arrayAdd(Object *elem) |
222 | { array->add(elem); } | 222 | { array->add(elem); } |
223 | 223 | ||
224 | inline Object *Object::arrayGet(int i, Object *obj) | 224 | inline Object *Object::arrayGet(int i, Object *obj) |
225 | { return array->get(i, obj); } | 225 | { return array->get(i, obj); } |
226 | 226 | ||
227 | inline Object *Object::arrayGetNF(int i, Object *obj) | 227 | inline 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 | ||
236 | inline int Object::dictGetLength() | 236 | inline int Object::dictGetLength() |
237 | { return dict->getLength(); } | 237 | { return dict->getLength(); } |
238 | 238 | ||
239 | inline void Object::dictAdd(char *key, Object *val) | 239 | inline void Object::dictAdd(char *key, Object *val) |
240 | { dict->add(key, val); } | 240 | { dict->add(key, val); } |
241 | 241 | ||
242 | inline GBool Object::dictIs(char *dictType) | 242 | inline GBool Object::dictIs(char *dictType) |
243 | { return dict->is(dictType); } | 243 | { return dict->is(dictType); } |
244 | 244 | ||
245 | inline GBool Object::isDict(char *dictType) | 245 | inline GBool Object::isDict(char *dictType) |
246 | { return type == objDict && dictIs(dictType); } | 246 | { return type == objDict && dictIs(dictType); } |
247 | 247 | ||
248 | inline Object *Object::dictLookup(char *key, Object *obj) | 248 | inline Object *Object::dictLookup(char *key, Object *obj) |
249 | { return dict->lookup(key, obj); } | 249 | { return dict->lookup(key, obj); } |
250 | 250 | ||
251 | inline Object *Object::dictLookupNF(char *key, Object *obj) | 251 | inline Object *Object::dictLookupNF(char *key, Object *obj) |
252 | { return dict->lookupNF(key, obj); } | 252 | { return dict->lookupNF(key, obj); } |
253 | 253 | ||
254 | inline char *Object::dictGetKey(int i) | 254 | inline char *Object::dictGetKey(int i) |
255 | { return dict->getKey(i); } | 255 | { return dict->getKey(i); } |
256 | 256 | ||
257 | inline Object *Object::dictGetVal(int i, Object *obj) | 257 | inline Object *Object::dictGetVal(int i, Object *obj) |
258 | { return dict->getVal(i, obj); } | 258 | { return dict->getVal(i, obj); } |
259 | 259 | ||
260 | inline Object *Object::dictGetValNF(int i, Object *obj) | 260 | inline 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 | ||
269 | inline GBool Object::streamIs(char *dictType) | 269 | inline GBool Object::streamIs(char *dictType) |
270 | { return stream->getDict()->is(dictType); } | 270 | { return stream->getDict()->is(dictType); } |
271 | 271 | ||
272 | inline GBool Object::isStream(char *dictType) | 272 | inline GBool Object::isStream(char *dictType) |
273 | { return type == objStream && streamIs(dictType); } | 273 | { return type == objStream && streamIs(dictType); } |
274 | 274 | ||
275 | inline void Object::streamReset() | 275 | inline void Object::streamReset() |
276 | { stream->reset(); } | 276 | { stream->reset(); } |
277 | 277 | ||
278 | inline void Object::streamClose() | 278 | inline void Object::streamClose() |
279 | { stream->close(); } | 279 | { stream->close(); } |
280 | 280 | ||
281 | inline int Object::streamGetChar() | 281 | inline int Object::streamGetChar() |
282 | { return stream->getChar(); } | 282 | { return stream->getChar(); } |
283 | 283 | ||
284 | inline int Object::streamLookChar() | 284 | inline int Object::streamLookChar() |
285 | { return stream->lookChar(); } | 285 | { return stream->lookChar(); } |
286 | 286 | ||
287 | inline char *Object::streamGetLine(char *buf, int size) | 287 | inline char *Object::streamGetLine(char *buf, int size) |
288 | { return stream->getLine(buf, size); } | 288 | { return stream->getLine(buf, size); } |
289 | 289 | ||
290 | inline int Object::streamGetPos() | 290 | inline Guint Object::streamGetPos() |
291 | { return stream->getPos(); } | 291 | { return stream->getPos(); } |
292 | 292 | ||
293 | inline void Object::streamSetPos(int pos) | 293 | inline void Object::streamSetPos(Guint pos, int dir) |
294 | { stream->setPos(pos); } | 294 | { stream->setPos(pos, dir); } |
295 | 295 | ||
296 | inline Dict *Object::streamGetDict() | 296 | inline Dict *Object::streamGetDict() |
297 | { return stream->getDict(); } | 297 | { return stream->getDict(); } |
298 | 298 | ||
299 | #endif | 299 | #endif |
diff --git a/noncore/unsupported/qpdf/xpdf/OutputDev.cc b/noncore/unsupported/qpdf/xpdf/OutputDev.cc index 3c02835..1004f0f 100644 --- a/noncore/unsupported/qpdf/xpdf/OutputDev.cc +++ b/noncore/unsupported/qpdf/xpdf/OutputDev.cc | |||
@@ -1,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 | ||
24 | void OutputDev::setDefaultCTM(fouble *ctm) { | 24 | void 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 | ||
40 | void OutputDev::cvtDevToUser(int dx, int dy, fouble *ux, fouble *uy) { | 40 | void 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 | ||
45 | void OutputDev::cvtUserToDev(fouble ux, fouble uy, int *dx, int *dy) { | 45 | void 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 | ||
50 | void OutputDev::updateAll(GfxState *state) { | 50 | void 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 | ||
62 | GBool OutputDev::beginType3Char(GfxState *state, | ||
63 | CharCode code, Unicode *u, int uLen) { | ||
64 | return gFalse; | ||
65 | } | ||
66 | |||
62 | void OutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str, | 67 | void OutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str, |
63 | int width, int height, GBool invert, | 68 | int width, int height, GBool invert, |
64 | GBool inlineImg) { | 69 | GBool inlineImg) { |
65 | int i, j; | 70 | int i, j; |
66 | 71 | ||
67 | if (inlineImg) { | 72 | if (inlineImg) { |
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 | ||
76 | void OutputDev::drawImage(GfxState *state, Object *ref, Stream *str, | 81 | void 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 |
92 | void OutputDev::opiBegin(GfxState *state, Dict *opiDict) { | 97 | void OutputDev::opiBegin(GfxState *state, Dict *opiDict) { |
93 | } | 98 | } |
94 | 99 | ||
95 | void OutputDev::opiEnd(GfxState *state, Dict *opiDict) { | 100 | void 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 | ||
19 | class GString; | 19 | class GString; |
20 | class GfxState; | 20 | class GfxState; |
21 | class GfxColorSpace; | 21 | class GfxColorSpace; |
22 | class GfxImageColorMap; | 22 | class GfxImageColorMap; |
23 | class Stream; | 23 | class Stream; |
24 | class Link; | 24 | class Link; |
25 | class Catalog; | 25 | class Catalog; |
26 | 26 | ||
27 | //------------------------------------------------------------------------ | 27 | //------------------------------------------------------------------------ |
28 | // OutputDev | 28 | // OutputDev |
29 | //------------------------------------------------------------------------ | 29 | //------------------------------------------------------------------------ |
30 | 30 | ||
31 | class OutputDev { | 31 | class OutputDev { |
32 | public: | 32 | public: |
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 | |||
137 | private: | 152 | private: |
138 | 153 | ||
139 | fouble defCTM[6]; // default coordinate transform matrix | 154 | fouble defCTM[6]; // default coordinate transform matrix |
140 | fouble defICTM[6]; // inverse of default CTM | 155 | fouble defICTM[6]; // inverse of default CTM |
141 | }; | 156 | }; |
142 | 157 | ||
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 | ||
40 | PDFDoc::PDFDoc(GString *fileNameA, GString *ownerPassword, | 41 | PDFDoc::PDFDoc(GString *fileNameA, GString *ownerPassword, |
41 | GString *userPassword, GBool printCommandsA) { | 42 | GString *userPassword, GBool printCommandsA) { |
42 | Object obj; | 43 | Object obj; |
43 | GString *fileName2; | 44 | GString *fileName2; |
44 | 45 | ||
45 | ok = gFalse; | 46 | ok = gFalse; |
47 | errCode = errNone; | ||
46 | 48 | ||
47 | file = NULL; | 49 | file = NULL; |
48 | str = NULL; | 50 | str = NULL; |
49 | xref = NULL; | 51 | xref = NULL; |
50 | catalog = NULL; | 52 | catalog = NULL; |
51 | links = NULL; | 53 | links = NULL; |
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 | ||
85 | PDFDoc::PDFDoc(BaseStream *strA, GString *ownerPassword, | 89 | PDFDoc::PDFDoc(BaseStream *strA, GString *ownerPassword, |
86 | GString *userPassword, GBool printCommandsA) { | 90 | GString *userPassword, GBool printCommandsA) { |
87 | ok = gFalse; | 91 | ok = gFalse; |
92 | errCode = errNone; | ||
88 | fileName = NULL; | 93 | fileName = NULL; |
89 | file = NULL; | 94 | file = NULL; |
90 | str = strA; | 95 | str = strA; |
91 | xref = NULL; | 96 | xref = NULL; |
92 | catalog = NULL; | 97 | catalog = NULL; |
93 | links = NULL; | 98 | links = NULL; |
94 | printCommands = printCommandsA; | 99 | printCommands = printCommandsA; |
95 | ok = setup(ownerPassword, userPassword); | 100 | ok = setup(ownerPassword, userPassword); |
96 | } | 101 | } |
97 | 102 | ||
98 | GBool PDFDoc::setup(GString *ownerPassword, GString *userPassword) { | 103 | GBool 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 | ||
120 | PDFDoc::~PDFDoc() { | 127 | PDFDoc::~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. |
143 | void PDFDoc::checkHeader() { | 150 | void 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 | ||
172 | void PDFDoc::displayPage(OutputDev *out, int page, fouble zoom, | 179 | void 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 | ||
191 | void PDFDoc::displayPages(OutputDev *out, int firstPage, int lastPage, | 198 | void 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 | ||
200 | GBool PDFDoc::isLinearized() { | 207 | GBool PDFDoc::isLinearized() { |
201 | Parser *parser; | 208 | Parser *parser; |
202 | Object obj1, obj2, obj3, obj4, obj5; | 209 | Object obj1, obj2, obj3, obj4, obj5; |
203 | GBool lin; | 210 | GBool lin; |
204 | 211 | ||
205 | lin = gFalse; | 212 | lin = gFalse; |
206 | obj1.initNull(); | 213 | obj1.initNull(); |
207 | parser = new Parser(xref, new Lexer(xref, str->makeSubStream(str->getStart(), | 214 | parser = new Parser(xref, |
208 | -1, &obj1))); | 215 | new Lexer(xref, |
216 | str->makeSubStream(str->getStart(), gFalse, 0, &obj1))); | ||
209 | parser->getObj(&obj1); | 217 | parser->getObj(&obj1); |
210 | parser->getObj(&obj2); | 218 | parser->getObj(&obj2); |
211 | parser->getObj(&obj3); | 219 | parser->getObj(&obj3); |
212 | parser->getObj(&obj4); | 220 | parser->getObj(&obj4); |
213 | if (obj1.isInt() && obj2.isInt() && obj3.isCmd("obj") && | 221 | if (obj1.isInt() && obj2.isInt() && obj3.isCmd("obj") && |
214 | obj4.isDict()) { | 222 | obj4.isDict()) { |
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 | ||
229 | GBool PDFDoc::saveAs(GString *name) { | 237 | GBool 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 | ||
246 | void PDFDoc::getLinks(Page *page) { | 254 | void 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 | ||
22 | class GString; | 22 | class GString; |
23 | class BaseStream; | 23 | class BaseStream; |
24 | class OutputDev; | 24 | class OutputDev; |
25 | class Links; | 25 | class Links; |
26 | class LinkAction; | 26 | class LinkAction; |
27 | class LinkDest; | 27 | class LinkDest; |
28 | 28 | ||
29 | //------------------------------------------------------------------------ | 29 | //------------------------------------------------------------------------ |
30 | // PDFDoc | 30 | // PDFDoc |
31 | //------------------------------------------------------------------------ | 31 | //------------------------------------------------------------------------ |
32 | 32 | ||
33 | class PDFDoc { | 33 | class PDFDoc { |
34 | public: | 34 | public: |
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 | ||
124 | private: | 127 | private: |
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. | ||
21 | static char specialChars[256] = { | ||
22 | 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, // 0x | ||
23 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x | ||
24 | 1, 0, 0, 0, 0, 2, 0, 0, 2, 2, 0, 0, 0, 0, 0, 2, // 2x | ||
25 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, // 3x | ||
26 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 4x | ||
27 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 0, // 5x | ||
28 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 6x | ||
29 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 0, // 7x | ||
30 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x | ||
31 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x | ||
32 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // ax | ||
33 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // bx | ||
34 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // cx | ||
35 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // dx | ||
36 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // ex | ||
37 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // fx | ||
38 | }; | ||
39 | |||
40 | //------------------------------------------------------------------------ | ||
41 | |||
42 | PSTokenizer::PSTokenizer(int (*getCharFuncA)(void *), void *dataA) { | ||
43 | getCharFunc = getCharFuncA; | ||
44 | data = dataA; | ||
45 | charBuf = -1; | ||
46 | } | ||
47 | |||
48 | PSTokenizer::~PSTokenizer() { | ||
49 | } | ||
50 | |||
51 | GBool PSTokenizer::getToken(char *buf, int size, int *length) { | ||
52 | GBool comment, backslash; | ||
53 | int c; | ||
54 | int i; | ||
55 | |||
56 | // skip whitespace and comments | ||
57 | comment = gFalse; | ||
58 | while (1) { | ||
59 | if ((c = getChar()) == EOF) { | ||
60 | buf[0] = '\0'; | ||
61 | *length = 0; | ||
62 | return gFalse; | ||
63 | } | ||
64 | if (comment) { | ||
65 | if (c == '\x0a' || c == '\x0d') { | ||
66 | comment = gFalse; | ||
67 | } | ||
68 | } else if (c == '%') { | ||
69 | comment = gTrue; | ||
70 | } else if (specialChars[c] != 1) { | ||
71 | break; | ||
72 | } | ||
73 | } | ||
74 | |||
75 | // read a token | ||
76 | i = 0; | ||
77 | buf[i++] = c; | ||
78 | if (c == '(') { | ||
79 | backslash = gFalse; | ||
80 | while ((c = lookChar()) != EOF) { | ||
81 | if (i < size - 1) { | ||
82 | buf[i++] = c; | ||
83 | } | ||
84 | getChar(); | ||
85 | if (c == '\\') { | ||
86 | backslash = gTrue; | ||
87 | } else if (!backslash && c == ')') { | ||
88 | break; | ||
89 | } else { | ||
90 | backslash = gFalse; | ||
91 | } | ||
92 | } | ||
93 | } else if (c == '<') { | ||
94 | while ((c = lookChar()) != EOF) { | ||
95 | getChar(); | ||
96 | if (i < size - 1) { | ||
97 | buf[i++] = c; | ||
98 | } | ||
99 | if (c == '>') { | ||
100 | break; | ||
101 | } | ||
102 | } | ||
103 | } else if (c != '[' && c != ']') { | ||
104 | while ((c = lookChar()) != EOF && !specialChars[c]) { | ||
105 | getChar(); | ||
106 | if (i < size - 1) { | ||
107 | buf[i++] = c; | ||
108 | } | ||
109 | } | ||
110 | } | ||
111 | buf[i] = '\0'; | ||
112 | *length = i; | ||
113 | |||
114 | return gTrue; | ||
115 | } | ||
116 | |||
117 | int PSTokenizer::lookChar() { | ||
118 | if (charBuf < 0) { | ||
119 | charBuf = (*getCharFunc)(data); | ||
120 | } | ||
121 | return charBuf; | ||
122 | } | ||
123 | |||
124 | int PSTokenizer::getChar() { | ||
125 | int c; | ||
126 | |||
127 | if (charBuf < 0) { | ||
128 | charBuf = (*getCharFunc)(data); | ||
129 | } | ||
130 | c = charBuf; | ||
131 | charBuf = -1; | ||
132 | return c; | ||
133 | } | ||
diff --git a/noncore/unsupported/qpdf/xpdf/PSTokenizer.h b/noncore/unsupported/qpdf/xpdf/PSTokenizer.h new file mode 100644 index 0000000..1053c67 --- a/dev/null +++ b/noncore/unsupported/qpdf/xpdf/PSTokenizer.h | |||
@@ -0,0 +1,39 @@ | |||
1 | //======================================================================== | ||
2 | // | ||
3 | // PSTokenizer.h | ||
4 | // | ||
5 | // Copyright 2002 Glyph & Cog, LLC | ||
6 | // | ||
7 | //======================================================================== | ||
8 | |||
9 | #ifndef PSTOKENIZER_H | ||
10 | #define PSTOKENIZER_H | ||
11 | |||
12 | #ifdef __GNUC__ | ||
13 | #pragma interface | ||
14 | #endif | ||
15 | |||
16 | #include "gtypes.h" | ||
17 | |||
18 | //------------------------------------------------------------------------ | ||
19 | |||
20 | class PSTokenizer { | ||
21 | public: | ||
22 | |||
23 | PSTokenizer(int (*getCharFuncA)(void *), void *dataA); | ||
24 | ~PSTokenizer(); | ||
25 | |||
26 | // Get the next PostScript token. Returns false at end-of-stream. | ||
27 | GBool getToken(char *buf, int size, int *length); | ||
28 | |||
29 | private: | ||
30 | |||
31 | int lookChar(); | ||
32 | int getChar(); | ||
33 | |||
34 | int (*getCharFunc)(void *); | ||
35 | void *data; | ||
36 | int charBuf; | ||
37 | }; | ||
38 | |||
39 | #endif | ||
diff --git a/noncore/unsupported/qpdf/xpdf/Page.cc b/noncore/unsupported/qpdf/xpdf/Page.cc index 17c4481..9cc08c4 100644 --- a/noncore/unsupported/qpdf/xpdf/Page.cc +++ b/noncore/unsupported/qpdf/xpdf/Page.cc | |||
@@ -1,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 | ||
32 | PageAttrs::PageAttrs(PageAttrs *attrs, Dict *dict) { | 32 | PageAttrs::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 | ||
105 | PageAttrs::~PageAttrs() { | 113 | PageAttrs::~PageAttrs() { |
114 | lastModified.free(); | ||
115 | boxColorInfo.free(); | ||
116 | group.free(); | ||
117 | metadata.free(); | ||
118 | pieceInfo.free(); | ||
119 | separationInfo.free(); | ||
106 | resources.free(); | 120 | resources.free(); |
107 | } | 121 | } |
108 | 122 | ||
109 | GBool PageAttrs::readBox(Dict *dict, char *key, PDFRectangle *box) { | 123 | GBool PageAttrs::readBox(Dict *dict, char *key, PDFRectangle *box) { |
110 | PDFRectangle tmp; | 124 | PDFRectangle tmp; |
111 | Object obj1, obj2; | 125 | Object obj1, obj2; |
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 | ||
159 | Page::Page(XRef *xrefA, int numA, Dict *pageDict, PageAttrs *attrsA, | 173 | Page::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 | ||
198 | Page::~Page() { | 212 | Page::~Page() { |
199 | delete attrs; | 213 | delete attrs; |
200 | annots.free(); | 214 | annots.free(); |
201 | contents.free(); | 215 | contents.free(); |
202 | } | 216 | } |
203 | 217 | ||
204 | void Page::display(OutputDev *out, fouble dpi, int rotate, | 218 | void 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 | ||
18 | class Dict; | 18 | class Dict; |
19 | class XRef; | 19 | class XRef; |
20 | class OutputDev; | 20 | class OutputDev; |
21 | class Links; | 21 | class Links; |
22 | class Catalog; | 22 | class Catalog; |
23 | 23 | ||
24 | //------------------------------------------------------------------------ | 24 | //------------------------------------------------------------------------ |
25 | 25 | ||
26 | struct PDFRectangle { | 26 | struct 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 | ||
34 | class PageAttrs { | 34 | class PageAttrs { |
35 | public: | 35 | public: |
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 | ||
57 | private: | 71 | private: |
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 | ||
76 | class Page { | 96 | class Page { |
77 | public: | 97 | public: |
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 | ||
114 | private: | 140 | private: |
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 | ||
25 | Parser::Parser(XRef *xrefA, Lexer *lexerA) { | 25 | Parser::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 | ||
33 | Parser::~Parser() { | 33 | Parser::~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 |
40 | Object *Parser::getObj(Object *obj, | 40 | Object *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 |
44 | Object *Parser::getObj(Object *obj) { | 44 | Object *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 | ||
155 | Stream *Parser::makeStream(Object *dict) { | 155 | Stream *Parser::makeStream(Object *dict) { |
156 | Object obj; | 156 | Object obj; |
157 | Stream *str; | 157 | Stream *str; |
158 | int pos, endPos, length; | 158 | Guint pos, endPos, length; |
159 | 159 | ||
160 | // get stream start position | 160 | // get stream start position |
161 | lexer->skipToNextLine(); | 161 | lexer->skipToNextLine(); |
162 | pos = lexer->getPos(); | 162 | pos = lexer->getPos(); |
163 | 163 | ||
164 | // get length | 164 | // get length |
165 | dict->dictLookup("Length", &obj); | 165 | dict->dictLookup("Length", &obj); |
166 | if (obj.isInt()) { | 166 | if (obj.isInt()) { |
167 | length = obj.getInt(); | 167 | length = (Guint)obj.getInt(); |
168 | obj.free(); | 168 | obj.free(); |
169 | } else { | 169 | } else { |
170 | error(getPos(), "Bad 'Length' attribute in stream"); | 170 | error(getPos(), "Bad 'Length' attribute in stream"); |
171 | obj.free(); | 171 | obj.free(); |
172 | return NULL; | 172 | return NULL; |
173 | } | 173 | } |
174 | 174 | ||
175 | // check for length in damaged file | 175 | // check for length in damaged file |
176 | if ((endPos = xref->getStreamEnd(pos)) >= 0) { | 176 | if (xref->getStreamEnd(pos, &endPos)) { |
177 | length = endPos - pos; | 177 | length = endPos - pos; |
178 | } | 178 | } |
179 | 179 | ||
180 | // make base stream | 180 | // make base stream |
181 | str = lexer->getStream()->getBaseStream()->makeSubStream(pos, length, dict); | 181 | str = lexer->getStream()->getBaseStream()->makeSubStream(pos, gTrue, |
182 | length, dict); | ||
182 | 183 | ||
183 | // get filters | 184 | // get filters |
184 | str = str->addFilters(dict); | 185 | str = str->addFilters(dict); |
185 | 186 | ||
186 | // skip over stream data | 187 | // skip over stream data |
187 | lexer->setPos(pos + length); | 188 | lexer->setPos(pos + length); |
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 | ||
200 | void Parser::shift() { | 201 | void 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 | ||
22 | class Parser { | 22 | class Parser { |
23 | public: | 23 | public: |
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 | ||
46 | private: | 46 | private: |
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 | ||
11 | struct CCITTCode { | 11 | struct 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 |
33 | static CCITTCode twoDimTab1[128] = { | 33 | static 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) |
106 | static CCITTCode whiteTab1[32] = { | 106 | static 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 |
129 | static CCITTCode whiteTab2[512] = { | 129 | static 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__ |
34 | static GBool setDJSYSFLAGS = gFalse; | 34 | static 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) |
39 | extern "C" int unlink(char *filename); | 39 | extern "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 | ||
56 | Stream::Stream() { | 56 | Stream::Stream() { |
57 | ref = 1; | 57 | ref = 1; |
58 | } | 58 | } |
59 | 59 | ||
60 | Stream::~Stream() { | 60 | Stream::~Stream() { |
61 | } | 61 | } |
62 | 62 | ||
63 | void Stream::close() { | 63 | void Stream::close() { |
64 | } | 64 | } |
65 | 65 | ||
66 | int Stream::getRawChar() { | 66 | int 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 | ||
71 | char *Stream::getLine(char *buf, int size) { | 71 | char *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 | ||
92 | GString *Stream::getPSFilter(char *indent) { | 92 | GString *Stream::getPSFilter(char *indent) { |
93 | return new GString(); | 93 | return new GString(); |
94 | } | 94 | } |
95 | 95 | ||
96 | Stream *Stream::addFilters(Object *dict) { | 96 | Stream *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", ¶ms); | 108 | dict->dictLookup("DecodeParms", ¶ms); |
109 | if (params.isNull()) { | 109 | if (params.isNull()) { |
110 | params.free(); | 110 | params.free(); |
111 | dict->dictLookup("DP", ¶ms); | 111 | dict->dictLookup("DP", ¶ms); |
112 | } | 112 | } |
113 | if (obj.isName()) { | 113 | if (obj.isName()) { |
114 | str = makeFilter(obj.getName(), str, ¶ms); | 114 | str = makeFilter(obj.getName(), str, ¶ms); |
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, ¶ms2); | 119 | params.arrayGet(i, ¶ms2); |
120 | else | 120 | else |
121 | params2.initNull(); | 121 | params2.initNull(); |
122 | if (obj2.isName()) { | 122 | if (obj2.isName()) { |
123 | str = makeFilter(obj2.getName(), str, ¶ms2); | 123 | str = makeFilter(obj2.getName(), str, ¶ms2); |
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 | ||
140 | Stream *Stream::makeFilter(char *name, Stream *str, Object *params) { | 140 | Stream *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 | ||
269 | BaseStream::BaseStream(Object *dictA) { | 269 | BaseStream::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 | ||
276 | BaseStream::~BaseStream() { | 276 | BaseStream::~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 |
285 | void BaseStream::doDecryption(Guchar *fileKey, int keyLength, | 285 | void 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 | ||
295 | FilterStream::FilterStream(Stream *strA) { | 295 | FilterStream::FilterStream(Stream *strA) { |
296 | str = strA; | 296 | str = strA; |
297 | } | 297 | } |
298 | 298 | ||
299 | FilterStream::~FilterStream() { | 299 | FilterStream::~FilterStream() { |
300 | } | 300 | } |
301 | 301 | ||
302 | void FilterStream::close() { | 302 | void FilterStream::close() { |
303 | str->close(); | 303 | str->close(); |
304 | } | 304 | } |
305 | 305 | ||
306 | void FilterStream::setPos(int pos) { | 306 | void FilterStream::setPos(Guint pos, int dir) { |
307 | error(-1, "Internal: called setPos() on FilterStream"); | 307 | error(-1, "Internal: called setPos() on FilterStream"); |
308 | } | 308 | } |
309 | 309 | ||
310 | //------------------------------------------------------------------------ | 310 | //------------------------------------------------------------------------ |
311 | // ImageStream | 311 | // ImageStream |
312 | //------------------------------------------------------------------------ | 312 | //------------------------------------------------------------------------ |
313 | 313 | ||
314 | ImageStream::ImageStream(Stream *strA, int widthA, int nCompsA, int nBitsA) { | 314 | ImageStream::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 | ||
332 | ImageStream::~ImageStream() { | 332 | ImageStream::~ImageStream() { |
333 | gfree(imgLine); | 333 | gfree(imgLine); |
334 | } | 334 | } |
335 | 335 | ||
336 | void ImageStream::reset() { | 336 | void ImageStream::reset() { |
337 | str->reset(); | 337 | str->reset(); |
338 | } | 338 | } |
339 | 339 | ||
340 | GBool ImageStream::getPixel(Guchar *pix) { | 340 | GBool 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 | ||
388 | void ImageStream::skipLine() { | 388 | void 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 | ||
401 | StreamPredictor::StreamPredictor(Stream *strA, int predictorA, | 401 | StreamPredictor::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 | ||
417 | StreamPredictor::~StreamPredictor() { | 417 | StreamPredictor::~StreamPredictor() { |
418 | gfree(predLine); | 418 | gfree(predLine); |
419 | } | 419 | } |
420 | 420 | ||
421 | int StreamPredictor::lookChar() { | 421 | int 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 | ||
430 | int StreamPredictor::getChar() { | 430 | int 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 | ||
439 | GBool StreamPredictor::getNextLine() { | 439 | GBool 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 | ||
557 | FileStream::FileStream(FILE *fA, int startA, int lengthA, Object *dictA): | 557 | FileStream::FileStream(FILE *fA, Guint startA, GBool limitedA, |
558 | Guint lengthA, Object *dictA): | ||
558 | BaseStream(dictA) { | 559 | BaseStream(dictA) { |
559 | f = fA; | 560 | f = fA; |
560 | start = startA; | 561 | start = startA; |
562 | limited = limitedA; | ||
561 | length = lengthA; | 563 | length = lengthA; |
562 | bufPtr = bufEnd = buf; | 564 | bufPtr = bufEnd = buf; |
563 | bufPos = start; | 565 | bufPos = start; |
564 | savePos = -1; | 566 | savePos = 0; |
567 | saved = gFalse; | ||
565 | } | 568 | } |
566 | 569 | ||
567 | FileStream::~FileStream() { | 570 | FileStream::~FileStream() { |
568 | close(); | 571 | close(); |
569 | } | 572 | } |
570 | 573 | ||
571 | Stream *FileStream::makeSubStream(int startA, int lengthA, Object *dictA) { | 574 | Stream *FileStream::makeSubStream(Guint startA, GBool limitedA, |
572 | return new FileStream(f, startA, lengthA, dictA); | 575 | Guint lengthA, Object *dictA) { |
576 | return new FileStream(f, startA, limitedA, lengthA, dictA); | ||
573 | } | 577 | } |
574 | 578 | ||
575 | void FileStream::reset() { | 579 | void FileStream::reset() { |
576 | savePos = (int)ftell(f); | 580 | #if HAVE_FSEEK64 |
581 | savePos = (Guint)ftell64(f); | ||
582 | fseek64(f, start, SEEK_SET); | ||
583 | #else | ||
584 | savePos = (Guint)ftell(f); | ||
577 | fseek(f, start, SEEK_SET); | 585 | fseek(f, start, SEEK_SET); |
586 | #endif | ||
587 | saved = gTrue; | ||
578 | bufPtr = bufEnd = buf; | 588 | bufPtr = bufEnd = buf; |
579 | bufPos = start; | 589 | bufPos = start; |
580 | #ifndef NO_DECRYPTION | 590 | #ifndef NO_DECRYPTION |
581 | if (decrypt) | 591 | if (decrypt) |
582 | decrypt->reset(); | 592 | decrypt->reset(); |
583 | #endif | 593 | #endif |
584 | } | 594 | } |
585 | 595 | ||
586 | void FileStream::close() { | 596 | void FileStream::close() { |
587 | if (savePos >= 0) { | 597 | if (saved) { |
598 | #if HAVE_FSEEK64 | ||
599 | fseek64(f, savePos, SEEK_SET); | ||
600 | #else | ||
588 | fseek(f, savePos, SEEK_SET); | 601 | fseek(f, savePos, SEEK_SET); |
589 | savePos = -1; | 602 | #endif |
603 | saved = gFalse; | ||
590 | } | 604 | } |
591 | } | 605 | } |
592 | 606 | ||
593 | GBool FileStream::fillBuf() { | 607 | GBool FileStream::fillBuf() { |
594 | int n; | 608 | int n; |
595 | #ifndef NO_DECRYPTION | 609 | #ifndef NO_DECRYPTION |
596 | char *p; | 610 | char *p; |
597 | #endif | 611 | #endif |
598 | 612 | ||
599 | bufPos += bufEnd - buf; | 613 | bufPos += bufEnd - buf; |
600 | bufPtr = bufEnd = buf; | 614 | bufPtr = bufEnd = buf; |
601 | if (length >= 0 && bufPos >= start + length) { | 615 | if (limited && bufPos >= start + length) { |
602 | return gFalse; | 616 | return gFalse; |
603 | } | 617 | } |
604 | if (length >= 0 && bufPos + fileStreamBufSize > start + length) { | 618 | if (limited && bufPos + fileStreamBufSize > start + length) { |
605 | n = start + length - bufPos; | 619 | n = start + length - bufPos; |
606 | } else { | 620 | } else { |
607 | n = fileStreamBufSize; | 621 | n = fileStreamBufSize; |
608 | } | 622 | } |
609 | n = fread(buf, 1, n, f); | 623 | n = fread(buf, 1, n, f); |
610 | bufEnd = buf + n; | 624 | bufEnd = buf + n; |
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 | ||
624 | void FileStream::setPos(int pos) { | 638 | void FileStream::setPos(Guint pos, int dir) { |
625 | long size; | 639 | Guint size; |
626 | 640 | ||
627 | if (pos >= 0) { | 641 | if (dir >= 0) { |
642 | #if HAVE_FSEEK64 | ||
643 | fseek64(f, pos, SEEK_SET); | ||
644 | #else | ||
628 | fseek(f, pos, SEEK_SET); | 645 | fseek(f, pos, SEEK_SET); |
646 | #endif | ||
629 | bufPos = pos; | 647 | bufPos = pos; |
630 | } else { | 648 | } else { |
649 | #if HAVE_FSEEK64 | ||
650 | fseek64(f, 0, SEEK_END); | ||
651 | size = (Guint)ftell64(f); | ||
652 | #else | ||
631 | fseek(f, 0, SEEK_END); | 653 | fseek(f, 0, SEEK_END); |
632 | size = ftell(f); | 654 | size = (Guint)ftell(f); |
633 | if (pos < -size) | 655 | #endif |
634 | pos = (int)(-size); | 656 | if (pos > size) |
657 | pos = (Guint)size; | ||
635 | #ifdef __CYGWIN32__ | 658 | #ifdef __CYGWIN32__ |
636 | //~ work around a bug in cygwin's implementation of fseek | 659 | //~ work around a bug in cygwin's implementation of fseek |
637 | rewind(f); | 660 | rewind(f); |
638 | #endif | 661 | #endif |
639 | fseek(f, pos, SEEK_END); | 662 | #if HAVE_FSEEK64 |
640 | bufPos = (int)ftell(f); | 663 | fseek64(f, -(int)pos, SEEK_END); |
664 | bufPos = (Guint)ftell64(f); | ||
665 | #else | ||
666 | fseek(f, -(int)pos, SEEK_END); | ||
667 | bufPos = (Guint)ftell(f); | ||
668 | #endif | ||
641 | } | 669 | } |
642 | bufPtr = bufEnd = buf; | 670 | bufPtr = bufEnd = buf; |
643 | } | 671 | } |
644 | 672 | ||
645 | void FileStream::moveStart(int delta) { | 673 | void FileStream::moveStart(int delta) { |
646 | start += delta; | 674 | start += delta; |
647 | bufPtr = bufEnd = buf; | 675 | bufPtr = bufEnd = buf; |
648 | bufPos = start; | 676 | bufPos = start; |
649 | } | 677 | } |
650 | 678 | ||
651 | //------------------------------------------------------------------------ | 679 | //------------------------------------------------------------------------ |
680 | // MemStream | ||
681 | //------------------------------------------------------------------------ | ||
682 | |||
683 | MemStream::MemStream(char *bufA, Guint lengthA, Object *dictA): | ||
684 | BaseStream(dictA) { | ||
685 | buf = bufA; | ||
686 | needFree = gFalse; | ||
687 | length = lengthA; | ||
688 | bufEnd = buf + length; | ||
689 | bufPtr = buf; | ||
690 | } | ||
691 | |||
692 | MemStream::~MemStream() { | ||
693 | if (needFree) { | ||
694 | gfree(buf); | ||
695 | } | ||
696 | } | ||
697 | |||
698 | Stream *MemStream::makeSubStream(Guint start, GBool limited, | ||
699 | Guint lengthA, Object *dictA) { | ||
700 | Guint newLength; | ||
701 | |||
702 | if (!limited || start + lengthA > length) { | ||
703 | newLength = length - start; | ||
704 | } else { | ||
705 | newLength = lengthA; | ||
706 | } | ||
707 | return new MemStream(buf + start, newLength, dictA); | ||
708 | } | ||
709 | |||
710 | void MemStream::reset() { | ||
711 | bufPtr = buf; | ||
712 | #ifndef NO_DECRYPTION | ||
713 | if (decrypt) { | ||
714 | decrypt->reset(); | ||
715 | } | ||
716 | #endif | ||
717 | } | ||
718 | |||
719 | void MemStream::close() { | ||
720 | } | ||
721 | |||
722 | void MemStream::setPos(Guint pos, int dir) { | ||
723 | if (dir >= 0) { | ||
724 | if (pos > length) { | ||
725 | bufPtr = bufEnd; | ||
726 | } else { | ||
727 | bufPtr = buf + pos; | ||
728 | } | ||
729 | } else { | ||
730 | if (pos > length) { | ||
731 | bufPtr = buf; | ||
732 | } else { | ||
733 | bufPtr = bufEnd - pos; | ||
734 | } | ||
735 | } | ||
736 | } | ||
737 | |||
738 | void MemStream::moveStart(int delta) { | ||
739 | buf += delta; | ||
740 | bufPtr = buf; | ||
741 | } | ||
742 | |||
743 | #ifndef NO_DECRYPTION | ||
744 | void MemStream::doDecryption(Guchar *fileKey, int keyLength, | ||
745 | int objNum, int objGen) { | ||
746 | char *newBuf; | ||
747 | char *p, *q; | ||
748 | |||
749 | this->BaseStream::doDecryption(fileKey, keyLength, objNum, objGen); | ||
750 | if (decrypt) { | ||
751 | newBuf = (char *)gmalloc(bufEnd - buf); | ||
752 | for (p = buf, q = newBuf; p < bufEnd; ++p, ++q) { | ||
753 | *q = (char)decrypt->decryptByte((Guchar)*p); | ||
754 | } | ||
755 | bufEnd = newBuf + (bufEnd - buf); | ||
756 | bufPtr = newBuf + (bufPtr - buf); | ||
757 | buf = newBuf; | ||
758 | needFree = gTrue; | ||
759 | } | ||
760 | } | ||
761 | #endif | ||
762 | |||
763 | //------------------------------------------------------------------------ | ||
652 | // EmbedStream | 764 | // EmbedStream |
653 | //------------------------------------------------------------------------ | 765 | //------------------------------------------------------------------------ |
654 | 766 | ||
655 | EmbedStream::EmbedStream(Stream *strA, Object *dictA): | 767 | EmbedStream::EmbedStream(Stream *strA, Object *dictA): |
656 | BaseStream(dictA) { | 768 | BaseStream(dictA) { |
657 | str = strA; | 769 | str = strA; |
658 | } | 770 | } |
659 | 771 | ||
660 | EmbedStream::~EmbedStream() { | 772 | EmbedStream::~EmbedStream() { |
661 | } | 773 | } |
662 | 774 | ||
663 | Stream *EmbedStream::makeSubStream(int start, int length, Object *dictA) { | 775 | Stream *EmbedStream::makeSubStream(Guint start, GBool limited, |
776 | Guint length, Object *dictA) { | ||
664 | error(-1, "Internal: called makeSubStream() on EmbedStream"); | 777 | error(-1, "Internal: called makeSubStream() on EmbedStream"); |
665 | return NULL; | 778 | return NULL; |
666 | } | 779 | } |
667 | 780 | ||
668 | void EmbedStream::setPos(int pos) { | 781 | void EmbedStream::setPos(Guint pos, int dir) { |
669 | error(-1, "Internal: called setPos() on EmbedStream"); | 782 | error(-1, "Internal: called setPos() on EmbedStream"); |
670 | } | 783 | } |
671 | 784 | ||
672 | int EmbedStream::getStart() { | 785 | Guint EmbedStream::getStart() { |
673 | error(-1, "Internal: called getStart() on EmbedStream"); | 786 | error(-1, "Internal: called getStart() on EmbedStream"); |
674 | return 0; | 787 | return 0; |
675 | } | 788 | } |
676 | 789 | ||
677 | void EmbedStream::moveStart(int start) { | 790 | void EmbedStream::moveStart(int delta) { |
678 | error(-1, "Internal: called moveStart() on EmbedStream"); | 791 | error(-1, "Internal: called moveStart() on EmbedStream"); |
679 | } | 792 | } |
680 | 793 | ||
681 | //------------------------------------------------------------------------ | 794 | //------------------------------------------------------------------------ |
682 | // ASCIIHexStream | 795 | // ASCIIHexStream |
683 | //------------------------------------------------------------------------ | 796 | //------------------------------------------------------------------------ |
684 | 797 | ||
685 | ASCIIHexStream::ASCIIHexStream(Stream *strA): | 798 | ASCIIHexStream::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 | ||
691 | ASCIIHexStream::~ASCIIHexStream() { | 804 | ASCIIHexStream::~ASCIIHexStream() { |
692 | delete str; | 805 | delete str; |
693 | } | 806 | } |
694 | 807 | ||
695 | void ASCIIHexStream::reset() { | 808 | void ASCIIHexStream::reset() { |
696 | str->reset(); | 809 | str->reset(); |
697 | buf = EOF; | 810 | buf = EOF; |
698 | eof = gFalse; | 811 | eof = gFalse; |
699 | } | 812 | } |
700 | 813 | ||
701 | int ASCIIHexStream::lookChar() { | 814 | int 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 | ||
754 | GString *ASCIIHexStream::getPSFilter(char *indent) { | 867 | GString *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 | ||
764 | GBool ASCIIHexStream::isBinary(GBool last) { | 877 | GBool 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 | ||
772 | ASCII85Stream::ASCII85Stream(Stream *strA): | 885 | ASCII85Stream::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 | ||
778 | ASCII85Stream::~ASCII85Stream() { | 891 | ASCII85Stream::~ASCII85Stream() { |
779 | delete str; | 892 | delete str; |
780 | } | 893 | } |
781 | 894 | ||
782 | void ASCII85Stream::reset() { | 895 | void 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 | ||
788 | int ASCII85Stream::lookChar() { | 901 | int 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 | ||
832 | GString *ASCII85Stream::getPSFilter(char *indent) { | 945 | GString *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 | ||
842 | GBool ASCII85Stream::isBinary(GBool last) { | 955 | GBool 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 | ||
850 | LZWStream::LZWStream(Stream *strA, int predictor, int columns, int colors, | 963 | LZWStream::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 | ||
863 | LZWStream::~LZWStream() { | 976 | LZWStream::~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 | ||
880 | int LZWStream::getChar() { | 993 | int 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 | ||
887 | int LZWStream::lookChar() { | 1000 | int 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 | ||
894 | int LZWStream::getRawChar() { | 1007 | int LZWStream::getRawChar() { |
895 | return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); | 1008 | return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); |
896 | } | 1009 | } |
897 | 1010 | ||
898 | void LZWStream::reset() { | 1011 | void 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 | ||
988 | void LZWStream::dumpFile(FILE *f) { | 1097 | void 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 | ||
1111 | int LZWStream::getCode() { | 1220 | int 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 | ||
1126 | GBool LZWStream::fillBuf() { | 1235 | GBool 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 | ||
1146 | GString *LZWStream::getPSFilter(char *indent) { | 1255 | GString *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 | ||
3144 | err: | 3253 | err: |
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. |
3154 | void FlateStream::compHuffmanCodes(FlateHuffmanTab *tab, int n) { | 3263 | void 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 | ||
3192 | int FlateStream::getHuffmanCodeWord(FlateHuffmanTab *tab) { | 3301 | int 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 | ||
3226 | int FlateStream::getCodeWord(int bits) { | 3335 | int 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 | ||
3245 | EOFStream::EOFStream(Stream *strA): | 3354 | EOFStream::EOFStream(Stream *strA): |
3246 | FilterStream(strA) { | 3355 | FilterStream(strA) { |
3247 | } | 3356 | } |
3248 | 3357 | ||
3249 | EOFStream::~EOFStream() { | 3358 | EOFStream::~EOFStream() { |
3250 | delete str; | 3359 | delete str; |
3251 | } | 3360 | } |
3252 | 3361 | ||
3253 | //------------------------------------------------------------------------ | 3362 | //------------------------------------------------------------------------ |
3254 | // FixedLengthEncoder | 3363 | // FixedLengthEncoder |
3255 | //------------------------------------------------------------------------ | 3364 | //------------------------------------------------------------------------ |
3256 | 3365 | ||
3257 | FixedLengthEncoder::FixedLengthEncoder(Stream *strA, int lengthA): | 3366 | FixedLengthEncoder::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 | ||
3263 | FixedLengthEncoder::~FixedLengthEncoder() { | 3372 | FixedLengthEncoder::~FixedLengthEncoder() { |
3264 | if (str->isEncoder()) | 3373 | if (str->isEncoder()) |
3265 | delete str; | 3374 | delete str; |
3266 | } | 3375 | } |
3267 | 3376 | ||
3268 | void FixedLengthEncoder::reset() { | 3377 | void FixedLengthEncoder::reset() { |
3269 | str->reset(); | 3378 | str->reset(); |
3270 | count = 0; | 3379 | count = 0; |
3271 | } | 3380 | } |
3272 | 3381 | ||
3273 | void FixedLengthEncoder::close() { | 3382 | void FixedLengthEncoder::close() { |
3274 | } | 3383 | } |
3275 | 3384 | ||
3276 | int FixedLengthEncoder::getChar() { | 3385 | int 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 | ||
3283 | int FixedLengthEncoder::lookChar() { | 3392 | int FixedLengthEncoder::lookChar() { |
3284 | if (length >= 0 && count >= length) | 3393 | if (length >= 0 && count >= length) |
3285 | return EOF; | 3394 | return EOF; |
3286 | return str->getChar(); | 3395 | return str->getChar(); |
3287 | } | 3396 | } |
3288 | 3397 | ||
3289 | //------------------------------------------------------------------------ | 3398 | //------------------------------------------------------------------------ |
3399 | // ASCIIHexEncoder | ||
3400 | //------------------------------------------------------------------------ | ||
3401 | |||
3402 | ASCIIHexEncoder::ASCIIHexEncoder(Stream *strA): | ||
3403 | FilterStream(strA) { | ||
3404 | bufPtr = bufEnd = buf; | ||
3405 | lineLen = 0; | ||
3406 | eof = gFalse; | ||
3407 | } | ||
3408 | |||
3409 | ASCIIHexEncoder::~ASCIIHexEncoder() { | ||
3410 | if (str->isEncoder()) { | ||
3411 | delete str; | ||
3412 | } | ||
3413 | } | ||
3414 | |||
3415 | void ASCIIHexEncoder::reset() { | ||
3416 | str->reset(); | ||
3417 | bufPtr = bufEnd = buf; | ||
3418 | lineLen = 0; | ||
3419 | eof = gFalse; | ||
3420 | } | ||
3421 | |||
3422 | void ASCIIHexEncoder::close() { | ||
3423 | } | ||
3424 | |||
3425 | GBool ASCIIHexEncoder::fillBuf() { | ||
3426 | static char *hex = "0123456789abcdef"; | ||
3427 | int c; | ||
3428 | |||
3429 | if (eof) { | ||
3430 | return gFalse; | ||
3431 | } | ||
3432 | bufPtr = bufEnd = buf; | ||
3433 | if ((c = str->getChar()) == EOF) { | ||
3434 | *bufEnd++ = '>'; | ||
3435 | eof = gTrue; | ||
3436 | } else { | ||
3437 | if (lineLen >= 64) { | ||
3438 | *bufEnd++ = '\n'; | ||
3439 | lineLen = 0; | ||
3440 | } | ||
3441 | *bufEnd++ = hex[(c >> 4) & 0x0f]; | ||
3442 | *bufEnd++ = hex[c & 0x0f]; | ||
3443 | lineLen += 2; | ||
3444 | } | ||
3445 | return gTrue; | ||
3446 | } | ||
3447 | |||
3448 | //------------------------------------------------------------------------ | ||
3290 | // ASCII85Encoder | 3449 | // ASCII85Encoder |
3291 | //------------------------------------------------------------------------ | 3450 | //------------------------------------------------------------------------ |
3292 | 3451 | ||
3293 | ASCII85Encoder::ASCII85Encoder(Stream *strA): | 3452 | ASCII85Encoder::ASCII85Encoder(Stream *strA): |
3294 | FilterStream(strA) { | 3453 | FilterStream(strA) { |
3295 | bufPtr = bufEnd = buf; | 3454 | bufPtr = bufEnd = buf; |
3296 | lineLen = 0; | 3455 | lineLen = 0; |
3297 | eof = gFalse; | 3456 | eof = gFalse; |
3298 | } | 3457 | } |
3299 | 3458 | ||
3300 | ASCII85Encoder::~ASCII85Encoder() { | 3459 | ASCII85Encoder::~ASCII85Encoder() { |
3301 | if (str->isEncoder()) | 3460 | if (str->isEncoder()) |
3302 | delete str; | 3461 | delete str; |
3303 | } | 3462 | } |
3304 | 3463 | ||
3305 | void ASCII85Encoder::reset() { | 3464 | void 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 | ||
3312 | void ASCII85Encoder::close() { | 3471 | void ASCII85Encoder::close() { |
3313 | } | 3472 | } |
3314 | 3473 | ||
3315 | GBool ASCII85Encoder::fillBuf() { | 3474 | GBool 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 | ||
3365 | RunLengthEncoder::RunLengthEncoder(Stream *strA): | 3524 | RunLengthEncoder::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 | ||
3371 | RunLengthEncoder::~RunLengthEncoder() { | 3530 | RunLengthEncoder::~RunLengthEncoder() { |
3372 | if (str->isEncoder()) | 3531 | if (str->isEncoder()) |
3373 | delete str; | 3532 | delete str; |
3374 | } | 3533 | } |
3375 | 3534 | ||
3376 | void RunLengthEncoder::reset() { | 3535 | void 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 | ||
3382 | void RunLengthEncoder::close() { | 3541 | void 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 | // |
3393 | GBool RunLengthEncoder::fillBuf() { | 3552 | GBool 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 |
21 | class Decrypt; | 21 | class Decrypt; |
22 | #endif | 22 | #endif |
23 | class BaseStream; | 23 | class BaseStream; |
24 | 24 | ||
25 | //------------------------------------------------------------------------ | 25 | //------------------------------------------------------------------------ |
26 | 26 | ||
27 | enum StreamKind { | 27 | enum 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 | ||
43 | class Stream { | 43 | class Stream { |
44 | public: | 44 | public: |
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 | ||
103 | private: | 105 | private: |
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 | ||
116 | class BaseStream: public Stream { | 118 | class BaseStream: public Stream { |
117 | public: | 119 | public: |
118 | 120 | ||
119 | BaseStream(Object *dictA); | 121 | BaseStream(Object *dictA); |
120 | virtual ~BaseStream(); | 122 | virtual ~BaseStream(); |
121 | virtual Stream *makeSubStream(int start, int length, Object *dict) = 0; | 123 | virtual Stream *makeSubStream(Guint start, GBool limited, |
122 | virtual void setPos(int pos) = 0; | 124 | Guint length, Object *dict) = 0; |
125 | virtual void setPos(Guint pos, int dir = 0) = 0; | ||
123 | virtual BaseStream *getBaseStream() { return this; } | 126 | virtual BaseStream *getBaseStream() { return this; } |
124 | virtual Dict *getDict() { return dict.getDict(); } | 127 | virtual Dict *getDict() { return dict.getDict(); } |
125 | 128 | ||
126 | // Get/set position of first byte of stream within the file. | 129 | // Get/set position of first byte of stream within the file. |
127 | virtual int getStart() = 0; | 130 | virtual Guint getStart() = 0; |
128 | virtual void moveStart(int delta) = 0; | 131 | virtual void moveStart(int delta) = 0; |
129 | 132 | ||
130 | #ifndef NO_DECRYPTION | 133 | #ifndef NO_DECRYPTION |
131 | // Set decryption for this stream. | 134 | // Set decryption for this stream. |
132 | void doDecryption(Guchar *fileKey, int keyLength, int objNum, int objGen); | 135 | virtual void doDecryption(Guchar *fileKey, int keyLength, |
136 | int objNum, int objGen); | ||
133 | #endif | 137 | #endif |
134 | 138 | ||
135 | #ifndef NO_DECRYPTION | 139 | #ifndef NO_DECRYPTION |
136 | protected: | 140 | protected: |
137 | 141 | ||
138 | Decrypt *decrypt; | 142 | Decrypt *decrypt; |
139 | #endif | 143 | #endif |
140 | 144 | ||
141 | private: | 145 | private: |
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 | ||
152 | class FilterStream: public Stream { | 156 | class FilterStream: public Stream { |
153 | public: | 157 | public: |
154 | 158 | ||
155 | FilterStream(Stream *strA); | 159 | FilterStream(Stream *strA); |
156 | virtual ~FilterStream(); | 160 | virtual ~FilterStream(); |
157 | virtual void close(); | 161 | virtual void close(); |
158 | virtual int getPos() { return str->getPos(); } | 162 | virtual int getPos() { return str->getPos(); } |
159 | virtual void setPos(int pos); | 163 | virtual void setPos(Guint pos, int dir = 0); |
160 | virtual BaseStream *getBaseStream() { return str->getBaseStream(); } | 164 | virtual BaseStream *getBaseStream() { return str->getBaseStream(); } |
161 | virtual Dict *getDict() { return str->getDict(); } | 165 | virtual Dict *getDict() { return str->getDict(); } |
162 | 166 | ||
163 | protected: | 167 | protected: |
164 | 168 | ||
165 | Stream *str; | 169 | Stream *str; |
166 | }; | 170 | }; |
167 | 171 | ||
168 | //------------------------------------------------------------------------ | 172 | //------------------------------------------------------------------------ |
169 | // ImageStream | 173 | // ImageStream |
170 | //------------------------------------------------------------------------ | 174 | //------------------------------------------------------------------------ |
171 | 175 | ||
172 | class ImageStream { | 176 | class ImageStream { |
173 | public: | 177 | public: |
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 | ||
192 | private: | 196 | private: |
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 | ||
207 | class StreamPredictor { | 211 | class StreamPredictor { |
208 | public: | 212 | public: |
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 | ||
220 | private: | 224 | private: |
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 | ||
242 | class FileStream: public BaseStream { | 246 | class FileStream: public BaseStream { |
243 | public: | 247 | public: |
244 | 248 | ||
245 | FileStream(FILE *fA, int startA, int lengthA, Object *dictA); | 249 | FileStream(FILE *fA, Guint startA, GBool limitedA, |
250 | Guint lengthA, Object *dictA); | ||
246 | virtual ~FileStream(); | 251 | virtual ~FileStream(); |
247 | virtual Stream *makeSubStream(int startA, int lengthA, Object *dictA); | 252 | virtual Stream *makeSubStream(Guint startA, GBool limitedA, |
253 | Guint lengthA, Object *dictA); | ||
248 | virtual StreamKind getKind() { return strFile; } | 254 | virtual StreamKind getKind() { return strFile; } |
249 | virtual void reset(); | 255 | virtual void reset(); |
250 | virtual void close(); | 256 | virtual void close(); |
251 | virtual int getChar() | 257 | virtual int getChar() |
252 | { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); } | 258 | { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); } |
253 | virtual int lookChar() | 259 | virtual int lookChar() |
254 | { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); } | 260 | { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); } |
255 | virtual int getPos() { return bufPos + (bufPtr - buf); } | 261 | virtual int getPos() { return bufPos + (bufPtr - buf); } |
256 | virtual void setPos(int pos); | 262 | virtual void setPos(Guint pos, int dir = 0); |
257 | virtual GBool isBinary(GBool last = gTrue) { return last; } | 263 | virtual GBool isBinary(GBool last = gTrue) { return last; } |
258 | virtual int getStart() { return start; } | 264 | virtual Guint getStart() { return start; } |
259 | virtual void moveStart(int delta); | 265 | virtual void moveStart(int delta); |
260 | 266 | ||
261 | private: | 267 | private: |
262 | 268 | ||
263 | GBool fillBuf(); | 269 | GBool fillBuf(); |
264 | 270 | ||
265 | FILE *f; | 271 | FILE *f; |
266 | int start; | 272 | Guint start; |
267 | int length; | 273 | GBool limited; |
274 | Guint length; | ||
268 | char buf[fileStreamBufSize]; | 275 | char buf[fileStreamBufSize]; |
269 | char *bufPtr; | 276 | char *bufPtr; |
270 | char *bufEnd; | 277 | char *bufEnd; |
271 | int bufPos; | 278 | Guint bufPos; |
272 | int savePos; | 279 | int savePos; |
280 | GBool saved; | ||
281 | }; | ||
282 | |||
283 | //------------------------------------------------------------------------ | ||
284 | // MemStream | ||
285 | //------------------------------------------------------------------------ | ||
286 | |||
287 | class MemStream: public BaseStream { | ||
288 | public: | ||
289 | |||
290 | MemStream(char *bufA, Guint lengthA, Object *dictA); | ||
291 | virtual ~MemStream(); | ||
292 | virtual Stream *makeSubStream(Guint start, GBool limited, | ||
293 | Guint lengthA, Object *dictA); | ||
294 | virtual StreamKind getKind() { return strWeird; } | ||
295 | virtual void reset(); | ||
296 | virtual void close(); | ||
297 | virtual int getChar() | ||
298 | { return (bufPtr < bufEnd) ? (*bufPtr++ & 0xff) : EOF; } | ||
299 | virtual int lookChar() | ||
300 | { return (bufPtr < bufEnd) ? (*bufPtr & 0xff) : EOF; } | ||
301 | virtual int getPos() { return bufPtr - buf; } | ||
302 | virtual void setPos(Guint pos, int dir = 0); | ||
303 | virtual GBool isBinary(GBool last = gTrue) { return last; } | ||
304 | virtual Guint getStart() { return 0; } | ||
305 | virtual void moveStart(int delta); | ||
306 | #ifndef NO_DECRYPTION | ||
307 | virtual void doDecryption(Guchar *fileKey, int keyLength, | ||
308 | int objNum, int objGen); | ||
309 | #endif | ||
310 | |||
311 | private: | ||
312 | |||
313 | char *buf; | ||
314 | Guint length; | ||
315 | GBool needFree; | ||
316 | char *bufEnd; | ||
317 | char *bufPtr; | ||
273 | }; | 318 | }; |
274 | 319 | ||
275 | //------------------------------------------------------------------------ | 320 | //------------------------------------------------------------------------ |
276 | // EmbedStream | 321 | // EmbedStream |
277 | // | 322 | // |
278 | // This is a special stream type used for embedded streams (inline | 323 | // This is a special stream type used for embedded streams (inline |
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 | ||
285 | class EmbedStream: public BaseStream { | 330 | class EmbedStream: public BaseStream { |
286 | public: | 331 | public: |
287 | 332 | ||
288 | EmbedStream(Stream *strA, Object *dictA); | 333 | EmbedStream(Stream *strA, Object *dictA); |
289 | virtual ~EmbedStream(); | 334 | virtual ~EmbedStream(); |
290 | virtual Stream *makeSubStream(int start, int length, Object *dictA); | 335 | virtual Stream *makeSubStream(Guint start, GBool limited, |
336 | Guint length, Object *dictA); | ||
291 | virtual StreamKind getKind() { return str->getKind(); } | 337 | virtual StreamKind getKind() { return str->getKind(); } |
292 | virtual void reset() {} | 338 | virtual void reset() {} |
293 | virtual int getChar() { return str->getChar(); } | 339 | virtual int getChar() { return str->getChar(); } |
294 | virtual int lookChar() { return str->lookChar(); } | 340 | virtual int lookChar() { return str->lookChar(); } |
295 | virtual int getPos() { return str->getPos(); } | 341 | virtual int getPos() { return str->getPos(); } |
296 | virtual void setPos(int pos); | 342 | virtual void setPos(Guint pos, int dir = 0); |
297 | virtual GBool isBinary(GBool last = gTrue) { return last; } | 343 | virtual GBool isBinary(GBool last = gTrue) { return last; } |
298 | virtual int getStart(); | 344 | virtual Guint getStart(); |
299 | virtual void moveStart(int delta); | 345 | virtual void moveStart(int delta); |
300 | 346 | ||
301 | private: | 347 | private: |
302 | 348 | ||
303 | Stream *str; | 349 | Stream *str; |
304 | }; | 350 | }; |
305 | 351 | ||
306 | //------------------------------------------------------------------------ | 352 | //------------------------------------------------------------------------ |
307 | // ASCIIHexStream | 353 | // ASCIIHexStream |
308 | //------------------------------------------------------------------------ | 354 | //------------------------------------------------------------------------ |
309 | 355 | ||
310 | class ASCIIHexStream: public FilterStream { | 356 | class ASCIIHexStream: public FilterStream { |
311 | public: | 357 | public: |
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 | ||
323 | private: | 369 | private: |
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 | ||
333 | class ASCII85Stream: public FilterStream { | 379 | class ASCII85Stream: public FilterStream { |
334 | public: | 380 | public: |
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 | ||
346 | private: | 392 | private: |
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 | ||
358 | class LZWStream: public FilterStream { | 404 | class LZWStream: public FilterStream { |
359 | public: | 405 | public: |
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 | ||
372 | private: | 418 | private: |
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 | ||
394 | class RunLengthStream: public FilterStream { | 440 | class RunLengthStream: public FilterStream { |
395 | public: | 441 | public: |
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 | ||
408 | private: | 454 | private: |
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 | ||
422 | struct CCITTCodeTable; | 468 | struct CCITTCodeTable; |
423 | 469 | ||
424 | class CCITTFaxStream: public FilterStream { | 470 | class CCITTFaxStream: public FilterStream { |
425 | public: | 471 | public: |
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 | ||
439 | private: | 485 | private: |
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 |
472 | struct DCTCompInfo { | 518 | struct 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 |
482 | struct DCTHuffTable { | 528 | struct 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 | ||
489 | class DCTStream: public FilterStream { | 535 | class DCTStream: public FilterStream { |
490 | public: | 536 | public: |
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 | ||
502 | private: | 548 | private: |
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 |
555 | struct FlateCode { | 601 | struct 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 |
562 | struct FlateHuffmanTab { | 608 | struct 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 |
568 | struct FlateDecode { | 614 | struct 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 | ||
573 | class FlateStream: public FilterStream { | 619 | class FlateStream: public FilterStream { |
574 | public: | 620 | public: |
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 | ||
587 | private: | 633 | private: |
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 | ||
624 | class EOFStream: public FilterStream { | 670 | class EOFStream: public FilterStream { |
625 | public: | 671 | public: |
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 | ||
641 | class FixedLengthEncoder: public FilterStream { | 687 | class FixedLengthEncoder: public FilterStream { |
642 | public: | 688 | public: |
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 | ||
655 | private: | 701 | private: |
656 | 702 | ||
657 | int length; | 703 | int length; |
658 | int count; | 704 | int count; |
659 | }; | 705 | }; |
660 | 706 | ||
661 | //------------------------------------------------------------------------ | 707 | //------------------------------------------------------------------------ |
708 | // ASCIIHexEncoder | ||
709 | //------------------------------------------------------------------------ | ||
710 | |||
711 | class ASCIIHexEncoder: public FilterStream { | ||
712 | public: | ||
713 | |||
714 | ASCIIHexEncoder(Stream *strA); | ||
715 | virtual ~ASCIIHexEncoder(); | ||
716 | virtual StreamKind getKind() { return strWeird; } | ||
717 | virtual void reset(); | ||
718 | virtual void close(); | ||
719 | virtual int getChar() | ||
720 | { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); } | ||
721 | virtual int lookChar() | ||
722 | { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); } | ||
723 | virtual GString *getPSFilter(char *indent) { return NULL; } | ||
724 | virtual GBool isBinary(GBool last = gTrue) { return gFalse; } | ||
725 | virtual GBool isEncoder() { return gTrue; } | ||
726 | |||
727 | private: | ||
728 | |||
729 | char buf[4]; | ||
730 | char *bufPtr; | ||
731 | char *bufEnd; | ||
732 | int lineLen; | ||
733 | GBool eof; | ||
734 | |||
735 | GBool fillBuf(); | ||
736 | }; | ||
737 | |||
738 | //------------------------------------------------------------------------ | ||
662 | // ASCII85Encoder | 739 | // ASCII85Encoder |
663 | //------------------------------------------------------------------------ | 740 | //------------------------------------------------------------------------ |
664 | 741 | ||
665 | class ASCII85Encoder: public FilterStream { | 742 | class ASCII85Encoder: public FilterStream { |
666 | public: | 743 | public: |
667 | 744 | ||
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 | ||
681 | private: | 758 | private: |
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 | ||
696 | class RunLengthEncoder: public FilterStream { | 773 | class RunLengthEncoder: public FilterStream { |
697 | public: | 774 | public: |
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 | ||
712 | private: | 789 | private: |
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 | ||
37 | TextString::TextString(GfxState *state, fouble fontSize) { | 37 | TextString::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 | ||
59 | TextString::~TextString() { | 65 | TextString::~TextString() { |
60 | gfree(text); | 66 | gfree(text); |
61 | gfree(xRight); | 67 | gfree(xRight); |
62 | } | 68 | } |
63 | 69 | ||
64 | void TextString::addChar(GfxState *state, fouble x, fouble y, | 70 | void 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 | ||
83 | TextPage::TextPage(GBool rawOrderA) { | 89 | TextPage::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 | ||
93 | TextPage::~TextPage() { | 99 | TextPage::~TextPage() { |
94 | clear(); | 100 | clear(); |
95 | } | 101 | } |
96 | 102 | ||
97 | void TextPage::updateFont(GfxState *state) { | 103 | void TextPage::updateFont(GfxState *state) { |
98 | GfxFont *font; | 104 | GfxFont *font; |
99 | fouble *fm; | 105 | fouble *fm; |
100 | char *name; | 106 | char *name; |
101 | int code; | 107 | int code; |
108 | fouble w; | ||
102 | 109 | ||
103 | // adjust the font size | 110 | // adjust the font size |
104 | fontSize = state->getTransformedFontSize(); | 111 | fontSize = state->getTransformedFontSize(); |
105 | if ((font = state->getFont()) && font->getType() == fontType3) { | 112 | if ((font = state->getFont()) && font->getType() == fontType3) { |
106 | // This is a hack which makes it possible to deal with some Type 3 | 113 | // This is a hack which makes it possible to deal with some Type 3 |
107 | // fonts. The problem is that it's impossible to know what the | 114 | // fonts. The problem is that it's impossible to know what the |
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 | ||
129 | void TextPage::beginString(GfxState *state) { | 139 | void 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 | ||
140 | void TextPage::addChar(GfxState *state, fouble x, fouble y, | 150 | void 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 | ||
164 | void TextPage::endString() { | 176 | void 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 | ||
216 | void TextPage::coalesce() { | 228 | void 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 | ||
276 | GBool TextPage::findText(Unicode *s, int len, | 288 | GBool 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 | ||
354 | GString *TextPage::getText(fouble xMin, fouble yMin, | 366 | GString *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 | ||
432 | void TextPage::dump(FILE *f) { | 444 | void TextPage::dump(void *outputStream, TextOutputFunc outputFunc) { |
433 | UnicodeMap *uMap; | 445 | UnicodeMap *uMap; |
434 | char space[8], eol[16], eop[8], buf[8]; | 446 | char space[8], eol[16], eop[8], buf[8]; |
435 | int spaceLen, eolLen, eopLen, n; | 447 | int spaceLen, eolLen, eopLen, n; |
436 | TextString *str1, *str2, *str3; | 448 | TextString *str1, *str2, *str3; |
437 | fouble yMin, yMax; | 449 | fouble yMin, yMax; |
438 | int col1, col2, d, i; | 450 | int col1, col2, d, i; |
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 | ||
594 | void TextPage::clear() { | 606 | void 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 | ||
626 | static void outputToFile(void *stream, char *text, int len) { | ||
627 | fwrite(text, 1, len, (FILE *)stream); | ||
628 | } | ||
629 | |||
614 | TextOutputDev::TextOutputDev(char *fileName, GBool rawOrderA, GBool append) { | 630 | TextOutputDev::TextOutputDev(char *fileName, GBool rawOrderA, GBool append) { |
615 | text = NULL; | 631 | text = NULL; |
616 | rawOrder = rawOrderA; | 632 | rawOrder = rawOrderA; |
617 | ok = gTrue; | 633 | ok = gTrue; |
618 | 634 | ||
619 | // open file | 635 | // open file |
620 | needClose = gFalse; | 636 | needClose = gFalse; |
621 | if (fileName) { | 637 | if (fileName) { |
622 | if (!strcmp(fileName, "-")) { | 638 | if (!strcmp(fileName, "-")) { |
623 | f = stdout; | 639 | outputStream = stdout; |
624 | } else if ((f = fopen(fileName, append ? "a" : "w"))) { | 640 | } else if ((outputStream = fopen(fileName, append ? "ab" : "wb"))) { |
625 | needClose = gTrue; | 641 | needClose = gTrue; |
626 | } else { | 642 | } else { |
627 | error(-1, "Couldn't open text file '%s'", fileName); | 643 | error(-1, "Couldn't open text file '%s'", fileName); |
628 | ok = gFalse; | 644 | ok = gFalse; |
629 | return; | 645 | return; |
630 | } | 646 | } |
647 | outputFunc = &outputToFile; | ||
631 | } else { | 648 | } else { |
632 | f = NULL; | 649 | outputStream = NULL; |
633 | } | 650 | } |
634 | 651 | ||
635 | // set up text object | 652 | // set up text object |
636 | text = new TextPage(rawOrder); | 653 | text = new TextPage(rawOrder); |
637 | } | 654 | } |
638 | 655 | ||
656 | TextOutputDev::TextOutputDev(TextOutputFunc func, void *stream, | ||
657 | GBool rawOrderA) { | ||
658 | outputFunc = func; | ||
659 | outputStream = stream; | ||
660 | needClose = gFalse; | ||
661 | rawOrder = rawOrderA; | ||
662 | text = new TextPage(rawOrder); | ||
663 | ok = gTrue; | ||
664 | } | ||
665 | |||
639 | TextOutputDev::~TextOutputDev() { | 666 | TextOutputDev::~TextOutputDev() { |
640 | if (needClose) { | 667 | if (needClose) { |
641 | #ifdef MACOS | 668 | #ifdef MACOS |
642 | ICS_MapRefNumAndAssign((short)f->handle); | 669 | ICS_MapRefNumAndAssign((short)((FILE *)outputStream)->handle); |
643 | #endif | 670 | #endif |
644 | fclose(f); | 671 | fclose((FILE *)outputStream); |
645 | } | 672 | } |
646 | if (text) { | 673 | if (text) { |
647 | delete text; | 674 | delete text; |
648 | } | 675 | } |
649 | } | 676 | } |
650 | 677 | ||
651 | void TextOutputDev::startPage(int pageNum, GfxState *state) { | 678 | void TextOutputDev::startPage(int pageNum, GfxState *state) { |
652 | text->clear(); | 679 | text->clear(); |
653 | } | 680 | } |
654 | 681 | ||
655 | void TextOutputDev::endPage() { | 682 | void TextOutputDev::endPage() { |
656 | text->coalesce(); | 683 | text->coalesce(); |
657 | if (f) { | 684 | if (outputStream) { |
658 | text->dump(f); | 685 | text->dump(outputStream, outputFunc); |
659 | } | 686 | } |
660 | } | 687 | } |
661 | 688 | ||
662 | void TextOutputDev::updateFont(GfxState *state) { | 689 | void TextOutputDev::updateFont(GfxState *state) { |
663 | text->updateFont(state); | 690 | text->updateFont(state); |
664 | } | 691 | } |
665 | 692 | ||
666 | void TextOutputDev::beginString(GfxState *state, GString *s) { | 693 | void TextOutputDev::beginString(GfxState *state, GString *s) { |
667 | text->beginString(state); | 694 | text->beginString(state); |
668 | } | 695 | } |
669 | 696 | ||
670 | void TextOutputDev::endString(GfxState *state) { | 697 | void TextOutputDev::endString(GfxState *state) { |
671 | text->endString(); | 698 | text->endString(); |
672 | } | 699 | } |
673 | 700 | ||
674 | void TextOutputDev::drawChar(GfxState *state, fouble x, fouble y, | 701 | void 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 | ||
681 | GBool TextOutputDev::findText(Unicode *s, int len, | 708 | GBool 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 | ||
21 | class GfxState; | 21 | class GfxState; |
22 | class GString; | 22 | class GString; |
23 | 23 | ||
24 | //------------------------------------------------------------------------ | 24 | //------------------------------------------------------------------------ |
25 | |||
26 | typedef void (*TextOutputFunc)(void *stream, char *text, int len); | ||
27 | |||
28 | //------------------------------------------------------------------------ | ||
25 | // TextString | 29 | // TextString |
26 | //------------------------------------------------------------------------ | 30 | //------------------------------------------------------------------------ |
27 | 31 | ||
28 | class TextString { | 32 | class TextString { |
29 | public: | 33 | public: |
30 | 34 | ||
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 | ||
41 | private: | 45 | private: |
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 | ||
60 | class TextPage { | 64 | class TextPage { |
61 | public: | 65 | public: |
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 | ||
105 | private: | 109 | private: |
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 | ||
123 | class TextOutputDev: public OutputDev { | 127 | class TextOutputDev: public OutputDev { |
124 | public: | 128 | public: |
125 | 129 | ||
126 | // Open a text output file. If <fileName> is NULL, no file is | 130 | // Open a text output file. If <fileName> is NULL, no file is |
127 | // written (this is useful, e.g., for searching text). If | 131 | // written (this is useful, e.g., for searching text). If |
128 | // <rawOrder> is true, the text is kept in content stream order. | 132 | // <rawOrder> is true, the text is kept in content stream order. |
129 | TextOutputDev(char *fileName, GBool rawOrderA, GBool append); | 133 | TextOutputDev(char *fileName, GBool rawOrderA, GBool append); |
130 | 134 | ||
135 | // Create a TextOutputDev which will write to a generic stream. If | ||
136 | // <rawOrder> is true, the text is kept in content stream order. | ||
137 | TextOutputDev(TextOutputFunc func, void *stream, GBool rawOrderA); | ||
138 | |||
131 | // Destructor. | 139 | // Destructor. |
132 | virtual ~TextOutputDev(); | 140 | virtual ~TextOutputDev(); |
133 | 141 | ||
134 | // Check if file was successfully created. | 142 | // Check if file was successfully created. |
135 | virtual GBool isOk() { return ok; } | 143 | virtual GBool isOk() { return ok; } |
136 | 144 | ||
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 | ||
180 | private: | 192 | private: |
181 | 193 | ||
182 | FILE *f; // text file | 194 | TextOutputFunc outputFunc;// output function |
183 | GBool needClose; // need to close the file? | 195 | void *outputStream; // output stream |
196 | GBool needClose; // need to close the output file? | ||
197 | // (only if outputStream is a FILE*) | ||
184 | TextPage *text; // text for the current page | 198 | TextPage *text; // text for the current page |
185 | GBool rawOrder; // keep text in content stream order | 199 | GBool rawOrder; // keep text in content stream order |
186 | GBool ok; // set up ok? | 200 | GBool ok; // set up ok? |
187 | }; | 201 | }; |
188 | 202 | ||
189 | #endif | 203 | #endif |
diff --git a/noncore/unsupported/qpdf/xpdf/UnicodeMap.cc b/noncore/unsupported/qpdf/xpdf/UnicodeMap.cc index ab823b1..75f23d2 100644 --- a/noncore/unsupported/qpdf/xpdf/UnicodeMap.cc +++ b/noncore/unsupported/qpdf/xpdf/UnicodeMap.cc | |||
@@ -1,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 | ||
28 | struct UnicodeMapExt { | 28 | struct 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 | ||
36 | UnicodeMap *UnicodeMap::parse(GString *encodingNameA) { | 36 | UnicodeMap *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 | ||
107 | UnicodeMap::UnicodeMap(GString *encodingNameA) { | 107 | UnicodeMap::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 | ||
117 | UnicodeMap::UnicodeMap(char *encodingNameA, | 117 | UnicodeMap::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 | ||
128 | UnicodeMap::UnicodeMap(char *encodingNameA, UnicodeMapFunc funcA) { | 128 | UnicodeMap::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 | ||
137 | UnicodeMap::~UnicodeMap() { | 137 | UnicodeMap::~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 | ||
147 | void UnicodeMap::incRefCnt() { | 147 | void UnicodeMap::incRefCnt() { |
148 | ++refCnt; | 148 | ++refCnt; |
149 | } | 149 | } |
150 | 150 | ||
151 | void UnicodeMap::decRefCnt() { | 151 | void UnicodeMap::decRefCnt() { |
152 | if (--refCnt == 0) { | 152 | if (--refCnt == 0) { |
153 | delete this; | 153 | delete this; |
154 | } | 154 | } |
155 | } | 155 | } |
156 | 156 | ||
157 | GBool UnicodeMap::match(GString *encodingNameA) { | 157 | GBool UnicodeMap::match(GString *encodingNameA) { |
158 | return !encodingName->cmp(encodingNameA); | 158 | return !encodingName->cmp(encodingNameA); |
159 | } | 159 | } |
160 | 160 | ||
161 | int UnicodeMap::mapUnicode(Unicode u, char *buf, int bufSize) { | 161 | int 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 | ||
21 | class GString; | 21 | class GString; |
22 | 22 | ||
23 | //------------------------------------------------------------------------ | 23 | //------------------------------------------------------------------------ |
24 | 24 | ||
25 | enum UnicodeMapKind { | 25 | enum 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 | ||
31 | typedef int (*UnicodeMapFunc)(Unicode u, char *buf, int bufSize); | 31 | typedef int (*UnicodeMapFunc)(Unicode u, char *buf, int bufSize); |
32 | 32 | ||
33 | struct UnicodeMapRange { | 33 | struct 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 | ||
38 | struct UnicodeMapExt; | 38 | struct UnicodeMapExt; |
39 | 39 | ||
40 | //------------------------------------------------------------------------ | 40 | //------------------------------------------------------------------------ |
41 | 41 | ||
42 | class UnicodeMap { | 42 | class UnicodeMap { |
43 | public: | 43 | public: |
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 | ||
74 | private: | 74 | private: |
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 | ||
94 | class UnicodeMapCache { | 94 | class UnicodeMapCache { |
95 | public: | 95 | public: |
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 | ||
105 | private: | 105 | private: |
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 | ||
9 | static UnicodeMapRange latin1UnicodeMapRanges[] = { | 9 | static UnicodeMapRange latin1UnicodeMapRanges[] = { |
10 | { 0x000a, 0x000a, 0x0a, 1 }, | 10 | { 0x000a, 0x000a, 0x0a, 1 }, |
11 | { 0x000c, 0x000d, 0x0c, 1 }, | 11 | { 0x000c, 0x000d, 0x0c, 1 }, |
12 | { 0x0020, 0x007e, 0x20, 1 }, | 12 | { 0x0020, 0x007e, 0x20, 1 }, |
13 | { 0x00a0, 0x00a0, 0x20, 1 }, | 13 | { 0x00a0, 0x00a0, 0x20, 1 }, |
14 | { 0x00a1, 0x00ac, 0xa1, 1 }, | 14 | { 0x00a1, 0x00ac, 0xa1, 1 }, |
15 | { 0x00ae, 0x00ff, 0xae, 1 }, | 15 | { 0x00ae, 0x00ff, 0xae, 1 }, |
16 | { 0x010c, 0x010c, 0x43, 1 }, | ||
17 | { 0x010d, 0x010d, 0x63, 1 }, | ||
16 | { 0x0131, 0x0131, 0x69, 1 }, | 18 | { 0x0131, 0x0131, 0x69, 1 }, |
17 | { 0x0141, 0x0141, 0x4c, 1 }, | 19 | { 0x0141, 0x0141, 0x4c, 1 }, |
18 | { 0x0142, 0x0142, 0x6c, 1 }, | 20 | { 0x0142, 0x0142, 0x6c, 1 }, |
19 | { 0x0152, 0x0152, 0x4f45, 2 }, | 21 | { 0x0152, 0x0152, 0x4f45, 2 }, |
20 | { 0x0153, 0x0153, 0x6f65, 2 }, | 22 | { 0x0153, 0x0153, 0x6f65, 2 }, |
21 | { 0x0160, 0x0160, 0x53, 1 }, | 23 | { 0x0160, 0x0160, 0x53, 1 }, |
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 | ||
52 | static UnicodeMapRange ascii7UnicodeMapRanges[] = { | 71 | static 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 | ||
146 | static UnicodeMapRange symbolUnicodeMapRanges[] = { | 204 | static 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 | ||
271 | static UnicodeMapRange zapfDingbatsUnicodeMapRanges[] = { | 329 | static 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 | ||
51 | XRef::XRef(BaseStream *strA, GString *ownerPassword, GString *userPassword) { | 52 | XRef::XRef(BaseStream *strA, GString *ownerPassword, GString *userPassword) { |
52 | int pos; | 53 | Guint pos; |
53 | int i; | 54 | int i; |
54 | 55 | ||
55 | ok = gTrue; | 56 | ok = gTrue; |
57 | errCode = errNone; | ||
56 | size = 0; | 58 | size = 0; |
57 | entries = NULL; | 59 | entries = NULL; |
58 | streamEnds = NULL; | 60 | streamEnds = NULL; |
59 | streamEndsLen = 0; | 61 | streamEndsLen = 0; |
60 | 62 | ||
61 | // read the trailer | 63 | // read the trailer |
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 | ||
108 | XRef::~XRef() { | 113 | XRef::~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. |
118 | int XRef::readTrailer() { | 123 | Guint XRef::readTrailer() { |
119 | Parser *parser; | 124 | Parser *parser; |
120 | Object obj; | 125 | Object obj; |
121 | char buf[xrefSearchSize+1]; | 126 | char buf[xrefSearchSize+1]; |
122 | int n, pos, pos1; | 127 | int n; |
128 | Guint pos, pos1; | ||
123 | char *p; | 129 | char *p; |
124 | int c; | 130 | int c; |
125 | int i; | 131 | int i; |
126 | 132 | ||
127 | // read last xrefSearchSize bytes | 133 | // read last xrefSearchSize bytes |
128 | str->setPos(-xrefSearchSize); | 134 | str->setPos(xrefSearchSize, -1); |
129 | for (n = 0; n < xrefSearchSize; ++n) { | 135 | for (n = 0; n < xrefSearchSize; ++n) { |
130 | if ((c = str->getChar()) == EOF) | 136 | if ((c = str->getChar()) == EOF) |
131 | break; | 137 | break; |
132 | buf[n] = c; | 138 | buf[n] = c; |
133 | } | 139 | } |
134 | buf[n] = '\0'; | 140 | buf[n] = '\0'; |
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. |
207 | GBool XRef::readXRef(int *pos) { | 214 | GBool XRef::readXRef(Guint *pos) { |
208 | Parser *parser; | 215 | Parser *parser; |
209 | Object obj, obj2; | 216 | Object obj, obj2; |
210 | char s[20]; | 217 | char s[20]; |
211 | GBool more; | 218 | GBool more; |
212 | int first, newSize, n, i, j; | 219 | int first, newSize, n, i, j; |
213 | int c; | 220 | int c; |
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. |
336 | GBool XRef::constructXRef() { | 344 | GBool XRef::constructXRef() { |
337 | Parser *parser; | 345 | Parser *parser; |
338 | Object obj; | 346 | Object obj; |
339 | char buf[256]; | 347 | char buf[256]; |
340 | int pos; | 348 | Guint pos; |
341 | int num, gen; | 349 | int num, gen; |
342 | int newSize; | 350 | int newSize; |
343 | int streamEndsSize; | 351 | int streamEndsSize; |
344 | char *p; | 352 | char *p; |
345 | int i; | 353 | int i; |
346 | GBool gotRoot; | 354 | GBool gotRoot; |
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 |
438 | GBool XRef::checkEncrypted(GString *ownerPassword, GString *userPassword) { | 448 | GBool 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 |
521 | GBool XRef::checkEncrypted(GString *ownerPassword, GString *userPassword) { | 531 | GBool 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 | ||
535 | GBool XRef::okToPrint(GBool ignoreOwnerPW) { | 545 | GBool 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 | ||
544 | GBool XRef::okToChange(GBool ignoreOwnerPW) { | 554 | GBool 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 | ||
553 | GBool XRef::okToCopy(GBool ignoreOwnerPW) { | 563 | GBool 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 | ||
562 | GBool XRef::okToAddNotes(GBool ignoreOwnerPW) { | 572 | GBool 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 | ||
571 | Object *XRef::fetch(int num, int gen, Object *obj) { | 581 | Object *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 | ||
612 | Object *XRef::getDocInfo(Object *obj) { | 623 | Object *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. |
617 | Object *XRef::getDocInfoNF(Object *obj) { | 628 | Object *XRef::getDocInfoNF(Object *obj) { |
618 | return trailerDict.dictLookupNF("Info", obj); | 629 | return trailerDict.dictLookupNF("Info", obj); |
619 | } | 630 | } |
620 | 631 | ||
621 | int XRef::getStreamEnd(int streamStart) { | 632 | GBool XRef::getStreamEnd(Guint streamStart, Guint *streamEnd) { |
622 | int a, b, m; | 633 | int a, b, m; |
623 | 634 | ||
624 | if (streamEndsLen == 0 || | 635 | if (streamEndsLen == 0 || |
625 | streamStart > streamEnds[streamEndsLen - 1]) { | 636 | streamStart > streamEnds[streamEndsLen - 1]) { |
626 | return -1; | 637 | return gFalse; |
627 | } | 638 | } |
628 | 639 | ||
629 | a = -1; | 640 | a = -1; |
630 | b = streamEndsLen - 1; | 641 | b = streamEndsLen - 1; |
631 | // invariant: streamEnds[a] < streamStart <= streamEnds[b] | 642 | // invariant: streamEnds[a] < streamStart <= streamEnds[b] |
632 | while (b - a > 1) { | 643 | while (b - a > 1) { |
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 | |||
655 | Guint XRef::strToUnsigned(char *s) { | ||
656 | Guint x; | ||
657 | char *p; | ||
658 | int i; | ||
659 | |||
660 | x = 0; | ||
661 | for (p = s, i = 0; *p && isdigit(*p) && i < 10; ++p, ++i) { | ||
662 | x = 10 * x + (*p - '0'); | ||
663 | } | ||
664 | return x; | ||
641 | } | 665 | } |
diff --git a/noncore/unsupported/qpdf/xpdf/XRef.h b/noncore/unsupported/qpdf/xpdf/XRef.h index a44c495..7876fa6 100644 --- a/noncore/unsupported/qpdf/xpdf/XRef.h +++ b/noncore/unsupported/qpdf/xpdf/XRef.h | |||
@@ -1,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 | ||
19 | class Dict; | 19 | class Dict; |
20 | class Stream; | 20 | class Stream; |
21 | 21 | ||
22 | //------------------------------------------------------------------------ | 22 | //------------------------------------------------------------------------ |
23 | // XRef | 23 | // XRef |
24 | //------------------------------------------------------------------------ | 24 | //------------------------------------------------------------------------ |
25 | 25 | ||
26 | struct XRefEntry { | 26 | struct XRefEntry { |
27 | int offset; | 27 | Guint offset; |
28 | int gen; | 28 | int gen; |
29 | GBool used; | 29 | GBool used; |
30 | }; | 30 | }; |
31 | 31 | ||
32 | class XRef { | 32 | class XRef { |
33 | public: | 33 | public: |
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 | ||
81 | private: | 84 | private: |
82 | 85 | ||
83 | BaseStream *str; // input stream | 86 | BaseStream *str; // input stream |
84 | int start; // offset in file (to allow for garbage | 87 | Guint start; // offset in file (to allow for garbage |
85 | // at beginning of file) | 88 | // at beginning of file) |
86 | XRefEntry *entries; // xref entries | 89 | XRefEntry *entries; // xref entries |
87 | int size; // size of <entries> array | 90 | int size; // size of <entries> array |
88 | int rootNum, rootGen; // catalog dict | 91 | int rootNum, rootGen; // catalog dict |
89 | GBool ok; // true if xref table is valid | 92 | GBool ok; // true if xref table is valid |
93 | int errCode; // error code (if <ok> is false) | ||
90 | Object trailerDict; // trailer dictionary | 94 | Object trailerDict; // trailer dictionary |
91 | int lastXRefPos; // offset of last xref table | 95 | Guint lastXRefPos; // offset of last xref table |
92 | int *streamEnds; // 'endstream' positions - only used in | 96 | Guint *streamEnds; // 'endstream' positions - only used in |
93 | // damaged files | 97 | // damaged files |
94 | int streamEndsLen; // number of valid entries in streamEnds | 98 | int streamEndsLen; // number of valid entries in streamEnds |
95 | #ifndef NO_DECRYPTION | 99 | #ifndef NO_DECRYPTION |
96 | GBool encrypted; // true if file is encrypted | 100 | GBool encrypted; // true if file is encrypted |
97 | int encVersion; // encryption algorithm | 101 | int encVersion; // encryption algorithm |
98 | int encRevision; // security handler revision | 102 | int encRevision; // security handler revision |
99 | int keyLength; // length of key, in bytes | 103 | int keyLength; // length of key, in bytes |
100 | int permFlags; // permission bits | 104 | int permFlags; // permission bits |
101 | Guchar fileKey[16]; // file decryption key | 105 | Guchar fileKey[16]; // file decryption key |
102 | GBool ownerPasswordOk;// true if owner password is correct | 106 | GBool ownerPasswordOk;// true if owner password is correct |
103 | #endif | 107 | #endif |
104 | 108 | ||
105 | int readTrailer(); | 109 | Guint readTrailer(); |
106 | GBool readXRef(int *pos); | 110 | GBool readXRef(Guint *pos); |
107 | GBool constructXRef(); | 111 | GBool constructXRef(); |
108 | GBool checkEncrypted(GString *ownerPassword, GString *userPassword); | 112 | GBool checkEncrypted(GString *ownerPassword, GString *userPassword); |
113 | Guint strToUnsigned(char *s); | ||
109 | }; | 114 | }; |
110 | 115 | ||
111 | #endif | 116 | #endif |