1a96d7823Smrg/************************************************************************ 2a96d7823SmrgCopyright 1989 by Digital Equipment Corporation, Maynard, Massachusetts. 3a96d7823Smrg 4a96d7823Smrg All Rights Reserved 5a96d7823Smrg 6a96d7823SmrgPermission to use, copy, modify, and distribute this software and its 7a96d7823Smrgdocumentation for any purpose and without fee is hereby granted, 8a96d7823Smrgprovided that the above copyright notice appear in all copies and that 9a96d7823Smrgboth that copyright notice and this permission notice appear in 10a96d7823Smrgsupporting documentation, and that the name of Digital not be 11a96d7823Smrgused in advertising or publicity pertaining to distribution of the 12a96d7823Smrgsoftware without specific, written prior permission. 13a96d7823Smrg 14a96d7823SmrgDIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 15a96d7823SmrgALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 16a96d7823SmrgDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 17a96d7823SmrgANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 18a96d7823SmrgWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 19a96d7823SmrgARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 20a96d7823SmrgSOFTWARE. 21a96d7823Smrg 22a96d7823Smrg************************************************************************/ 23a96d7823Smrg 24a96d7823Smrg/* 25a96d7823Smrg 26a96d7823SmrgCopyright 1994, 1998 The Open Group 27a96d7823Smrg 28a96d7823SmrgPermission to use, copy, modify, distribute, and sell this software and its 29a96d7823Smrgdocumentation for any purpose is hereby granted without fee, provided that 30a96d7823Smrgthe above copyright notice appear in all copies and that both that 31a96d7823Smrgcopyright notice and this permission notice appear in supporting 32a96d7823Smrgdocumentation. 33a96d7823Smrg 34a96d7823SmrgThe above copyright notice and this permission notice shall be included 35a96d7823Smrgin all copies or substantial portions of the Software. 36a96d7823Smrg 37a96d7823SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 38a96d7823SmrgOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 39a96d7823SmrgMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 40a96d7823SmrgIN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR 41a96d7823SmrgOTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 42a96d7823SmrgARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 43a96d7823SmrgOTHER DEALINGS IN THE SOFTWARE. 44a96d7823Smrg 45a96d7823SmrgExcept as contained in this notice, the name of The Open Group shall 46a96d7823Smrgnot be used in advertising or otherwise to promote the sale, use or 47a96d7823Smrgother dealings in this Software without prior written authorization 48a96d7823Smrgfrom The Open Group. 49a96d7823Smrg 50a96d7823Smrg*/ 51a96d7823Smrg 52a96d7823Smrg#ifdef HAVE_CONFIG_H 53a96d7823Smrg#include <config.h> 54a96d7823Smrg#endif 55a96d7823Smrg#include "libxfontint.h" 56c7b4381aSmrg#include "src/util/replace.h" 57a96d7823Smrg 58a96d7823Smrg#include <ctype.h> 59a96d7823Smrg#include <X11/fonts/fntfilst.h> 60a96d7823Smrg#include <X11/fonts/bitmap.h> 61a96d7823Smrg#include "snfstr.h" 62a96d7823Smrg 63a96d7823Smrg#include <stdarg.h> 64a96d7823Smrg 65a96d7823Smrgstatic void _X_ATTRIBUTE_PRINTF(1, 2) 66a96d7823SmrgsnfError(const char* message, ...) 67a96d7823Smrg{ 68a96d7823Smrg va_list args; 69a96d7823Smrg 70a96d7823Smrg va_start(args, message); 71a96d7823Smrg 72a96d7823Smrg fprintf(stderr, "SNF Error: "); 73a96d7823Smrg vfprintf(stderr, message, args); 74a96d7823Smrg va_end(args); 75a96d7823Smrg} 76a96d7823Smrg 77a96d7823Smrgstatic void snfUnloadFont(FontPtr pFont); 78a96d7823Smrg 79a96d7823Smrgstatic int 80a96d7823SmrgsnfReadCharInfo(FontFilePtr file, CharInfoPtr charInfo, char *base) 81a96d7823Smrg{ 82a96d7823Smrg snfCharInfoRec snfCharInfo; 83a96d7823Smrg 84a96d7823Smrg#define Width(m) ((m).rightSideBearing - (m).leftSideBearing) 85a96d7823Smrg#define Height(m) ((m).ascent + (m).descent) 86a96d7823Smrg 87a96d7823Smrg if (FontFileRead(file, (char *) &snfCharInfo, sizeof snfCharInfo) != 88a96d7823Smrg sizeof(snfCharInfo)) { 89a96d7823Smrg return BadFontName; 90a96d7823Smrg } 91a96d7823Smrg charInfo->metrics = snfCharInfo.metrics; 92a96d7823Smrg if (snfCharInfo.exists) 93a96d7823Smrg charInfo->bits = base + snfCharInfo.byteOffset; 94a96d7823Smrg else 95a96d7823Smrg charInfo->bits = 0; 96a96d7823Smrg return Successful; 97a96d7823Smrg} 98a96d7823Smrg 99a96d7823Smrgstatic int 100a96d7823SmrgsnfReadxCharInfo(FontFilePtr file, xCharInfo *charInfo) 101a96d7823Smrg{ 102a96d7823Smrg snfCharInfoRec snfCharInfo; 103a96d7823Smrg 104a96d7823Smrg if (FontFileRead(file, (char *) &snfCharInfo, sizeof snfCharInfo) != 105a96d7823Smrg sizeof(snfCharInfo)) { 106a96d7823Smrg return BadFontName; 107a96d7823Smrg } 108a96d7823Smrg *charInfo = snfCharInfo.metrics; 109a96d7823Smrg return Successful; 110a96d7823Smrg} 111a96d7823Smrg 112a96d7823Smrgstatic void 113a96d7823SmrgsnfCopyInfo(snfFontInfoPtr snfInfo, FontInfoPtr pFontInfo) 114a96d7823Smrg{ 115a96d7823Smrg pFontInfo->firstCol = snfInfo->firstCol; 116a96d7823Smrg pFontInfo->lastCol = snfInfo->lastCol; 117a96d7823Smrg pFontInfo->firstRow = snfInfo->firstRow; 118a96d7823Smrg pFontInfo->lastRow = snfInfo->lastRow; 119a96d7823Smrg pFontInfo->defaultCh = snfInfo->chDefault; 120a96d7823Smrg pFontInfo->noOverlap = snfInfo->noOverlap; 121a96d7823Smrg pFontInfo->terminalFont = snfInfo->terminalFont; 122a96d7823Smrg pFontInfo->constantMetrics = snfInfo->constantMetrics; 123a96d7823Smrg pFontInfo->constantWidth = snfInfo->constantWidth; 124a96d7823Smrg pFontInfo->inkInside = snfInfo->inkInside; 125a96d7823Smrg pFontInfo->inkMetrics = snfInfo->inkMetrics; 126a96d7823Smrg pFontInfo->allExist = snfInfo->allExist; 127a96d7823Smrg pFontInfo->drawDirection = snfInfo->drawDirection; 128a96d7823Smrg pFontInfo->anamorphic = FALSE; 129a96d7823Smrg pFontInfo->cachable = TRUE; 130a96d7823Smrg pFontInfo->maxOverlap = 0; 131a96d7823Smrg pFontInfo->minbounds = snfInfo->minbounds.metrics; 132a96d7823Smrg pFontInfo->maxbounds = snfInfo->maxbounds.metrics; 133a96d7823Smrg pFontInfo->fontAscent = snfInfo->fontAscent; 134a96d7823Smrg pFontInfo->fontDescent = snfInfo->fontDescent; 135a96d7823Smrg pFontInfo->nprops = snfInfo->nProps; 136a96d7823Smrg} 137a96d7823Smrg 138a96d7823Smrgstatic int 139a96d7823SmrgsnfReadProps(snfFontInfoPtr snfInfo, FontInfoPtr pFontInfo, FontFilePtr file) 140a96d7823Smrg{ 141a96d7823Smrg char *strings; 142a96d7823Smrg FontPropPtr pfp; 143a96d7823Smrg snfFontPropPtr psnfp; 144a96d7823Smrg char *propspace; 145a96d7823Smrg int bytestoalloc; 146a96d7823Smrg int i; 147a96d7823Smrg 148a96d7823Smrg bytestoalloc = snfInfo->nProps * sizeof(snfFontPropRec) + 149a96d7823Smrg BYTESOFSTRINGINFO(snfInfo); 150a96d7823Smrg propspace = malloc(bytestoalloc); 151a96d7823Smrg if (!propspace) { 152a96d7823Smrg snfError("snfReadProps(): Couldn't allocate propspace (%d)\n", bytestoalloc); 153a96d7823Smrg return AllocError; 154a96d7823Smrg } 155a96d7823Smrg 156a96d7823Smrg if (FontFileRead(file, propspace, bytestoalloc) != bytestoalloc) { 157a96d7823Smrg free(propspace); 158a96d7823Smrg return BadFontName; 159a96d7823Smrg } 160a96d7823Smrg psnfp = (snfFontPropPtr) propspace; 161a96d7823Smrg 162a96d7823Smrg strings = propspace + BYTESOFPROPINFO(snfInfo); 163a96d7823Smrg 164a96d7823Smrg for (i = 0, pfp = pFontInfo->props; i < snfInfo->nProps; i++, pfp++, psnfp++) { 165a96d7823Smrg pfp->name = MakeAtom(&strings[psnfp->name], 166a96d7823Smrg (unsigned) strlen(&strings[psnfp->name]), 1); 167a96d7823Smrg pFontInfo->isStringProp[i] = psnfp->indirect; 168a96d7823Smrg if (psnfp->indirect) 169a96d7823Smrg pfp->value = (INT32) MakeAtom(&strings[psnfp->value], 170a96d7823Smrg (unsigned) strlen(&strings[psnfp->value]), 1); 171a96d7823Smrg else 172a96d7823Smrg pfp->value = psnfp->value; 173a96d7823Smrg } 174a96d7823Smrg 175a96d7823Smrg free(propspace); 176a96d7823Smrg return Successful; 177a96d7823Smrg} 178a96d7823Smrg 179a96d7823Smrgstatic int 180a96d7823SmrgsnfReadHeader(snfFontInfoPtr snfInfo, FontFilePtr file) 181a96d7823Smrg{ 182a96d7823Smrg if (FontFileRead(file, (char *) snfInfo, sizeof *snfInfo) != sizeof *snfInfo) 183a96d7823Smrg return BadFontName; 184a96d7823Smrg 185a96d7823Smrg if (snfInfo->version1 != FONT_FILE_VERSION || 186a96d7823Smrg snfInfo->version2 != FONT_FILE_VERSION) 187a96d7823Smrg return BadFontName; 188a96d7823Smrg return Successful; 189a96d7823Smrg} 190a96d7823Smrg 191a96d7823Smrgstatic int snf_set; 192a96d7823Smrgstatic int snf_bit, snf_byte, snf_glyph, snf_scan; 193a96d7823Smrg 194a96d7823Smrgvoid 195a96d7823SmrgSnfSetFormat (int bit, int byte, int glyph, int scan) 196a96d7823Smrg{ 197a96d7823Smrg snf_bit = bit; 198a96d7823Smrg snf_byte = byte; 199a96d7823Smrg snf_glyph = glyph; 200a96d7823Smrg snf_scan = scan; 201a96d7823Smrg snf_set = 1; 202a96d7823Smrg} 203a96d7823Smrg 204a96d7823Smrgstatic void 205a96d7823SmrgSnfGetFormat (int *bit, int *byte, int *glyph, int *scan) 206a96d7823Smrg{ 207a96d7823Smrg if (!snf_set) 208a96d7823Smrg FontDefaultFormat (&snf_bit, &snf_byte, &snf_glyph, &snf_scan); 209a96d7823Smrg *bit = snf_bit; 210a96d7823Smrg *byte = snf_byte; 211a96d7823Smrg *glyph = snf_glyph; 212a96d7823Smrg *scan = snf_scan; 213a96d7823Smrg} 214a96d7823Smrg 215a96d7823Smrgint 216a96d7823SmrgsnfReadFont(FontPtr pFont, FontFilePtr file, 217a96d7823Smrg int bit, int byte, int glyph, int scan) 218a96d7823Smrg{ 219a96d7823Smrg snfFontInfoRec fi; 220a96d7823Smrg unsigned bytestoalloc; 221a96d7823Smrg int i, j; 222a96d7823Smrg char *fontspace; 223a96d7823Smrg BitmapFontPtr bitmapFont; 224a96d7823Smrg int num_chars; 225a96d7823Smrg int bitmapsSize; 226a96d7823Smrg int ret; 227a96d7823Smrg int metrics_off; 228a96d7823Smrg int encoding_off; 229a96d7823Smrg int props_off; 230a96d7823Smrg int isStringProp_off; 231a96d7823Smrg int ink_off; 232a96d7823Smrg char *bitmaps; 233a96d7823Smrg int def_bit, def_byte, def_glyph, def_scan; 234a96d7823Smrg 235a96d7823Smrg ret = snfReadHeader(&fi, file); 236a96d7823Smrg if (ret != Successful) 237a96d7823Smrg return ret; 238a96d7823Smrg 239a96d7823Smrg SnfGetFormat (&def_bit, &def_byte, &def_glyph, &def_scan); 240a96d7823Smrg 241a96d7823Smrg /* 242a96d7823Smrg * we'll allocate one chunk of memory and split it among the various parts 243a96d7823Smrg * of the font: 244a96d7823Smrg * 245a96d7823Smrg * BitmapFontRec CharInfoRec's Glyphs Encoding DIX Properties Ink CharInfoRec's 246a96d7823Smrg * 247a96d7823Smrg * If the glyphpad is not the same as the font file, then the glyphs 248a96d7823Smrg * are allocated separately, to be later realloc'ed when we know 249a96d7823Smrg * how big to make them. 250a96d7823Smrg */ 251a96d7823Smrg 252a96d7823Smrg bitmapsSize = BYTESOFGLYPHINFO(&fi); 253a96d7823Smrg num_chars = n2dChars(&fi); 254a96d7823Smrg bytestoalloc = sizeof(BitmapFontRec); /* bitmapFont */ 255a96d7823Smrg metrics_off = bytestoalloc; 256a96d7823Smrg bytestoalloc += num_chars * sizeof(CharInfoRec); /* metrics */ 257a96d7823Smrg encoding_off = bytestoalloc; 258a96d7823Smrg bytestoalloc += NUM_SEGMENTS(num_chars) * sizeof(CharInfoPtr**); 259a96d7823Smrg /* encoding */ 260a96d7823Smrg props_off = bytestoalloc; 261a96d7823Smrg bytestoalloc += fi.nProps * sizeof(FontPropRec); /* props */ 262a96d7823Smrg isStringProp_off = bytestoalloc; 263a96d7823Smrg bytestoalloc += fi.nProps * sizeof(char); /* isStringProp */ 264a96d7823Smrg bytestoalloc = (bytestoalloc + 3) & ~3; 265a96d7823Smrg ink_off = bytestoalloc; 266a96d7823Smrg if (fi.inkMetrics) 267a96d7823Smrg bytestoalloc += num_chars * sizeof(xCharInfo); /* ink_metrics */ 268a96d7823Smrg 269a96d7823Smrg fontspace = malloc(bytestoalloc); 270a96d7823Smrg if (!fontspace) { 271a96d7823Smrg snfError("snfReadFont(): Couldn't allocate fontspace (%d)\n", bytestoalloc); 272a96d7823Smrg return AllocError; 273a96d7823Smrg } 274a96d7823Smrg bitmaps = malloc (bitmapsSize); 275a96d7823Smrg if (!bitmaps) 276a96d7823Smrg { 277a96d7823Smrg snfError("snfReadFont(): Couldn't allocate bitmaps (%d)\n", bitmapsSize); 278a96d7823Smrg free (fontspace); 279a96d7823Smrg return AllocError; 280a96d7823Smrg } 281a96d7823Smrg /* 282a96d7823Smrg * now fix up pointers 283a96d7823Smrg */ 284a96d7823Smrg 285a96d7823Smrg bitmapFont = (BitmapFontPtr) fontspace; 286a96d7823Smrg bitmapFont->num_chars = num_chars; 287a96d7823Smrg bitmapFont->metrics = (CharInfoPtr) (fontspace + metrics_off); 288a96d7823Smrg bitmapFont->encoding = (CharInfoPtr **) (fontspace + encoding_off); 289a96d7823Smrg bitmapFont->bitmaps = bitmaps; 290a96d7823Smrg bitmapFont->pDefault = NULL; 291a96d7823Smrg bitmapFont->bitmapExtra = NULL; 292a96d7823Smrg pFont->info.props = (FontPropPtr) (fontspace + props_off); 293a96d7823Smrg pFont->info.isStringProp = (char *) (fontspace + isStringProp_off); 294a96d7823Smrg if (fi.inkMetrics) 295a96d7823Smrg bitmapFont->ink_metrics = (xCharInfo *) (fontspace + ink_off); 296a96d7823Smrg else 297a96d7823Smrg bitmapFont->ink_metrics = 0; 298a96d7823Smrg 299a96d7823Smrg /* 300a96d7823Smrg * read the CharInfo 301a96d7823Smrg */ 302a96d7823Smrg 303a96d7823Smrg ret = Successful; 304a96d7823Smrg memset(bitmapFont->encoding, 0, 305a96d7823Smrg NUM_SEGMENTS(num_chars)*sizeof(CharInfoPtr*)); 306a96d7823Smrg for (i = 0; ret == Successful && i < num_chars; i++) { 307a96d7823Smrg ret = snfReadCharInfo(file, &bitmapFont->metrics[i], bitmaps); 308a96d7823Smrg if (bitmapFont->metrics[i].bits) { 309a96d7823Smrg if (!bitmapFont->encoding[SEGMENT_MAJOR(i)]) { 310a96d7823Smrg bitmapFont->encoding[SEGMENT_MAJOR(i)]= 311a96d7823Smrg calloc(BITMAP_FONT_SEGMENT_SIZE, sizeof(CharInfoPtr)); 312a96d7823Smrg if (!bitmapFont->encoding[SEGMENT_MAJOR(i)]) { 313a96d7823Smrg ret = AllocError; 314a96d7823Smrg break; 315a96d7823Smrg } 316a96d7823Smrg } 317a96d7823Smrg ACCESSENCODINGL(bitmapFont->encoding,i) = &bitmapFont->metrics[i]; 318a96d7823Smrg } 319a96d7823Smrg } 320a96d7823Smrg 321a96d7823Smrg if (ret != Successful) { 322a96d7823Smrg free(bitmaps); 323a96d7823Smrg if(bitmapFont->encoding) { 324a96d7823Smrg for(j=0; j<SEGMENT_MAJOR(i); j++) 325a96d7823Smrg free(bitmapFont->encoding[i]); 326a96d7823Smrg } 327a96d7823Smrg free(fontspace); 328a96d7823Smrg return ret; 329a96d7823Smrg } 330a96d7823Smrg /* 331a96d7823Smrg * read the glyphs 332a96d7823Smrg */ 333a96d7823Smrg 334a96d7823Smrg if (FontFileRead(file, bitmaps, bitmapsSize) != bitmapsSize) { 335a96d7823Smrg free(bitmaps); 336a96d7823Smrg free(fontspace); 337a96d7823Smrg return BadFontName; 338a96d7823Smrg } 339a96d7823Smrg 340a96d7823Smrg if (def_bit != bit) 341a96d7823Smrg BitOrderInvert((unsigned char *)bitmaps, bitmapsSize); 342a96d7823Smrg if ((def_byte == def_bit) != (bit == byte)) { 343a96d7823Smrg switch (bit == byte ? def_scan : scan) { 344a96d7823Smrg case 1: 345a96d7823Smrg break; 346a96d7823Smrg case 2: 347a96d7823Smrg TwoByteSwap((unsigned char *)bitmaps, bitmapsSize); 348a96d7823Smrg break; 349a96d7823Smrg case 4: 350a96d7823Smrg FourByteSwap((unsigned char *)bitmaps, bitmapsSize); 351a96d7823Smrg break; 352a96d7823Smrg } 353a96d7823Smrg } 354a96d7823Smrg if (def_glyph != glyph) { 355a96d7823Smrg char *padbitmaps; 356a96d7823Smrg int sizepadbitmaps; 357a96d7823Smrg int sizechar; 358a96d7823Smrg CharInfoPtr metric; 359a96d7823Smrg 360a96d7823Smrg sizepadbitmaps = 0; 361a96d7823Smrg metric = bitmapFont->metrics; 362a96d7823Smrg for (i = 0; i < num_chars; i++) 363a96d7823Smrg { 364a96d7823Smrg if (metric->bits) 365a96d7823Smrg sizepadbitmaps += BYTES_FOR_GLYPH(metric,glyph); 366a96d7823Smrg metric++; 367a96d7823Smrg } 368a96d7823Smrg padbitmaps = malloc(sizepadbitmaps); 369a96d7823Smrg if (!padbitmaps) { 370a96d7823Smrg snfError("snfReadFont(): Couldn't allocate padbitmaps (%d)\n", sizepadbitmaps); 371a96d7823Smrg free (bitmaps); 372a96d7823Smrg free (fontspace); 373a96d7823Smrg return AllocError; 374a96d7823Smrg } 375a96d7823Smrg metric = bitmapFont->metrics; 376a96d7823Smrg bitmapFont->bitmaps = padbitmaps; 377a96d7823Smrg for (i = 0; i < num_chars; i++) { 378a96d7823Smrg sizechar = RepadBitmap(metric->bits, padbitmaps, 379a96d7823Smrg def_glyph, glyph, 380a96d7823Smrg metric->metrics.rightSideBearing - 381a96d7823Smrg metric->metrics.leftSideBearing, 382a96d7823Smrg metric->metrics.ascent + metric->metrics.descent); 383a96d7823Smrg metric->bits = padbitmaps; 384a96d7823Smrg padbitmaps += sizechar; 385a96d7823Smrg metric++; 386a96d7823Smrg } 387a96d7823Smrg free(bitmaps); 388a96d7823Smrg } 389a96d7823Smrg 390a96d7823Smrg /* now read and atom'ize properties */ 391a96d7823Smrg 392a96d7823Smrg ret = snfReadProps(&fi, &pFont->info, file); 393a96d7823Smrg if (ret != Successful) { 394a96d7823Smrg free(fontspace); 395a96d7823Smrg return ret; 396a96d7823Smrg } 397a96d7823Smrg snfCopyInfo(&fi, &pFont->info); 398a96d7823Smrg 399a96d7823Smrg /* finally, read the ink metrics if the exist */ 400a96d7823Smrg 401a96d7823Smrg if (fi.inkMetrics) { 402a96d7823Smrg ret = Successful; 403a96d7823Smrg ret = snfReadxCharInfo(file, &pFont->info.ink_minbounds); 404a96d7823Smrg ret = snfReadxCharInfo(file, &pFont->info.ink_maxbounds); 405a96d7823Smrg for (i = 0; ret == Successful && i < num_chars; i++) 406a96d7823Smrg ret = snfReadxCharInfo(file, &bitmapFont->ink_metrics[i]); 407a96d7823Smrg if (ret != Successful) { 408a96d7823Smrg free(fontspace); 409a96d7823Smrg return ret; 410a96d7823Smrg } 411a96d7823Smrg } else { 412a96d7823Smrg pFont->info.ink_minbounds = pFont->info.minbounds; 413a96d7823Smrg pFont->info.ink_maxbounds = pFont->info.maxbounds; 414a96d7823Smrg } 415a96d7823Smrg 416a96d7823Smrg if (pFont->info.defaultCh != (unsigned short) NO_SUCH_CHAR) { 417a96d7823Smrg unsigned int r, 418a96d7823Smrg c, 419a96d7823Smrg cols; 420a96d7823Smrg 421a96d7823Smrg r = pFont->info.defaultCh >> 8; 422a96d7823Smrg c = pFont->info.defaultCh & 0xFF; 423a96d7823Smrg if (pFont->info.firstRow <= r && r <= pFont->info.lastRow && 424a96d7823Smrg pFont->info.firstCol <= c && c <= pFont->info.lastCol) { 425a96d7823Smrg cols = pFont->info.lastCol - pFont->info.firstCol + 1; 426a96d7823Smrg r = r - pFont->info.firstRow; 427a96d7823Smrg c = c - pFont->info.firstCol; 428a96d7823Smrg bitmapFont->pDefault = &bitmapFont->metrics[r * cols + c]; 429a96d7823Smrg } 430a96d7823Smrg } 431a96d7823Smrg bitmapFont->bitmapExtra = (BitmapExtraPtr) 0; 432a96d7823Smrg pFont->fontPrivate = (pointer) bitmapFont; 433a96d7823Smrg pFont->get_glyphs = bitmapGetGlyphs; 434a96d7823Smrg pFont->get_metrics = bitmapGetMetrics; 435a96d7823Smrg pFont->unload_font = snfUnloadFont; 436a96d7823Smrg pFont->unload_glyphs = NULL; 437a96d7823Smrg pFont->bit = bit; 438a96d7823Smrg pFont->byte = byte; 439a96d7823Smrg pFont->glyph = glyph; 440a96d7823Smrg pFont->scan = scan; 441a96d7823Smrg return Successful; 442a96d7823Smrg} 443a96d7823Smrg 444a96d7823Smrgint 445a96d7823SmrgsnfReadFontInfo(FontInfoPtr pFontInfo, FontFilePtr file) 446a96d7823Smrg{ 447a96d7823Smrg int ret; 448a96d7823Smrg snfFontInfoRec fi; 449a96d7823Smrg int bytestoskip; 450a96d7823Smrg int num_chars; 451a96d7823Smrg 452a96d7823Smrg ret = snfReadHeader(&fi, file); 453a96d7823Smrg if (ret != Successful) 454a96d7823Smrg return ret; 455a96d7823Smrg snfCopyInfo(&fi, pFontInfo); 456a96d7823Smrg 457c7b4381aSmrg pFontInfo->props = mallocarray(fi.nProps, sizeof(FontPropRec)); 458a96d7823Smrg if (!pFontInfo->props) { 459a96d7823Smrg snfError("snfReadFontInfo(): Couldn't allocate props (%d*%d)\n", 460a96d7823Smrg fi.nProps, (int) sizeof(FontPropRec)); 461a96d7823Smrg return AllocError; 462a96d7823Smrg } 463c7b4381aSmrg pFontInfo->isStringProp = mallocarray(fi.nProps, sizeof(char)); 464a96d7823Smrg if (!pFontInfo->isStringProp) { 465a96d7823Smrg snfError("snfReadFontInfo(): Couldn't allocate isStringProp (%d*%d)\n", 466a96d7823Smrg fi.nProps, (int) sizeof(char)); 467a96d7823Smrg free(pFontInfo->props); 468a96d7823Smrg return AllocError; 469a96d7823Smrg } 470a96d7823Smrg num_chars = n2dChars(&fi); 471a96d7823Smrg bytestoskip = num_chars * sizeof(snfCharInfoRec); /* charinfos */ 472a96d7823Smrg bytestoskip += BYTESOFGLYPHINFO(&fi); 473a96d7823Smrg (void)FontFileSkip(file, bytestoskip); 474a96d7823Smrg 475a96d7823Smrg ret = snfReadProps(&fi, pFontInfo, file); 476a96d7823Smrg if (ret != Successful) { 477a96d7823Smrg free(pFontInfo->props); 478a96d7823Smrg free(pFontInfo->isStringProp); 479a96d7823Smrg return ret; 480a96d7823Smrg } 481a96d7823Smrg if (fi.inkMetrics) { 482a96d7823Smrg ret = snfReadxCharInfo(file, &pFontInfo->ink_minbounds); 483a96d7823Smrg if (ret != Successful) { 484a96d7823Smrg free(pFontInfo->props); 485a96d7823Smrg free(pFontInfo->isStringProp); 486a96d7823Smrg return ret; 487a96d7823Smrg } 488a96d7823Smrg ret = snfReadxCharInfo(file, &pFontInfo->ink_maxbounds); 489a96d7823Smrg if (ret != Successful) { 490a96d7823Smrg free(pFontInfo->props); 491a96d7823Smrg free(pFontInfo->isStringProp); 492a96d7823Smrg return ret; 493a96d7823Smrg } 494a96d7823Smrg } else { 495a96d7823Smrg pFontInfo->ink_minbounds = pFontInfo->minbounds; 496a96d7823Smrg pFontInfo->ink_maxbounds = pFontInfo->maxbounds; 497a96d7823Smrg } 498a96d7823Smrg return Successful; 499a96d7823Smrg 500a96d7823Smrg} 501a96d7823Smrg 502a96d7823Smrgstatic void 503a96d7823SmrgsnfUnloadFont(FontPtr pFont) 504a96d7823Smrg{ 505a96d7823Smrg BitmapFontPtr bitmapFont; 506a96d7823Smrg 507a96d7823Smrg bitmapFont = (BitmapFontPtr) pFont->fontPrivate; 508a96d7823Smrg free (bitmapFont->bitmaps); 509a96d7823Smrg free (bitmapFont); 510a96d7823Smrg DestroyFontRec (pFont); 511a96d7823Smrg} 512a96d7823Smrg 513