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