home *** CD-ROM | disk | FTP | other *** search
- Path: uunet!island!argv
- From: argv@island.uu.net (Dan Heller)
- Newsgroups: comp.sources.x
- Subject: v04i060: xtroff -- troff previewer for X11, Part15/18
- Message-ID: <895@island.uu.net>
- Date: 19 Jul 89 09:13:17 GMT
- Organization: Island Graphics, Marin County, California
- Lines: 1052
- Approved: island!argv@sun.com
-
- Submitted-by: Mark Moraes <moraes@ai.toronto.edu>
- Posting-number: Volume 4, Issue 60
- Archive-name: xtroff/part15
-
-
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 15 (of 18)."
- # Contents: xtroff/font.c
- # Wrapped by moraes@neat.ai on Thu Jul 13 20:55:22 1989
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'xtroff/font.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'xtroff/font.c'\"
- else
- echo shar: Extracting \"'xtroff/font.c'\" \(29184 characters\)
- sed "s/^X//" >'xtroff/font.c' <<'END_OF_FILE'
- X/*
- X * SunTroff - A program to display the output of Device Independent
- X * Troff as a window on a Sun Workstation.
- X *
- X * font.c - All the stuff you will ever need to deal with
- X * troff fonts, versatec fonts for the screen and picking
- X * the best font to use when nothing else is available.
- X * Tries to be intelligent about the best font to use and
- X * to cache all the information it figures out.
- X *
- X * Authors - The original version of this program was written by
- X * Richard L. Hyde (Purdue)
- X * David Slattengren (Berkeley)
- X * It was nearly all rewritten, cleaned up and a more elegant
- X * user interface installed by
- X * Malcolm Slaney (Schlumberger Palo Alto Research)
- X *
- X * Legalese - This command was developed as an independent project
- X * to satisfy a need of the author. This program may contain
- X * bugs and the user is cautioned to independently verify that
- X * the program is suitable for the user's intended purpose.
- X * The program is made available on an ``as is'' basis with
- X * all faults and without any implied or expressed warranties
- X * or support from either the author, Malcolm Slaney, or
- X * Schlumberger Palo Alto Research Laboratory.
- X *
- X * I am putting this program in the public domain. You are
- X * free to use it as you wish. In return I ask two things.
- X * First, that you do not remove the names of the authors
- X * from this work. Secondly, if you make changes or
- X * improvements to this program that you pass these back to
- X * the author so that everybody can benefit from the
- X * improvements.
- X *
- X * Malcolm Slaney (December 1986)
- X * Schlumberger Palo Alto Research
- X * 3340 Hillview Avenue
- X * Palo Alto, CA 94304
- X * (415) 496-4669
- X * spar!malcolm@decwrl.dec.com
- X * malcolm@ecn.purdue.edu
- X * malcolm@spar.slb.com (Someday)
- X */
- X
- X#include "suntroff.h"
- X#include <sys/dir.h>
- X
- X#ifndef SUNTOOLS
- Xextern Display *dpy;
- Xextern GC gc;
- Xextern int SUNRES;
- X/*
- X * Maximum number of fonts to list - make it too big and XListFonts
- X * will fail. Make it large enough to list all fonts you have - 1k
- X * should be enough for most installations
- X */
- X#define MAX_XFONTS 1024
- X#endif
- X
- X#ifdef SUNTOOLS
- X/* emalloc - call fatal() if it can't get memory */
- Xchar *
- Xemalloc(n)
- Xint n;
- X{
- X char *cp = malloc((unsigned int) n);
- X if (cp == NULL)
- X fatal("Can't allocate memory\n");
- X return(cp);
- X}
- X#else
- Xextern char *XtMalloc();
- X#define emalloc(n) XtMalloc((unsigned int) (n))
- X#endif
- Xextern char *malloc();
- X
- X/* rfont () - allocate space and read section of font description
- X *
- X * fp - font file
- X * n - number of bytes to read
- X * file - file name
- X * exit - pointer to table section
- X */
- Xchar *
- Xrfont(fp, n, file)
- Xint fp;
- Xint n;
- Xchar *file;
- X{
- X char *p;
- X extern char *malloc();
- X
- X if((p = (char *) malloc((unsigned) n)) == NULL)
- X fatal("Can't allocate space for reading %d bytes of typesetter information.\n", n);
- X if (read(fp, p, n) != n)
- X fatal("Can't read font information from %s.\n", file);
- X return(p);
- X}
- X
- X/*
- X Each typesetter has a DESC.out file that contains information about
- X the capabilities of the device. The InitFonts function reads this
- X file and puts the information in a useable format for this program.
- X
- X The following information is present in the file:
- X Device A binary image of the Device structure
- X (see dev.h)
- X
- X PointSizeTable An array of shorts that map a point size
- X number (used in the output file format) into
- X a real paper point size.
- X
- X SpecialCharacterNumber An array of indexes that can be used to map
- X a special character number (- 128) into the
- X special character name array that follows.
- X
- X SpecialCharacterName Many null terminated strings representing
- X the names of the special characters that are
- X recognized by this device.
- X
- X Then for each of the Device.nfonts fonts the following information
- X is present (index by i, the font number).
- X FontInformation[i]: Lots of miscellaneous information about the
- X font.
- X WidthTable[i] A pointer to a table of characters indicating
- X the width of each character in the font. The
- X width listed is that of point size 'unitwidth'
- X (see the Device structure.)
- X Kerning[i] A pointer to a table of ascender/descender
- X information
- X CodeTable[i] A pointer to a table giving the code sent to
- X the typesetter to actually produce this
- X character.
- X AsciiTable[i] A pointer to a table giving the mapping
- X between the ASCII code for a character and
- X the character number in the device width
- X tables. Note: The first 128-32 entries of this
- X table give the mapping to the printable ascii
- X characters. Those indices above 128-32 are
- X used for the special characters defined in the
- X SpecialCharacterName[SpecialCharacterNumber]
- X array.
- X
- XTo look up a character do the following....
- XIf the character is a printable ascii simply subtract 32 from its character
- Xcode, and look up this number in the AsciiTable. The number retuned by
- Xthe AsciiTable can be used to index into the WidthTable, Kerning and
- XCodeTables.
- X
- XIf the character is a special character then it is necessary to search
- Xthrough the names listed in the SpecialCharacterName array until a match
- Xis found. Then add 128-32 to this number and then do the above procedure.
- X
- X*/
- X
- Xstruct Typesetter TypesetterList = {
- X "*********", };
- X
- Xstruct Typesetter *UserTypesetter = NULL, *OutputTypesetter = NULL,
- X *DefaultTypesetter = NULL;
- X
- X#ifndef SUNTOOLS
- X#define DEFAULTFONT "r"
- X#else SUNTOOLS
- X#define DEFAULTFONT "R"
- X#endif SUNTOOLS
- X
- Xstatic char *FontName = NULL;
- X
- X /* The table below is used
- X * to keep the mapping between
- X * font positions as used by
- X * the user and the actual
- X * font name.
- X */
- Xstatic char FontPosition[NFONTS][MaxFontName+1];
- X
- X/* LoadDevice - This routine is called by the routine that parses device
- X * control requests in the user's input file. At this point the
- X * user has specified the desired typesetter.....we first check
- X * check to see if we already know about this one. If not then we
- X * call the InitFonts() routine to load the description file.
- X *
- X * This routine is simply called with the name of the typesetter.
- X * All typesetters are stored in a linked list so we just skip down
- X * the list until we find a match.
- X */
- Xstruct Typesetter *
- XLoadDevice(Device)
- Xchar *Device;
- X{
- X struct Typesetter *CurrentTypesetter, *LastTypesetter;
- X extern char *malloc();
- X
- X for (CurrentTypesetter = &TypesetterList;
- X CurrentTypesetter;
- X CurrentTypesetter = CurrentTypesetter->NextTypesetter){
- X if (STREQ(Device,CurrentTypesetter->Name)){
- X return(CurrentTypesetter);
- X }
- X LastTypesetter = CurrentTypesetter;
- X }
- X CurrentTypesetter = (struct Typesetter *)
- X malloc(sizeof(*CurrentTypesetter));
- X if (!CurrentTypesetter) {
- X fatal("Can't get space for typesetter description.\n");
- X }
- X
- X LastTypesetter->NextTypesetter = CurrentTypesetter;
- X CurrentTypesetter->NextTypesetter = NULL;
- X strncpy(CurrentTypesetter->Name,Device,MAXNAME);
- X
- X InitFonts(CurrentTypesetter);
- X return(CurrentTypesetter);
- X}
- X
- X/*
- X * InitFonts - Given a typesetter structure (that is empty except for the
- X * name) go out and read the description file (DESC.out) and fill in
- X * all the entries.
- X *
- X * This is called by the LoadDevice() routine when a typesetter,
- X * previously unknown to this program, is requested.
- X */
- XInitFonts(Typesetter)
- Xstruct Typesetter *Typesetter;
- X{
- X char temp[BUFSIZ];
- X int i;
- X int fp;
- X
- X sprintf(temp,"%s/dev%s/DESC.out",FONTDIR,Typesetter->Name);
- X if ((fp = open(temp, O_RDONLY)) == NULL)
- X fatal("Can't open typesetter description %s.\n",temp);
- X
- X if (read(fp, (char *) &Typesetter->Device, sizeof(Typesetter->Device))
- X != sizeof(Typesetter->Device)) {
- X fatal("Can't read header of %s.\n",temp);
- X }
- X
- X Typesetter->PointSizeTable = (short *) rfont(fp,
- X sizeof(short) * (Typesetter->Device.nsizes + 1), temp);
- X
- X Typesetter->SpecialCharacterNumber = (short *) rfont(fp,
- X sizeof(short) * Typesetter->Device.nchtab, temp);
- X
- X Typesetter->SpecialCharacterName = (char *) rfont(fp,
- X Typesetter->Device.lchname, temp);
- X
- X Typesetter->WidthTable = (char **)emalloc(NFONTS*sizeof(char *));
- X Typesetter->CodeTable = (char **)emalloc(NFONTS*sizeof(char *));
- X Typesetter->AsciiTable = (char **)emalloc(NFONTS*sizeof(char *));
- X
- X for (i=1;i<=Typesetter->Device.nfonts;i++){
- X int NumberWidths;
- X
- X Typesetter->FontInformation[i] = (struct Font *) rfont(fp,
- X sizeof(struct Font), temp);
- X NumberWidths = Typesetter->FontInformation[i]->nwfont & 0377;
- X
- X Typesetter->WidthTable[i] = rfont(fp, 3 * NumberWidths +
- X Typesetter->Device.nchtab + 128 - 32, temp);
- X /* Skip Kerning Table */
- X
- X Typesetter->CodeTable[i] = Typesetter->WidthTable[i] +
- X 2 * NumberWidths;
- X
- X Typesetter->AsciiTable[i] = Typesetter->WidthTable[i] +
- X 3 * NumberWidths;
- X
- X SetFontPositionBuffer(i,Typesetter->FontInformation[i]->namefont,
- X Typesetter->FontInformation[i]->intname);
- X }
- X
- X close(fp);
- X
- X /* Clear out the rest of the
- X font table. */
- X for (i=Typesetter->Device.nfonts+1;i<NFONTS;i++){
- X Typesetter->FontInformation[i] = (struct Font *) 0;
- X }
- X
- X /* Set up the default font
- X position (0) */
- X Typesetter->FontInformation[0] =
- X (struct Font *)emalloc(sizeof (struct Font));
- X Typesetter->WidthTable[0] = (char *)emalloc(3 * 255 +
- X Typesetter->Device.nchtab + 128 - 32);
- X Typesetter->FontInformation[0]->nwfont = 255;
- X Typesetter->CodeTable[0] = Typesetter->WidthTable[0] + 2 * 255;
- X Typesetter->AsciiTable[0] = Typesetter->WidthTable[0] + 3 * 255;
- X Typesetter->FontBitHead.NextFont = NULL;
- X Typesetter->FontBitHead.NextSize = NULL;
- X *(Typesetter->FontBitHead.Name) = NULL;
- X
- X#ifdef FONTDEBUG
- X PrintDevice(Typesetter);
- X#endif FONTDEBUG
- X}
- X
- X/* InitTypesetter () - This routine is called in response to the "x i"
- X * device control request in the user's input file. This routine
- X * needs to do only two things. Both of these things could be done
- X * in the LoadDevice routine but we do them here just so we have
- X * something to do in this routine.
- X *
- X * First, we use ReadFontDirectory() to figure out which fonts we
- X * have bits we can use on the screen.
- X *
- X * Second, we load the FontPosition table with the default font
- X * position mapping information.
- X */
- XInitTypesetter()
- X{
- X int i;
- X
- X if (!ReadFontDirectory(UserTypesetter)){
- X#ifdef TYPEDEBUG
- X printf("Loading the %s DESC.out file\n",DEFAULT_TYPESETTER);
- X#endif TYPEDEBUG
- X if (!DefaultTypesetter){
- X DefaultTypesetter = LoadDevice(DEFAULT_TYPESETTER);
- X if (!DefaultTypesetter){
- X fatal("Can't read default typesetter DESC\n");
- X }
- X }
- X OutputTypesetter = DefaultTypesetter;
- X#ifdef TYPEDEBUG
- X printf("Attempting to load bits for %s.\n",
- X OutputTypesetter->Name);
- X#endif TYPEDEBUG
- X if (!ReadFontDirectory(DefaultTypesetter)){
- X fatal("Can't get font bits for default typesetter.\n");
- X }
- X } else {
- X OutputTypesetter = UserTypesetter;
- X }
- X
- X for (i=0;i<UserTypesetter->Device.nfonts;i++){
- X strncpy(FontPosition[i],
- X UserTypesetter->FontInformation[i]->namefont,
- X MaxFontName);
- X }
- X for (i; i<NFONTS; i++){
- X FontPosition[i][0] = 0;
- X }
- X
- X#ifdef FONTDEBUG
- X PrintFontDirectory(OutputTypesetter);
- X#endif FONTDEBUG
- X}
- X
- X/* SetFontPosition - Given a font number and a font name (from the "x f"
- X * device request) if the font is not already loaded (in that position)
- X * get the font info and store the name in the FontPostion buffer
- X */
- XSetFontPosition(FontNumber,FontName,InternalFontName)
- Xint FontNumber;
- Xchar *FontName, *InternalFontName;
- X{
- X char temp[BUFSIZ];
- X int NumberWidths;
- X FILE *fp;
- X struct Typesetter *Typesetter = OutputTypesetter;
- X int norig;
- X
- X
- X if (FontNumber < 0 || FontNumber > NFONTS)
- X fatal("illegal x font command %d %s", FontNumber, FontName);
- X#ifdef FONTDEBUG
- X printf("x font %d %s - FontPosition[%d]= %s\n", FontNumber, FontName,
- X FontNumber, FontPosition[FontNumber]);
- X#endif /* FONTDEBUG */
- X if (strncmp(FontPosition[FontNumber], FontName, MaxFontName) == 0)
- X return;
- X if (Typesetter->FontInformation[FontNumber] == 0) {
- X#ifdef FONTDEBUG
- X printf("allocating space for %s/dev%s/%s.out\n", FONTDIR,
- X Typesetter->Name, FontName);
- X#endif /* FONTDEBUG */
- X Typesetter->FontInformation[FontNumber] =
- X (struct Font *)emalloc(sizeof (struct Font));
- X Typesetter->WidthTable[FontNumber] = (char *)emalloc(3 * 255 +
- X Typesetter->Device.nchtab + 128 - 32);
- X Typesetter->FontInformation[FontNumber]->nwfont = 255;
- X Typesetter->CodeTable[FontNumber] =
- X Typesetter->WidthTable[FontNumber] + 2 * 255;
- X Typesetter->AsciiTable[FontNumber] =
- X Typesetter->WidthTable[FontNumber] + 3 * 255;
- X }
- X SetFontPositionBuffer(FontNumber,FontName,InternalFontName);
- X
- X /* open the font file */
- X sprintf(temp,"%s/dev%s/%s.out",FONTDIR,Typesetter->Name,
- X FontName);
- X fp = fopen(temp,"r");
- X if (!fp){
- X warning("Can't open typesetter description %s.\n",temp);
- X#ifdef FONTDEBUG
- X printf("Can't open typesetter description %s.\n",temp);
- X#endif /* FONTDEBUG */
- X return;
- X }
- X norig = Typesetter->FontInformation[FontNumber]->nwfont & 0xff;
- X
- X fread((char *) Typesetter->FontInformation[FontNumber],
- X sizeof(struct Font), 1, fp);
- X NumberWidths = Typesetter->FontInformation[FontNumber]->nwfont & 0377;
- X if (NumberWidths > norig) {
- X#ifdef FONTDEBUG
- X printf("allocating space for %s/dev%s/%s.out\n", FONTDIR,
- X Typesetter->Name, FontName);
- X#endif /* FONTDEBUG */
- X Typesetter->WidthTable[FontNumber] = (char *)emalloc(3 * 255 +
- X Typesetter->Device.nchtab + 128 - 32);
- X norig = 255;
- X }
- X fread(Typesetter->WidthTable[FontNumber], NumberWidths * 3 +
- X Typesetter->Device.nchtab + 128 - 32, 1, fp);
- X fclose(fp);
- X
- X Typesetter->CodeTable[FontNumber] =
- X Typesetter->WidthTable[FontNumber] + 2 * NumberWidths;
- X Typesetter->AsciiTable[FontNumber] =
- X Typesetter->WidthTable[FontNumber] + 3 * NumberWidths;
- X Typesetter->FontInformation[FontNumber]->nwfont = norig;
- X}
- X
- X/* SetFontPositionBuffer - Given a font number and a font name, store the
- X * name in the font position table
- X */
- X/*ARGSUSED*/
- XSetFontPositionBuffer(FontNumber,FontName,InternalFontName)
- Xint FontNumber;
- Xchar *FontName, *InternalFontName;
- X{
- X int i;
- X char *cp;
- X
- X if (FontNumber >= 0 && FontNumber <= NFONTS){
- X strncpy(FontPosition[FontNumber], FontName, MaxFontName);
- X#ifndef SUNTOOLS
- X for(i = 0, cp = FontPosition[FontNumber]; *cp &&
- X i < MaxFontName; i++, cp++)
- X if (isascii(*cp) && islower(*cp))
- X *cp = tolower(*cp);
- X#endif
- X }
- X}
- X
- X/* SetFontSize - Given a point size change the current font to this new
- X * font. Most of the work needed is done by VirtualLoadFont. But
- X * then VirtualLoadFont doesn't really do any work....it just caches
- X * the information until it is needed later.
- X */
- XSetFontSize(n)
- Xint n; /* Actual Point Size */
- X{
- X size = n;
- X ditsiz = (float)(SUNRES * n)/75.;
- X#ifdef FONTDEBUG
- X printf("SetFontSize(%d)\n",n);
- X printf("ditsiz=%g\n",ditsiz);
- X#endif /* FONTDEBUG */
- X
- X if (FontName == NULL) {
- X if ((FontName = (char *) malloc(sizeof(DEFAULTFONT))) == NULL)
- X fatal("Can't allocate font name space\n");
- X strcpy(FontName, DEFAULTFONT);
- X }
- X VirtualLoadFont(FontName,size);
- X}
- X
- X/* SetFont - Given a font number this routine looks it up in the FontPosition
- X * mapping table. All the real work is done by the VirtualLoadFont()
- X * routine.
- X */
- XSetFont(n)
- Xint n; /* Internal Font Number */
- X{
- X if (n >= 0 &&
- X n < NFONTS){
- X font = n;
- X FontName = FontPosition[n];
- X VirtualLoadFont(FontName,size);
- X }
- X}
- X
- X#ifdef FONTDEBUG
- X
- X/* PrintDevice - Print out an ASCII representation of the DESC.out file
- X * so that the correct operation of the InitFonts routine can be
- X * verified. This also will verify that the DESC.out file and the
- X * dev.h file used to compile this program are compatible.
- X */
- XPrintDevice(Typesetter)
- Xstruct Typesetter *Typesetter;
- X{
- X int i;
- X struct dev *Device;
- X short *SpecialCharacterNumber;
- X char *SpecialCharacterName;
- X
- X Device = &Typesetter->Device;
- X
- X printf("# Debugging output for suntroff of main device.\n");
- X
- X printf("res %d\n",Device->res);
- X printf("hor %d\n",Device->hor);
- X printf("vert %d\n",Device->vert);
- X printf("unitwidth %d\n",Device->unitwidth);
- X printf("paperwidth %d\n",Device->paperwidth);
- X printf("paperlength %d\n",Device->paperlength);
- X
- X printf("sizes");
- X for (i=0;i<Device->nsizes;i++){
- X printf(" %d",Typesetter->PointSizeTable[i]);
- X }
- X printf("\n");
- X
- X printf("fonts %d",Device->nfonts);
- X fflush(stdout);
- X for (i=1;i<=Device->nfonts;i++){
- X if (Typesetter->FontInformation[i]){
- X printf(" %s",Typesetter->FontInformation[i]->namefont);
- X } else {
- X printf("FontInformation[i=%d] is null.\n",i);
- X }
- X }
- X printf("\n");
- X
- X printf("charset\n");
- X
- X SpecialCharacterName = Typesetter->SpecialCharacterName;
- X SpecialCharacterNumber = Typesetter->SpecialCharacterNumber;
- X
- X for (i=0;i<Device->nchtab;i++){
- X printf(" %2s",
- X &SpecialCharacterName[SpecialCharacterNumber[i]]);
- X if (i%10 == 0)
- X printf("\n");
- X }
- X printf("\n");
- X
- X#if FONTDEBUG > 1
- X for (i=0;i<=Device->nfonts;i++){
- X PrintFont(Typesetter,i);
- X }
- X#endif FONTDEBUG > 1
- X}
- X
- X/* PrintFont - Print out an ASCII representation for the information in
- X * a font description file.
- X */
- XPrintFont(Typesetter,i)
- Xstruct Typesetter *Typesetter;
- Xint i;
- X{
- X int j;
- X struct Font **FontInformation1;
- X char **AsciiTable, **CodeTable, **WidthTable;
- X short *SpecialCharacterNumber;
- X char *SpecialCharacterName;
- X struct Font **FontInformation;
- X
- X FontInformation = Typesetter->FontInformation;
- X AsciiTable = Typesetter->AsciiTable;
- X CodeTable = Typesetter->CodeTable;
- X WidthTable = Typesetter->WidthTable;
- X SpecialCharacterNumber = Typesetter->SpecialCharacterNumber;
- X SpecialCharacterName = Typesetter->SpecialCharacterName;
- X
- X if (!FontInformation[i]){
- X printf("There is no font information for font %d.\n",i);
- X }
- X printf("\n#\n");
- X printf("name %s\n",FontInformation[i]->namefont);
- X printf("internalname %s\n",FontInformation[1]->intname);
- X printf("ligatures ");
- X if (FontInformation[i]->ligfont & LFF) printf(" ff");
- X if (FontInformation[i]->ligfont & LFI) printf(" fi");
- X if (FontInformation[i]->ligfont & LFL) printf(" fl");
- X if (FontInformation[i]->ligfont & LFFI) printf(" ffi");
- X if (FontInformation[i]->ligfont & LFFL) printf(" ffl");
- X printf(" 0\ncharset\n");
- X for (j=0;j<FontInformation[i]->nwfont;j++){
- X int k;
- X
- X for (k=0;k<Typesetter->Device.nchtab+128-32;k++){
- X if (AsciiTable[i][k] == j){
- X break;
- X }
- X }
- X if (k < Typesetter->Device.nchtab+128-32){
- X if (k < 128-32){
- X printf("%c\t",k+32);
- X } else {
- X printf("%s\t",
- X &SpecialCharacterName
- X [SpecialCharacterNumber[k-(128-32)]]);
- X }
- X } else {
- X printf("Couldn't find %d\t",j);
- X }
- X printf("%d\t%d\t%d\n",
- X WidthTable[i][j],0,CodeTable[i][j]);
- X }
- X fflush(stdout);
- X}
- X
- X
- X#endif FONTDEBUG
- X
- X/* ReadFontDirectory - Given a Typesetter go out to the BITDIR directory
- X * and figure out which fonts exist. This information is important
- X * because it will allow the VirtualLoadFont() routine to search through
- X * memory instead of probing the file system every time it wants to
- X * change fonts. Reading the entire directory is much more efficient
- X * then trying to do random probes looking for the closest match to
- X * a font.
- X */
- X/*
- X * For X Windows, the workstation that your display is on, and the
- X * machine you're running xtroff on may be quite different - and might
- X * have access to completely different fonts as a result. So we use
- X * XListFonts()
- X */
- XReadFontDirectory(Typesetter)
- Xstruct Typesetter *Typesetter;
- X{
- X#ifdef SUNTOOLS
- X DIR *dfp;
- X struct direct *DirectoryEntry;
- X char Directory[BUFSIZ];
- X#else
- X int nf;
- X char **fontNames;
- X/* MAXDEVICE is the maximum length of the name of the device - (eg) devsun */
- X#define MAXDEVICE 32
- X char fontfamily[MAXDEVICE+8];
- X char devname[MAXDEVICE];
- X int devnamelen;
- X char *dpi;
- X int dotsperinch;
- X#endif
- X char *FontName, *FontSize, *p;
- X char *FileName;
- X char *Device;
- X
- X Device = Typesetter->Name;
- X if (Typesetter->FontBitHead.NextFont){
- X return(1);
- X }
- X
- X#ifdef SUNTOOLS
- X sprintf(Directory,"%s/dev%s",BITDIR,Device);
- X dfp = opendir(Directory);
- X if (!dfp){
- X return(0);
- X }
- X
- X while(DirectoryEntry = readdir(dfp)){
- X
- X if (!DirectoryEntry->d_fileno){
- X continue;
- X }
- X FontSize = FontName = DirectoryEntry->d_name;
- X#else SUNTOOLS
- X sprintf(devname, "dev%s", Device);
- X devnamelen = strlen(devname);
- X sprintf(fontfamily, "%s.*.*", devname);
- X /*
- X * Pity we can't give a better pattern - now if they had
- X * regular expressions......
- X */
- X fontNames = XListFonts(dpy, fontfamily, MAX_XFONTS, &nf);
- X if (nf == 0)
- X return(0);
- X while(--nf >= 0){
- X FontSize = FontName = fontNames[nf] + devnamelen + 1;
- X#endif SUNTOOLS
- X while (isalpha(*FontSize)){
- X FontSize++;
- X }
- X if (!*FontSize || FontName == FontSize)
- X continue; /* No Size */
- X *FontSize = '\0';
- X
- X p = ++FontSize;
- X while (isdigit(*p)){
- X p++;
- X }
- X#ifdef SUNTOOLS
- X if (p == FontSize || *p != '\0'){
- X continue;
- X }
- X FileName = (char *)malloc(strlen(Directory)+strlen(FontName)
- X +strlen(FontSize)+4);
- X if (!FileName){
- X fatal("Can't allocate file name space.\n");
- X }
- X sprintf(FileName,"%s/%s.%s",Directory,FontName,FontSize);
- X InsertFont(Typesetter,FontName,atoi(FontSize),FileName);
- X }
- X closedir(dfp);
- X#else SUNTOOLS
- X if (*p == '\0') {
- X dpi = "75";
- X dotsperinch = atoi(dpi);
- X FileName = (char *)emalloc(devnamelen + strlen(FontName)
- X + strlen(FontSize) + strlen(dpi) + 4);
- X sprintf(FileName, "%s.%s.%s", devname, FontName, FontSize);
- X InsertFont(Typesetter, FontName,
- X (dotsperinch * atoi(FontSize) + (SUNRES / 2))
- X / SUNRES, FileName);
- X } else {
- X if (p == FontSize || *p != '.'){
- X continue;
- X }
- X
- X *p++ = '\0';
- X dpi = p;
- X while (isdigit(*p)) {
- X p++;
- X }
- X
- X if (p == dpi || *p != '\0') {
- X continue;
- X }
- X dotsperinch = atoi(dpi);
- X FileName = (char *)malloc(devnamelen + strlen(FontName)
- X + strlen(FontSize) + strlen(dpi) + 4);
- X if (!FileName){
- X fatal("Can't allocate file name space.\n");
- X }
- X (void) sprintf(FileName, "%s.%s.%s.%s", devname,
- X FontName, FontSize, dpi);
- X InsertFont(Typesetter, FontName,
- X (dotsperinch * atoi(FontSize) + (SUNRES / 2))
- X / SUNRES, FileName);
- X }
- X }
- X XFreeFontNames(fontNames);
- X#endif SUNTOOLS
- X return(1);
- X}
- X
- X/* PrintFontDirectory - Print out all the fonts found by the ReadFontDirectory
- X * routine.
- X */
- XPrintFontDirectory(Typesetter)
- Xstruct Typesetter *Typesetter;
- X{
- X struct FontBitStruct *FontPointer, *SizePointer;
- X char *Device;
- X
- X Device = Typesetter->Name;
- X printf("Found the following fonts for %s.",Device);
- X
- X for (FontPointer = &Typesetter->FontBitHead;
- X FontPointer;
- X FontPointer = FontPointer->NextFont){
- X printf("\n%s\t",FontPointer->Name);
- X for (SizePointer = FontPointer;
- X SizePointer;
- X SizePointer = SizePointer -> NextSize){
- X printf("%d ",SizePointer->Size);
- X }
- X }
- X printf("\n");
- X}
- X
- X/* InsertFont - OK, we've found a file name in the BITDIR that looks like
- X * a proper font name, add it to the font list for the current
- X * typesetter. This routine just looks for the proper point in the
- X * two dimensional (name and size) linked list. AddFont() does
- X * all the real work.
- X */
- XInsertFont(Typesetter,Name,Size,FileName)
- Xstruct Typesetter *Typesetter;
- Xchar *Name, *FileName;
- Xint Size;
- X{
- X struct FontBitStruct *FontPointer, *SizePointer, *CurrentFont;
- X struct FontBitStruct *AddFont();
- X
- X for (FontPointer = &Typesetter->FontBitHead;
- X FontPointer;
- X FontPointer = FontPointer->NextFont){
- X if (STREQ(Name,FontPointer->Name)){
- X for (SizePointer = FontPointer;
- X SizePointer;
- X SizePointer = SizePointer->NextSize){
- X if (SizePointer->Size == Size){
- X return;
- X }
- X CurrentFont = SizePointer;
- X }
- X CurrentFont->NextSize = AddFont(Name,Size,FileName);
- X return;
- X }
- X CurrentFont = FontPointer;
- X }
- X CurrentFont->NextFont = AddFont(Name,Size,FileName);
- X}
- X
- X/* AddFont - Add a structure to the list of available fonts indicating that
- X * the font Name and Size are available in the indicated FileName.
- X */
- Xstruct FontBitStruct *
- XAddFont(Name,Size,FileName)
- Xchar *Name, *FileName;
- Xint Size;
- X{
- X
- X struct FontBitStruct *font;
- X
- X font = (struct FontBitStruct *)malloc(sizeof(*font));
- X if (!font){
- X fatal("Can't get storage for font cache.\n");
- X }
- X
- X strncpy(font->Name,Name,MaxFontName);
- X font->Size = Size;
- X font->NextFont = font->NextSize = NULL;
- X font->Bits = NULL;
- X font->FileName = FileName;
- X return(font);
- X}
- X
- X/* VirtualLoadFont - Given a desired FontName and PointSize find the font
- X * that we have screen bits for that is as close as possible. Close
- X * is defined as being the same name and the largest point size that
- X * is smaller than the desired.
- X *
- X * If we don't have the correct font name then go ahead and use the
- X * "R" font. We don't bother giving the user an error message, but
- X * we probably should.
- X *
- X * Once we have the best font name, then look down the list until
- X * we can find the best point size match. If we can't find an exact
- X * match then use the NextBestFont which is the largest point size
- X * that is smaller than the desired (we try to avoid overlapping the
- X * characters). If we didn't find the exact match then we install
- X * our best approximation as the correct choice so the user only
- X * sees one point size substitution error message.
- X */
- Xstruct FontBitStruct *
- XVirtualLoadFont(FontName,PointSize)
- Xchar *FontName; /* Actual Font Name */
- Xint PointSize; /* Actual Point Size */
- X{
- X struct FontBitStruct *NewFont, *NextBestFont, *FindFont(), *LastFont;
- X
- X if (!FontName || FontName[0] == 0)
- X fatal("Bad font found in VirtualLoadFont.\n");
- X
- X#ifndef SUNTOOLS
- X /*
- X * X11 has this brain dead convention that all font names must
- X * be lower case! Case independent, forsooth...
- X */
- X {
- X register char *s;
- X for(s = FontName; *s; s++)
- X if (isascii(*s) && isupper(*s))
- X *s = tolower(*s);
- X }
- X#endif SUNTOOLS
- X
- X if (CurrentFont && CurrentFont->Size == PointSize &&
- X STREQ(CurrentFont->Name, FontName)){
- X return CurrentFont;
- X }
- X
- X NewFont = FindFont(FontName);
- X if (!NewFont){
- X NewFont = FindFont(DEFAULTFONT);
- X }
- X if (!NewFont){
- X fatal("Couldn't find either the %s or the R font.",FontName);
- X }
- X
- X NextBestFont = NewFont;
- X
- X#ifdef FONTDEBUG
- X printf("Loading font name %s, point size %d.\n",
- X FontName,PointSize);
- X if (CurrentFont)
- X printf("Current font is %s, point size %d.\n",
- X CurrentFont->Name, CurrentFont->Size);
- X#endif
- X
- X while (NewFont){
- X if (NewFont->Size == PointSize){
- X CurrentFont = NewFont;
- X return(CurrentFont);
- X }
- X
- X if (NextBestFont->Size > PointSize &&
- X NewFont->Size < NextBestFont->Size){
- X NextBestFont = NewFont;
- X
- X }
- X
- X if (NewFont->Size < PointSize &&
- X NextBestFont->Size < NewFont->Size){
- X NextBestFont = NewFont;
- X }
- X LastFont = NewFont;
- X NewFont = NewFont->NextSize;
- X }
- X if (abs(PointSize - NextBestFont->Size) > 1){
- X warning("Couldn't find point size %d of the %s font. Using point size %d instead",
- X PointSize,FontName, NextBestFont->Size);
- X }
- X /*
- X * Don't have the correct size....so fake an entry so the user only
- X * gets one error message.
- X */
- X if (PointSize != NextBestFont->Size){
- X if (!LastFont ->NextSize){
- X NewFont = AddFont(FontName, PointSize,
- X NextBestFont->FileName);
- X NewFont->Bits = NextBestFont->Bits;
- X NextBestFont = LastFont->NextSize = NewFont;
- X }
- X }
- X CurrentFont = NextBestFont;
- X return CurrentFont;
- X}
- X
- X/* Findfont - Given a font name, find it on the list of available output
- X * type styles. This routine is called by the VirtualLoadFont routine.
- X */
- Xstruct FontBitStruct *
- XFindFont(FontName)
- Xchar *FontName;
- X{
- X struct FontBitStruct *NewFont;
- X
- X if (!OutputTypesetter){
- X fatal("Program error: No typesetter specified.\n");
- X }
- X for (NewFont= &OutputTypesetter->FontBitHead;
- X NewFont;
- X NewFont=NewFont->NextFont){
- X if (STREQ(NewFont->Name,FontName)){
- X return(NewFont);
- X }
- X }
- X return(0);
- X}
- X
- X/* LoadFontBits - OK, the user has already requested a point size and
- X * typeface. The VirtualLoadFont() routine has figured out which
- X * of the available output fonts is best to use.
- X *
- X * Now this routine actually goes out and loads the correct (Versatec)
- X * font file. All the real work is done by the SunTools pf_open()
- X * routine. Thanks, Sun.
- X */
- X
- XLoadFontBits(){
- X#ifdef SUNTOOLS
- X struct pixfont *pf_open();
- X
- X if (CurrentFont->Bits){
- X return; /* Already Loaded */
- X }
- X#ifdef FONTDEBUG
- X printf("Loading the bits from %s.\n",CurrentFont->FileName);
- X#endif FONTDEBUG
- X
- X CurrentFont->Bits = pf_open(CurrentFont->FileName);
- X
- X if (!CurrentFont->Bits){
- X fatal("Can't read fonts from %s.\n",
- X CurrentFont->FileName);
- X }
- X#else SUNTOOLS
- X static Font curxfont = 0;
- X
- X if (CurrentFont->Bits){
- X if (curxfont != CurrentFont->Bits->fid) {
- X#ifdef FONTDEBUG
- X printf("changing to font %s\n", CurrentFont->FileName);
- X#endif FONTDEBUG
- X curxfont = CurrentFont->Bits->fid;
- X XSetFont(dpy, gc, curxfont);
- X }
- X return; /* Already Loaded */
- X }
- X
- X#ifdef FONTDEBUG
- X printf("Loading the bits from %s.\n",CurrentFont->FileName);
- X#endif FONTDEBUG
- X
- X CurrentFont->Bits = XLoadQueryFont(dpy, CurrentFont->FileName);
- X
- X if (!CurrentFont->Bits){
- X fatal("Can't read fonts from %s.\n",
- X CurrentFont->FileName);
- X }
- X curxfont = CurrentFont->Bits->fid;
- X XSetFont(dpy, gc, curxfont);
- X#endif SUNTOOLS
- X}
- END_OF_FILE
- if test 29184 -ne `wc -c <'xtroff/font.c'`; then
- echo shar: \"'xtroff/font.c'\" unpacked with wrong size!
- fi
- # end of 'xtroff/font.c'
- fi
- echo shar: End of archive 15 \(of 18\).
- cp /dev/null ark15isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 18 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-