| @@ -1,963 +1,971 @@ | | | @@ -1,963 +1,971 @@ |
1 | /* $Xorg: bdfread.c,v 1.5 2001/02/09 02:04:01 xorgcvs Exp $ */ | | 1 | /* $Xorg: bdfread.c,v 1.5 2001/02/09 02:04:01 xorgcvs Exp $ */ |
2 | | | 2 | |
3 | /************************************************************************ | | 3 | /************************************************************************ |
4 | Copyright 1989 by Digital Equipment Corporation, Maynard, Massachusetts. | | 4 | Copyright 1989 by Digital Equipment Corporation, Maynard, Massachusetts. |
5 | | | 5 | |
6 | All Rights Reserved | | 6 | All Rights Reserved |
7 | | | 7 | |
8 | Permission to use, copy, modify, and distribute this software and its | | 8 | Permission to use, copy, modify, and distribute this software and its |
9 | documentation for any purpose and without fee is hereby granted, | | 9 | documentation for any purpose and without fee is hereby granted, |
10 | provided that the above copyright notice appear in all copies and that | | 10 | provided that the above copyright notice appear in all copies and that |
11 | both that copyright notice and this permission notice appear in | | 11 | both that copyright notice and this permission notice appear in |
12 | supporting documentation, and that the name of Digital not be | | 12 | supporting documentation, and that the name of Digital not be |
13 | used in advertising or publicity pertaining to distribution of the | | 13 | used in advertising or publicity pertaining to distribution of the |
14 | software without specific, written prior permission. | | 14 | software without specific, written prior permission. |
15 | | | 15 | |
16 | DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING | | 16 | DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING |
17 | ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL | | 17 | ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL |
18 | DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR | | 18 | DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR |
19 | ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, | | 19 | ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, |
20 | WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, | | 20 | WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, |
21 | ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS | | 21 | ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS |
22 | SOFTWARE. | | 22 | SOFTWARE. |
23 | | | 23 | |
24 | ************************************************************************/ | | 24 | ************************************************************************/ |
25 | | | 25 | |
26 | /* | | 26 | /* |
27 | | | 27 | |
28 | Copyright 1994, 1998 The Open Group | | 28 | Copyright 1994, 1998 The Open Group |
29 | | | 29 | |
30 | Permission to use, copy, modify, distribute, and sell this software and its | | 30 | Permission to use, copy, modify, distribute, and sell this software and its |
31 | documentation for any purpose is hereby granted without fee, provided that | | 31 | documentation for any purpose is hereby granted without fee, provided that |
32 | the above copyright notice appear in all copies and that both that | | 32 | the above copyright notice appear in all copies and that both that |
33 | copyright notice and this permission notice appear in supporting | | 33 | copyright notice and this permission notice appear in supporting |
34 | documentation. | | 34 | documentation. |
35 | | | 35 | |
36 | The above copyright notice and this permission notice shall be included | | 36 | The above copyright notice and this permission notice shall be included |
37 | in all copies or substantial portions of the Software. | | 37 | in all copies or substantial portions of the Software. |
38 | | | 38 | |
39 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | | 39 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
40 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | | 40 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
41 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | | 41 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
42 | IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR | | 42 | IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR |
43 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | | 43 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, |
44 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | | 44 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
45 | OTHER DEALINGS IN THE SOFTWARE. | | 45 | OTHER DEALINGS IN THE SOFTWARE. |
46 | | | 46 | |
47 | Except as contained in this notice, the name of The Open Group shall | | 47 | Except as contained in this notice, the name of The Open Group shall |
48 | not be used in advertising or otherwise to promote the sale, use or | | 48 | not be used in advertising or otherwise to promote the sale, use or |
49 | other dealings in this Software without prior written authorization | | 49 | other dealings in this Software without prior written authorization |
50 | from The Open Group. | | 50 | from The Open Group. |
51 | | | 51 | |
52 | */ | | 52 | */ |
53 | /* $XFree86: xc/lib/font/bitmap/bdfread.c,v 1.13 2003/05/27 22:26:48 tsi Exp $ */ | | 53 | /* $XFree86: xc/lib/font/bitmap/bdfread.c,v 1.13 2003/05/27 22:26:48 tsi Exp $ */ |
54 | | | 54 | |
55 | #ifndef FONTMODULE | | 55 | #ifndef FONTMODULE |
56 | #include <ctype.h> | | 56 | #include <ctype.h> |
57 | #endif | | 57 | #endif |
58 | #include "fntfilst.h" | | 58 | #include "fntfilst.h" |
59 | #include "fontutil.h" | | 59 | #include "fontutil.h" |
60 | /* use bitmap structure */ | | 60 | /* use bitmap structure */ |
61 | #include "bitmap.h" | | 61 | #include "bitmap.h" |
62 | #include "bdfint.h" | | 62 | #include "bdfint.h" |
63 | | | 63 | |
64 | #if HAVE_STDINT_H | | 64 | #if HAVE_STDINT_H |
65 | #include <stdint.h> | | 65 | #include <stdint.h> |
66 | #elif !defined(INT32_MAX) | | 66 | #elif !defined(INT32_MAX) |
67 | #define INT32_MAX 0x7fffffff | | 67 | #define INT32_MAX 0x7fffffff |
68 | #endif | | 68 | #endif |
69 | | | 69 | |
70 | #define INDICES 256 | | 70 | #define INDICES 256 |
71 | #define MAXENCODING 0xFFFF | | 71 | #define MAXENCODING 0xFFFF |
72 | #define BDFLINELEN 1024 | | 72 | #define BDFLINELEN 1024 |
| | | 73 | #define BDFLINESTR "%1023s" /* scanf specifier to read a BDFLINELEN string */ |
73 | | | 74 | |
74 | static Bool bdfPadToTerminal(FontPtr pFont); | | 75 | static Bool bdfPadToTerminal(FontPtr pFont); |
75 | extern int bdfFileLineNum; | | 76 | extern int bdfFileLineNum; |
76 | | | 77 | |
77 | /***====================================================================***/ | | 78 | /***====================================================================***/ |
78 | | | 79 | |
79 | static Bool | | 80 | static Bool |
80 | bdfReadBitmap(CharInfoPtr pCI, FontFilePtr file, int bit, int byte, | | 81 | bdfReadBitmap(CharInfoPtr pCI, FontFilePtr file, int bit, int byte, |
81 | int glyph, int scan, CARD32 *sizes) | | 82 | int glyph, int scan, CARD32 *sizes) |
82 | { | | 83 | { |
83 | int widthBits, | | 84 | int widthBits, |
84 | widthBytes, | | 85 | widthBytes, |
85 | widthHexChars; | | 86 | widthHexChars; |
86 | int height, | | 87 | int height, |
87 | row; | | 88 | row; |
88 | int i, | | 89 | int i, |
89 | inLineLen, | | 90 | inLineLen, |
90 | nextByte; | | 91 | nextByte; |
91 | unsigned char *pInBits, | | 92 | unsigned char *pInBits, |
92 | *picture, | | 93 | *picture, |
93 | *line = NULL; | | 94 | *line = NULL; |
94 | unsigned char lineBuf[BDFLINELEN]; | | 95 | unsigned char lineBuf[BDFLINELEN]; |
95 | | | 96 | |
96 | widthBits = GLYPHWIDTHPIXELS(pCI); | | 97 | widthBits = GLYPHWIDTHPIXELS(pCI); |
97 | height = GLYPHHEIGHTPIXELS(pCI); | | 98 | height = GLYPHHEIGHTPIXELS(pCI); |
98 | | | 99 | |
99 | widthBytes = BYTES_PER_ROW(widthBits, glyph); | | 100 | widthBytes = BYTES_PER_ROW(widthBits, glyph); |
100 | if (widthBytes * height > 0) { | | 101 | if (widthBytes * height > 0) { |
101 | picture = (unsigned char *) xalloc(widthBytes * height); | | 102 | picture = (unsigned char *) xalloc(widthBytes * height); |
102 | if (!picture) { | | 103 | if (!picture) { |
103 | bdfError("Couldn't allocate picture (%d*%d)\n", widthBytes, height); | | 104 | bdfError("Couldn't allocate picture (%d*%d)\n", widthBytes, height); |
104 | goto BAILOUT; | | 105 | goto BAILOUT; |
105 | } | | 106 | } |
106 | } else | | 107 | } else |
107 | picture = NULL; | | 108 | picture = NULL; |
108 | pCI->bits = (char *) picture; | | 109 | pCI->bits = (char *) picture; |
109 | | | 110 | |
110 | if (sizes) { | | 111 | if (sizes) { |
111 | for (i = 0; i < GLYPHPADOPTIONS; i++) | | 112 | for (i = 0; i < GLYPHPADOPTIONS; i++) |
112 | sizes[i] += BYTES_PER_ROW(widthBits, (1 << i)) * height; | | 113 | sizes[i] += BYTES_PER_ROW(widthBits, (1 << i)) * height; |
113 | } | | 114 | } |
114 | nextByte = 0; | | 115 | nextByte = 0; |
115 | widthHexChars = BYTES_PER_ROW(widthBits, 1); | | 116 | widthHexChars = BYTES_PER_ROW(widthBits, 1); |
116 | | | 117 | |
117 | /* 5/31/89 (ef) -- hack, hack, hack. what *am* I supposed to do with */ | | 118 | /* 5/31/89 (ef) -- hack, hack, hack. what *am* I supposed to do with */ |
118 | /* 0 width characters? */ | | 119 | /* 0 width characters? */ |
119 | | | 120 | |
120 | for (row = 0; row < height; row++) { | | 121 | for (row = 0; row < height; row++) { |
121 | line = bdfGetLine(file, lineBuf, BDFLINELEN); | | 122 | line = bdfGetLine(file, lineBuf, BDFLINELEN); |
122 | if (!line) | | 123 | if (!line) |
123 | break; | | 124 | break; |
124 | | | 125 | |
125 | if (widthBits == 0) { | | 126 | if (widthBits == 0) { |
126 | if ((!line) || (bdfIsPrefix(line, "ENDCHAR"))) | | 127 | if ((!line) || (bdfIsPrefix(line, "ENDCHAR"))) |
127 | break; | | 128 | break; |
128 | else | | 129 | else |
129 | continue; | | 130 | continue; |
130 | } | | 131 | } |
131 | pInBits = line; | | 132 | pInBits = line; |
132 | inLineLen = strlen((char *) pInBits); | | 133 | inLineLen = strlen((char *) pInBits); |
133 | | | 134 | |
134 | if (inLineLen & 1) { | | 135 | if (inLineLen & 1) { |
135 | bdfError("odd number of characters in hex encoding\n"); | | 136 | bdfError("odd number of characters in hex encoding\n"); |
136 | line[inLineLen++] = '0'; | | 137 | line[inLineLen++] = '0'; |
137 | line[inLineLen] = '\0'; | | 138 | line[inLineLen] = '\0'; |
138 | } | | 139 | } |
139 | inLineLen >>= 1; | | 140 | inLineLen >>= 1; |
140 | i = inLineLen; | | 141 | i = inLineLen; |
141 | if (i > widthHexChars) | | 142 | if (i > widthHexChars) |
142 | i = widthHexChars; | | 143 | i = widthHexChars; |
143 | for (; i > 0; i--, pInBits += 2) | | 144 | for (; i > 0; i--, pInBits += 2) |
144 | picture[nextByte++] = bdfHexByte(pInBits); | | 145 | picture[nextByte++] = bdfHexByte(pInBits); |
145 | | | 146 | |
146 | /* pad if line is too short */ | | 147 | /* pad if line is too short */ |
147 | if (inLineLen < widthHexChars) { | | 148 | if (inLineLen < widthHexChars) { |
148 | for (i = widthHexChars - inLineLen; i > 0; i--) | | 149 | for (i = widthHexChars - inLineLen; i > 0; i--) |
149 | picture[nextByte++] = 0; | | 150 | picture[nextByte++] = 0; |
150 | } else { | | 151 | } else { |
151 | unsigned char mask; | | 152 | unsigned char mask; |
152 | | | 153 | |
153 | mask = 0xff << (8 - (widthBits & 0x7)); | | 154 | mask = 0xff << (8 - (widthBits & 0x7)); |
154 | if (mask && picture[nextByte - 1] & ~mask) { | | 155 | if (mask && picture[nextByte - 1] & ~mask) { |
155 | picture[nextByte - 1] &= mask; | | 156 | picture[nextByte - 1] &= mask; |
156 | } | | 157 | } |
157 | } | | 158 | } |
158 | | | 159 | |
159 | if (widthBytes > widthHexChars) { | | 160 | if (widthBytes > widthHexChars) { |
160 | i = widthBytes - widthHexChars; | | 161 | i = widthBytes - widthHexChars; |
161 | while (i-- > 0) | | 162 | while (i-- > 0) |
162 | picture[nextByte++] = 0; | | 163 | picture[nextByte++] = 0; |
163 | } | | 164 | } |
164 | } | | 165 | } |
165 | | | 166 | |
166 | if ((line && (!bdfIsPrefix(line, "ENDCHAR"))) || (height == 0)) | | 167 | if ((line && (!bdfIsPrefix(line, "ENDCHAR"))) || (height == 0)) |
167 | line = bdfGetLine(file, lineBuf, BDFLINELEN); | | 168 | line = bdfGetLine(file, lineBuf, BDFLINELEN); |
168 | | | 169 | |
169 | if ((!line) || (!bdfIsPrefix(line, "ENDCHAR"))) { | | 170 | if ((!line) || (!bdfIsPrefix(line, "ENDCHAR"))) { |
170 | bdfError("missing 'ENDCHAR'\n"); | | 171 | bdfError("missing 'ENDCHAR'\n"); |
171 | goto BAILOUT; | | 172 | goto BAILOUT; |
172 | } | | 173 | } |
173 | if (nextByte != height * widthBytes) { | | 174 | if (nextByte != height * widthBytes) { |
174 | bdfError("bytes != rows * bytes_per_row (%d != %d * %d)\n", | | 175 | bdfError("bytes != rows * bytes_per_row (%d != %d * %d)\n", |
175 | nextByte, height, widthBytes); | | 176 | nextByte, height, widthBytes); |
176 | goto BAILOUT; | | 177 | goto BAILOUT; |
177 | } | | 178 | } |
178 | if (picture != NULL) { | | 179 | if (picture != NULL) { |
179 | if (bit == LSBFirst) | | 180 | if (bit == LSBFirst) |
180 | BitOrderInvert(picture, nextByte); | | 181 | BitOrderInvert(picture, nextByte); |
181 | if (bit != byte) { | | 182 | if (bit != byte) { |
182 | if (scan == 2) | | 183 | if (scan == 2) |
183 | TwoByteSwap(picture, nextByte); | | 184 | TwoByteSwap(picture, nextByte); |
184 | else if (scan == 4) | | 185 | else if (scan == 4) |
185 | FourByteSwap(picture, nextByte); | | 186 | FourByteSwap(picture, nextByte); |
186 | } | | 187 | } |
187 | } | | 188 | } |
188 | return (TRUE); | | 189 | return (TRUE); |
189 | BAILOUT: | | 190 | BAILOUT: |
190 | if (picture) | | 191 | if (picture) |
191 | xfree(picture); | | 192 | xfree(picture); |
192 | pCI->bits = NULL; | | 193 | pCI->bits = NULL; |
193 | return (FALSE); | | 194 | return (FALSE); |
194 | } | | 195 | } |
195 | | | 196 | |
196 | /***====================================================================***/ | | 197 | /***====================================================================***/ |
197 | | | 198 | |
198 | static Bool | | 199 | static Bool |
199 | bdfSkipBitmap(FontFilePtr file, int height) | | 200 | bdfSkipBitmap(FontFilePtr file, int height) |
200 | { | | 201 | { |
201 | unsigned char *line; | | 202 | unsigned char *line; |
202 | int i = 0; | | 203 | int i = 0; |
203 | unsigned char lineBuf[BDFLINELEN]; | | 204 | unsigned char lineBuf[BDFLINELEN]; |
204 | | | 205 | |
205 | do { | | 206 | do { |
206 | line = bdfGetLine(file, lineBuf, BDFLINELEN); | | 207 | line = bdfGetLine(file, lineBuf, BDFLINELEN); |
207 | i++; | | 208 | i++; |
208 | } while (line && !bdfIsPrefix(line, "ENDCHAR") && i <= height); | | 209 | } while (line && !bdfIsPrefix(line, "ENDCHAR") && i <= height); |
209 | | | 210 | |
210 | if (i > 1 && line && !bdfIsPrefix(line, "ENDCHAR")) { | | 211 | if (i > 1 && line && !bdfIsPrefix(line, "ENDCHAR")) { |
211 | bdfError("Error in bitmap, missing 'ENDCHAR'\n"); | | 212 | bdfError("Error in bitmap, missing 'ENDCHAR'\n"); |
212 | return (FALSE); | | 213 | return (FALSE); |
213 | } | | 214 | } |
214 | return (TRUE); | | 215 | return (TRUE); |
215 | } | | 216 | } |
216 | | | 217 | |
217 | /***====================================================================***/ | | 218 | /***====================================================================***/ |
218 | | | 219 | |
219 | static void | | 220 | static void |
220 | bdfFreeFontBits(FontPtr pFont) | | 221 | bdfFreeFontBits(FontPtr pFont) |
221 | { | | 222 | { |
222 | BitmapFontPtr bitmapFont; | | 223 | BitmapFontPtr bitmapFont; |
223 | BitmapExtraPtr bitmapExtra; | | 224 | BitmapExtraPtr bitmapExtra; |
224 | int i, nencoding; | | 225 | int i, nencoding; |
225 | | | 226 | |
226 | bitmapFont = (BitmapFontPtr) pFont->fontPrivate; | | 227 | bitmapFont = (BitmapFontPtr) pFont->fontPrivate; |
227 | bitmapExtra = (BitmapExtraPtr) bitmapFont->bitmapExtra; | | 228 | bitmapExtra = (BitmapExtraPtr) bitmapFont->bitmapExtra; |
228 | xfree(bitmapFont->ink_metrics); | | 229 | xfree(bitmapFont->ink_metrics); |
229 | if(bitmapFont->encoding) { | | 230 | if(bitmapFont->encoding) { |
230 | nencoding = (pFont->info.lastCol - pFont->info.firstCol + 1) * | | 231 | nencoding = (pFont->info.lastCol - pFont->info.firstCol + 1) * |
231 | (pFont->info.lastRow - pFont->info.firstRow + 1); | | 232 | (pFont->info.lastRow - pFont->info.firstRow + 1); |
232 | for(i=0; i<NUM_SEGMENTS(nencoding); i++) | | 233 | for(i=0; i<NUM_SEGMENTS(nencoding); i++) |
233 | xfree(bitmapFont->encoding[i]); | | 234 | xfree(bitmapFont->encoding[i]); |
234 | } | | 235 | } |
235 | xfree(bitmapFont->encoding); | | 236 | xfree(bitmapFont->encoding); |
236 | for (i = 0; i < bitmapFont->num_chars; i++) | | 237 | for (i = 0; i < bitmapFont->num_chars; i++) |
237 | xfree(bitmapFont->metrics[i].bits); | | 238 | xfree(bitmapFont->metrics[i].bits); |
238 | xfree(bitmapFont->metrics); | | 239 | xfree(bitmapFont->metrics); |
239 | if (bitmapExtra) | | 240 | if (bitmapExtra) |
240 | { | | 241 | { |
241 | xfree (bitmapExtra->glyphNames); | | 242 | xfree (bitmapExtra->glyphNames); |
242 | xfree (bitmapExtra->sWidths); | | 243 | xfree (bitmapExtra->sWidths); |
243 | xfree (bitmapExtra); | | 244 | xfree (bitmapExtra); |
244 | } | | 245 | } |
245 | xfree(pFont->info.props); | | 246 | xfree(pFont->info.props); |
246 | xfree(bitmapFont); | | 247 | xfree(bitmapFont); |
247 | } | | 248 | } |
248 | | | 249 | |
249 | | | 250 | |
250 | static Bool | | 251 | static Bool |
251 | bdfReadCharacters(FontFilePtr file, FontPtr pFont, bdfFileState *pState, | | 252 | bdfReadCharacters(FontFilePtr file, FontPtr pFont, bdfFileState *pState, |
252 | int bit, int byte, int glyph, int scan) | | 253 | int bit, int byte, int glyph, int scan) |
253 | { | | 254 | { |
254 | unsigned char *line; | | 255 | unsigned char *line; |
255 | register CharInfoPtr ci; | | 256 | register CharInfoPtr ci; |
256 | int i, | | 257 | int i, |
257 | ndx, | | 258 | ndx, |
258 | nchars, | | 259 | nchars, |
259 | nignored; | | 260 | nignored; |
260 | unsigned int char_row, char_col; | | 261 | unsigned int char_row, char_col; |
261 | int numEncodedGlyphs = 0; | | 262 | int numEncodedGlyphs = 0; |
262 | CharInfoPtr *bdfEncoding[256]; | | 263 | CharInfoPtr *bdfEncoding[256]; |
263 | BitmapFontPtr bitmapFont; | | 264 | BitmapFontPtr bitmapFont; |
264 | BitmapExtraPtr bitmapExtra; | | 265 | BitmapExtraPtr bitmapExtra; |
265 | CARD32 *bitmapsSizes; | | 266 | CARD32 *bitmapsSizes; |
266 | unsigned char lineBuf[BDFLINELEN]; | | 267 | unsigned char lineBuf[BDFLINELEN]; |
267 | int nencoding; | | 268 | int nencoding; |
268 | | | 269 | |
269 | bitmapFont = (BitmapFontPtr) pFont->fontPrivate; | | 270 | bitmapFont = (BitmapFontPtr) pFont->fontPrivate; |
270 | bitmapExtra = (BitmapExtraPtr) bitmapFont->bitmapExtra; | | 271 | bitmapExtra = (BitmapExtraPtr) bitmapFont->bitmapExtra; |
271 | | | 272 | |
272 | if (bitmapExtra) { | | 273 | if (bitmapExtra) { |
273 | bitmapsSizes = bitmapExtra->bitmapsSizes; | | 274 | bitmapsSizes = bitmapExtra->bitmapsSizes; |
274 | for (i = 0; i < GLYPHPADOPTIONS; i++) | | 275 | for (i = 0; i < GLYPHPADOPTIONS; i++) |
275 | bitmapsSizes[i] = 0; | | 276 | bitmapsSizes[i] = 0; |
276 | } else | | 277 | } else |
277 | bitmapsSizes = NULL; | | 278 | bitmapsSizes = NULL; |
278 | | | 279 | |
279 | bzero(bdfEncoding, sizeof(bdfEncoding)); | | 280 | bzero(bdfEncoding, sizeof(bdfEncoding)); |
280 | bitmapFont->metrics = NULL; | | 281 | bitmapFont->metrics = NULL; |
281 | ndx = 0; | | 282 | ndx = 0; |
282 | | | 283 | |
283 | line = bdfGetLine(file, lineBuf, BDFLINELEN); | | 284 | line = bdfGetLine(file, lineBuf, BDFLINELEN); |
284 | | | 285 | |
285 | if ((!line) || (sscanf((char *) line, "CHARS %d", &nchars) != 1)) { | | 286 | if ((!line) || (sscanf((char *) line, "CHARS %d", &nchars) != 1)) { |
286 | bdfError("bad 'CHARS' in bdf file\n"); | | 287 | bdfError("bad 'CHARS' in bdf file\n"); |
287 | return (FALSE); | | 288 | return (FALSE); |
288 | } | | 289 | } |
289 | if (nchars < 1) { | | 290 | if (nchars < 1) { |
290 | bdfError("invalid number of CHARS in BDF file\n"); | | 291 | bdfError("invalid number of CHARS in BDF file\n"); |
291 | return (FALSE); | | 292 | return (FALSE); |
292 | } | | 293 | } |
293 | if (nchars > INT32_MAX / sizeof(CharInfoRec)) { | | 294 | if (nchars > INT32_MAX / sizeof(CharInfoRec)) { |
294 | bdfError("Couldn't allocate pCI (%d*%d)\n", nchars, | | 295 | bdfError("Couldn't allocate pCI (%d*%d)\n", nchars, |
295 | sizeof(CharInfoRec)); | | 296 | sizeof(CharInfoRec)); |
296 | goto BAILOUT; | | 297 | goto BAILOUT; |
297 | } | | 298 | } |
298 | ci = (CharInfoPtr) xalloc(nchars * sizeof(CharInfoRec)); | | 299 | ci = (CharInfoPtr) xalloc(nchars * sizeof(CharInfoRec)); |
299 | if (!ci) { | | 300 | if (!ci) { |
300 | bdfError("Couldn't allocate pCI (%d*%d)\n", nchars, | | 301 | bdfError("Couldn't allocate pCI (%d*%d)\n", nchars, |
301 | sizeof(CharInfoRec)); | | 302 | sizeof(CharInfoRec)); |
302 | goto BAILOUT; | | 303 | goto BAILOUT; |
303 | } | | 304 | } |
304 | bzero((char *)ci, nchars * sizeof(CharInfoRec)); | | 305 | bzero((char *)ci, nchars * sizeof(CharInfoRec)); |
305 | bitmapFont->metrics = ci; | | 306 | bitmapFont->metrics = ci; |
306 | | | 307 | |
307 | if (bitmapExtra) { | | 308 | if (bitmapExtra) { |
308 | bitmapExtra->glyphNames = (Atom *) xalloc(nchars * sizeof(Atom)); | | 309 | bitmapExtra->glyphNames = (Atom *) xalloc(nchars * sizeof(Atom)); |
309 | if (!bitmapExtra->glyphNames) { | | 310 | if (!bitmapExtra->glyphNames) { |
310 | bdfError("Couldn't allocate glyphNames (%d*%d)\n", | | 311 | bdfError("Couldn't allocate glyphNames (%d*%d)\n", |
311 | nchars, sizeof(Atom)); | | 312 | nchars, sizeof(Atom)); |
312 | goto BAILOUT; | | 313 | goto BAILOUT; |
313 | } | | 314 | } |
314 | } | | 315 | } |
315 | if (bitmapExtra) { | | 316 | if (bitmapExtra) { |
316 | bitmapExtra->sWidths = (int *) xalloc(nchars * sizeof(int)); | | 317 | bitmapExtra->sWidths = (int *) xalloc(nchars * sizeof(int)); |
317 | if (!bitmapExtra->sWidths) { | | 318 | if (!bitmapExtra->sWidths) { |
318 | bdfError("Couldn't allocate sWidth (%d *%d)\n", | | 319 | bdfError("Couldn't allocate sWidth (%d *%d)\n", |
319 | nchars, sizeof(int)); | | 320 | nchars, sizeof(int)); |
320 | return FALSE; | | 321 | return FALSE; |
321 | } | | 322 | } |
322 | } | | 323 | } |
323 | line = bdfGetLine(file, lineBuf, BDFLINELEN); | | 324 | line = bdfGetLine(file, lineBuf, BDFLINELEN); |
324 | pFont->info.firstRow = 256; | | 325 | pFont->info.firstRow = 256; |
325 | pFont->info.lastRow = 0; | | 326 | pFont->info.lastRow = 0; |
326 | pFont->info.firstCol = 256; | | 327 | pFont->info.firstCol = 256; |
327 | pFont->info.lastCol = 0; | | 328 | pFont->info.lastCol = 0; |
328 | nignored = 0; | | 329 | nignored = 0; |
329 | for (ndx = 0; (ndx < nchars) && (line) && (bdfIsPrefix(line, "STARTCHAR"));) { | | 330 | for (ndx = 0; (ndx < nchars) && (line) && (bdfIsPrefix(line, "STARTCHAR"));) { |
330 | int t; | | 331 | int t; |
331 | int wx; /* x component of width */ | | 332 | int wx; /* x component of width */ |
332 | int wy; /* y component of width */ | | 333 | int wy; /* y component of width */ |
333 | int bw; /* bounding-box width */ | | 334 | int bw; /* bounding-box width */ |
334 | int bh; /* bounding-box height */ | | 335 | int bh; /* bounding-box height */ |
335 | int bl; /* bounding-box left */ | | 336 | int bl; /* bounding-box left */ |
336 | int bb; /* bounding-box bottom */ | | 337 | int bb; /* bounding-box bottom */ |
337 | int enc, | | 338 | int enc, |
338 | enc2; /* encoding */ | | 339 | enc2; /* encoding */ |
339 | unsigned char *p; /* temp pointer into line */ | | 340 | unsigned char *p; /* temp pointer into line */ |
340 | char charName[100]; | | 341 | char charName[100]; |
341 | int ignore; | | 342 | int ignore; |
342 | | | 343 | |
343 | if (sscanf((char *) line, "STARTCHAR %99s", charName) != 1) { | | 344 | if (sscanf((char *) line, "STARTCHAR %99s", charName) != 1) { |
344 | bdfError("bad character name in BDF file\n"); | | 345 | bdfError("bad character name in BDF file\n"); |
345 | goto BAILOUT; /* bottom of function, free and return error */ | | 346 | goto BAILOUT; /* bottom of function, free and return error */ |
346 | } | | 347 | } |
347 | if (bitmapExtra) | | 348 | if (bitmapExtra) |
348 | bitmapExtra->glyphNames[ndx] = bdfForceMakeAtom(charName, NULL); | | 349 | bitmapExtra->glyphNames[ndx] = bdfForceMakeAtom(charName, NULL); |
349 | | | 350 | |
350 | line = bdfGetLine(file, lineBuf, BDFLINELEN); | | 351 | line = bdfGetLine(file, lineBuf, BDFLINELEN); |
351 | if (!line || (t = sscanf((char *) line, "ENCODING %d %d", &enc, &enc2)) < 1) { | | 352 | if (!line || (t = sscanf((char *) line, "ENCODING %d %d", &enc, &enc2)) < 1) { |
352 | bdfError("bad 'ENCODING' in BDF file\n"); | | 353 | bdfError("bad 'ENCODING' in BDF file\n"); |
353 | goto BAILOUT; | | 354 | goto BAILOUT; |
354 | } | | 355 | } |
355 | if (enc < -1 || (t == 2 && enc2 < -1)) { | | 356 | if (enc < -1 || (t == 2 && enc2 < -1)) { |
356 | bdfError("bad ENCODING value"); | | 357 | bdfError("bad ENCODING value"); |
357 | goto BAILOUT; | | 358 | goto BAILOUT; |
358 | } | | 359 | } |
359 | if (t == 2 && enc == -1) | | 360 | if (t == 2 && enc == -1) |
360 | enc = enc2; | | 361 | enc = enc2; |
361 | ignore = 0; | | 362 | ignore = 0; |
362 | if (enc == -1) { | | 363 | if (enc == -1) { |
363 | if (!bitmapExtra) { | | 364 | if (!bitmapExtra) { |
364 | nignored++; | | 365 | nignored++; |
365 | ignore = 1; | | 366 | ignore = 1; |
366 | } | | 367 | } |
367 | } else if (enc > MAXENCODING) { | | 368 | } else if (enc > MAXENCODING) { |
368 | bdfError("char '%s' has encoding too large (%d)\n", | | 369 | bdfError("char '%s' has encoding too large (%d)\n", |
369 | charName, enc); | | 370 | charName, enc); |
370 | } else { | | 371 | } else { |
371 | char_row = (enc >> 8) & 0xFF; | | 372 | char_row = (enc >> 8) & 0xFF; |
372 | char_col = enc & 0xFF; | | 373 | char_col = enc & 0xFF; |
373 | if (char_row < pFont->info.firstRow) | | 374 | if (char_row < pFont->info.firstRow) |
374 | pFont->info.firstRow = char_row; | | 375 | pFont->info.firstRow = char_row; |
375 | if (char_row > pFont->info.lastRow) | | 376 | if (char_row > pFont->info.lastRow) |
376 | pFont->info.lastRow = char_row; | | 377 | pFont->info.lastRow = char_row; |
377 | if (char_col < pFont->info.firstCol) | | 378 | if (char_col < pFont->info.firstCol) |
378 | pFont->info.firstCol = char_col; | | 379 | pFont->info.firstCol = char_col; |
379 | if (char_col > pFont->info.lastCol) | | 380 | if (char_col > pFont->info.lastCol) |
380 | pFont->info.lastCol = char_col; | | 381 | pFont->info.lastCol = char_col; |
381 | if (bdfEncoding[char_row] == (CharInfoPtr *) NULL) { | | 382 | if (bdfEncoding[char_row] == (CharInfoPtr *) NULL) { |
382 | bdfEncoding[char_row] = | | 383 | bdfEncoding[char_row] = |
383 | (CharInfoPtr *) xalloc(256 * sizeof(CharInfoPtr)); | | 384 | (CharInfoPtr *) xalloc(256 * sizeof(CharInfoPtr)); |
384 | if (!bdfEncoding[char_row]) { | | 385 | if (!bdfEncoding[char_row]) { |
385 | bdfError("Couldn't allocate row %d of encoding (%d*%d)\n", | | 386 | bdfError("Couldn't allocate row %d of encoding (%d*%d)\n", |
386 | char_row, INDICES, sizeof(CharInfoPtr)); | | 387 | char_row, INDICES, sizeof(CharInfoPtr)); |
387 | goto BAILOUT; | | 388 | goto BAILOUT; |
388 | } | | 389 | } |
389 | for (i = 0; i < 256; i++) | | 390 | for (i = 0; i < 256; i++) |
390 | bdfEncoding[char_row][i] = (CharInfoPtr) NULL; | | 391 | bdfEncoding[char_row][i] = (CharInfoPtr) NULL; |
391 | } | | 392 | } |
392 | if (bdfEncoding[char_row] != NULL) { | | 393 | if (bdfEncoding[char_row] != NULL) { |
393 | bdfEncoding[char_row][char_col] = ci; | | 394 | bdfEncoding[char_row][char_col] = ci; |
394 | numEncodedGlyphs++; | | 395 | numEncodedGlyphs++; |
395 | } | | 396 | } |
396 | } | | 397 | } |
397 | | | 398 | |
398 | line = bdfGetLine(file, lineBuf, BDFLINELEN); | | 399 | line = bdfGetLine(file, lineBuf, BDFLINELEN); |
399 | if ((!line) || (sscanf((char *) line, "SWIDTH %d %d", &wx, &wy) != 2)) { | | 400 | if ((!line) || (sscanf((char *) line, "SWIDTH %d %d", &wx, &wy) != 2)) { |
400 | bdfError("bad 'SWIDTH'\n"); | | 401 | bdfError("bad 'SWIDTH'\n"); |
401 | goto BAILOUT; | | 402 | goto BAILOUT; |
402 | } | | 403 | } |
403 | if (wy != 0) { | | 404 | if (wy != 0) { |
404 | bdfError("SWIDTH y value must be zero\n"); | | 405 | bdfError("SWIDTH y value must be zero\n"); |
405 | goto BAILOUT; | | 406 | goto BAILOUT; |
406 | } | | 407 | } |
407 | if (bitmapExtra) | | 408 | if (bitmapExtra) |
408 | bitmapExtra->sWidths[ndx] = wx; | | 409 | bitmapExtra->sWidths[ndx] = wx; |
409 | | | 410 | |
410 | /* 5/31/89 (ef) -- we should be able to ditch the character and recover */ | | 411 | /* 5/31/89 (ef) -- we should be able to ditch the character and recover */ |
411 | /* from all of these. */ | | 412 | /* from all of these. */ |
412 | | | 413 | |
413 | line = bdfGetLine(file, lineBuf, BDFLINELEN); | | 414 | line = bdfGetLine(file, lineBuf, BDFLINELEN); |
414 | if ((!line) || (sscanf((char *) line, "DWIDTH %d %d", &wx, &wy) != 2)) { | | 415 | if ((!line) || (sscanf((char *) line, "DWIDTH %d %d", &wx, &wy) != 2)) { |
415 | bdfError("bad 'DWIDTH'\n"); | | 416 | bdfError("bad 'DWIDTH'\n"); |
416 | goto BAILOUT; | | 417 | goto BAILOUT; |
417 | } | | 418 | } |
418 | if (wy != 0) { | | 419 | if (wy != 0) { |
419 | bdfError("DWIDTH y value must be zero\n"); | | 420 | bdfError("DWIDTH y value must be zero\n"); |
420 | goto BAILOUT; | | 421 | goto BAILOUT; |
421 | } | | 422 | } |
422 | line = bdfGetLine(file, lineBuf, BDFLINELEN); | | 423 | line = bdfGetLine(file, lineBuf, BDFLINELEN); |
423 | if ((!line) || (sscanf((char *) line, "BBX %d %d %d %d", &bw, &bh, &bl, &bb) != 4)) { | | 424 | if ((!line) || (sscanf((char *) line, "BBX %d %d %d %d", &bw, &bh, &bl, &bb) != 4)) { |
424 | bdfError("bad 'BBX'\n"); | | 425 | bdfError("bad 'BBX'\n"); |
425 | goto BAILOUT; | | 426 | goto BAILOUT; |
426 | } | | 427 | } |
427 | if ((bh < 0) || (bw < 0)) { | | 428 | if ((bh < 0) || (bw < 0)) { |
428 | bdfError("character '%s' has a negative sized bitmap, %dx%d\n", | | 429 | bdfError("character '%s' has a negative sized bitmap, %dx%d\n", |
429 | charName, bw, bh); | | 430 | charName, bw, bh); |
430 | goto BAILOUT; | | 431 | goto BAILOUT; |
431 | } | | 432 | } |
432 | line = bdfGetLine(file, lineBuf, BDFLINELEN); | | 433 | line = bdfGetLine(file, lineBuf, BDFLINELEN); |
433 | if ((line) && (bdfIsPrefix(line, "ATTRIBUTES"))) { | | 434 | if ((line) && (bdfIsPrefix(line, "ATTRIBUTES"))) { |
434 | for (p = line + strlen("ATTRIBUTES "); | | 435 | for (p = line + strlen("ATTRIBUTES "); |
435 | (*p == ' ') || (*p == '\t'); | | 436 | (*p == ' ') || (*p == '\t'); |
436 | p++) | | 437 | p++) |
437 | /* empty for loop */ ; | | 438 | /* empty for loop */ ; |
438 | ci->metrics.attributes = (bdfHexByte(p) << 8) + bdfHexByte(p + 2); | | 439 | ci->metrics.attributes = (bdfHexByte(p) << 8) + bdfHexByte(p + 2); |
439 | line = bdfGetLine(file, lineBuf, BDFLINELEN); | | 440 | line = bdfGetLine(file, lineBuf, BDFLINELEN); |
440 | } else | | 441 | } else |
441 | ci->metrics.attributes = 0; | | 442 | ci->metrics.attributes = 0; |
442 | | | 443 | |
443 | if (!line || !bdfIsPrefix(line, "BITMAP")) { | | 444 | if (!line || !bdfIsPrefix(line, "BITMAP")) { |
444 | bdfError("missing 'BITMAP'\n"); | | 445 | bdfError("missing 'BITMAP'\n"); |
445 | goto BAILOUT; | | 446 | goto BAILOUT; |
446 | } | | 447 | } |
447 | /* collect data for generated properties */ | | 448 | /* collect data for generated properties */ |
448 | if ((strlen(charName) == 1)) { | | 449 | if ((strlen(charName) == 1)) { |
449 | if ((charName[0] >= '0') && (charName[0] <= '9')) { | | 450 | if ((charName[0] >= '0') && (charName[0] <= '9')) { |
450 | pState->digitWidths += wx; | | 451 | pState->digitWidths += wx; |
451 | pState->digitCount++; | | 452 | pState->digitCount++; |
452 | } else if (charName[0] == 'x') { | | 453 | } else if (charName[0] == 'x') { |
453 | pState->exHeight = (bh + bb) <= 0 ? bh : bh + bb; | | 454 | pState->exHeight = (bh + bb) <= 0 ? bh : bh + bb; |
454 | } | | 455 | } |
455 | } | | 456 | } |
456 | if (!ignore) { | | 457 | if (!ignore) { |
457 | ci->metrics.leftSideBearing = bl; | | 458 | ci->metrics.leftSideBearing = bl; |
458 | ci->metrics.rightSideBearing = bl + bw; | | 459 | ci->metrics.rightSideBearing = bl + bw; |
459 | ci->metrics.ascent = bh + bb; | | 460 | ci->metrics.ascent = bh + bb; |
460 | ci->metrics.descent = -bb; | | 461 | ci->metrics.descent = -bb; |
461 | ci->metrics.characterWidth = wx; | | 462 | ci->metrics.characterWidth = wx; |
462 | ci->bits = NULL; | | 463 | ci->bits = NULL; |
463 | bdfReadBitmap(ci, file, bit, byte, glyph, scan, bitmapsSizes); | | 464 | bdfReadBitmap(ci, file, bit, byte, glyph, scan, bitmapsSizes); |
464 | ci++; | | 465 | ci++; |
465 | ndx++; | | 466 | ndx++; |
466 | } else | | 467 | } else |
467 | bdfSkipBitmap(file, bh); | | 468 | bdfSkipBitmap(file, bh); |
468 | | | 469 | |
469 | line = bdfGetLine(file, lineBuf, BDFLINELEN); /* get STARTCHAR or | | 470 | line = bdfGetLine(file, lineBuf, BDFLINELEN); /* get STARTCHAR or |
470 | * ENDFONT */ | | 471 | * ENDFONT */ |
471 | } | | 472 | } |
472 | | | 473 | |
473 | if (ndx + nignored != nchars) { | | 474 | if (ndx + nignored != nchars) { |
474 | bdfError("%d too few characters\n", nchars - (ndx + nignored)); | | 475 | bdfError("%d too few characters\n", nchars - (ndx + nignored)); |
475 | goto BAILOUT; | | 476 | goto BAILOUT; |
476 | } | | 477 | } |
477 | nchars = ndx; | | 478 | nchars = ndx; |
478 | bitmapFont->num_chars = nchars; | | 479 | bitmapFont->num_chars = nchars; |
479 | if ((line) && (bdfIsPrefix(line, "STARTCHAR"))) { | | 480 | if ((line) && (bdfIsPrefix(line, "STARTCHAR"))) { |
480 | bdfError("more characters than specified\n"); | | 481 | bdfError("more characters than specified\n"); |
481 | goto BAILOUT; | | 482 | goto BAILOUT; |
482 | } | | 483 | } |
483 | if ((!line) || (!bdfIsPrefix(line, "ENDFONT"))) { | | 484 | if ((!line) || (!bdfIsPrefix(line, "ENDFONT"))) { |
484 | bdfError("missing 'ENDFONT'\n"); | | 485 | bdfError("missing 'ENDFONT'\n"); |
485 | goto BAILOUT; | | 486 | goto BAILOUT; |
486 | } | | 487 | } |
487 | if (numEncodedGlyphs == 0) | | 488 | if (numEncodedGlyphs == 0) |
488 | bdfWarning("No characters with valid encodings\n"); | | 489 | bdfWarning("No characters with valid encodings\n"); |
489 | | | 490 | |
490 | nencoding = (pFont->info.lastRow - pFont->info.firstRow + 1) * | | 491 | nencoding = (pFont->info.lastRow - pFont->info.firstRow + 1) * |
491 | (pFont->info.lastCol - pFont->info.firstCol + 1); | | 492 | (pFont->info.lastCol - pFont->info.firstCol + 1); |
492 | bitmapFont->encoding = | | 493 | bitmapFont->encoding = |
493 | (CharInfoPtr **) xcalloc(NUM_SEGMENTS(nencoding), | | 494 | (CharInfoPtr **) xcalloc(NUM_SEGMENTS(nencoding), |
494 | sizeof(CharInfoPtr*)); | | 495 | sizeof(CharInfoPtr*)); |
495 | if (!bitmapFont->encoding) { | | 496 | if (!bitmapFont->encoding) { |
496 | bdfError("Couldn't allocate ppCI (%d,%d)\n", | | 497 | bdfError("Couldn't allocate ppCI (%d,%d)\n", |
497 | NUM_SEGMENTS(nencoding), | | 498 | NUM_SEGMENTS(nencoding), |
498 | sizeof(CharInfoPtr*)); | | 499 | sizeof(CharInfoPtr*)); |
499 | goto BAILOUT; | | 500 | goto BAILOUT; |
500 | } | | 501 | } |
501 | pFont->info.allExist = TRUE; | | 502 | pFont->info.allExist = TRUE; |
502 | i = 0; | | 503 | i = 0; |
503 | for (char_row = pFont->info.firstRow; | | 504 | for (char_row = pFont->info.firstRow; |
504 | char_row <= pFont->info.lastRow; | | 505 | char_row <= pFont->info.lastRow; |
505 | char_row++) { | | 506 | char_row++) { |
506 | if (bdfEncoding[char_row] == (CharInfoPtr *) NULL) { | | 507 | if (bdfEncoding[char_row] == (CharInfoPtr *) NULL) { |
507 | pFont->info.allExist = FALSE; | | 508 | pFont->info.allExist = FALSE; |
508 | i += pFont->info.lastCol - pFont->info.firstCol + 1; | | 509 | i += pFont->info.lastCol - pFont->info.firstCol + 1; |
509 | } else { | | 510 | } else { |
510 | for (char_col = pFont->info.firstCol; | | 511 | for (char_col = pFont->info.firstCol; |
511 | char_col <= pFont->info.lastCol; | | 512 | char_col <= pFont->info.lastCol; |
512 | char_col++) { | | 513 | char_col++) { |
513 | if (!bdfEncoding[char_row][char_col]) | | 514 | if (!bdfEncoding[char_row][char_col]) |
514 | pFont->info.allExist = FALSE; | | 515 | pFont->info.allExist = FALSE; |
515 | else { | | 516 | else { |
516 | if (!bitmapFont->encoding[SEGMENT_MAJOR(i)]) { | | 517 | if (!bitmapFont->encoding[SEGMENT_MAJOR(i)]) { |
517 | bitmapFont->encoding[SEGMENT_MAJOR(i)]= | | 518 | bitmapFont->encoding[SEGMENT_MAJOR(i)]= |
518 | (CharInfoPtr*)xcalloc(BITMAP_FONT_SEGMENT_SIZE, | | 519 | (CharInfoPtr*)xcalloc(BITMAP_FONT_SEGMENT_SIZE, |
519 | sizeof(CharInfoPtr)); | | 520 | sizeof(CharInfoPtr)); |
520 | if (!bitmapFont->encoding[SEGMENT_MAJOR(i)]) | | 521 | if (!bitmapFont->encoding[SEGMENT_MAJOR(i)]) |
521 | goto BAILOUT; | | 522 | goto BAILOUT; |
522 | } | | 523 | } |
523 | ACCESSENCODINGL(bitmapFont->encoding,i) = | | 524 | ACCESSENCODINGL(bitmapFont->encoding,i) = |
524 | bdfEncoding[char_row][char_col]; | | 525 | bdfEncoding[char_row][char_col]; |
525 | } | | 526 | } |
526 | i++; | | 527 | i++; |
527 | } | | 528 | } |
528 | } | | 529 | } |
529 | } | | 530 | } |
530 | for (i = 0; i < 256; i++) | | 531 | for (i = 0; i < 256; i++) |
531 | if (bdfEncoding[i]) | | 532 | if (bdfEncoding[i]) |
532 | xfree(bdfEncoding[i]); | | 533 | xfree(bdfEncoding[i]); |
533 | return (TRUE); | | 534 | return (TRUE); |
534 | BAILOUT: | | 535 | BAILOUT: |
535 | for (i = 0; i < 256; i++) | | 536 | for (i = 0; i < 256; i++) |
536 | if (bdfEncoding[i]) | | 537 | if (bdfEncoding[i]) |
537 | xfree(bdfEncoding[i]); | | 538 | xfree(bdfEncoding[i]); |
538 | /* bdfFreeFontBits will clean up the rest */ | | 539 | /* bdfFreeFontBits will clean up the rest */ |
539 | return (FALSE); | | 540 | return (FALSE); |
540 | } | | 541 | } |
541 | | | 542 | |
542 | /***====================================================================***/ | | 543 | /***====================================================================***/ |
543 | | | 544 | |
544 | static Bool | | 545 | static Bool |
545 | bdfReadHeader(FontFilePtr file, bdfFileState *pState) | | 546 | bdfReadHeader(FontFilePtr file, bdfFileState *pState) |
546 | { | | 547 | { |
547 | unsigned char *line; | | 548 | unsigned char *line; |
548 | char namebuf[BDFLINELEN]; | | 549 | char namebuf[BDFLINELEN]; |
549 | unsigned char lineBuf[BDFLINELEN]; | | 550 | unsigned char lineBuf[BDFLINELEN]; |
550 | | | 551 | |
551 | line = bdfGetLine(file, lineBuf, BDFLINELEN); | | 552 | line = bdfGetLine(file, lineBuf, BDFLINELEN); |
552 | if (!line || sscanf((char *) line, "STARTFONT %s", namebuf) != 1 || | | 553 | if (!line || |
| | | 554 | sscanf((char *) line, "STARTFONT " BDFLINESTR, namebuf) != 1 || |
553 | !bdfStrEqual(namebuf, "2.1")) { | | 555 | !bdfStrEqual(namebuf, "2.1")) { |
554 | bdfError("bad 'STARTFONT'\n"); | | 556 | bdfError("bad 'STARTFONT'\n"); |
555 | return (FALSE); | | 557 | return (FALSE); |
556 | } | | 558 | } |
557 | line = bdfGetLine(file, lineBuf, BDFLINELEN); | | 559 | line = bdfGetLine(file, lineBuf, BDFLINELEN); |
558 | if (!line || sscanf((char *) line, "FONT %[^\n]", pState->fontName) != 1) { | | 560 | #if MAXFONTNAMELEN != 1024 |
| | | 561 | # error "need to adjust sscanf length limit to be MAXFONTNAMELEN - 1" |
| | | 562 | #endif |
| | | 563 | if (!line || |
| | | 564 | sscanf((char *) line, "FONT %1023[^\n]", pState->fontName) != 1) { |
559 | bdfError("bad 'FONT'\n"); | | 565 | bdfError("bad 'FONT'\n"); |
560 | return (FALSE); | | 566 | return (FALSE); |
561 | } | | 567 | } |
562 | line = bdfGetLine(file, lineBuf, BDFLINELEN); | | 568 | line = bdfGetLine(file, lineBuf, BDFLINELEN); |
563 | if (!line || !bdfIsPrefix(line, "SIZE")) { | | 569 | if (!line || !bdfIsPrefix(line, "SIZE")) { |
564 | bdfError("missing 'SIZE'\n"); | | 570 | bdfError("missing 'SIZE'\n"); |
565 | return (FALSE); | | 571 | return (FALSE); |
566 | } | | 572 | } |
567 | if (sscanf((char *) line, "SIZE %f%d%d", &pState->pointSize, | | 573 | if (sscanf((char *) line, "SIZE %f%d%d", &pState->pointSize, |
568 | &pState->resolution_x, &pState->resolution_y) != 3) { | | 574 | &pState->resolution_x, &pState->resolution_y) != 3) { |
569 | bdfError("bad 'SIZE'\n"); | | 575 | bdfError("bad 'SIZE'\n"); |
570 | return (FALSE); | | 576 | return (FALSE); |
571 | } | | 577 | } |
572 | if (pState->pointSize < 1 || | | 578 | if (pState->pointSize < 1 || |
573 | pState->resolution_x < 1 || pState->resolution_y < 1) { | | 579 | pState->resolution_x < 1 || pState->resolution_y < 1) { |
574 | bdfError("SIZE values must be > 0\n"); | | 580 | bdfError("SIZE values must be > 0\n"); |
575 | return (FALSE); | | 581 | return (FALSE); |
576 | } | | 582 | } |
577 | line = bdfGetLine(file, lineBuf, BDFLINELEN); | | 583 | line = bdfGetLine(file, lineBuf, BDFLINELEN); |
578 | if (!line || !bdfIsPrefix(line, "FONTBOUNDINGBOX")) { | | 584 | if (!line || !bdfIsPrefix(line, "FONTBOUNDINGBOX")) { |
579 | bdfError("missing 'FONTBOUNDINGBOX'\n"); | | 585 | bdfError("missing 'FONTBOUNDINGBOX'\n"); |
580 | return (FALSE); | | 586 | return (FALSE); |
581 | } | | 587 | } |
582 | return (TRUE); | | 588 | return (TRUE); |
583 | } | | 589 | } |
584 | | | 590 | |
585 | /***====================================================================***/ | | 591 | /***====================================================================***/ |
586 | | | 592 | |
587 | static Bool | | 593 | static Bool |
588 | bdfReadProperties(FontFilePtr file, FontPtr pFont, bdfFileState *pState) | | 594 | bdfReadProperties(FontFilePtr file, FontPtr pFont, bdfFileState *pState) |
589 | { | | 595 | { |
590 | int nProps, props_left, | | 596 | int nProps, props_left, |
591 | nextProp; | | 597 | nextProp; |
592 | char *stringProps; | | 598 | char *stringProps; |
593 | FontPropPtr props; | | 599 | FontPropPtr props; |
594 | char namebuf[BDFLINELEN], | | 600 | char namebuf[BDFLINELEN], |
595 | secondbuf[BDFLINELEN], | | 601 | secondbuf[BDFLINELEN], |
596 | thirdbuf[BDFLINELEN]; | | 602 | thirdbuf[BDFLINELEN]; |
597 | unsigned char *line; | | 603 | unsigned char *line; |
598 | unsigned char lineBuf[BDFLINELEN]; | | 604 | unsigned char lineBuf[BDFLINELEN]; |
599 | BitmapFontPtr bitmapFont = (BitmapFontPtr) pFont->fontPrivate; | | 605 | BitmapFontPtr bitmapFont = (BitmapFontPtr) pFont->fontPrivate; |
600 | | | 606 | |
601 | line = bdfGetLine(file, lineBuf, BDFLINELEN); | | 607 | line = bdfGetLine(file, lineBuf, BDFLINELEN); |
602 | if (!line || !bdfIsPrefix(line, "STARTPROPERTIES")) { | | 608 | if (!line || !bdfIsPrefix(line, "STARTPROPERTIES")) { |
603 | bdfError("missing 'STARTPROPERTIES'\n"); | | 609 | bdfError("missing 'STARTPROPERTIES'\n"); |
604 | return (FALSE); | | 610 | return (FALSE); |
605 | } | | 611 | } |
606 | if (sscanf((char *) line, "STARTPROPERTIES %d", &nProps) != 1) { | | 612 | if (sscanf((char *) line, "STARTPROPERTIES %d", &nProps) != 1) { |
607 | bdfError("bad 'STARTPROPERTIES'\n"); | | 613 | bdfError("bad 'STARTPROPERTIES'\n"); |
608 | return (FALSE); | | 614 | return (FALSE); |
609 | } | | 615 | } |
610 | pFont->info.isStringProp = NULL; | | 616 | pFont->info.isStringProp = NULL; |
611 | pFont->info.props = NULL; | | 617 | pFont->info.props = NULL; |
612 | pFont->info.nprops = 0; | | 618 | pFont->info.nprops = 0; |
613 | | | 619 | |
614 | stringProps = (char *) xalloc((nProps + BDF_GENPROPS) * sizeof(char)); | | 620 | stringProps = (char *) xalloc((nProps + BDF_GENPROPS) * sizeof(char)); |
615 | pFont->info.isStringProp = stringProps; | | 621 | pFont->info.isStringProp = stringProps; |
616 | if (stringProps == NULL) { | | 622 | if (stringProps == NULL) { |
617 | bdfError("Couldn't allocate stringProps (%d*%d)\n", | | 623 | bdfError("Couldn't allocate stringProps (%d*%d)\n", |
618 | (nProps + BDF_GENPROPS), sizeof(Bool)); | | 624 | (nProps + BDF_GENPROPS), sizeof(Bool)); |
619 | goto BAILOUT; | | 625 | goto BAILOUT; |
620 | } | | 626 | } |
621 | pFont->info.props = props = (FontPropPtr) xalloc((nProps + BDF_GENPROPS) * | | 627 | pFont->info.props = props = (FontPropPtr) xalloc((nProps + BDF_GENPROPS) * |
622 | sizeof(FontPropRec)); | | 628 | sizeof(FontPropRec)); |
623 | if (props == NULL) { | | 629 | if (props == NULL) { |
624 | bdfError("Couldn't allocate props (%d*%d)\n", nProps + BDF_GENPROPS, | | 630 | bdfError("Couldn't allocate props (%d*%d)\n", nProps + BDF_GENPROPS, |
625 | sizeof(FontPropRec)); | | 631 | sizeof(FontPropRec)); |
626 | goto BAILOUT; | | 632 | goto BAILOUT; |
627 | } | | 633 | } |
628 | bzero((char *)props, (nProps + BDF_GENPROPS) * sizeof(FontPropRec)); | | 634 | bzero((char *)props, (nProps + BDF_GENPROPS) * sizeof(FontPropRec)); |
629 | | | 635 | |
630 | nextProp = 0; | | 636 | nextProp = 0; |
631 | props_left = nProps; | | 637 | props_left = nProps; |
632 | while (props_left-- > 0) { | | 638 | while (props_left-- > 0) { |
633 | line = bdfGetLine(file, lineBuf, BDFLINELEN); | | 639 | line = bdfGetLine(file, lineBuf, BDFLINELEN); |
634 | if (line == NULL || bdfIsPrefix(line, "ENDPROPERTIES")) { | | 640 | if (line == NULL || bdfIsPrefix(line, "ENDPROPERTIES")) { |
635 | bdfError("\"STARTPROPERTIES %d\" followed by only %d properties\n", | | 641 | bdfError("\"STARTPROPERTIES %d\" followed by only %d properties\n", |
636 | nProps, nProps - props_left - 1); | | 642 | nProps, nProps - props_left - 1); |
637 | goto BAILOUT; | | 643 | goto BAILOUT; |
638 | } | | 644 | } |
639 | while (*line && isspace(*line)) | | 645 | while (*line && isspace(*line)) |
640 | line++; | | 646 | line++; |
641 | | | 647 | |
642 | switch (sscanf((char *) line, "%s%s%s", namebuf, secondbuf, thirdbuf)) { | | 648 | switch (sscanf((char *) line, |
| | | 649 | BDFLINESTR BDFLINESTR BDFLINESTR, |
| | | 650 | namebuf, secondbuf, thirdbuf)) { |
643 | default: | | 651 | default: |
644 | bdfError("missing '%s' parameter value\n", namebuf); | | 652 | bdfError("missing '%s' parameter value\n", namebuf); |
645 | goto BAILOUT; | | 653 | goto BAILOUT; |
646 | | | 654 | |
647 | case 2: | | 655 | case 2: |
648 | /* | | 656 | /* |
649 | * Possibilites include: valid quoted string with no white space | | 657 | * Possibilites include: valid quoted string with no white space |
650 | * valid integer value invalid value | | 658 | * valid integer value invalid value |
651 | */ | | 659 | */ |
652 | if (secondbuf[0] == '"') { | | 660 | if (secondbuf[0] == '"') { |
653 | stringProps[nextProp] = TRUE; | | 661 | stringProps[nextProp] = TRUE; |
654 | props[nextProp].value = | | 662 | props[nextProp].value = |
655 | bdfGetPropertyValue((char *)line + strlen(namebuf) + 1); | | 663 | bdfGetPropertyValue((char *)line + strlen(namebuf) + 1); |
656 | if (!props[nextProp].value) | | 664 | if (!props[nextProp].value) |
657 | goto BAILOUT; | | 665 | goto BAILOUT; |
658 | break; | | 666 | break; |
659 | } else if (bdfIsInteger(secondbuf)) { | | 667 | } else if (bdfIsInteger(secondbuf)) { |
660 | stringProps[nextProp] = FALSE; | | 668 | stringProps[nextProp] = FALSE; |
661 | props[nextProp].value = atoi(secondbuf); | | 669 | props[nextProp].value = atoi(secondbuf); |
662 | break; | | 670 | break; |
663 | } else { | | 671 | } else { |
664 | bdfError("invalid '%s' parameter value\n", namebuf); | | 672 | bdfError("invalid '%s' parameter value\n", namebuf); |
665 | goto BAILOUT; | | 673 | goto BAILOUT; |
666 | } | | 674 | } |
667 | | | 675 | |
668 | case 3: | | 676 | case 3: |
669 | /* | | 677 | /* |
670 | * Possibilites include: valid quoted string with some white space | | 678 | * Possibilites include: valid quoted string with some white space |
671 | * invalid value (reject even if second string is integer) | | 679 | * invalid value (reject even if second string is integer) |
672 | */ | | 680 | */ |
673 | if (secondbuf[0] == '"') { | | 681 | if (secondbuf[0] == '"') { |
674 | stringProps[nextProp] = TRUE; | | 682 | stringProps[nextProp] = TRUE; |
675 | props[nextProp].value = | | 683 | props[nextProp].value = |
676 | bdfGetPropertyValue((char *)line + strlen(namebuf) + 1); | | 684 | bdfGetPropertyValue((char *)line + strlen(namebuf) + 1); |
677 | if (!props[nextProp].value) | | 685 | if (!props[nextProp].value) |
678 | goto BAILOUT; | | 686 | goto BAILOUT; |
679 | break; | | 687 | break; |
680 | } else { | | 688 | } else { |
681 | bdfError("invalid '%s' parameter value\n", namebuf); | | 689 | bdfError("invalid '%s' parameter value\n", namebuf); |
682 | goto BAILOUT; | | 690 | goto BAILOUT; |
683 | } | | 691 | } |
684 | } | | 692 | } |
685 | props[nextProp].name = bdfForceMakeAtom(namebuf, NULL); | | 693 | props[nextProp].name = bdfForceMakeAtom(namebuf, NULL); |
686 | if (props[nextProp].name == None) { | | 694 | if (props[nextProp].name == None) { |
687 | bdfError("Empty property name.\n"); | | 695 | bdfError("Empty property name.\n"); |
688 | goto BAILOUT; | | 696 | goto BAILOUT; |
689 | } | | 697 | } |
690 | if (!bdfSpecialProperty(pFont, &props[nextProp], | | 698 | if (!bdfSpecialProperty(pFont, &props[nextProp], |
691 | stringProps[nextProp], pState)) | | 699 | stringProps[nextProp], pState)) |
692 | nextProp++; | | 700 | nextProp++; |
693 | } | | 701 | } |
694 | | | 702 | |
695 | line = bdfGetLine(file, lineBuf, BDFLINELEN); | | 703 | line = bdfGetLine(file, lineBuf, BDFLINELEN); |
696 | if (!line || !bdfIsPrefix(line, "ENDPROPERTIES")) { | | 704 | if (!line || !bdfIsPrefix(line, "ENDPROPERTIES")) { |
697 | bdfError("missing 'ENDPROPERTIES'\n"); | | 705 | bdfError("missing 'ENDPROPERTIES'\n"); |
698 | goto BAILOUT; | | 706 | goto BAILOUT; |
699 | } | | 707 | } |
700 | if (!pState->haveFontAscent || !pState->haveFontDescent) { | | 708 | if (!pState->haveFontAscent || !pState->haveFontDescent) { |
701 | bdfError("missing 'FONT_ASCENT' or 'FONT_DESCENT' properties\n"); | | 709 | bdfError("missing 'FONT_ASCENT' or 'FONT_DESCENT' properties\n"); |
702 | goto BAILOUT; | | 710 | goto BAILOUT; |
703 | } | | 711 | } |
704 | if (bitmapFont->bitmapExtra) { | | 712 | if (bitmapFont->bitmapExtra) { |
705 | bitmapFont->bitmapExtra->info.fontAscent = pFont->info.fontAscent; | | 713 | bitmapFont->bitmapExtra->info.fontAscent = pFont->info.fontAscent; |
706 | bitmapFont->bitmapExtra->info.fontDescent = pFont->info.fontDescent; | | 714 | bitmapFont->bitmapExtra->info.fontDescent = pFont->info.fontDescent; |
707 | } | | 715 | } |
708 | if (!pState->pointSizeProp) { | | 716 | if (!pState->pointSizeProp) { |
709 | props[nextProp].name = bdfForceMakeAtom("POINT_SIZE", NULL); | | 717 | props[nextProp].name = bdfForceMakeAtom("POINT_SIZE", NULL); |
710 | props[nextProp].value = (INT32) (pState->pointSize * 10.0); | | 718 | props[nextProp].value = (INT32) (pState->pointSize * 10.0); |
711 | stringProps[nextProp] = FALSE; | | 719 | stringProps[nextProp] = FALSE; |
712 | pState->pointSizeProp = &props[nextProp]; | | 720 | pState->pointSizeProp = &props[nextProp]; |
713 | nextProp++; | | 721 | nextProp++; |
714 | } | | 722 | } |
715 | if (!pState->fontProp) { | | 723 | if (!pState->fontProp) { |
716 | props[nextProp].name = bdfForceMakeAtom("FONT", NULL); | | 724 | props[nextProp].name = bdfForceMakeAtom("FONT", NULL); |
717 | props[nextProp].value = (INT32) bdfForceMakeAtom(pState->fontName, NULL); | | 725 | props[nextProp].value = (INT32) bdfForceMakeAtom(pState->fontName, NULL); |
718 | stringProps[nextProp] = TRUE; | | 726 | stringProps[nextProp] = TRUE; |
719 | pState->fontProp = &props[nextProp]; | | 727 | pState->fontProp = &props[nextProp]; |
720 | nextProp++; | | 728 | nextProp++; |
721 | } | | 729 | } |
722 | if (!pState->weightProp) { | | 730 | if (!pState->weightProp) { |
723 | props[nextProp].name = bdfForceMakeAtom("WEIGHT", NULL); | | 731 | props[nextProp].name = bdfForceMakeAtom("WEIGHT", NULL); |
724 | props[nextProp].value = -1; /* computed later */ | | 732 | props[nextProp].value = -1; /* computed later */ |
725 | stringProps[nextProp] = FALSE; | | 733 | stringProps[nextProp] = FALSE; |
726 | pState->weightProp = &props[nextProp]; | | 734 | pState->weightProp = &props[nextProp]; |
727 | nextProp++; | | 735 | nextProp++; |
728 | } | | 736 | } |
729 | if (!pState->resolutionProp && | | 737 | if (!pState->resolutionProp && |
730 | pState->resolution_x == pState->resolution_y) { | | 738 | pState->resolution_x == pState->resolution_y) { |
731 | props[nextProp].name = bdfForceMakeAtom("RESOLUTION", NULL); | | 739 | props[nextProp].name = bdfForceMakeAtom("RESOLUTION", NULL); |
732 | props[nextProp].value = (INT32) ((pState->resolution_x * 100.0) / 72.27); | | 740 | props[nextProp].value = (INT32) ((pState->resolution_x * 100.0) / 72.27); |
733 | stringProps[nextProp] = FALSE; | | 741 | stringProps[nextProp] = FALSE; |
734 | pState->resolutionProp = &props[nextProp]; | | 742 | pState->resolutionProp = &props[nextProp]; |
735 | nextProp++; | | 743 | nextProp++; |
736 | } | | 744 | } |
737 | if (!pState->resolutionXProp) { | | 745 | if (!pState->resolutionXProp) { |
738 | props[nextProp].name = bdfForceMakeAtom("RESOLUTION_X", NULL); | | 746 | props[nextProp].name = bdfForceMakeAtom("RESOLUTION_X", NULL); |
739 | props[nextProp].value = (INT32) pState->resolution_x; | | 747 | props[nextProp].value = (INT32) pState->resolution_x; |
740 | stringProps[nextProp] = FALSE; | | 748 | stringProps[nextProp] = FALSE; |
741 | pState->resolutionProp = &props[nextProp]; | | 749 | pState->resolutionProp = &props[nextProp]; |
742 | nextProp++; | | 750 | nextProp++; |
743 | } | | 751 | } |
744 | if (!pState->resolutionYProp) { | | 752 | if (!pState->resolutionYProp) { |
745 | props[nextProp].name = bdfForceMakeAtom("RESOLUTION_Y", NULL); | | 753 | props[nextProp].name = bdfForceMakeAtom("RESOLUTION_Y", NULL); |
746 | props[nextProp].value = (INT32) pState->resolution_y; | | 754 | props[nextProp].value = (INT32) pState->resolution_y; |
747 | stringProps[nextProp] = FALSE; | | 755 | stringProps[nextProp] = FALSE; |
748 | pState->resolutionProp = &props[nextProp]; | | 756 | pState->resolutionProp = &props[nextProp]; |
749 | nextProp++; | | 757 | nextProp++; |
750 | } | | 758 | } |
751 | if (!pState->xHeightProp) { | | 759 | if (!pState->xHeightProp) { |
752 | props[nextProp].name = bdfForceMakeAtom("X_HEIGHT", NULL); | | 760 | props[nextProp].name = bdfForceMakeAtom("X_HEIGHT", NULL); |
753 | props[nextProp].value = -1; /* computed later */ | | 761 | props[nextProp].value = -1; /* computed later */ |
754 | stringProps[nextProp] = FALSE; | | 762 | stringProps[nextProp] = FALSE; |
755 | pState->xHeightProp = &props[nextProp]; | | 763 | pState->xHeightProp = &props[nextProp]; |
756 | nextProp++; | | 764 | nextProp++; |
757 | } | | 765 | } |
758 | if (!pState->quadWidthProp) { | | 766 | if (!pState->quadWidthProp) { |
759 | props[nextProp].name = bdfForceMakeAtom("QUAD_WIDTH", NULL); | | 767 | props[nextProp].name = bdfForceMakeAtom("QUAD_WIDTH", NULL); |
760 | props[nextProp].value = -1; /* computed later */ | | 768 | props[nextProp].value = -1; /* computed later */ |
761 | stringProps[nextProp] = FALSE; | | 769 | stringProps[nextProp] = FALSE; |
762 | pState->quadWidthProp = &props[nextProp]; | | 770 | pState->quadWidthProp = &props[nextProp]; |
763 | nextProp++; | | 771 | nextProp++; |
764 | } | | 772 | } |
765 | pFont->info.nprops = nextProp; | | 773 | pFont->info.nprops = nextProp; |
766 | return (TRUE); | | 774 | return (TRUE); |
767 | BAILOUT: | | 775 | BAILOUT: |
768 | if (pFont->info.isStringProp) { | | 776 | if (pFont->info.isStringProp) { |
769 | xfree(pFont->info.isStringProp); | | 777 | xfree(pFont->info.isStringProp); |
770 | pFont->info.isStringProp = NULL; | | 778 | pFont->info.isStringProp = NULL; |
771 | } | | 779 | } |
772 | if (pFont->info.props) { | | 780 | if (pFont->info.props) { |
773 | xfree(pFont->info.props); | | 781 | xfree(pFont->info.props); |
774 | pFont->info.props = NULL; | | 782 | pFont->info.props = NULL; |
775 | } | | 783 | } |
776 | while (line && bdfIsPrefix(line, "ENDPROPERTIES")) | | 784 | while (line && bdfIsPrefix(line, "ENDPROPERTIES")) |
777 | line = bdfGetLine(file, lineBuf, BDFLINELEN); | | 785 | line = bdfGetLine(file, lineBuf, BDFLINELEN); |
778 | return (FALSE); | | 786 | return (FALSE); |
779 | } | | 787 | } |
780 | | | 788 | |
781 | /***====================================================================***/ | | 789 | /***====================================================================***/ |
782 | | | 790 | |
783 | static void | | 791 | static void |
784 | bdfUnloadFont(FontPtr pFont) | | 792 | bdfUnloadFont(FontPtr pFont) |
785 | { | | 793 | { |
786 | bdfFreeFontBits (pFont); | | 794 | bdfFreeFontBits (pFont); |
787 | DestroyFontRec(pFont); | | 795 | DestroyFontRec(pFont); |
788 | } | | 796 | } |
789 | | | 797 | |
790 | int | | 798 | int |
791 | bdfReadFont(FontPtr pFont, FontFilePtr file, | | 799 | bdfReadFont(FontPtr pFont, FontFilePtr file, |
792 | int bit, int byte, int glyph, int scan) | | 800 | int bit, int byte, int glyph, int scan) |
793 | { | | 801 | { |
794 | bdfFileState state; | | 802 | bdfFileState state; |
795 | xCharInfo *min, | | 803 | xCharInfo *min, |
796 | *max; | | 804 | *max; |
797 | BitmapFontPtr bitmapFont; | | 805 | BitmapFontPtr bitmapFont; |
798 | | | 806 | |
799 | pFont->fontPrivate = 0; | | 807 | pFont->fontPrivate = 0; |
800 | | | 808 | |
801 | bzero(&state, sizeof(bdfFileState)); | | 809 | bzero(&state, sizeof(bdfFileState)); |
802 | bdfFileLineNum = 0; | | 810 | bdfFileLineNum = 0; |
803 | | | 811 | |
804 | if (!bdfReadHeader(file, &state)) | | 812 | if (!bdfReadHeader(file, &state)) |
805 | goto BAILOUT; | | 813 | goto BAILOUT; |
806 | | | 814 | |
807 | bitmapFont = (BitmapFontPtr) xalloc(sizeof(BitmapFontRec)); | | 815 | bitmapFont = (BitmapFontPtr) xalloc(sizeof(BitmapFontRec)); |
808 | if (!bitmapFont) { | | 816 | if (!bitmapFont) { |
809 | bdfError("Couldn't allocate bitmapFontRec (%d)\n", sizeof(BitmapFontRec)); | | 817 | bdfError("Couldn't allocate bitmapFontRec (%d)\n", sizeof(BitmapFontRec)); |
810 | goto BAILOUT; | | 818 | goto BAILOUT; |
811 | } | | 819 | } |
812 | bzero((char *)bitmapFont, sizeof(BitmapFontRec)); | | 820 | bzero((char *)bitmapFont, sizeof(BitmapFontRec)); |
813 | | | 821 | |
814 | pFont->fontPrivate = (pointer) bitmapFont; | | 822 | pFont->fontPrivate = (pointer) bitmapFont; |
815 | bitmapFont->metrics = 0; | | 823 | bitmapFont->metrics = 0; |
816 | bitmapFont->ink_metrics = 0; | | 824 | bitmapFont->ink_metrics = 0; |
817 | bitmapFont->bitmaps = 0; | | 825 | bitmapFont->bitmaps = 0; |
818 | bitmapFont->encoding = 0; | | 826 | bitmapFont->encoding = 0; |
819 | bitmapFont->pDefault = NULL; | | 827 | bitmapFont->pDefault = NULL; |
820 | | | 828 | |
821 | bitmapFont->bitmapExtra = (BitmapExtraPtr) xalloc(sizeof(BitmapExtraRec)); | | 829 | bitmapFont->bitmapExtra = (BitmapExtraPtr) xalloc(sizeof(BitmapExtraRec)); |
822 | if (!bitmapFont->bitmapExtra) { | | 830 | if (!bitmapFont->bitmapExtra) { |
823 | bdfError("Couldn't allocate bitmapExtra (%d)\n", sizeof(BitmapExtraRec)); | | 831 | bdfError("Couldn't allocate bitmapExtra (%d)\n", sizeof(BitmapExtraRec)); |
824 | goto BAILOUT; | | 832 | goto BAILOUT; |
825 | } | | 833 | } |
826 | bzero((char *)bitmapFont->bitmapExtra, sizeof(BitmapExtraRec)); | | 834 | bzero((char *)bitmapFont->bitmapExtra, sizeof(BitmapExtraRec)); |
827 | | | 835 | |
828 | bitmapFont->bitmapExtra->glyphNames = 0; | | 836 | bitmapFont->bitmapExtra->glyphNames = 0; |
829 | bitmapFont->bitmapExtra->sWidths = 0; | | 837 | bitmapFont->bitmapExtra->sWidths = 0; |
830 | | | 838 | |
831 | if (!bdfReadProperties(file, pFont, &state)) | | 839 | if (!bdfReadProperties(file, pFont, &state)) |
832 | goto BAILOUT; | | 840 | goto BAILOUT; |
833 | | | 841 | |
834 | if (!bdfReadCharacters(file, pFont, &state, bit, byte, glyph, scan)) | | 842 | if (!bdfReadCharacters(file, pFont, &state, bit, byte, glyph, scan)) |
835 | goto BAILOUT; | | 843 | goto BAILOUT; |
836 | | | 844 | |
837 | if (state.haveDefaultCh) { | | 845 | if (state.haveDefaultCh) { |
838 | unsigned int r, c, cols; | | 846 | unsigned int r, c, cols; |
839 | | | 847 | |
840 | r = pFont->info.defaultCh >> 8; | | 848 | r = pFont->info.defaultCh >> 8; |
841 | c = pFont->info.defaultCh & 0xFF; | | 849 | c = pFont->info.defaultCh & 0xFF; |
842 | if (pFont->info.firstRow <= r && r <= pFont->info.lastRow && | | 850 | if (pFont->info.firstRow <= r && r <= pFont->info.lastRow && |
843 | pFont->info.firstCol <= c && c <= pFont->info.lastCol) { | | 851 | pFont->info.firstCol <= c && c <= pFont->info.lastCol) { |
844 | cols = pFont->info.lastCol - pFont->info.firstCol + 1; | | 852 | cols = pFont->info.lastCol - pFont->info.firstCol + 1; |
845 | r = r - pFont->info.firstRow; | | 853 | r = r - pFont->info.firstRow; |
846 | c = c - pFont->info.firstCol; | | 854 | c = c - pFont->info.firstCol; |
847 | bitmapFont->pDefault = ACCESSENCODING(bitmapFont->encoding, | | 855 | bitmapFont->pDefault = ACCESSENCODING(bitmapFont->encoding, |
848 | r * cols + c); | | 856 | r * cols + c); |
849 | } | | 857 | } |
850 | } | | 858 | } |
851 | pFont->bit = bit; | | 859 | pFont->bit = bit; |
852 | pFont->byte = byte; | | 860 | pFont->byte = byte; |
853 | pFont->glyph = glyph; | | 861 | pFont->glyph = glyph; |
854 | pFont->scan = scan; | | 862 | pFont->scan = scan; |
855 | pFont->info.anamorphic = FALSE; | | 863 | pFont->info.anamorphic = FALSE; |
856 | pFont->info.cachable = TRUE; | | 864 | pFont->info.cachable = TRUE; |
857 | bitmapComputeFontBounds(pFont); | | 865 | bitmapComputeFontBounds(pFont); |
858 | if (FontCouldBeTerminal(&pFont->info)) { | | 866 | if (FontCouldBeTerminal(&pFont->info)) { |
859 | bdfPadToTerminal(pFont); | | 867 | bdfPadToTerminal(pFont); |
860 | bitmapComputeFontBounds(pFont); | | 868 | bitmapComputeFontBounds(pFont); |
861 | } | | 869 | } |
862 | FontComputeInfoAccelerators(&pFont->info); | | 870 | FontComputeInfoAccelerators(&pFont->info); |
863 | if (bitmapFont->bitmapExtra) | | 871 | if (bitmapFont->bitmapExtra) |
864 | FontComputeInfoAccelerators(&bitmapFont->bitmapExtra->info); | | 872 | FontComputeInfoAccelerators(&bitmapFont->bitmapExtra->info); |
865 | if (pFont->info.constantMetrics) { | | 873 | if (pFont->info.constantMetrics) { |
866 | if (!bitmapAddInkMetrics(pFont)) { | | 874 | if (!bitmapAddInkMetrics(pFont)) { |
867 | bdfError("Failed to add bitmap ink metrics\n"); | | 875 | bdfError("Failed to add bitmap ink metrics\n"); |
868 | goto BAILOUT; | | 876 | goto BAILOUT; |
869 | } | | 877 | } |
870 | } | | 878 | } |
871 | if (bitmapFont->bitmapExtra) | | 879 | if (bitmapFont->bitmapExtra) |
872 | bitmapFont->bitmapExtra->info.inkMetrics = pFont->info.inkMetrics; | | 880 | bitmapFont->bitmapExtra->info.inkMetrics = pFont->info.inkMetrics; |
873 | | | 881 | |
874 | bitmapComputeFontInkBounds(pFont); | | 882 | bitmapComputeFontInkBounds(pFont); |
875 | /* ComputeFontAccelerators (pFont); */ | | 883 | /* ComputeFontAccelerators (pFont); */ |
876 | | | 884 | |
877 | /* generate properties */ | | 885 | /* generate properties */ |
878 | min = &pFont->info.ink_minbounds; | | 886 | min = &pFont->info.ink_minbounds; |
879 | max = &pFont->info.ink_maxbounds; | | 887 | max = &pFont->info.ink_maxbounds; |
880 | if (state.xHeightProp && (state.xHeightProp->value == -1)) | | 888 | if (state.xHeightProp && (state.xHeightProp->value == -1)) |
881 | state.xHeightProp->value = state.exHeight ? | | 889 | state.xHeightProp->value = state.exHeight ? |
882 | state.exHeight : min->ascent; | | 890 | state.exHeight : min->ascent; |
883 | | | 891 | |
884 | if (state.quadWidthProp && (state.quadWidthProp->value == -1)) | | 892 | if (state.quadWidthProp && (state.quadWidthProp->value == -1)) |
885 | state.quadWidthProp->value = state.digitCount ? | | 893 | state.quadWidthProp->value = state.digitCount ? |
886 | (INT32) (state.digitWidths / state.digitCount) : | | 894 | (INT32) (state.digitWidths / state.digitCount) : |
887 | (min->characterWidth + max->characterWidth) / 2; | | 895 | (min->characterWidth + max->characterWidth) / 2; |
888 | | | 896 | |
889 | if (state.weightProp && (state.weightProp->value == -1)) | | 897 | if (state.weightProp && (state.weightProp->value == -1)) |
890 | state.weightProp->value = bitmapComputeWeight(pFont); | | 898 | state.weightProp->value = bitmapComputeWeight(pFont); |
891 | | | 899 | |
892 | pFont->get_glyphs = bitmapGetGlyphs; | | 900 | pFont->get_glyphs = bitmapGetGlyphs; |
893 | pFont->get_metrics = bitmapGetMetrics; | | 901 | pFont->get_metrics = bitmapGetMetrics; |
894 | pFont->unload_font = bdfUnloadFont; | | 902 | pFont->unload_font = bdfUnloadFont; |
895 | pFont->unload_glyphs = NULL; | | 903 | pFont->unload_glyphs = NULL; |
896 | return Successful; | | 904 | return Successful; |
897 | BAILOUT: | | 905 | BAILOUT: |
898 | if (pFont->fontPrivate) | | 906 | if (pFont->fontPrivate) |
899 | bdfFreeFontBits (pFont); | | 907 | bdfFreeFontBits (pFont); |
900 | return AllocError; | | 908 | return AllocError; |
901 | } | | 909 | } |
902 | | | 910 | |
903 | int | | 911 | int |
904 | bdfReadFontInfo(FontInfoPtr pFontInfo, FontFilePtr file) | | 912 | bdfReadFontInfo(FontInfoPtr pFontInfo, FontFilePtr file) |
905 | { | | 913 | { |
906 | FontRec font; | | 914 | FontRec font; |
907 | int ret; | | 915 | int ret; |
908 | | | 916 | |
909 | bzero(&font, sizeof (FontRec)); | | 917 | bzero(&font, sizeof (FontRec)); |
910 | | | 918 | |
911 | ret = bdfReadFont(&font, file, MSBFirst, LSBFirst, 1, 1); | | 919 | ret = bdfReadFont(&font, file, MSBFirst, LSBFirst, 1, 1); |
912 | if (ret == Successful) { | | 920 | if (ret == Successful) { |
913 | *pFontInfo = font.info; | | 921 | *pFontInfo = font.info; |
914 | font.info.props = 0; | | 922 | font.info.props = 0; |
915 | font.info.isStringProp = 0; | | 923 | font.info.isStringProp = 0; |
916 | font.info.nprops = 0; | | 924 | font.info.nprops = 0; |
917 | bdfFreeFontBits (&font); | | 925 | bdfFreeFontBits (&font); |
918 | } | | 926 | } |
919 | return ret; | | 927 | return ret; |
920 | } | | 928 | } |
921 | | | 929 | |
922 | static Bool | | 930 | static Bool |
923 | bdfPadToTerminal(FontPtr pFont) | | 931 | bdfPadToTerminal(FontPtr pFont) |
924 | { | | 932 | { |
925 | BitmapFontPtr bitmapFont; | | 933 | BitmapFontPtr bitmapFont; |
926 | BitmapExtraPtr bitmapExtra; | | 934 | BitmapExtraPtr bitmapExtra; |
927 | int i; | | 935 | int i; |
928 | int new_size; | | 936 | int new_size; |
929 | CharInfoRec new; | | 937 | CharInfoRec new; |
930 | int w, | | 938 | int w, |
931 | h; | | 939 | h; |
932 | | | 940 | |
933 | bitmapFont = (BitmapFontPtr) pFont->fontPrivate; | | 941 | bitmapFont = (BitmapFontPtr) pFont->fontPrivate; |
934 | | | 942 | |
935 | bzero(&new, sizeof(CharInfoRec)); | | 943 | bzero(&new, sizeof(CharInfoRec)); |
936 | new.metrics.ascent = pFont->info.fontAscent; | | 944 | new.metrics.ascent = pFont->info.fontAscent; |
937 | new.metrics.descent = pFont->info.fontDescent; | | 945 | new.metrics.descent = pFont->info.fontDescent; |
938 | new.metrics.leftSideBearing = 0; | | 946 | new.metrics.leftSideBearing = 0; |
939 | new.metrics.rightSideBearing = pFont->info.minbounds.characterWidth; | | 947 | new.metrics.rightSideBearing = pFont->info.minbounds.characterWidth; |
940 | new.metrics.characterWidth = new.metrics.rightSideBearing; | | 948 | new.metrics.characterWidth = new.metrics.rightSideBearing; |
941 | new_size = BYTES_FOR_GLYPH(&new, pFont->glyph); | | 949 | new_size = BYTES_FOR_GLYPH(&new, pFont->glyph); |
942 | | | 950 | |
943 | for (i = 0; i < bitmapFont->num_chars; i++) { | | 951 | for (i = 0; i < bitmapFont->num_chars; i++) { |
944 | new.bits = (char *) xalloc(new_size); | | 952 | new.bits = (char *) xalloc(new_size); |
945 | if (!new.bits) { | | 953 | if (!new.bits) { |
946 | bdfError("Couldn't allocate bits (%d)\n", new_size); | | 954 | bdfError("Couldn't allocate bits (%d)\n", new_size); |
947 | return FALSE; | | 955 | return FALSE; |
948 | } | | 956 | } |
949 | FontCharReshape(pFont, &bitmapFont->metrics[i], &new); | | 957 | FontCharReshape(pFont, &bitmapFont->metrics[i], &new); |
950 | new.metrics.attributes = bitmapFont->metrics[i].metrics.attributes; | | 958 | new.metrics.attributes = bitmapFont->metrics[i].metrics.attributes; |
951 | xfree(bitmapFont->metrics[i].bits); | | 959 | xfree(bitmapFont->metrics[i].bits); |
952 | bitmapFont->metrics[i] = new; | | 960 | bitmapFont->metrics[i] = new; |
953 | } | | 961 | } |
954 | bitmapExtra = bitmapFont->bitmapExtra; | | 962 | bitmapExtra = bitmapFont->bitmapExtra; |
955 | if (bitmapExtra) { | | 963 | if (bitmapExtra) { |
956 | w = GLYPHWIDTHPIXELS(&new); | | 964 | w = GLYPHWIDTHPIXELS(&new); |
957 | h = GLYPHHEIGHTPIXELS(&new); | | 965 | h = GLYPHHEIGHTPIXELS(&new); |
958 | for (i = 0; i < GLYPHPADOPTIONS; i++) | | 966 | for (i = 0; i < GLYPHPADOPTIONS; i++) |
959 | bitmapExtra->bitmapsSizes[i] = bitmapFont->num_chars * | | 967 | bitmapExtra->bitmapsSizes[i] = bitmapFont->num_chars * |
960 | (BYTES_PER_ROW(w, 1 << i) * h); | | 968 | (BYTES_PER_ROW(w, 1 << i) * h); |
961 | } | | 969 | } |
962 | return TRUE; | | 970 | return TRUE; |
963 | } | | 971 | } |