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