1
/* $Xorg: bdfread.c,v 1.5 2001/02/09 02:04:01 xorgcvs Exp $ */
3
/************************************************************************
4
Copyright 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
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.
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
24
************************************************************************/
28
Copyright 1994, 1998 The Open Group
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
36
The above copyright notice and this permission notice shall be included
37
in all copies or substantial portions of the Software.
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.
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
53
/* $XFree86: xc/lib/font/bitmap/bdfread.c,v 1.12tsi Exp $ */
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>
69
#define MAXENCODING 0xFFFF
70
#define BDFLINELEN 1024
72
static Bool bdfPadToTerminal(FontPtr pFont);
73
extern int bdfFileLineNum;
75
/***====================================================================***/
78
bdfReadBitmap(CharInfoPtr pCI, FontFilePtr file, int bit, int byte,
79
int glyph, int scan, CARD32 *sizes)
89
unsigned char *pInBits,
92
unsigned char lineBuf[BDFLINELEN];
94
widthBits = GLYPHWIDTHPIXELS(pCI);
95
height = GLYPHHEIGHTPIXELS(pCI);
97
widthBytes = BYTES_PER_ROW(widthBits, glyph);
98
if (widthBytes * height > 0) {
99
picture = (unsigned char *) xalloc(widthBytes * height);
101
bdfError("Couldn't allocate picture (%d*%d)\n", widthBytes, height);
106
pCI->bits = (char *) picture;
109
for (i = 0; i < GLYPHPADOPTIONS; i++)
110
sizes[i] += BYTES_PER_ROW(widthBits, (1 << i)) * height;
113
widthHexChars = BYTES_PER_ROW(widthBits, 1);
115
/* 5/31/89 (ef) -- hack, hack, hack. what *am* I supposed to do with */
116
/* 0 width characters? */
118
for (row = 0; row < height; row++) {
119
line = bdfGetLine(file, lineBuf, BDFLINELEN);
123
if (widthBits == 0) {
124
if ((!line) || (bdfIsPrefix(line, "ENDCHAR")))
130
inLineLen = strlen((char *) pInBits);
133
bdfError("odd number of characters in hex encoding\n");
134
line[inLineLen++] = '0';
135
line[inLineLen] = '\0';
139
if (i > widthHexChars)
141
for (; i > 0; i--, pInBits += 2)
142
picture[nextByte++] = bdfHexByte(pInBits);
144
/* pad if line is too short */
145
if (inLineLen < widthHexChars) {
146
for (i = widthHexChars - inLineLen; i > 0; i--)
147
picture[nextByte++] = 0;
151
mask = 0xff << (8 - (widthBits & 0x7));
152
if (mask && picture[nextByte - 1] & ~mask) {
153
picture[nextByte - 1] &= mask;
157
if (widthBytes > widthHexChars) {
158
i = widthBytes - widthHexChars;
160
picture[nextByte++] = 0;
164
if ((line && (!bdfIsPrefix(line, "ENDCHAR"))) || (height == 0))
165
line = bdfGetLine(file, lineBuf, BDFLINELEN);
167
if ((!line) || (!bdfIsPrefix(line, "ENDCHAR"))) {
168
bdfError("missing 'ENDCHAR'\n");
171
if (nextByte != height * widthBytes) {
172
bdfError("bytes != rows * bytes_per_row (%d != %d * %d)\n",
173
nextByte, height, widthBytes);
176
if (picture != NULL) {
178
BitOrderInvert(picture, nextByte);
181
TwoByteSwap(picture, nextByte);
183
FourByteSwap(picture, nextByte);
194
/***====================================================================***/
197
bdfSkipBitmap(FontFilePtr file, int height)
201
unsigned char lineBuf[BDFLINELEN];
204
line = bdfGetLine(file, lineBuf, BDFLINELEN);
206
} while (line && !bdfIsPrefix(line, "ENDCHAR") && i <= height);
208
if (i > 1 && line && !bdfIsPrefix(line, "ENDCHAR")) {
209
bdfError("Error in bitmap, missing 'ENDCHAR'\n");
215
/***====================================================================***/
218
bdfFreeFontBits(FontPtr pFont)
220
BitmapFontPtr bitmapFont;
221
BitmapExtraPtr bitmapExtra;
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]);
233
xfree(bitmapFont->encoding);
234
for (i = 0; i < bitmapFont->num_chars; i++)
235
xfree(bitmapFont->metrics[i].bits);
236
xfree(bitmapFont->metrics);
239
xfree (bitmapExtra->glyphNames);
240
xfree (bitmapExtra->sWidths);
243
xfree(pFont->info.props);
249
bdfReadCharacters(FontFilePtr file, FontPtr pFont, bdfFileState *pState,
250
int bit, int byte, int glyph, int scan)
253
register CharInfoPtr ci;
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];
267
bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
268
bitmapExtra = (BitmapExtraPtr) bitmapFont->bitmapExtra;
271
bitmapsSizes = bitmapExtra->bitmapsSizes;
272
for (i = 0; i < GLYPHPADOPTIONS; i++)
277
bzero(bdfEncoding, sizeof(bdfEncoding));
278
bitmapFont->metrics = NULL;
281
line = bdfGetLine(file, lineBuf, BDFLINELEN);
283
if ((!line) || (sscanf((char *) line, "CHARS %d", &nchars) != 1)) {
284
bdfError("bad 'CHARS' in bdf file\n");
288
bdfError("invalid number of CHARS in BDF file\n");
291
ci = (CharInfoPtr) xalloc(nchars * sizeof(CharInfoRec));
293
bdfError("Couldn't allocate pCI (%d*%d)\n", nchars,
294
sizeof(CharInfoRec));
297
bzero((char *)ci, nchars * sizeof(CharInfoRec));
298
bitmapFont->metrics = ci;
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));
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));
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;
322
for (ndx = 0; (ndx < nchars) && (line) && (bdfIsPrefix(line, "STARTCHAR"));) {
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 */
332
unsigned char *p; /* temp pointer into line */
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 */
341
bitmapExtra->glyphNames[ndx] = bdfForceMakeAtom(charName, NULL);
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");
348
if (enc < -1 || (t == 2 && enc2 < -1)) {
349
bdfError("bad ENCODING value");
352
if (t == 2 && enc == -1)
360
} else if (enc > MAXENCODING) {
361
bdfError("char '%s' has encoding too large (%d)\n",
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));
382
for (i = 0; i < 256; i++)
383
bdfEncoding[char_row][i] = (CharInfoPtr) NULL;
385
if (bdfEncoding[char_row] != NULL) {
386
bdfEncoding[char_row][char_col] = ci;
391
line = bdfGetLine(file, lineBuf, BDFLINELEN);
392
if ((!line) || (sscanf((char *) line, "SWIDTH %d %d", &wx, &wy) != 2)) {
393
bdfError("bad 'SWIDTH'\n");
397
bdfError("SWIDTH y value must be zero\n");
401
bitmapExtra->sWidths[ndx] = wx;
403
/* 5/31/89 (ef) -- we should be able to ditch the character and recover */
404
/* from all of these. */
406
line = bdfGetLine(file, lineBuf, BDFLINELEN);
407
if ((!line) || (sscanf((char *) line, "DWIDTH %d %d", &wx, &wy) != 2)) {
408
bdfError("bad 'DWIDTH'\n");
412
bdfError("DWIDTH y value must be zero\n");
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");
420
if ((bh < 0) || (bw < 0)) {
421
bdfError("character '%s' has a negative sized bitmap, %dx%d\n",
425
line = bdfGetLine(file, lineBuf, BDFLINELEN);
426
if ((line) && (bdfIsPrefix(line, "ATTRIBUTES"))) {
427
for (p = line + strlen("ATTRIBUTES ");
428
(*p == ' ') || (*p == '\t');
430
/* empty for loop */ ;
431
ci->metrics.attributes = (bdfHexByte(p) << 8) + bdfHexByte(p + 2);
432
line = bdfGetLine(file, lineBuf, BDFLINELEN);
434
ci->metrics.attributes = 0;
436
if (!line || !bdfIsPrefix(line, "BITMAP")) {
437
bdfError("missing 'BITMAP'\n");
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;
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;
456
bdfReadBitmap(ci, file, bit, byte, glyph, scan, bitmapsSizes);
460
bdfSkipBitmap(file, bh);
462
line = bdfGetLine(file, lineBuf, BDFLINELEN); /* get STARTCHAR or
466
if (ndx + nignored != nchars) {
467
bdfError("%d too few characters\n", nchars - (ndx + nignored));
471
bitmapFont->num_chars = nchars;
472
if ((line) && (bdfIsPrefix(line, "STARTCHAR"))) {
473
bdfError("more characters than specified\n");
476
if ((!line) || (!bdfIsPrefix(line, "ENDFONT"))) {
477
bdfError("missing 'ENDFONT'\n");
480
if (numEncodedGlyphs == 0)
481
bdfWarning("No characters with valid encodings\n");
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*));
494
pFont->info.allExist = TRUE;
496
for (char_row = pFont->info.firstRow;
497
char_row <= pFont->info.lastRow;
499
if (bdfEncoding[char_row] == (CharInfoPtr *) NULL) {
500
pFont->info.allExist = FALSE;
501
i += pFont->info.lastCol - pFont->info.firstCol + 1;
503
for (char_col = pFont->info.firstCol;
504
char_col <= pFont->info.lastCol;
506
if (!bdfEncoding[char_row][char_col])
507
pFont->info.allExist = FALSE;
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)])
516
ACCESSENCODINGL(bitmapFont->encoding,i) =
517
bdfEncoding[char_row][char_col];
523
for (i = 0; i < 256; i++)
525
xfree(bdfEncoding[i]);
528
for (i = 0; i < 256; i++)
530
xfree(bdfEncoding[i]);
531
/* bdfFreeFontBits will clean up the rest */
535
/***====================================================================***/
538
bdfReadHeader(FontFilePtr file, bdfFileState *pState)
541
char namebuf[BDFLINELEN];
542
unsigned char lineBuf[BDFLINELEN];
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");
550
line = bdfGetLine(file, lineBuf, BDFLINELEN);
551
if (!line || sscanf((char *) line, "FONT %[^\n]", pState->fontName) != 1) {
552
bdfError("bad 'FONT'\n");
555
line = bdfGetLine(file, lineBuf, BDFLINELEN);
556
if (!line || !bdfIsPrefix(line, "SIZE")) {
557
bdfError("missing 'SIZE'\n");
560
if (sscanf((char *) line, "SIZE %f%d%d", &pState->pointSize,
561
&pState->resolution_x, &pState->resolution_y) != 3) {
562
bdfError("bad 'SIZE'\n");
565
if (pState->pointSize < 1 ||
566
pState->resolution_x < 1 || pState->resolution_y < 1) {
567
bdfError("SIZE values must be > 0\n");
570
line = bdfGetLine(file, lineBuf, BDFLINELEN);
571
if (!line || !bdfIsPrefix(line, "FONTBOUNDINGBOX")) {
572
bdfError("missing 'FONTBOUNDINGBOX'\n");
578
/***====================================================================***/
581
bdfReadProperties(FontFilePtr file, FontPtr pFont, bdfFileState *pState)
583
int nProps, props_left,
587
char namebuf[BDFLINELEN],
588
secondbuf[BDFLINELEN],
589
thirdbuf[BDFLINELEN];
591
unsigned char lineBuf[BDFLINELEN];
592
BitmapFontPtr bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
594
line = bdfGetLine(file, lineBuf, BDFLINELEN);
595
if (!line || !bdfIsPrefix(line, "STARTPROPERTIES")) {
596
bdfError("missing 'STARTPROPERTIES'\n");
599
if (sscanf((char *) line, "STARTPROPERTIES %d", &nProps) != 1) {
600
bdfError("bad 'STARTPROPERTIES'\n");
603
pFont->info.isStringProp = NULL;
604
pFont->info.props = NULL;
605
pFont->info.nprops = 0;
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));
614
pFont->info.props = props = (FontPropPtr) xalloc((nProps + BDF_GENPROPS) *
615
sizeof(FontPropRec));
617
bdfError("Couldn't allocate props (%d*%d)\n", nProps + BDF_GENPROPS,
618
sizeof(FontPropRec));
621
bzero((char *)props, (nProps + BDF_GENPROPS) * sizeof(FontPropRec));
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);
632
while (*line && isspace(*line))
635
switch (sscanf((char *) line, "%s%s%s", namebuf, secondbuf, thirdbuf)) {
637
bdfError("missing '%s' parameter value\n", namebuf);
642
* Possibilites include: valid quoted string with no white space
643
* valid integer value invalid value
645
if (secondbuf[0] == '"') {
646
stringProps[nextProp] = TRUE;
647
props[nextProp].value =
648
bdfGetPropertyValue((char *)line + strlen(namebuf) + 1);
649
if (!props[nextProp].value)
652
} else if (bdfIsInteger(secondbuf)) {
653
stringProps[nextProp] = FALSE;
654
props[nextProp].value = atoi(secondbuf);
657
bdfError("invalid '%s' parameter value\n", namebuf);
663
* Possibilites include: valid quoted string with some white space
664
* invalid value (reject even if second string is integer)
666
if (secondbuf[0] == '"') {
667
stringProps[nextProp] = TRUE;
668
props[nextProp].value =
669
bdfGetPropertyValue((char *)line + strlen(namebuf) + 1);
670
if (!props[nextProp].value)
674
bdfError("invalid '%s' parameter value\n", namebuf);
678
props[nextProp].name = bdfForceMakeAtom(namebuf, NULL);
679
if (props[nextProp].name == None) {
680
bdfError("Empty property name.\n");
683
if (!bdfSpecialProperty(pFont, &props[nextProp],
684
stringProps[nextProp], pState))
688
line = bdfGetLine(file, lineBuf, BDFLINELEN);
689
if (!line || !bdfIsPrefix(line, "ENDPROPERTIES")) {
690
bdfError("missing 'ENDPROPERTIES'\n");
693
if (!pState->haveFontAscent || !pState->haveFontDescent) {
694
bdfError("missing 'FONT_ASCENT' or 'FONT_DESCENT' properties\n");
697
if (bitmapFont->bitmapExtra) {
698
bitmapFont->bitmapExtra->info.fontAscent = pFont->info.fontAscent;
699
bitmapFont->bitmapExtra->info.fontDescent = pFont->info.fontDescent;
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];
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];
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];
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];
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];
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];
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];
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];
758
pFont->info.nprops = nextProp;
761
if (pFont->info.isStringProp) {
762
xfree(pFont->info.isStringProp);
763
pFont->info.isStringProp = NULL;
765
if (pFont->info.props) {
766
xfree(pFont->info.props);
767
pFont->info.props = NULL;
769
while (line && bdfIsPrefix(line, "ENDPROPERTIES"))
770
line = bdfGetLine(file, lineBuf, BDFLINELEN);
774
/***====================================================================***/
777
bdfUnloadFont(FontPtr pFont)
779
bdfFreeFontBits (pFont);
780
DestroyFontRec(pFont);
784
bdfReadFont(FontPtr pFont, FontFilePtr file,
785
int bit, int byte, int glyph, int scan)
790
BitmapFontPtr bitmapFont;
792
pFont->fontPrivate = 0;
794
bzero(&state, sizeof(bdfFileState));
797
if (!bdfReadHeader(file, &state))
800
bitmapFont = (BitmapFontPtr) xalloc(sizeof(BitmapFontRec));
802
bdfError("Couldn't allocate bitmapFontRec (%d)\n", sizeof(BitmapFontRec));
805
bzero((char *)bitmapFont, sizeof(BitmapFontRec));
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;
814
bitmapFont->bitmapExtra = (BitmapExtraPtr) xalloc(sizeof(BitmapExtraRec));
815
if (!bitmapFont->bitmapExtra) {
816
bdfError("Couldn't allocate bitmapExtra (%d)\n", sizeof(BitmapExtraRec));
819
bzero((char *)bitmapFont->bitmapExtra, sizeof(BitmapExtraRec));
821
bitmapFont->bitmapExtra->glyphNames = 0;
822
bitmapFont->bitmapExtra->sWidths = 0;
824
if (!bdfReadProperties(file, pFont, &state))
827
if (!bdfReadCharacters(file, pFont, &state, bit, byte, glyph, scan))
830
if (state.haveDefaultCh) {
831
unsigned int r, c, cols;
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,
846
pFont->glyph = glyph;
848
pFont->info.anamorphic = FALSE;
849
pFont->info.cachable = TRUE;
850
bitmapComputeFontBounds(pFont);
851
if (FontCouldBeTerminal(&pFont->info)) {
852
bdfPadToTerminal(pFont);
853
bitmapComputeFontBounds(pFont);
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");
864
if (bitmapFont->bitmapExtra)
865
bitmapFont->bitmapExtra->info.inkMetrics = pFont->info.inkMetrics;
867
bitmapComputeFontInkBounds(pFont);
868
/* ComputeFontAccelerators (pFont); */
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;
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;
882
if (state.weightProp && (state.weightProp->value == -1))
883
state.weightProp->value = bitmapComputeWeight(pFont);
885
pFont->get_glyphs = bitmapGetGlyphs;
886
pFont->get_metrics = bitmapGetMetrics;
887
pFont->unload_font = bdfUnloadFont;
888
pFont->unload_glyphs = NULL;
891
if (pFont->fontPrivate)
892
bdfFreeFontBits (pFont);
897
bdfReadFontInfo(FontInfoPtr pFontInfo, FontFilePtr file)
902
bzero(&font, sizeof (FontRec));
904
ret = bdfReadFont(&font, file, MSBFirst, LSBFirst, 1, 1);
905
if (ret == Successful) {
906
*pFontInfo = font.info;
908
font.info.isStringProp = 0;
909
font.info.nprops = 0;
910
bdfFreeFontBits (&font);
916
bdfPadToTerminal(FontPtr pFont)
918
BitmapFontPtr bitmapFont;
919
BitmapExtraPtr bitmapExtra;
926
bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
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);
936
for (i = 0; i < bitmapFont->num_chars; i++) {
937
new.bits = (char *) xalloc(new_size);
939
bdfError("Couldn't allocate bits (%d)\n", new_size);
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;
947
bitmapExtra = bitmapFont->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);