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