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