TeXhax Digest Monday, April 10, 1989 Volume 89 : Issue 34 Moderators: Tiina Modisett and Pierre MacKay %% The TeXhax digest is brought to you as a service of the TeX Users Group %%% %% in cooperation with the UnixTeX distribution service at the %%% %% University of Washington %%% Today's Topics: Dvipage and fonts on sun 386i --------------------------------------------------------------------------- Date: Fri, 7 Apr 89 10:21:33 CDT From: wwc@boole.ece.wisc.edu (William W. Carlson) Subject: Dvipage and fonts on sun 386i Keywords: dvipage, fonts, SUN 386 Here is the difinitive solution... diff from dvipage 3.0. It contains no 386 dependent code but uses the "correct" level raster ops... *** dvipage.1-dist Wed Mar 1 12:05:01 1989 --- dvipage.1 Wed Mar 1 13:47:23 1989 *************** *** 123,132 **** button down. .PP Dvipage understands both the old format PXL font files, ! and the new GF packed font files. It searches for font files in a list of standard places (by default: ``/nfs/tex-server/tex/1988/lib/tex/fonts'') ! accepting either GF files or PXL files, whichever is found. If the exact font specified is not found, dvipage searches all the font directories for the closest font match. --- 123,132 ---- button down. .PP Dvipage understands both the old format PXL font files, ! the new GF packed font files, and the most efficient PK font files. It searches for font files in a list of standard places (by default: ``/nfs/tex-server/tex/1988/lib/tex/fonts'') ! accepting either PK files, GF files or PXL files, whichever is found. If the exact font specified is not found, dvipage searches all the font directories for the closest font match. *************** *** 158,164 **** The argument is a colon separated list of directories which contain either font files, or subdirectories grouping fonts by family. ! Either PXL or GF type files can be used. If the environment variable .B FONT_AREA, is set, it also specifies a colon separated --- 158,164 ---- The argument is a colon separated list of directories which contain either font files, or subdirectories grouping fonts by family. ! Either PXL, PK, or GF type files can be used. If the environment variable .B FONT_AREA, is set, it also specifies a colon separated *************** *** 170,175 **** --- 170,181 ---- .I flag is 0, use of PXL files is suppressed. Default is non zero, enabling the use of PXL files. + .TP + .BI \-K " flag" + If + .I flag + is 0, use of PK files is suppressed. + Default is non zero, enabling the use of PK files. .TP .BI \-G " flag" If *** dvipage.c-dist Wed Mar 1 12:04:42 1989 --- dvipage.c Wed Mar 1 13:55:19 1989 *************** *** 155,160 **** --- 155,161 ---- char *font_path; /* Font path name for search */ bool use_gf = USE_GF; /* Enable the use of GF fonts. */ bool use_pxl = USE_PXL; /* Enable the use of PXL fonts. */ + bool use_pk = USE_PK; /* Enable the use of PK fonts. */ FILE *dvifp = NULL; /* File pointer */ *************** *** 358,376 **** /* * Create a disp_frame. */ ! disp_frame = window_create(0, FRAME, ! WIN_X, 300, ! WIN_Y, 50, /* I hate the bug where the window is off the screen */ ! WIN_WIDTH, ! (int)(page_w * DEFAULT_COLOUR_RES / ! DEFAULT_COLOUR_SAMPLING) + 10, ! WIN_HEIGHT, ! (int)(page_h * DEFAULT_COLOUR_RES / ! DEFAULT_COLOUR_SAMPLING) + 20, ! FRAME_ARGC_PTR_ARGV, &argc, argv, ! FRAME_LABEL, DVIPAGE_LABEL, ! FRAME_ICON, &icon, ! 0); /* * Create the disp_canvas. --- 359,393 ---- /* * Create a disp_frame. */ ! if (((struct cursor *)hand_cursor)->cur_shape->pr_depth == 1) { ! disp_frame = window_create(0, FRAME, ! WIN_X, 350, ! WIN_Y, 90, ! WIN_WIDTH, ! (int)min(((page_w-2) * DEFAULT_MONO_RES / ! DEFAULT_MONO_SAMPLING) + 10, 802) , ! WIN_HEIGHT, ! (int)min(((page_h-2) * DEFAULT_MONO_RES / ! DEFAULT_MONO_SAMPLING) + 20, 810), ! FRAME_ARGC_PTR_ARGV, &argc, argv, ! FRAME_LABEL, DVIPAGE_LABEL, ! FRAME_ICON, &icon, ! 0); ! } else { ! disp_frame = window_create(0, FRAME, ! WIN_X, 300, ! WIN_Y, 50, /* I hate the bug where the window is off the screen */ ! WIN_WIDTH, ! (int)(page_w * DEFAULT_COLOUR_RES / ! DEFAULT_COLOUR_SAMPLING) + 10, ! WIN_HEIGHT, ! (int)(page_h * DEFAULT_COLOUR_RES / ! DEFAULT_COLOUR_SAMPLING) + 20, ! FRAME_ARGC_PTR_ARGV, &argc, argv, ! FRAME_LABEL, DVIPAGE_LABEL, ! FRAME_ICON, &icon, ! 0); ! } /* * Create the disp_canvas. *************** *** 424,429 **** --- 441,448 ---- fprintf(stderr, " [-P flag] # Enable or disable the use of PXL files \\\n"); fprintf(stderr, + " [-K flag] # Enable or disable the use of PK files \\\n"); + fprintf(stderr, " [-G flag] # Enable or disable the use of GF files \\\n"); fprintf(stderr, " [-l] # Don't preload font data \\\n"); *************** *** 461,466 **** --- 480,489 ---- use_pxl = a_integer(argc, argv); break; + case 'K': + use_pk = a_integer(argc, argv); + break; + case 'G': use_gf = a_integer(argc, argv); break; *************** *** 609,620 **** if(set_start_x != 0.0) start_x = (int)(set_start_x * resolution); else ! start_x = 0; if(set_start_y != 0.0) start_y = (int)(set_start_y * resolution); else ! start_y = 0; /* * Insert the window into the heap now, so that if a message is --- 632,643 ---- if(set_start_x != 0.0) start_x = (int)(set_start_x * resolution); else ! start_x = (int)(DEFAULT_START_X * resolution); if(set_start_y != 0.0) start_y = (int)(set_start_y * resolution); else ! start_y = (int)(DEFAULT_START_Y * resolution); /* * Insert the window into the heap now, so that if a message is *** dvipage.h-dist Wed Mar 1 12:04:41 1989 --- dvipage.h Wed Mar 1 12:04:38 1989 *************** *** 61,67 **** "/nfs/tex-server/tex/1988/lib/tex/fonts:/fonts/tex/pxl" #else !sparc #define FONT_AREA \ ! "/nfs/tex-server/tex/1988/lib/tex/fonts:/usr/spar/font/tex/pxl" #endif sparc #endif FONT_AREA --- 61,67 ---- "/nfs/tex-server/tex/1988/lib/tex/fonts:/fonts/tex/pxl" #else !sparc #define FONT_AREA \ ! "/usr/local/lib/tex82/fonts/sun:/usr/local/lib/tex82/fonts/sun/pk" #endif sparc #endif FONT_AREA *************** *** 71,76 **** --- 71,77 ---- */ #define USE_GF 1 #define USE_PXL 1 + #define USE_PK 1 /* * Define a command which will print the whole document. *************** *** 102,107 **** --- 103,115 ---- #define DEFAULT_ORIGIN_Y (1) /* inches */ /* + * default starting display... makes better use of screen. + */ + + #define DEFAULT_START_X (-1) /* inches */ + #define DEFAULT_START_Y (-1) /* inches */ + + /* * These are the defaults for resolution and sampling factors * of fonts for colour and mono screens. */ *************** *** 121,127 **** --- 129,140 ---- /* * Some limits in the program. Change for extraordinary TeX files. */ + #ifdef NOFILE + #define MAXOPEN NOFILE-6 /* leave room for stdio, */ + /* window, message,popup */ + #else #define MAXOPEN 12 /* Max number of open font files. */ + #endif #define STACKSIZE 100 /* dvi stack max length */ #define STRSIZE MAXPATHLEN /* Max string length */ #define MAX_SHEETS 512 /* Pages remembered in table */ *************** *** 233,238 **** --- 246,252 ---- int fileOffset; struct pixrect *pixrectptr; } address; + int flags; } where; int tfmw; }; *************** *** 266,271 **** --- 280,286 ---- #define TYPE_PXL 1 #define TYPE_GF 2 + #define TYPE_PK 3 /* * mem_pixrect: *************** *** 296,301 **** --- 311,317 ---- extern char *font_path; extern bool use_gf; extern bool use_pxl; + extern bool use_pk; extern FILE *dvifp; *** findfile.c-dist Wed Mar 1 12:04:40 1989 --- findfile.c Wed Mar 1 12:04:39 1989 *************** *** 107,112 **** --- 107,155 ---- } *p = '\0'; + if(use_pk) + { + /* + * Try flat structure. + */ + sprintf(fontptr->name, "%s/%s.%dpk", + dir, fontptr->n, fontptr->font_gf_mag); + if(access(fontptr->name, R_OK) == 0) + { + if(verbose & DEBUG_FONTS) + fprintf(stderr, " Try %s; OK\n", + fontptr->name); + fontptr->type = TYPE_PK; + return TRUE; + } + else + { + if(verbose & DEBUG_FONTS) + fprintf(stderr, " Try %s; No\n", + fontptr->name); + } + + /* + * Try hierarchical structure. + */ + sprintf(fontptr->name, "%s/%s/%s.%dpk", + dir, fontptr->n, fontptr->n, fontptr->font_gf_mag); + if(access(fontptr->name, R_OK) == 0) + { + if(verbose & DEBUG_FONTS) + fprintf(stderr, " Try %s; OK\n", + fontptr->name); + fontptr->type = TYPE_PK; + return TRUE; + } + else + { + if(verbose & DEBUG_FONTS) + fprintf(stderr, " Try %s; No\n", + fontptr->name); + } + } + if(use_gf) { /* *************** *** 392,397 **** --- 435,470 ---- sprintf(fontptr->name, "%s/%s", dir, dirrecord->d_name); fontptr->type = TYPE_PXL; + + if(verbose & DEBUG_FONTS) + fprintf(stderr, + " New best match (%d %d %d) is %s\n", + df, dp, dm, fontptr->name); + + status = TRUE; + } + } + + /* + * Is this a PK file. + */ + if(use_pk && strcmp(qtype, "pk") == 0) + { + df = strdiff(family, qfamily); + dp = abs(point - qpoint); + dm = abs(fontptr->font_gf_mag - qmag); + if((df < *p_min_df) || + (df == *p_min_df && dp < *p_min_dp) || + (df == *p_min_df && dp == *p_min_dp && + dm < *p_min_dm)) + { + *p_min_df = df; + *p_min_dp = dp; + *p_min_dm = dm; + + sprintf(fontptr->name, "%s/%s", + dir, dirrecord->d_name); + fontptr->type = TYPE_PK; if(verbose & DEBUG_FONTS) fprintf(stderr, *** fonts.c-dist Wed Mar 1 12:04:39 1989 --- fonts.c Wed Mar 1 12:04:39 1989 *************** *** 371,378 **** --- 371,380 ---- forward bool init_gf_font_file(); forward bool init_pxl_font_file(); + forward bool init_pk_font_file(); forward bool read_gf_font_char(); forward bool read_pxl_font_char(); + forward bool read_pk_font_char(); /* * init_font_file: *************** *** 393,398 **** --- 395,403 ---- case TYPE_PXL: return init_pxl_font_file(font_fp, fontptr); + case TYPE_PK: + return init_pk_font_file(font_fp, fontptr); + default: fprintf(stderr, "Unknown type of font file; cant happen\n"); exit(1); *************** *** 419,424 **** --- 424,432 ---- case TYPE_PXL: return read_pxl_font_char(font_fp, fontptr, ptr); + case TYPE_PK: + return read_pk_font_char(font_fp, fontptr, ptr); + default: fprintf(stderr, "Unknown type of font file; cant happen\n"); exit(1); *************** *** 913,918 **** --- 921,928 ---- return TRUE; } + static u_char bit_mask[] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }; + /* * read_font_char: * Reads character from font file. *************** *** 927,935 **** register struct char_entry *ptr; { register struct pixrect *pr; ! register int nshorts, i, col, nints; ! register short *dp, *sp; ! int buf[8]; /* * Seek to start of char. --- 937,944 ---- register struct char_entry *ptr; { register struct pixrect *pr; ! register int i, j, nints, nbytes, bp; ! u_int buf; /* * Seek to start of char. *************** *** 941,958 **** * Read the char. */ pr = mem_create(ptr->width, ptr->height, 1); - nshorts = mpr_mdlinebytes(pr) >> 1; nints = (ptr->width + 31) >> 5; ! dp = mpr_d(pr)->md_image; ! for(col = 0; col < ptr->height; col++) ! { ! fread(buf, 4, nints, font_fp); ! sp = (short *) &buf[0]; ! for(i = nshorts; i > 0; i--) ! *dp++ = *sp++; } ptr->where.address.pixrectptr = pr; ptr->where.isloaded = TRUE; return TRUE; } --- 950,1334 ---- * Read the char. */ pr = mem_create(ptr->width, ptr->height, 1); nints = (ptr->width + 31) >> 5; ! pr_rop(pr, 0, 0, ptr->width, ptr->height, PIX_CLR, NULL, 0, 0); ! bp = 0; ! for (i=0; i < ptr->height; i++) { ! nbytes = nints * 4; ! for (j=0; jwidth; j++) { ! if(!(bp & 7)) { ! buf = getc(font_fp); ! nbytes--; ! } ! pr_put(pr, j, i, (buf & bit_mask[bp&7])?1:0); ! bp++; ! } ! while (nbytes--) ! getc(font_fp); ! bp = 0; } + ptr->where.address.pixrectptr = pr; ptr->where.isloaded = TRUE; return TRUE; + } + + /* + * PK font reading functions + */ + + /* ID byte value at the beginning of PK files */ + #define PK_ID 89 + + /* PK op codes */ + #define PK_XXX1 240 + #define PK_XXX2 241 + #define PK_XXX3 242 + #define PK_XXX4 243 + #define PK_YYY 244 + #define PK_POST 245 + #define PK_NOP 246 + #define PK_PRE 247 + + #define PK_REPEAT 0xe /* Repeat last row - repeat count in next nibble */ + #define PK_AGAIN 0xf /* Repeat only once */ + #define PK_LARGE 0x0 /* Long run vaule coming up */ + + + /* + * the macros that read pk values need these variables. + */ + static u_short _nyb_buf, + _nyb_flag, + _pk_repeat; + + + /* + * get the next nybble of the file. This macro requires + * that 2 integers named _nyb_buf and _nyb_flag be allocated elsewhere in + * the program. In addition, _nyb_flag must be initialized to 0. + */ + #define GET_NYB ((_nyb_flag ^= 1) ? \ + ((_nyb_buf = (unsigned)getc(font_fp)) >> 4) : \ + (_nyb_buf & 0xf)) + + /* + * The quantity to be packed into nybbles may require an odd number of + * nybbles which will cause the nybble fetching macro to get out of + * sync. The following macro ``clears'' the state of the nybble fetching + * routine and should be executed whenever transitioning from nybble to + * byte (or other) quantities. + */ + #define CLEAR_NYB _nyb_flag = 0; + + /* + * this macro gets a PK ``packed number'' from fp and puts it into x. + * It is an adaption of an algorithm presented in Tugboat V. 6, No. 3. + */ + #define GET_PACKED(x) x = get_packed(font_fp, dyn_f) + + static u_int + get_packed(font_fp, dyn_f) + register FILE *font_fp; + register u_int dyn_f; + { + register int i, j; + + i = GET_NYB; + if (i == 0) { + /* + * we have an arbitrarily long number. scan to + * find the first non-zero nybble which is the + * count of the nybbles in this value. + */ + do { + j = GET_NYB; + i++; + } while (j == 0); + + while (--i >= 0) + j = (j << 4) + GET_NYB; + + return (j + 193 - 15 * dyn_f); + } else if (i <= dyn_f) { + /* this nybble is the number we want. */ + return (i); + } else if (i < 14) { + return (i + 15 * (i - dyn_f - 1) + GET_NYB); + } else if (i == 14) { + _pk_repeat = get_packed (font_fp, dyn_f); + } else { + _pk_repeat = 1; + } + return (i); + } + + + bool + init_pk_font_file (font_fp, fontptr) + register FILE *font_fp; + register struct font_entry *fontptr; + { + register unsigned c, cc; + long pl, addr; + register u_int i; + u_int hppp, vppp; + int checksum; + u_int tfmw; + double cscale; + + fseek (font_fp, 0L, 0); /* make sure at the beginning of pk file */ + + if (get_unsigned(font_fp, 1) != PK_PRE) { + message("pk font file %s doesn't start with PRE\n", + fontptr->name); + fclose(fontptr->font_file_fd); + fontptr->font_file_fd = NO_FILE; + return TRUE; + } + + if (get_unsigned(font_fp, 1) != PK_ID) { + message("pk font file %s wrong version\n", + fontptr->name); + fclose(fontptr->font_file_fd); + fontptr->font_file_fd = NO_FILE; + return TRUE; + } + + fseek (font_fp, (long) get_unsigned(font_fp, 1), 1); /* skip comment */ + fontptr->designsize = get_unsigned(font_fp, 4); /* ds[4] */ + checksum = get_unsigned(font_fp, 4); /* checksum[4] */ + hppp = get_unsigned(font_fp, 4); /* hppp[4] */ + vppp = get_unsigned(font_fp, 4); /* vppp[4] */ + cscale = (double) fontptr->s / (double)(1 << 20); + + while ((c = get_unsigned(font_fp, 1)) != EOF) { + if (c >= PK_XXX1) { /* commands are just skipped */ + switch (c) { + case PK_XXX1: /* pk_xxx1 k[1] x[k] */ + fseek (font_fp, (long)get_unsigned(font_fp,1), 1); + break; + case PK_XXX2: /* pk_xxx2 k[2] x[k] */ + fseek (font_fp, (long)get_unsigned(font_fp,2), 1); + break; + case PK_XXX3: /* pk_xxx3 k[3] x[k] */ + fseek (font_fp, (long)get_unsigned(font_fp,3), 1); + break; + case PK_XXX4: /* pk_xxx4 k[4] x[4] */ + fseek (font_fp, (long)get_signed(font_fp,4), 1); + break; + case PK_YYY: /* pk_yyy y[4] */ + (void) get_unsigned(font_fp, 4); + break; + case PK_POST: + return TRUE; + case PK_PRE: + message("pk font file %s has extra PRE\n", + fontptr->name); + fclose(fontptr->font_file_fd); + fontptr->font_file_fd = NO_FILE; + return TRUE; + default: /* do nothing */ ; + } + } else { /* flag byte */ + switch (c & 0x07) { /* check flag byte */ + case 0:/* short form */ + case 1: + case 2: + case 3: + /* length */ + pl = (long) get_unsigned(font_fp, 1) + + (long) ((c & 0x03) << 8); + cc = get_unsigned(font_fp,1); /* char. code */ + tfmw = get_unsigned(font_fp,3); /* tfm width */ + (void) get_unsigned(font_fp,1); /* x-escapement */ + fontptr->ch[cc].width = get_unsigned(font_fp, 1); + fontptr->ch[cc].height = get_unsigned(font_fp, 1); + fontptr->ch[cc].xOffset = get_signed(font_fp, 1); + fontptr->ch[cc].yOffset = get_signed(font_fp, 1); + addr = ftell (font_fp); + pl -= 8; + break; + + case 4:/* extended short form */ + case 5: + case 6: + pl = (long) get_unsigned(font_fp, 2) + + (long) ((c & 0x03) << 16); + cc = get_unsigned(font_fp,1); /* char. code */ + tfmw = get_unsigned(font_fp,3); /* tfm width */ + (void) get_unsigned(font_fp,2); /* x-escapement */ + fontptr->ch[cc].width = get_unsigned(font_fp, 2); + fontptr->ch[cc].height = get_unsigned(font_fp, 2); + fontptr->ch[cc].xOffset = get_signed(font_fp, 2); + fontptr->ch[cc].yOffset = get_signed(font_fp, 2); + addr = ftell (font_fp); + pl -= 13; + break; + + case 7:/* long form */ + pl = get_unsigned(font_fp,4); + cc = get_unsigned(font_fp,4); /* char. code */ + tfmw = get_unsigned(font_fp,4); + (void) get_unsigned(font_fp,4); /* x-escapement */ + fontptr->ch[cc].width = get_unsigned(font_fp, 4); + fontptr->ch[cc].height = get_unsigned(font_fp, 4); + fontptr->ch[cc].xOffset = get_signed(font_fp, 4); + fontptr->ch[cc].yOffset = get_signed(font_fp, 4); + addr = ftell (font_fp); + pl -= 24; + break; + } + fontptr->ch[cc].tfmw = (int)(((double)tfmw * cscale) + 0.5); + fontptr->ch[cc].where.isloaded = 0; + fontptr->ch[cc].where.flags = c; + fontptr->ch[cc].where.address.fileOffset = addr;; + fseek (font_fp, pl, 1); /* skip until next flag byte */ + } + } + if((fontptr->c != 0) && (checksum != 0) && (fontptr->c != checksum)) + message("Bad font checksum %d != %d; font %s.", + checksum, fontptr->c, fontptr->name); + return TRUE; + } + + + /* + * load a PK character into memory. + */ + bool + read_pk_font_char(font_fp, fontptr, ptr) + register FILE *font_fp; + register struct font_entry *fontptr; + register struct char_entry *ptr; + { + register struct pixrect *pr; + int cw; /* character width */ + int ch; /* character height */ + u_int dyn_f; /* dynamic factor, part of a PK word. */ + register int i, j; + register int black, bits, bp, rc; + int rowp; + + if (ptr->width == 0 || ptr->height == 0) { + ptr->where.address.pixrectptr = (struct pixrect *) 0; + return; + } + fseek(font_fp, (long)ptr->where.address.fileOffset, 0); + + pr = mem_create(ptr->width, ptr->height, 1); + ptr->where.address.pixrectptr = pr; + + cw = ptr->width; ch = ptr->height; + pr_rop(pr, 0, 0, cw, ch, PIX_CLR, NULL, 0, 0); + + /* + * what remains is the data for the image. It can be packaged + * either as a run-encoding where successive values are the + * number of adjacent pixels to paint in the opposite color of + * the previous painting, or simply as a bitmap with no padding + * except (possibly) for the very last nybble to round up to a + * byte value. + * + * the data for the character is stored in successive bits with + * each new horizontal row at a long boundary. See the PXL + * file format. + */ + + /* + * grab the dyn_f out of the flag for this character. + */ + dyn_f = (ptr->where.flags >> 4) & 0xf; + /* + * the data returned by calloc is zeroed; we depend on that + * because we only turn on bits that are supposed to be + * black. + */ + if (dyn_f == 14) { + /* + * we have a bitmap rather than a run-encoding. + */ + u_int buf; + bp = 0; + for (i=0; i < ch; i++) { + for (j=0; jwhere.flags & (1 << 3); + bits = cw * ch; + CLEAR_NYB; + while (bp < bits) { + GET_PACKED(j); + + if (_pk_repeat != 0) { + rc = _pk_repeat; + rowp = bp / cw; + _pk_repeat = 0; + continue; + } + + /* + * we have a run count in j. + */ + if (black) { + register int k,l,m; + + l = bp / cw; /* starting row */ + m = (bp + j) / cw; /* ending row */ + k = bp % cw; /* start bit offset */ + i = (bp + j) % cw; /* ending bit offset */ + + if (j <= cw && (k < i || i == 0)) { + /* we're changing less than a row */ + pr_rop(pr, k, l, j, 1, PIX_SET, + NULL, 0, 0); + } else { + /* fill any fragment in the current row */ + pr_rop(pr, k, l, cw-k, 1, PIX_SET, + NULL, 0, 0); + + /* fill some number of full rows */ + pr_rop(pr, 0, l+1, cw, (j-(cw-k))/cw, + PIX_SET, NULL, 0, 0); + + /* fill any fragment in the last row */ + if (i) + pr_rop(pr, 0, m, i, 1, PIX_SET, + NULL, 0, 0); + } + } + bp += j; + + /* + * if there's a repeat count and we hit the end of + * a row, do the copy. + */ + if (rc && (bp - (rowp*cw)) >= cw) { + i = rowp+1; + j = rowp+1+rc; + if ((i*cw) != bp) { + pr_rop(pr, 0, j, cw, 1, PIX_SRC, + pr, 0, i); + } + j = rc; + while(j--) { + pr_rop(pr, 0, i, cw, 1, PIX_SRC, + pr, 0, rowp); + i++; + } + bp += rc * cw; + rc = 0; + } + black = !black; + } + } + + ptr->where.isloaded = TRUE; } ------------------------------------------------------------------------------- %%% The TeXhax digest is brought to you as a service of the TeX Users Group %%% in cooperation with the UnixTeX distribution service at the %%% University of Washington %%% %%% Concerning subscriptions, address changes, unsubscribing: %%% BITNET: send a one-line mail message to LISTSERV@xxx %%% where xxx is the nearest geographical site in the %%% tree shown below %%% SUBSCRIBE TEX-L % to subscribe %%% or UNSUBSCRIBE TEX-L %%% Here is the BITNET re-distribution tree as shown in a recent %%% REVIEW (The geography is guessed at from the subscription list) %%% %%% CLVM TAMVM1 FINHUTC %%% | | (Finland, UK, Scand, CERN) %%% | | | %%% TeXhax ----> UWAVM ----- MARIST ----- EB0UB011 ----- BNANDP11 %%% | (France,Italy,Spain) (Belgium) %%% | | %%% UBVM HEARN --- DEARN %%% (Netherlands) (Germany) %%% %%% Internet: send a similar one line mail message to %%% TeXhax-request@cs.washington.edu %%% Please be sure you send a valid internet address!! %%% in the form name@domain or name%routing@domain %%% and use the style of the Bitnet one-line message, so that %%% we can find your subscription request easily. %%% %%% All submissions to: TeXhax@cs.washington.edu %%% %%% Back issues available for FTPing as: %%% machine: directory: filename: %%% JUNE.CS.WASHINGTON.EDU TeXhax/TeXhaxyy.nn %%% yy = last two digits of current year %%% nn = issue number %%% %%% For further information about TeX Users Group services and publications %%% contact Karen at KLB@SEED.AMS.COM or write to TUG at %%% TeX Users Group %%% P.O. Box 9506 %%% Providence, R.I. 02940-9506 %%% Telephone (401) 751-7760 %%% %%% Current versions of the software now in general distribution: %%% TeX 2.95 (2.98 coming) metafont 1.7 %%% plain.tex 2.94 plain.mf 1.7 %%% LaTeX 2.09 ( 8/10/88) cmbase.mf see cm85.bug %%% SliTeX 2.09 gftodvi 1.7 %%% tangle 2.9 gftopk 1.4 %%% weave 2.9 gftype 2.2 %%% dvitype 2.9 pktype 2.2 %%% pltotf 2.3 pktogf 1.0 %%% tftopl 2.5 mft 0.3 %%% BibTeX 0.99c %%% AmSTeX 1.1d %%%\bye %%% End of TeXhax Digest ************************** -------