~ubuntu-branches/ubuntu/precise/libxfont/precise-updates

« back to all changes in this revision

Viewing changes to src/bitmap/bdfread.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Stone
  • Date: 2005-09-09 15:39:57 UTC
  • Revision ID: james.westby@ubuntu.com-20050909153957-o0ltjssizusljf72
Tags: upstream-0.99.0+cvs.20050909
ImportĀ upstreamĀ versionĀ 0.99.0+cvs.20050909

Show diffs side-by-side

added added

removed removed

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