|
|
1.1 ! root 1: /* ! 2: ! 3: Copyright 1986 by the University of Utah ! 4: ! 5: Permission to use, copy, modify, and distribute this ! 6: software and its documentation for any purpose and without ! 7: fee is hereby granted, provided that the above copyright ! 8: notice appear in all copies and that both that copyright ! 9: notice and this permission notice appear in supporting ! 10: documentation, and that the name of the University of Utah ! 11: not be used in advertising or publicity pertaining to ! 12: distribution of the software without specific, written ! 13: prior permission. The University of Utah makes no ! 14: representations about the suitability of this software for ! 15: any purpose. It is provided "as is" without express or ! 16: implied warranty. ! 17: ! 18: */ ! 19: ! 20: /* cvtfont.c Reads an X font from a file and stores an Apollo format ! 21: * copy on disk ! 22: * ! 23: * GetFont Takes a font name and converts the font ! 24: * ! 25: */ ! 26: ! 27: #include "Xapollo.h" ! 28: #include "vssite.h" ! 29: #include "../libvs100/param.h" ! 30: #include <errno.h> ! 31: #include <sys/file.h> ! 32: #include "/sys/ins/smdu.ins.c" ! 33: ! 34: extern int errno; ! 35: static gpr_$offset_t off; ! 36: status_$t status; ! 37: ! 38: char *strcpy(), *strcat(); ! 39: long lseek(); ! 40: ! 41: #define CHARPERFONT 256 ! 42: ! 43: static short ReverseBitsInByte[256] = { ! 44: 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, ! 45: 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, ! 46: 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, ! 47: 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, ! 48: 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, ! 49: 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, ! 50: 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, ! 51: 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, ! 52: 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, ! 53: 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, ! 54: 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, ! 55: 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, ! 56: 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, ! 57: 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, ! 58: 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, ! 59: 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff, ! 60: }; ! 61: ! 62: #define ReverseBitsInShort(s) ((ReverseBitsInByte[(s)&0xff]<<8)|ReverseBitsInByte[((s)>>8)&0xff]) ! 63: ! 64: ! 65: BITMAP * ! 66: make_bitmap( area, width, height ) ! 67: short * area; ! 68: int width; ! 69: int height; ! 70: { ! 71: ! 72: BITMAP * bm; ! 73: gpr_$bitmap_desc_t bitmap; ! 74: static gpr_$attribute_desc_t attr = -1; ! 75: gpr_$offset_t size; ! 76: ! 77: short * pointer; ! 78: short bwid; ! 79: int rowwid; ! 80: ! 81: register int i; ! 82: ! 83: if( (bm = (BITMAP *)malloc(sizeof(BITMAP))) == NULL ) ! 84: return( NULL ); ! 85: ! 86: bm->width = width; ! 87: bm->height = height; ! 88: bm->refcnt = 1; ! 89: bm->kind = (int)apollo_bitmap; ! 90: ! 91: size.x_size = bm->width; ! 92: size.y_size = bm->height; ! 93: ! 94: gpr_$allocate_attribute_block( attr, status ); ! 95: check_status(status, "make_bitmap "); ! 96: gpr_$allocate_bitmap_nc( size, (gpr_$plane_t)0, attr, bitmap, status ); ! 97: check_status(status, "make_bitmap "); ! 98: ! 99: bm->data = (caddr_t)bitmap; ! 100: gpr_$inq_bitmap_pointer( bitmap, pointer, bwid, status ); ! 101: ! 102: rowwid = ((width+15)>>4); ! 103: for( i=0; i<height; i++ ) ! 104: { ! 105: bcopy( area, pointer, rowwid*2 ); ! 106: pointer += bwid; ! 107: area += rowwid; ! 108: } ! 109: ! 110: return( bm ); ! 111: ! 112: } ! 113: ! 114: make_fontfile( fd, name, invert ) ! 115: FONT *fd; ! 116: char *name; ! 117: boolean invert; ! 118: ! 119: { ! 120: FontPriv *fpriv = (FontPriv *)fd->data; ! 121: BITMAP *bm; ! 122: short namelen; ! 123: smd_$font_table_t *ap_font_info; ! 124: smd_$v1_fdte_t *desc_entry; ! 125: int line_width, i, j; ! 126: short *memptr; ! 127: short *image_ptr; ! 128: long file_length; ! 129: char lname[64]; ! 130: ! 131: strcpy(lname, DEFAULT_APOLLO_FONT_PATH); ! 132: strcat(lname, name); ! 133: bm = fpriv->strike; ! 134: if (invert) { ! 135: gpr_$window_t window; ! 136: gpr_$position_t dest; ! 137: ! 138: strncat( lname, ".i", 2); ! 139: window.x_coord = 0; ! 140: window.y_coord = 0; ! 141: window.x_size = 224; ! 142: window.y_size = bm->height; ! 143: dest.x_coord = 0; ! 144: dest.y_coord = 0; ! 145: gpr_$set_bitmap( bm->data, status); ! 146: gpr_$set_raster_op( (gpr_$plane_t)0, (gpr_$raster_op_t)12, status ); ! 147: gpr_$bit_blt(bm->data, window, (short)0, dest, (short)0, status ); ! 148: } ! 149: gpr_$inq_bitmap_pointer(bm->data, (long)memptr, (short)line_width, status); ! 150: ! 151: namelen = strlen(lname); ! 152: file_length = 224 * 224 + sizeof( smd_$font_table_t ) + 65535; ! 153: ap_font_info = (smd_$font_table_t *) ! 154: ms_$crmapl( *lname, namelen, (long)0, file_length, ms_$nr_xor_1w, status ); ! 155: check_status(status, "Creating apollo font file"); ! 156: ! 157: image_ptr = (short *)&(ap_font_info->desc_table[127]); ! 158: ! 159: for (i=0; i<bm->height; i++) { ! 160: for (j=0; j<14; j++) { ! 161: *image_ptr = *memptr; ! 162: image_ptr++; ! 163: memptr++; ! 164: } ! 165: for (j=0; j<50; j++) ! 166: memptr++; ! 167: } ! 168: ap_font_info->v_spacing = 0; ! 169: ap_font_info->h_spacing = 0; ! 170: ! 171: ap_font_info->version = 1; ! 172: ap_font_info->chars_in_font = 127; ! 173: ap_font_info->max_up = fd->height; ! 174: ap_font_info->max_width = fpriv->maxwidth; ! 175: ap_font_info->max_right = fpriv->maxwidth; ! 176: ap_font_info->max_down = 0; ! 177: ap_font_info->max_height = fd->height; ! 178: ap_font_info->space_size = fpriv->widths[fd->space]; ! 179: ! 180: desc_entry = &(ap_font_info->desc_table); ! 181: for (i=0; i<127; i++) { ! 182: ap_font_info->index_table[i] = i+1; ! 183: ap_font_info->desc_table[i].left = 0; ! 184: ap_font_info->desc_table[i].right = fpriv->widths[i]; ! 185: ap_font_info->desc_table[i].up = fd->height; ! 186: ap_font_info->desc_table[i].down = 0; ! 187: ap_font_info->desc_table[i].width = fpriv->widths[i]; ! 188: ap_font_info->desc_table[i].x_pos = fpriv->leftarray[i] &0777; ! 189: ap_font_info->desc_table[i].y_pos = (fpriv->leftarray[i] >> 10) * fd->height; ! 190: desc_entry++; ! 191: } ! 192: ! 193: ap_font_info->raster_lines = (--desc_entry)->y_pos + fd->height; ! 194: if (ap_font_info->raster_lines <= (65535 / 28)) ! 195: ap_font_info->image_size = (ap_font_info->raster_lines + 4) * 28; ! 196: else ap_font_info->image_size = 65535; ! 197: ap_font_info->image_offset = smd_$font_header_size + ! 198: smd_$font_index_table_size + (smd_$v1_fdte_size * 127) ; ! 199: ms_$truncate( ap_font_info, ap_font_info->image_offset + ! 200: ap_font_info->image_size, status ); ! 201: ms_$unmap( ap_font_info, ap_font_info->image_offset + ! 202: ap_font_info->image_size, status ); ! 203: } ! 204: ! 205: FONT * ! 206: make_fontmap( fd ) ! 207: FONT *fd; ! 208: { ! 209: ! 210: int width; ! 211: int height; ! 212: BITMAP * bm; ! 213: gpr_$bitmap_desc_t bitmap; ! 214: static gpr_$attribute_desc_t attr = -1; ! 215: gpr_$window_t window; ! 216: gpr_$position_t dest; ! 217: static int got_attr = 0; ! 218: gpr_$offset_t size; ! 219: FontPriv *fpriv; ! 220: ! 221: short col, row; ! 222: short left, oldleft, wid, oldwid; ! 223: int start, stop; ! 224: ! 225: register int i; ! 226: ! 227: fpriv = (FontPriv *)fd->data; ! 228: bm = fpriv->strike; ! 229: width = fd->last * fd->avg_width; ! 230: height = (width / 224) + 1; ! 231: height = height * fd->height; ! 232: /* should check for height > ???some max value */ ! 233: size.x_size = 224; ! 234: size.y_size = height; ! 235: ! 236: gpr_$allocate_attribute_block( attr, status ); ! 237: check_status(status, "make_fontfile "); ! 238: gpr_$acquire_display( status ); ! 239: gpr_$allocate_bitmap( size, (gpr_$plane_t)0, attr, bitmap, status ); ! 240: check_status(status, "make_fontfile "); ! 241: ! 242: row = start = col = 0; ! 243: gpr_$set_bitmap( bitmap, status); ! 244: gpr_$set_raster_op(0, (gpr_$raster_op_t)12, status); ! 245: for (i=0; i<=fd->last; i++) { ! 246: left = fpriv->leftarray[i]; ! 247: wid = fpriv->widths[i]; ! 248: if ((left + wid) > (start + 224)) { ! 249: stop = oldleft + oldwid; ! 250: window.x_coord = start; ! 251: window.y_coord = 0; ! 252: window.x_size = stop - start; ! 253: window.y_size = fd->height; ! 254: dest.x_coord = 0; ! 255: dest.y_coord = row * fd->height; ! 256: gpr_$bit_blt(bm->data, window, (short)0, dest, (short)0, status); ! 257: start = stop; ! 258: row++; ! 259: col = 0; ! 260: } ! 261: oldleft = left; ! 262: oldwid = wid; ! 263: fpriv->leftarray[i] = col + (row << 10); ! 264: col += fpriv->widths[i]; ! 265: } ! 266: if (start != (oldleft + oldwid)) { ! 267: window.x_coord = start; ! 268: window.x_size = (left + wid) - start; ! 269: window.y_size = fd->height; ! 270: dest.y_coord = row * fd->height; ! 271: gpr_$bit_blt(bm->data, window, (short)0, dest, (short)0, status); ! 272: check_status( status, make_fontmap ); ! 273: } ! 274: bm->width = 224; ! 275: bm->height = height; ! 276: bm->refcnt = 1; ! 277: bm->kind = (int)apollo_bitmap; ! 278: ! 279: bm->data = (caddr_t)bitmap; ! 280: return( fd ); ! 281: ! 282: } ! 283: ! 284: ! 285: FONT ! 286: *GetFont (name) ! 287: char *name; ! 288: { ! 289: char fontname[256]; ! 290: int fontfile = -1; ! 291: FontData font; ! 292: #define chars ((BitMap *) font.f_characters) ! 293: int fontsize, leftsize, width, i, j; ! 294: char *fontarea; ! 295: register short *leftarea, *leftarray; ! 296: register FONT *fd; ! 297: register FontPriv *fpriv; ! 298: int tablesize = (CHARPERFONT + 1) * sizeof(short); ! 299: extern char *getenv(), *index(); ! 300: static char *Fontpath = NULL; ! 301: char *fontpath; ! 302: char lname[40]; ! 303: int namelen; ! 304: ! 305: if ((fontpath = Fontpath) == NULL) ! 306: fontpath = DEFAULT_FONT_PATH; ! 307: ! 308: fontfile = open (name, 0, 0); ! 309: ! 310: while (fontfile < 0) { ! 311: char *fend; ! 312: ! 313: if ((fend = index(fontpath, ':')) != 0) ! 314: *fend = '\0'; ! 315: if (*fontpath == '\0') { ! 316: errno = EINVAL; ! 317: return (NULL); ! 318: } ! 319: ! 320: if (*fontpath == '~') { ! 321: /* XXX - should implement ~foobar as well */ ! 322: strcpy (fontname, getenv("HOME")); ! 323: strcat (fontname, "/"); ! 324: fontpath++; ! 325: } else ! 326: *fontname = '\0'; ! 327: strcat (fontname, fontpath); ! 328: strcat (fontname, "/"); ! 329: strcat (fontname, name); ! 330: strcat (fontname, DEFAULT_FONT_SUFFIX); ! 331: ! 332: fontfile = open (fontname, 0, 0); ! 333: if (fend) { ! 334: *fend = ':'; ! 335: fontpath = ++fend; ! 336: } else ! 337: break; ! 338: } ! 339: if (read (fontfile, (caddr_t) &font, sizeof (FontData)) != sizeof (FontData)) { ! 340: close (fontfile); ! 341: errno = EINVAL; ! 342: return (NULL); ! 343: } ! 344: Swap_shorts((short *) &font, sizeof (FontData)>>1); ! 345: ! 346: fontsize = BitmapSize(chars->bm_width, chars->bm_height); ! 347: fontarea = (char *) malloc (fontsize); ! 348: bzero( fontarea, fontsize ); ! 349: lseek (fontfile, (long) font.f_characters[0], 0); ! 350: if (read (fontfile, fontarea, fontsize) != fontsize) { ! 351: close (fontfile); ! 352: free (fontarea); ! 353: errno = EINVAL; ! 354: return (NULL); ! 355: } ! 356: Swap_shorts((short *)fontarea, fontsize>>1); ! 357: ! 358: leftarea = (short *) malloc (tablesize); ! 359: bzero(leftarea, tablesize); ! 360: leftarray = (short *) malloc (tablesize); ! 361: if (font.f_fixedWidth == 0) { ! 362: leftsize = (font.f_lastChar - font.f_firstChar + 2) * sizeof (short); ! 363: lseek (fontfile, (long) font.f_leftArray[0], 0); ! 364: if (read (fontfile, & leftarea[font.f_firstChar], leftsize) ! 365: != leftsize) { ! 366: close (fontfile); ! 367: free (fontarea); ! 368: free ((caddr_t) leftarea); ! 369: free ((caddr_t) leftarray); ! 370: errno = EINVAL; ! 371: return (NULL); ! 372: } ! 373: Swap_shorts(((short *)& leftarea[font.f_firstChar]), leftsize>>1); ! 374: } else { /* if fixed with font, generate leftarray for use later */ ! 375: j = 0; ! 376: for (i = font.f_firstChar; i <= font.f_lastChar + 1; i++) { ! 377: leftarea[i] = j; ! 378: j += font.f_fixedWidth; ! 379: } ! 380: } ! 381: bcopy(leftarea, leftarray, tablesize); ! 382: ! 383: close (fontfile); ! 384: /* ! 385: * set up font data structures ! 386: */ ! 387: ! 388: fd = (FONT *) malloc (sizeof (FONT)); ! 389: ! 390: fd->height = chars->bm_height; ! 391: fd->first = font.f_firstChar; ! 392: fd->last = font.f_lastChar; ! 393: fd->base = font.f_baseline; ! 394: fd->space = font.f_spaceIndex; ! 395: fd->space += fd->first; ! 396: fd->refcnt = 1; ! 397: ! 398: ! 399: ! 400: fd->name = (char *) malloc (strlen (name) + 1); ! 401: strcpy (fd->name, name); ! 402: ! 403: ! 404: /* ! 405: * set up the private font structure ! 406: */ ! 407: fpriv = (FontPriv *) malloc (sizeof (FontPriv)); ! 408: ! 409: if (fd->avg_width = font.f_fixedWidth) { ! 410: fd->fixed = 1; ! 411: fpriv->maxwidth = fd->avg_width; ! 412: } ! 413: else ! 414: fd->fixed = 0; ! 415: fd->data = (caddr_t) fpriv; ! 416: ! 417: fpriv->widths = leftarea; ! 418: fpriv->leftarray = leftarray; ! 419: fpriv->maxwidth = 0; ! 420: ! 421: /* of course... the bits are all switched... naturally... of course... */ ! 422: { register short *sh = (short *) fontarea; ! 423: register short limit = ((chars->bm_width+15)>>4)*chars->bm_height; ! 424: do *sh = ReverseBitsInShort(*sh), sh++; ! 425: while (--limit != -1); ! 426: } ! 427: ! 428: /* convert the leftarray to the width table */ ! 429: for (i = fd->first; i <= fd->last; i++) { ! 430: width = fpriv->leftarray[i + 1] - fpriv->leftarray[i]; ! 431: if (width > fpriv->maxwidth) fpriv->maxwidth = width; ! 432: if (width < 0) { ! 433: width = 0; /* font sanity check */ ! 434: errno = EINVAL; ! 435: return(NULL); ! 436: } ! 437: fpriv->widths[i] = width; ! 438: } ! 439: fd->avg_width = ((fpriv->leftarray[fd->last] - ! 440: fpriv->leftarray[fd->first]) / (fd->last - fd->first)); ! 441: ! 442: if ((fpriv->strike = make_bitmap( fontarea, chars->bm_width, chars->bm_height) ) == NULL) { ! 443: free (fontarea); ! 444: free ((caddr_t) leftarea); ! 445: free ((caddr_t) leftarray); ! 446: free ((caddr_t) fd); ! 447: free ((caddr_t) fpriv); ! 448: errno = EINVAL; ! 449: return (NULL); ! 450: } ! 451: ! 452: make_fontmap(fd); ! 453: make_fontfile(fd, name, false); ! 454: make_fontfile(fd, name, true); ! 455: /* XXX free fontarea */ ! 456: ! 457: return (fd); ! 458: #undef chars ! 459: } ! 460: ! 461: OpenDisplay () ! 462: { ! 463: gpr_$bitmap_desc_t bm; ! 464: ! 465: off.x_size = 1024; ! 466: off.y_size = 1024; ! 467: gpr_$init( gpr_$direct, (short)1, off, (short)0, bm, status ); ! 468: if ( status.all != status_$ok ) { ! 469: error_$print( status ); ! 470: return( NULL ); ! 471: } ! 472: return; ! 473: ! 474: } ! 475: ! 476: #define swaps(x) n = ((char *) (x))[0];\ ! 477: ((char *) (x))[0] = ((char *) (x))[1];\ ! 478: ((char *) (x))[1] = n ! 479: ! 480: Swap_shorts (list, count) ! 481: register short *list; ! 482: register int count; ! 483: { ! 484: unsigned int n; ! 485: ! 486: while (--count >= 0) { ! 487: swaps(list); ! 488: list++; ! 489: } ! 490: } ! 491: ! 492: check_status(status, name) ! 493: status_$t status; ! 494: char *name; ! 495: { ! 496: if (status.all != status_$ok) { ! 497: fprintf(stderr, "%s", name); ! 498: error_$print(status); ! 499: exit(1); ! 500: } ! 501: } ! 502: main(argc, argv) ! 503: int argc; ! 504: char **argv; ! 505: { ! 506: char *fontname; ! 507: ! 508: OpenDisplay(); ! 509: fontname = *(++argv); ! 510: GetFont(fontname); ! 511: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.