|
|
1.1 ! root 1: /************************************************************************ ! 2: Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts, ! 3: and the Massachusetts Institute of Technology, Cambridge, Massachusetts. ! 4: ! 5: All Rights Reserved ! 6: ! 7: Permission to use, copy, modify, and distribute this software and its ! 8: documentation for any purpose and without fee is hereby granted, ! 9: provided that the above copyright notice appear in all copies and that ! 10: both that copyright notice and this permission notice appear in ! 11: supporting documentation, and that the names of Digital or MIT not be ! 12: used in advertising or publicity pertaining to distribution of the ! 13: software without specific, written prior permission. ! 14: ! 15: DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ! 16: ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL ! 17: DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ! 18: ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, ! 19: WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ! 20: ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS ! 21: SOFTWARE. ! 22: ! 23: ************************************************************************/ ! 24: ! 25: /* $Header: fonts.c,v 1.46 87/09/09 13:23:03 rws Exp $ */ ! 26: ! 27: #define NEED_REPLIES ! 28: #include "X.h" ! 29: #include "Xmd.h" ! 30: #include "Xproto.h" ! 31: #include "dixfontstr.h" ! 32: #include "fontstruct.h" ! 33: #include "scrnintstr.h" ! 34: #include "resource.h" ! 35: #include "osstruct.h" ! 36: #include "dix.h" ! 37: #include "cursorstr.h" ! 38: #include "misc.h" ! 39: #include "opaque.h" ! 40: ! 41: static FontPtr pFontHead = NullFont; ! 42: extern FontPtr defaultFont; ! 43: ! 44: ! 45: /* ! 46: * adding RT_FONT prevents conflict with default cursor font ! 47: */ ! 48: SetDefaultFont( defaultfontname) ! 49: char * defaultfontname; ! 50: { ! 51: FontPtr pf; ! 52: ! 53: if ((pf =OpenFont( strlen( defaultfontname), defaultfontname)) == NullFont) ! 54: return FALSE; ! 55: ! 56: AddResource( FakeClientID(0), RT_FONT, pf, CloseFont, RC_CORE); ! 57: defaultFont = pf; ! 58: return TRUE; ! 59: } ! 60: ! 61: /* ! 62: * Check reference count first, load font only if necessary. ! 63: */ ! 64: FontPtr ! 65: OpenFont( lenfname, pfilename) ! 66: int lenfname; ! 67: char * pfilename; ! 68: { ! 69: FontPtr pfont; ! 70: int lenpname; ! 71: char * ppathname; ! 72: FID pf; ! 73: int nscr; ! 74: ScreenPtr pscr; ! 75: ! 76: FontPtr ReadNFont(); ! 77: ! 78: /* ! 79: * call os-dependent code ! 80: */ ! 81: if ( (lenpname = ExpandFontName( &ppathname, lenfname, pfilename)) == 0) ! 82: { ! 83: #ifdef notdef ! 84: ErrorF( "OpenFont: ExpandFontName failed to find file '%s', (len = %d)\n", ! 85: pfilename, lenfname); ! 86: #endif ! 87: return NullFont; ! 88: } ! 89: /* ! 90: * first look up font name in list of opened fonts ! 91: */ ! 92: for ( pfont = pFontHead; ! 93: pfont != NullFont; ! 94: pfont = pfont->next) ! 95: if ( lenpname == pfont->lenpname ! 96: && strncmp( pfont->pathname, ppathname, pfont->lenpname) == 0) ! 97: { ! 98: /* ! 99: * found it! ! 100: */ ! 101: pfont->refcnt += 1; ! 102: Xfree(ppathname); ! 103: return pfont; ! 104: } ! 105: ! 106: /* ! 107: * if not found in fonts list, read it off disk ! 108: */ ! 109: ! 110: if ( (pf = FiOpenForRead( lenpname, ppathname)) == NullFID) ! 111: { ! 112: #ifdef notdef ! 113: ErrorF( ! 114: "OpenFont: failed to open font file %s\n", ! 115: ppathname); ! 116: #endif ! 117: Xfree(ppathname); ! 118: return NullFont; ! 119: } ! 120: pfont = ReadNFont( pf); ! 121: FiClose( pf); ! 122: ! 123: if ( pfont == NullFont) ! 124: { ! 125: #ifdef notdef ! 126: ErrorF( "OpenFont: ReadNFont failed on file %s\n", ppathname); ! 127: #endif ! 128: Xfree(ppathname); ! 129: return NullFont; ! 130: } ! 131: ! 132: pfont->lenpname = lenpname; ! 133: pfont->pathname = (char *)Xalloc( lenpname); /* record pathname */ ! 134: strncpy( pfont->pathname, ppathname, lenpname); ! 135: ! 136: pfont->refcnt = 1; ! 137: pfont->next = pFontHead; /* prepend to fonts list */ ! 138: pFontHead = pfont; ! 139: ! 140: /* ! 141: * since this font has been newly read off disk, ask each screen to ! 142: * realize it. ! 143: */ ! 144: for ( nscr=0, pscr=screenInfo.screen; ! 145: nscr<screenInfo.numScreens; ! 146: nscr++, pscr++) ! 147: { ! 148: if ( pscr->RealizeFont) ! 149: ( *pscr->RealizeFont)( pscr, pfont); ! 150: } ! 151: Xfree(ppathname); ! 152: return pfont; ! 153: } ! 154: ! 155: /* ! 156: * Decrement font's ref count, and free storage if ref count equals zero ! 157: */ ! 158: void ! 159: CloseFont( pfont) ! 160: FontPtr pfont; ! 161: { ! 162: FontPtr ptf; ! 163: FontPtr pbtf = NullFont; ! 164: int nscr; ! 165: ScreenPtr pscr; ! 166: ! 167: if (pfont == NullFont) ! 168: return ; ! 169: for ( ptf = pFontHead; ! 170: ptf != NullFont; ! 171: ptf = ptf->next) ! 172: { ! 173: if ( ptf == pfont || ptf == NullFont) ! 174: break; ! 175: pbtf = ptf; ! 176: } ! 177: if ( ptf == NullFont) ! 178: { ! 179: ErrorF( "CloseFont: couldn't find font to be closed %x\n", ptf); ! 180: return; ! 181: } ! 182: if ( --ptf->refcnt == 0) ! 183: { ! 184: if ( pbtf == NullFont) /* unlink ptf */ ! 185: pFontHead = ptf->next; ! 186: else ! 187: pbtf->next = ptf->next; ! 188: ! 189: /* ! 190: * since the last reference is gone, ask each screen to ! 191: * free any storage it may have allocated locally for it. ! 192: */ ! 193: for ( nscr=0, pscr=screenInfo.screen; ! 194: nscr<screenInfo.numScreens; ! 195: nscr++, pscr++) ! 196: { ! 197: if ( pscr->UnrealizeFont) ! 198: ( *pscr->UnrealizeFont)( pscr, ptf); ! 199: } ! 200: Xfree( ptf->pathname); ! 201: Xfree( ptf); ! 202: if (pfont == defaultFont) ! 203: defaultFont = NULL; ! 204: } ! 205: } ! 206: ! 207: ! 208: /* ! 209: * description ! 210: * ! 211: * Allocates storage with Xalloc(), and returns a pointer to it. ! 212: * Client can call Xfree() to deallocate font. ! 213: * ! 214: * file I/O is all in this routine ! 215: */ ! 216: FontPtr ! 217: ReadNFont( fp) ! 218: FID fp; /* caller has to FiOpenForRead the file himself */ ! 219: { ! 220: FontPtr pfont; ! 221: FontInfoRec fi; ! 222: DIXFontProp *pdfp; ! 223: FontPropPtr pffp; ! 224: char *propspace; ! 225: int bytestoread, bytestoalloc; ! 226: int bytesdata; ! 227: int i; ! 228: char *strings; ! 229: ! 230: /* swap bytes? XXX */ ! 231: ! 232: bytestoread = BYTESOFFONTINFO(&fi); ! 233: if ( FiRead( &fi, 1, bytestoread, fp) != bytestoread) ! 234: { ! 235: ErrorF("ReadNFont: unexpected EOF\n"); ! 236: return NullFont; ! 237: } ! 238: ! 239: if (fi.version1 != FONT_FILE_VERSION || fi.version2 != FONT_FILE_VERSION) ! 240: { ! 241: ErrorF("ReadNFont: bad font version; expected %d, got %d and %d\n", ! 242: FONT_FILE_VERSION, fi.version1, fi.version2); ! 243: return NullFont; ! 244: } ! 245: ! 246: bytesdata = BYTESOFFONTINFO(&fi); ! 247: bytesdata += BYTESOFCHARINFO(&fi); ! 248: bytesdata += BYTESOFGLYPHINFO(&fi); ! 249: ! 250: bytestoalloc = BYTESOFFONTINFO(&fi)+bytesdata+BYTESOFPROPINFO(&fi); ! 251: pfont = (FontPtr ) Xalloc(bytestoalloc); ! 252: ! 253: bytestoread = bytesdata - BYTESOFFONTINFO(&fi); ! 254: if ( FiRead((char *)(&pfont[1]) + BYTESOFFONTINFO(&fi), ! 255: 1, bytestoread, ! 256: fp ) != bytestoread) ! 257: { ! 258: ErrorF("ReadNFont: unexpected EOF\n"); ! 259: Xfree(pfont); ! 260: return NullFont; ! 261: } ! 262: ! 263: /* ! 264: * now fix up pointers ! 265: */ ! 266: pfont->pFI = (FontInfoPtr)&pfont[1]; ! 267: *pfont->pFI = fi; /* copy date previously read */ ! 268: ! 269: pfont->pCI = ADDRCharInfoRec(pfont->pFI); ! 270: ! 271: pfont->pGlyphs = ADDRCHARGLYPHS(pfont->pFI); ! 272: ! 273: pfont->pFP = ADDRXFONTPROPS(pfont->pFI); ! 274: ! 275: /* now read and atom'ize properties */ ! 276: ! 277: bytestoalloc = BYTESOFPROPINFO(pfont->pFI) + BYTESOFSTRINGINFO(pfont->pFI); ! 278: propspace = (char *) Xalloc(bytestoalloc); ! 279: ! 280: pffp = (FontPropPtr)propspace; ! 281: strings = propspace + BYTESOFPROPINFO(pfont->pFI); ! 282: ! 283: bytestoread = bytestoalloc; ! 284: if ( FiRead( ! 285: pffp, 1, ! 286: bytestoread, ! 287: fp) != bytestoread) ! 288: { ! 289: ErrorF("ReadNFont: unexpected EOF\n"); ! 290: Xfree(pfont); ! 291: Xfree(propspace); ! 292: return NullFont; ! 293: } ! 294: ! 295: for (i=0, pdfp=pfont->pFP; i<fi.nProps; i++, pdfp++, pffp++) ! 296: { ! 297: pdfp->name = MakeAtom( ! 298: &strings[pffp->name], strlen(&strings[pffp->name]), 1); ! 299: if (pffp->indirect) ! 300: pdfp->value = (INT32)MakeAtom( ! 301: &strings[pffp->value], strlen(&strings[pffp->value]), 1); ! 302: else ! 303: pdfp->value = pffp->value; ! 304: } ! 305: ! 306: Xfree(propspace); ! 307: ! 308: return pfont; ! 309: } ! 310: ! 311: Bool ! 312: DescribeFont(pfontname, lenfname, pfi, ppfp) ! 313: char *pfontname; ! 314: int lenfname; ! 315: FontInfoPtr pfi; ! 316: DIXFontPropPtr *ppfp; /* return */ ! 317: { ! 318: FontPtr pfont; ! 319: FID pf; ! 320: int i; ! 321: char *ppathname; ! 322: int lenpname; ! 323: int bytesskip, bytesprops; ! 324: DIXFontPropPtr pdfp; ! 325: FontPropPtr pffp, temp; ! 326: char *strings; ! 327: ! 328: if ((lenpname = ExpandFontName(&ppathname, lenfname, pfontname)) == 0) ! 329: return(FALSE); ! 330: /* ! 331: * first look up font name in list of opened fonts ! 332: */ ! 333: for ( pfont = pFontHead; ! 334: pfont != NullFont; ! 335: pfont = pfont->next) ! 336: if ( lenpname == pfont->lenpname ! 337: && strncmp( pfont->pathname, ppathname, pfont->lenpname) == 0) ! 338: { ! 339: *pfi = *pfont->pFI; ! 340: if (pfi->nProps > 0) ! 341: { ! 342: *ppfp = (DIXFontPropPtr)Xalloc(sizeof(DIXFontProp)*pfi->nProps); ! 343: if (*ppfp == NullDIXFontProp) ! 344: return(FALSE); ! 345: bcopy((char *)pfont->pFP, (char *)*ppfp, ! 346: sizeof(DIXFontProp)*pfi->nProps); ! 347: } ! 348: return(TRUE); ! 349: } ! 350: ! 351: /* have to read it off disk */ ! 352: if ((pf = FiOpenForRead(lenpname, ppathname)) == NullFID) ! 353: return(FALSE); ! 354: if ((FiRead(pfi, 1, sizeof(FontInfoRec), pf) != sizeof(FontInfoRec)) || ! 355: pfi->version1 != FONT_FILE_VERSION || ! 356: pfi->version2 != FONT_FILE_VERSION) ! 357: { ! 358: FiClose(pf); ! 359: return(FALSE); ! 360: } ! 361: ! 362: bytesskip = BYTESOFFONTINFO(pfi) - sizeof(FontInfoRec) + ! 363: BYTESOFCHARINFO(pfi) + BYTESOFGLYPHINFO(pfi); ! 364: bytesprops = BYTESOFPROPINFO(pfi) + BYTESOFSTRINGINFO(pfi); ! 365: ! 366: temp = (FontPropPtr)Xalloc(max(bytesskip, bytesprops)); ! 367: *ppfp = (DIXFontProp *)Xalloc(pfi->nProps * sizeof(DIXFontProp)); ! 368: ! 369: if ((!temp) || ! 370: (*ppfp == NullDIXFontProp) || ! 371: (FiRead((char *)temp, 1, bytesskip, pf) != bytesskip) || ! 372: (FiRead((char *)temp, 1, bytesprops, pf) != bytesprops)) ! 373: { ! 374: Xfree((char *)*ppfp); ! 375: *ppfp = NullDIXFontProp; ! 376: Xfree((char *)temp); ! 377: FiClose(pf); ! 378: return(FALSE); ! 379: } ! 380: strings = (char *)&temp[pfi->nProps]; ! 381: pffp = temp; ! 382: for (i=0, pdfp=(*ppfp); i<pfi->nProps; i++, pdfp++, pffp++) ! 383: { ! 384: pdfp->name = MakeAtom( ! 385: &strings[pffp->name], strlen(&strings[pffp->name]), 1); ! 386: if (pffp->indirect) ! 387: pdfp->value = (INT32)MakeAtom( ! 388: &strings[pffp->value], strlen(&strings[pffp->value]), 1); ! 389: else ! 390: pdfp->value = pffp->value; ! 391: } ! 392: Xfree((char *)temp); ! 393: FiClose(pf); ! 394: return(TRUE); ! 395: } ! 396: ! 397: ! 398: #ifdef notdef ! 399: /* ! 400: * assumes short is 2 bytes and long is 4, but nothing about padding ! 401: */ ! 402: #define _us unsigned short ! 403: #define _ul unsigned long ! 404: #define sw2( p) \ ! 405: *((_us *)p) = \ ! 406: *(_us *)p>>8 \ ! 407: | *(_us *)p<<8; ! 408: #define sw4( p) \ ! 409: *((_ul *)p) = \ ! 410: *(_ul *)p>>24 \ ! 411: | *(_ul *)p>>8 & 0x0000ff00 \ ! 412: | *(_ul *)p<<8 & 0x00ff0000 \ ! 413: | *(_ul *)p<<24; ! 414: ! 415: #else ! 416: ! 417: #define sw2( p) { \ ! 418: int t; \ ! 419: t = ((char *)p)[0]; \ ! 420: ((char *)p)[0] = ((char *)p)[1]; \ ! 421: ((char *)p)[1] = t; \ ! 422: } ! 423: #define sw4( p) { \ ! 424: int t; \ ! 425: t = ((char *)p)[0]; \ ! 426: ((char *)p)[0] = ((char *)p)[3]; \ ! 427: ((char *)p)[3] = t; \ ! 428: t = ((char *)p)[1]; \ ! 429: ((char *)p)[1] = ((char *)p)[2]; \ ! 430: ((char *)p)[2] = t; \ ! 431: } ! 432: ! 433: #endif ! 434: ! 435: void ! 436: QueryFont( pf, pr, nprotoxcistructs) ! 437: FontPtr pf; ! 438: xQueryFontReply * pr; /* caller must allocate this storage */ ! 439: int nprotoxcistructs; ! 440: { ! 441: FontInfoPtr pfi = pf->pFI; ! 442: CharInfoPtr pci; ! 443: DIXFontProp * pfp; ! 444: int ct; ! 445: xFontProp * prfp; ! 446: xCharInfo * prci; ! 447: ! 448: void queryCharInfo(); ! 449: ! 450: /* pr->length set in dispatch */ ! 451: pr->minCharOrByte2 = pfi->firstCol; ! 452: pr->defaultChar = pfi->chDefault; ! 453: pr->maxCharOrByte2 = pfi->lastCol; ! 454: pr->drawDirection = pfi->drawDirection; ! 455: pr->allCharsExist = pfi->allExist; ! 456: pr->minByte1 = pfi->firstRow; ! 457: pr->maxByte1 = pfi->lastRow; ! 458: pr->fontAscent = pfi->fontAscent; ! 459: pr->fontDescent = pfi->fontDescent; ! 460: ! 461: queryCharInfo( &pfi->minbounds, &pr->minBounds); ! 462: queryCharInfo( &pfi->maxbounds, &pr->maxBounds); ! 463: ! 464: pr->nFontProps = pfi->nProps; ! 465: pr->nCharInfos = nprotoxcistructs; ! 466: ! 467: ! 468: for ( ct=0, ! 469: pfp=pf->pFP, ! 470: prfp=(xFontProp *)(&pr[1]); ! 471: ct < pfi->nProps; ! 472: ct++, pfp++, prfp++) ! 473: { ! 474: prfp->name = pfp->name; ! 475: prfp->value = pfp->value; ! 476: } ! 477: ! 478: for ( ct=0, ! 479: pci = &pf->pCI[0], ! 480: prci=(xCharInfo *)(prfp); ! 481: ct<nprotoxcistructs; ! 482: ct++, pci++, prci++) ! 483: queryCharInfo( pci, prci); ! 484: } ! 485: ! 486: /* static */ void ! 487: queryCharInfo( pci, pr) ! 488: CharInfoPtr pci; ! 489: xCharInfo * pr; /* protocol packet to fill in */ ! 490: { ! 491: *pr = pci->metrics; ! 492: } ! 493: ! 494: /* static */ void ! 495: SwapFont( pr, hasGlyphs) ! 496: xQueryFontReply * pr; ! 497: Bool hasGlyphs; ! 498: { ! 499: int i; ! 500: xCharInfo * pxci; ! 501: int nchars, nprops; ! 502: char *pby; ! 503: register char n; ! 504: ! 505: swaps(&pr->sequenceNumber, n); ! 506: swapl(&pr->length, n); ! 507: nchars = pr->nCharInfos; ! 508: nprops = pr->nFontProps; ! 509: SwapFontInfo(pr); ! 510: pby = (char *) &pr[1]; ! 511: /* Font properties are an atom and either an int32 or a CARD32, so ! 512: * they are always 2 4 byte values */ ! 513: for(i = 0; i < nprops; i++) ! 514: { ! 515: swapl(pby, n); ! 516: pby += 4; ! 517: swapl(pby, n); ! 518: pby += 4; ! 519: } ! 520: if (hasGlyphs) ! 521: { ! 522: pxci = (xCharInfo *)pby; ! 523: for(i = 0; i< nchars; i++, pxci++) ! 524: SwapCharInfo(pxci); ! 525: } ! 526: } ! 527: ! 528: SwapFontInfo(pr) ! 529: xQueryFontReply *pr; ! 530: { ! 531: register char n; ! 532: ! 533: swaps(&pr->minCharOrByte2, n); ! 534: swaps(&pr->maxCharOrByte2, n); ! 535: swaps(&pr->defaultChar, n); ! 536: swaps(&pr->nFontProps, n); ! 537: swaps(&pr->fontAscent, n); ! 538: swaps(&pr->fontDescent, n); ! 539: SwapCharInfo( &pr->minBounds); ! 540: SwapCharInfo( &pr->maxBounds); ! 541: swapl(&pr->nCharInfos, n); ! 542: } ! 543: SwapCharInfo(pInfo) ! 544: xCharInfo *pInfo; ! 545: { ! 546: register char n; ! 547: ! 548: swaps(&pInfo->leftSideBearing, n); ! 549: swaps(&pInfo->rightSideBearing, n); ! 550: swaps(&pInfo->characterWidth, n); ! 551: swaps(&pInfo->ascent, n); ! 552: swaps(&pInfo->descent, n); ! 553: swaps(&pInfo->attributes, n); ! 554: } ! 555: ! 556: ! 557: /* text support routines. A charinfo array builder, and a bounding */ ! 558: /* box calculator */ ! 559: ! 560: void ! 561: GetGlyphs(font, count, chars, fontEncoding, glyphcount, glyphs) ! 562: FontPtr font; ! 563: int count; ! 564: register unsigned char *chars; ! 565: FontEncoding fontEncoding; ! 566: unsigned int *glyphcount; /* RETURN */ ! 567: CharInfoPtr glyphs[]; /* RETURN */ ! 568: { ! 569: CharInfoPtr pCI = font->pCI; ! 570: FontInfoPtr pFI = font->pFI; ! 571: unsigned int firstCol = pFI->firstCol; ! 572: unsigned int numCols = pFI->lastCol - firstCol + 1; ! 573: unsigned int firstRow = pFI->firstRow; ! 574: unsigned int numRows = pFI->lastRow - firstRow + 1; ! 575: unsigned int chDefault = pFI->chDefault; ! 576: register int i; ! 577: int n; ! 578: register unsigned int c; ! 579: register CharInfoPtr ci; ! 580: ! 581: n = 0; ! 582: switch (fontEncoding) { ! 583: ! 584: case Linear8Bit: ! 585: case TwoD8Bit: ! 586: for (i=0; i < count; i++) { ! 587: ! 588: c = (*chars++) - firstCol; ! 589: if (c < numCols) { ! 590: ci = &pCI[c]; ! 591: if (ci->exists) {glyphs[n++] = ci; continue;} ! 592: } ! 593: ! 594: c = chDefault - firstCol; ! 595: if (c < numCols) { ! 596: ci = &pCI[c]; ! 597: if (ci->exists) glyphs[n++] = ci; ! 598: } ! 599: } ! 600: break; ! 601: ! 602: case Linear16Bit: ! 603: for (i=0; i < count; i++) { ! 604: ! 605: chars++; ! 606: c = (*chars++) - firstCol; ! 607: if (c < numCols) { ! 608: ci = &pCI[c]; ! 609: if (ci->exists) {glyphs[n++] = ci; continue;} ! 610: } ! 611: ! 612: c = chDefault - firstCol; ! 613: if (c < numCols) { ! 614: ci = &pCI[c]; ! 615: if (ci->exists) glyphs[n++] = ci; ! 616: } ! 617: } ! 618: break; ! 619: ! 620: case TwoD16Bit: ! 621: for (i=0; i < count; i++) { ! 622: register unsigned int row; ! 623: register unsigned int col; ! 624: ! 625: row = (*chars++) - firstRow; ! 626: col = (*chars++) - firstCol; ! 627: if ((row < numRows) && (col < numCols)) { ! 628: c = row*numCols + col; ! 629: ci = &pCI[c]; ! 630: if (ci->exists) {glyphs[n++] = ci; continue;} ! 631: } ! 632: ! 633: row = (chDefault >> 8)-firstRow; ! 634: col = (chDefault & 0xff)-firstCol; ! 635: if ((row < numRows) && (col < numCols)) { ! 636: c = row*numCols + col; ! 637: ci = &pCI[c]; ! 638: if (ci->exists) glyphs[n++] = ci; ! 639: } ! 640: } ! 641: break; ! 642: } ! 643: *glyphcount = n; ! 644: } ! 645: ! 646: ! 647: ! 648: void ! 649: QueryGlyphExtents(font, charinfo, count, info) ! 650: FontPtr font; ! 651: CharInfoPtr *charinfo; ! 652: unsigned int count; ! 653: ExtentInfoRec *info; ! 654: { ! 655: int i; ! 656: ! 657: info->drawDirection = font->pFI->drawDirection; ! 658: ! 659: info->fontAscent = font->pFI->fontAscent; ! 660: info->fontDescent = font->pFI->fontDescent; ! 661: ! 662: if (count != 0) { ! 663: ! 664: info->overallAscent = charinfo[0]->metrics.ascent; ! 665: info->overallDescent = charinfo[0]->metrics.descent; ! 666: info->overallLeft = charinfo[0]->metrics.leftSideBearing; ! 667: info->overallRight = charinfo[0]->metrics.rightSideBearing; ! 668: info->overallWidth = charinfo[0]->metrics.characterWidth; ! 669: ! 670: for (i=1; i < count; i++) { ! 671: info->overallAscent = max( ! 672: info->overallAscent, ! 673: charinfo[i]->metrics.ascent); ! 674: info->overallDescent = max( ! 675: info->overallDescent, ! 676: charinfo[i]->metrics.descent); ! 677: info->overallLeft = min( ! 678: info->overallLeft, ! 679: info->overallWidth+charinfo[i]->metrics.leftSideBearing); ! 680: info->overallRight = max( ! 681: info->overallRight, ! 682: info->overallWidth+charinfo[i]->metrics.rightSideBearing); ! 683: /* yes, this order is correct; overallWidth IS incremented last */ ! 684: info->overallWidth += charinfo[i]->metrics.characterWidth; ! 685: } ! 686: ! 687: } else { ! 688: ! 689: info->overallAscent = 0; ! 690: info->overallDescent = 0; ! 691: info->overallWidth = 0; ! 692: info->overallLeft = 0; ! 693: info->overallRight = 0; ! 694: ! 695: } ! 696: } ! 697: ! 698: void ! 699: QueryTextExtents(font, count, chars, info) ! 700: FontPtr font; ! 701: unsigned int count; ! 702: unsigned short *chars; ! 703: ExtentInfoRec *info; ! 704: { ! 705: CharInfoPtr *charinfo = ! 706: (CharInfoPtr *)ALLOCATE_LOCAL(count*sizeof(CharInfoPtr)); ! 707: unsigned int n; ! 708: ! 709: if(!charinfo) ! 710: return; ! 711: if (font->pFI->lastRow == 0) ! 712: GetGlyphs(font, count, chars, Linear16Bit, &n, charinfo); ! 713: else ! 714: GetGlyphs(font, count, chars, TwoD16Bit, &n, charinfo); ! 715: ! 716: QueryGlyphExtents(font, charinfo, n, info); ! 717: ! 718: DEALLOCATE_LOCAL(charinfo); ! 719: } ! 720:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.