1 /************************************************************************
2 Copyright 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
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.
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
22 ************************************************************************/
26 Copyright 1994, 1998 The Open Group
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
34 The above copyright notice and this permission notice shall be included
35 in all copies or substantial portions of the Software.
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.
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
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>
65 #elif !defined(INT32_MAX)
66 #define INT32_MAX 0x7fffffff
70 #define MAXENCODING 0xFFFF
71 #define BDFLINELEN 1024
73 static Bool bdfPadToTerminal(FontPtr pFont);
74 extern int bdfFileLineNum;
76 /***====================================================================***/
79 bdfReadBitmap(CharInfoPtr pCI, FontFilePtr file, int bit, int byte,
80 int glyph, int scan, CARD32 *sizes)
90 unsigned char *pInBits,
93 unsigned char lineBuf[BDFLINELEN];
95 widthBits = GLYPHWIDTHPIXELS(pCI);
96 height = GLYPHHEIGHTPIXELS(pCI);
98 widthBytes = BYTES_PER_ROW(widthBits, glyph);
99 if (widthBytes * height > 0) {
100 picture = malloc(widthBytes * height);
102 bdfError("Couldn't allocate picture (%d*%d)\n", widthBytes, height);
107 pCI->bits = (char *) picture;
110 for (i = 0; i < GLYPHPADOPTIONS; i++)
111 sizes[i] += BYTES_PER_ROW(widthBits, (1 << i)) * height;
114 widthHexChars = BYTES_PER_ROW(widthBits, 1);
116 /* 5/31/89 (ef) -- hack, hack, hack. what *am* I supposed to do with */
117 /* 0 width characters? */
119 for (row = 0; row < height; row++) {
120 line = bdfGetLine(file, lineBuf, BDFLINELEN);
124 if (widthBits == 0) {
125 if ((!line) || (bdfIsPrefix(line, "ENDCHAR")))
131 inLineLen = strlen((char *) pInBits);
134 bdfError("odd number of characters in hex encoding\n");
135 line[inLineLen++] = '0';
136 line[inLineLen] = '\0';
140 if (i > widthHexChars)
142 for (; i > 0; i--, pInBits += 2)
143 picture[nextByte++] = bdfHexByte(pInBits);
145 /* pad if line is too short */
146 if (inLineLen < widthHexChars) {
147 for (i = widthHexChars - inLineLen; i > 0; i--)
148 picture[nextByte++] = 0;
152 mask = 0xff << (8 - (widthBits & 0x7));
153 if (mask && picture[nextByte - 1] & ~mask) {
154 picture[nextByte - 1] &= mask;
158 if (widthBytes > widthHexChars) {
159 i = widthBytes - widthHexChars;
161 picture[nextByte++] = 0;
165 if ((line && (!bdfIsPrefix(line, "ENDCHAR"))) || (height == 0))
166 line = bdfGetLine(file, lineBuf, BDFLINELEN);
168 if ((!line) || (!bdfIsPrefix(line, "ENDCHAR"))) {
169 bdfError("missing 'ENDCHAR'\n");
172 if (nextByte != height * widthBytes) {
173 bdfError("bytes != rows * bytes_per_row (%d != %d * %d)\n",
174 nextByte, height, widthBytes);
177 if (picture != NULL) {
179 BitOrderInvert(picture, nextByte);
182 TwoByteSwap(picture, nextByte);
184 FourByteSwap(picture, nextByte);
195 /***====================================================================***/
198 bdfSkipBitmap(FontFilePtr file, int height)
202 unsigned char lineBuf[BDFLINELEN];
205 line = bdfGetLine(file, lineBuf, BDFLINELEN);
207 } while (line && !bdfIsPrefix(line, "ENDCHAR") && i <= height);
209 if (i > 1 && line && !bdfIsPrefix(line, "ENDCHAR")) {
210 bdfError("Error in bitmap, missing 'ENDCHAR'\n");
216 /***====================================================================***/
219 bdfFreeFontBits(FontPtr pFont)
221 BitmapFontPtr bitmapFont;
222 BitmapExtraPtr bitmapExtra;
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); i++)
232 free(bitmapFont->encoding[i]);
234 free(bitmapFont->encoding);
235 for (i = 0; i < bitmapFont->num_chars; i++)
236 free(bitmapFont->metrics[i].bits);
237 free(bitmapFont->metrics);
240 free (bitmapExtra->glyphNames);
241 free (bitmapExtra->sWidths);
244 free(pFont->info.props);
250 bdfReadCharacters(FontFilePtr file, FontPtr pFont, bdfFileState *pState,
251 int bit, int byte, int glyph, int scan)
254 register CharInfoPtr ci;
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[BDFLINELEN];
268 bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
269 bitmapExtra = (BitmapExtraPtr) bitmapFont->bitmapExtra;
272 bitmapsSizes = bitmapExtra->bitmapsSizes;
273 for (i = 0; i < GLYPHPADOPTIONS; i++)
278 bzero(bdfEncoding, sizeof(bdfEncoding));
279 bitmapFont->metrics = NULL;
282 line = bdfGetLine(file, lineBuf, BDFLINELEN);
284 if ((!line) || (sscanf((char *) line, "CHARS %d", &nchars) != 1)) {
285 bdfError("bad 'CHARS' in bdf file\n");
289 bdfError("invalid number of CHARS in BDF file\n");
292 if (nchars > INT32_MAX / sizeof(CharInfoRec)) {
293 bdfError("Couldn't allocate pCI (%d*%d)\n", nchars,
294 sizeof(CharInfoRec));
297 ci = calloc(nchars, sizeof(CharInfoRec));
299 bdfError("Couldn't allocate pCI (%d*%d)\n", nchars,
300 sizeof(CharInfoRec));
303 bitmapFont->metrics = ci;
306 bitmapExtra->glyphNames = malloc(nchars * sizeof(Atom));
307 if (!bitmapExtra->glyphNames) {
308 bdfError("Couldn't allocate glyphNames (%d*%d)\n",
309 nchars, sizeof(Atom));
314 bitmapExtra->sWidths = malloc(nchars * sizeof(int));
315 if (!bitmapExtra->sWidths) {
316 bdfError("Couldn't allocate sWidth (%d *%d)\n",
317 nchars, sizeof(int));
321 line = bdfGetLine(file, lineBuf, BDFLINELEN);
322 pFont->info.firstRow = 256;
323 pFont->info.lastRow = 0;
324 pFont->info.firstCol = 256;
325 pFont->info.lastCol = 0;
327 for (ndx = 0; (ndx < nchars) && (line) && (bdfIsPrefix(line, "STARTCHAR"));) {
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 */
337 unsigned char *p; /* temp pointer into line */
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 */
346 bitmapExtra->glyphNames[ndx] = bdfForceMakeAtom(charName, NULL);
348 line = bdfGetLine(file, lineBuf, BDFLINELEN);
349 if (!line || (t = sscanf((char *) line, "ENCODING %d %d", &enc, &enc2)) < 1) {
350 bdfError("bad 'ENCODING' in BDF file\n");
353 if (enc < -1 || (t == 2 && enc2 < -1)) {
354 bdfError("bad ENCODING value");
357 if (t == 2 && enc == -1)
365 } else if (enc > MAXENCODING) {
366 bdfError("char '%s' has encoding too large (%d)\n",
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) {
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, INDICES, sizeof(CharInfoPtr));
386 for (i = 0; i < 256; i++)
387 bdfEncoding[char_row][i] = (CharInfoPtr) NULL;
389 if (bdfEncoding[char_row] != NULL) {
390 bdfEncoding[char_row][char_col] = ci;
395 line = bdfGetLine(file, lineBuf, BDFLINELEN);
396 if ((!line) || (sscanf((char *) line, "SWIDTH %d %d", &wx, &wy) != 2)) {
397 bdfError("bad 'SWIDTH'\n");
401 bdfError("SWIDTH y value must be zero\n");
405 bitmapExtra->sWidths[ndx] = wx;
407 /* 5/31/89 (ef) -- we should be able to ditch the character and recover */
408 /* from all of these. */
410 line = bdfGetLine(file, lineBuf, BDFLINELEN);
411 if ((!line) || (sscanf((char *) line, "DWIDTH %d %d", &wx, &wy) != 2)) {
412 bdfError("bad 'DWIDTH'\n");
416 bdfError("DWIDTH y value must be zero\n");
419 line = bdfGetLine(file, lineBuf, BDFLINELEN);
420 if ((!line) || (sscanf((char *) line, "BBX %d %d %d %d", &bw, &bh, &bl, &bb) != 4)) {
421 bdfError("bad 'BBX'\n");
424 if ((bh < 0) || (bw < 0)) {
425 bdfError("character '%s' has a negative sized bitmap, %dx%d\n",
429 line = bdfGetLine(file, lineBuf, BDFLINELEN);
430 if ((line) && (bdfIsPrefix(line, "ATTRIBUTES"))) {
431 for (p = line + strlen("ATTRIBUTES ");
432 (*p == ' ') || (*p == '\t');
434 /* empty for loop */ ;
435 ci->metrics.attributes = (bdfHexByte(p) << 8) + bdfHexByte(p + 2);
436 line = bdfGetLine(file, lineBuf, BDFLINELEN);
438 ci->metrics.attributes = 0;
440 if (!line || !bdfIsPrefix(line, "BITMAP")) {
441 bdfError("missing 'BITMAP'\n");
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;
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;
460 bdfReadBitmap(ci, file, bit, byte, glyph, scan, bitmapsSizes);
464 bdfSkipBitmap(file, bh);
466 line = bdfGetLine(file, lineBuf, BDFLINELEN); /* get STARTCHAR or
470 if (ndx + nignored != nchars) {
471 bdfError("%d too few characters\n", nchars - (ndx + nignored));
475 bitmapFont->num_chars = nchars;
476 if ((line) && (bdfIsPrefix(line, "STARTCHAR"))) {
477 bdfError("more characters than specified\n");
480 if ((!line) || (!bdfIsPrefix(line, "ENDFONT"))) {
481 bdfError("missing 'ENDFONT'\n");
484 if (numEncodedGlyphs == 0)
485 bdfWarning("No characters with valid encodings\n");
487 nencoding = (pFont->info.lastRow - pFont->info.firstRow + 1) *
488 (pFont->info.lastCol - pFont->info.firstCol + 1);
489 bitmapFont->encoding = calloc(NUM_SEGMENTS(nencoding),sizeof(CharInfoPtr*));
490 if (!bitmapFont->encoding) {
491 bdfError("Couldn't allocate ppCI (%d,%d)\n",
492 NUM_SEGMENTS(nencoding),
493 sizeof(CharInfoPtr*));
496 pFont->info.allExist = TRUE;
498 for (char_row = pFont->info.firstRow;
499 char_row <= pFont->info.lastRow;
501 if (bdfEncoding[char_row] == (CharInfoPtr *) NULL) {
502 pFont->info.allExist = FALSE;
503 i += pFont->info.lastCol - pFont->info.firstCol + 1;
505 for (char_col = pFont->info.firstCol;
506 char_col <= pFont->info.lastCol;
508 if (!bdfEncoding[char_row][char_col])
509 pFont->info.allExist = FALSE;
511 if (!bitmapFont->encoding[SEGMENT_MAJOR(i)]) {
512 bitmapFont->encoding[SEGMENT_MAJOR(i)]=
513 calloc(BITMAP_FONT_SEGMENT_SIZE,
514 sizeof(CharInfoPtr));
515 if (!bitmapFont->encoding[SEGMENT_MAJOR(i)])
518 ACCESSENCODINGL(bitmapFont->encoding,i) =
519 bdfEncoding[char_row][char_col];
525 for (i = 0; i < 256; i++)
527 free(bdfEncoding[i]);
530 for (i = 0; i < 256; i++)
532 free(bdfEncoding[i]);
533 /* bdfFreeFontBits will clean up the rest */
537 /***====================================================================***/
540 bdfReadHeader(FontFilePtr file, bdfFileState *pState)
543 char namebuf[BDFLINELEN];
544 unsigned char lineBuf[BDFLINELEN];
546 line = bdfGetLine(file, lineBuf, BDFLINELEN);
547 if (!line || sscanf((char *) line, "STARTFONT %s", namebuf) != 1 ||
548 !bdfStrEqual(namebuf, "2.1")) {
549 bdfError("bad 'STARTFONT'\n");
552 line = bdfGetLine(file, lineBuf, BDFLINELEN);
553 if (!line || sscanf((char *) line, "FONT %[^\n]", pState->fontName) != 1) {
554 bdfError("bad 'FONT'\n");
557 line = bdfGetLine(file, lineBuf, BDFLINELEN);
558 if (!line || !bdfIsPrefix(line, "SIZE")) {
559 bdfError("missing 'SIZE'\n");
562 if (sscanf((char *) line, "SIZE %f%d%d", &pState->pointSize,
563 &pState->resolution_x, &pState->resolution_y) != 3) {
564 bdfError("bad 'SIZE'\n");
567 if (pState->pointSize < 1 ||
568 pState->resolution_x < 1 || pState->resolution_y < 1) {
569 bdfError("SIZE values must be > 0\n");
572 line = bdfGetLine(file, lineBuf, BDFLINELEN);
573 if (!line || !bdfIsPrefix(line, "FONTBOUNDINGBOX")) {
574 bdfError("missing 'FONTBOUNDINGBOX'\n");
580 /***====================================================================***/
583 bdfReadProperties(FontFilePtr file, FontPtr pFont, bdfFileState *pState)
585 int nProps, props_left,
589 char namebuf[BDFLINELEN],
590 secondbuf[BDFLINELEN],
591 thirdbuf[BDFLINELEN];
593 unsigned char lineBuf[BDFLINELEN];
594 BitmapFontPtr bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
596 line = bdfGetLine(file, lineBuf, BDFLINELEN);
597 if (!line || !bdfIsPrefix(line, "STARTPROPERTIES")) {
598 bdfError("missing 'STARTPROPERTIES'\n");
601 if (sscanf((char *) line, "STARTPROPERTIES %d", &nProps) != 1) {
602 bdfError("bad 'STARTPROPERTIES'\n");
605 pFont->info.isStringProp = NULL;
606 pFont->info.props = NULL;
607 pFont->info.nprops = 0;
609 stringProps = malloc((nProps + BDF_GENPROPS) * sizeof(char));
610 pFont->info.isStringProp = stringProps;
611 if (stringProps == NULL) {
612 bdfError("Couldn't allocate stringProps (%d*%d)\n",
613 (nProps + BDF_GENPROPS), sizeof(Bool));
616 pFont->info.props = props = calloc(nProps + BDF_GENPROPS,
617 sizeof(FontPropRec));
619 bdfError("Couldn't allocate props (%d*%d)\n", nProps + BDF_GENPROPS,
620 sizeof(FontPropRec));
626 while (props_left-- > 0) {
627 line = bdfGetLine(file, lineBuf, BDFLINELEN);
628 if (line == NULL || bdfIsPrefix(line, "ENDPROPERTIES")) {
629 bdfError("\"STARTPROPERTIES %d\" followed by only %d properties\n",
630 nProps, nProps - props_left - 1);
633 while (*line && isspace(*line))
636 switch (sscanf((char *) line, "%s%s%s", namebuf, secondbuf, thirdbuf)) {
638 bdfError("missing '%s' parameter value\n", namebuf);
643 * Possibilites include: valid quoted string with no white space
644 * valid integer value invalid value
646 if (secondbuf[0] == '"') {
647 stringProps[nextProp] = TRUE;
648 props[nextProp].value =
649 bdfGetPropertyValue((char *)line + strlen(namebuf) + 1);
650 if (!props[nextProp].value)
653 } else if (bdfIsInteger(secondbuf)) {
654 stringProps[nextProp] = FALSE;
655 props[nextProp].value = atoi(secondbuf);
658 bdfError("invalid '%s' parameter value\n", namebuf);
664 * Possibilites include: valid quoted string with some white space
665 * invalid value (reject even if second string is integer)
667 if (secondbuf[0] == '"') {
668 stringProps[nextProp] = TRUE;
669 props[nextProp].value =
670 bdfGetPropertyValue((char *)line + strlen(namebuf) + 1);
671 if (!props[nextProp].value)
675 bdfError("invalid '%s' parameter value\n", namebuf);
679 props[nextProp].name = bdfForceMakeAtom(namebuf, NULL);
680 if (props[nextProp].name == None) {
681 bdfError("Empty property name.\n");
684 if (!bdfSpecialProperty(pFont, &props[nextProp],
685 stringProps[nextProp], pState))
689 line = bdfGetLine(file, lineBuf, BDFLINELEN);
690 if (!line || !bdfIsPrefix(line, "ENDPROPERTIES")) {
691 bdfError("missing 'ENDPROPERTIES'\n");
694 if (!pState->haveFontAscent || !pState->haveFontDescent) {
695 bdfError("missing 'FONT_ASCENT' or 'FONT_DESCENT' properties\n");
698 if (bitmapFont->bitmapExtra) {
699 bitmapFont->bitmapExtra->info.fontAscent = pFont->info.fontAscent;
700 bitmapFont->bitmapExtra->info.fontDescent = pFont->info.fontDescent;
702 if (!pState->pointSizeProp) {
703 props[nextProp].name = bdfForceMakeAtom("POINT_SIZE", NULL);
704 props[nextProp].value = (INT32) (pState->pointSize * 10.0);
705 stringProps[nextProp] = FALSE;
706 pState->pointSizeProp = &props[nextProp];
709 if (!pState->fontProp) {
710 props[nextProp].name = bdfForceMakeAtom("FONT", NULL);
711 props[nextProp].value = (INT32) bdfForceMakeAtom(pState->fontName, NULL);
712 stringProps[nextProp] = TRUE;
713 pState->fontProp = &props[nextProp];
716 if (!pState->weightProp) {
717 props[nextProp].name = bdfForceMakeAtom("WEIGHT", NULL);
718 props[nextProp].value = -1; /* computed later */
719 stringProps[nextProp] = FALSE;
720 pState->weightProp = &props[nextProp];
723 if (!pState->resolutionProp &&
724 pState->resolution_x == pState->resolution_y) {
725 props[nextProp].name = bdfForceMakeAtom("RESOLUTION", NULL);
726 props[nextProp].value = (INT32) ((pState->resolution_x * 100.0) / 72.27);
727 stringProps[nextProp] = FALSE;
728 pState->resolutionProp = &props[nextProp];
731 if (!pState->resolutionXProp) {
732 props[nextProp].name = bdfForceMakeAtom("RESOLUTION_X", NULL);
733 props[nextProp].value = (INT32) pState->resolution_x;
734 stringProps[nextProp] = FALSE;
735 pState->resolutionProp = &props[nextProp];
738 if (!pState->resolutionYProp) {
739 props[nextProp].name = bdfForceMakeAtom("RESOLUTION_Y", NULL);
740 props[nextProp].value = (INT32) pState->resolution_y;
741 stringProps[nextProp] = FALSE;
742 pState->resolutionProp = &props[nextProp];
745 if (!pState->xHeightProp) {
746 props[nextProp].name = bdfForceMakeAtom("X_HEIGHT", NULL);
747 props[nextProp].value = -1; /* computed later */
748 stringProps[nextProp] = FALSE;
749 pState->xHeightProp = &props[nextProp];
752 if (!pState->quadWidthProp) {
753 props[nextProp].name = bdfForceMakeAtom("QUAD_WIDTH", NULL);
754 props[nextProp].value = -1; /* computed later */
755 stringProps[nextProp] = FALSE;
756 pState->quadWidthProp = &props[nextProp];
759 pFont->info.nprops = nextProp;
762 if (pFont->info.isStringProp) {
763 free(pFont->info.isStringProp);
764 pFont->info.isStringProp = NULL;
766 if (pFont->info.props) {
767 free(pFont->info.props);
768 pFont->info.props = NULL;
770 while (line && bdfIsPrefix(line, "ENDPROPERTIES"))
771 line = bdfGetLine(file, lineBuf, BDFLINELEN);
775 /***====================================================================***/
778 bdfUnloadFont(FontPtr pFont)
780 bdfFreeFontBits (pFont);
781 DestroyFontRec(pFont);
785 bdfReadFont(FontPtr pFont, FontFilePtr file,
786 int bit, int byte, int glyph, int scan)
791 BitmapFontPtr bitmapFont;
793 pFont->fontPrivate = 0;
795 bzero(&state, sizeof(bdfFileState));
798 if (!bdfReadHeader(file, &state))
801 bitmapFont = calloc(1, sizeof(BitmapFontRec));
803 bdfError("Couldn't allocate bitmapFontRec (%d)\n", 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 = calloc(1, sizeof(BitmapExtraRec));
815 if (!bitmapFont->bitmapExtra) {
816 bdfError("Couldn't allocate bitmapExtra (%d)\n", sizeof(BitmapExtraRec));
820 bitmapFont->bitmapExtra->glyphNames = 0;
821 bitmapFont->bitmapExtra->sWidths = 0;
823 if (!bdfReadProperties(file, pFont, &state))
826 if (!bdfReadCharacters(file, pFont, &state, bit, byte, glyph, scan))
829 if (state.haveDefaultCh) {
830 unsigned int r, c, cols;
832 r = pFont->info.defaultCh >> 8;
833 c = pFont->info.defaultCh & 0xFF;
834 if (pFont->info.firstRow <= r && r <= pFont->info.lastRow &&
835 pFont->info.firstCol <= c && c <= pFont->info.lastCol) {
836 cols = pFont->info.lastCol - pFont->info.firstCol + 1;
837 r = r - pFont->info.firstRow;
838 c = c - pFont->info.firstCol;
839 bitmapFont->pDefault = ACCESSENCODING(bitmapFont->encoding,
845 pFont->glyph = glyph;
847 pFont->info.anamorphic = FALSE;
848 pFont->info.cachable = TRUE;
849 bitmapComputeFontBounds(pFont);
850 if (FontCouldBeTerminal(&pFont->info)) {
851 bdfPadToTerminal(pFont);
852 bitmapComputeFontBounds(pFont);
854 FontComputeInfoAccelerators(&pFont->info);
855 if (bitmapFont->bitmapExtra)
856 FontComputeInfoAccelerators(&bitmapFont->bitmapExtra->info);
857 if (pFont->info.constantMetrics) {
858 if (!bitmapAddInkMetrics(pFont)) {
859 bdfError("Failed to add bitmap ink metrics\n");
863 if (bitmapFont->bitmapExtra)
864 bitmapFont->bitmapExtra->info.inkMetrics = pFont->info.inkMetrics;
866 bitmapComputeFontInkBounds(pFont);
867 /* ComputeFontAccelerators (pFont); */
869 /* generate properties */
870 min = &pFont->info.ink_minbounds;
871 max = &pFont->info.ink_maxbounds;
872 if (state.xHeightProp && (state.xHeightProp->value == -1))
873 state.xHeightProp->value = state.exHeight ?
874 state.exHeight : min->ascent;
876 if (state.quadWidthProp && (state.quadWidthProp->value == -1))
877 state.quadWidthProp->value = state.digitCount ?
878 (INT32) (state.digitWidths / state.digitCount) :
879 (min->characterWidth + max->characterWidth) / 2;
881 if (state.weightProp && (state.weightProp->value == -1))
882 state.weightProp->value = bitmapComputeWeight(pFont);
884 pFont->get_glyphs = bitmapGetGlyphs;
885 pFont->get_metrics = bitmapGetMetrics;
886 pFont->unload_font = bdfUnloadFont;
887 pFont->unload_glyphs = NULL;
890 if (pFont->fontPrivate)
891 bdfFreeFontBits (pFont);
896 bdfReadFontInfo(FontInfoPtr pFontInfo, FontFilePtr file)
901 bzero(&font, sizeof (FontRec));
903 ret = bdfReadFont(&font, file, MSBFirst, LSBFirst, 1, 1);
904 if (ret == Successful) {
905 *pFontInfo = font.info;
907 font.info.isStringProp = 0;
908 font.info.nprops = 0;
909 bdfFreeFontBits (&font);
915 bdfPadToTerminal(FontPtr pFont)
917 BitmapFontPtr bitmapFont;
918 BitmapExtraPtr bitmapExtra;
925 bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
927 bzero(&new, sizeof(CharInfoRec));
928 new.metrics.ascent = pFont->info.fontAscent;
929 new.metrics.descent = pFont->info.fontDescent;
930 new.metrics.leftSideBearing = 0;
931 new.metrics.rightSideBearing = pFont->info.minbounds.characterWidth;
932 new.metrics.characterWidth = new.metrics.rightSideBearing;
933 new_size = BYTES_FOR_GLYPH(&new, pFont->glyph);
935 for (i = 0; i < bitmapFont->num_chars; i++) {
936 new.bits = malloc(new_size);
938 bdfError("Couldn't allocate bits (%d)\n", new_size);
941 FontCharReshape(pFont, &bitmapFont->metrics[i], &new);
942 new.metrics.attributes = bitmapFont->metrics[i].metrics.attributes;
943 free(bitmapFont->metrics[i].bits);
944 bitmapFont->metrics[i] = new;
946 bitmapExtra = bitmapFont->bitmapExtra;
948 w = GLYPHWIDTHPIXELS(&new);
949 h = GLYPHHEIGHTPIXELS(&new);
950 for (i = 0; i < GLYPHPADOPTIONS; i++)
951 bitmapExtra->bitmapsSizes[i] = bitmapFont->num_chars *
952 (BYTES_PER_ROW(w, 1 << i) * h);