home *** CD-ROM | disk | FTP | other *** search
- /*
- * list fonts, print info about them
- */
-
- /* Two versions:
- * large, with select/sort/help options -DFTS_LARGE
- * small, bare-bones (default)
- */
-
- #include <proto/exec.h>
- #include <proto/diskfont.h>
-
- #include <string.h>
- #include <exec/types.h>
- #include <exec/memory.h>
- #include <libraries/diskfont.h>
- #include <graphics/text.h>
-
- #define AFSIZE 2000L
-
- long brkclean();
- short fontcmpname();
- void mkflags(), combine(), fixname(), cleanup(), shortbits();
-
- #ifdef FTS_LARGE
- void showhelp(), doargs();
- short fontcmpsize(), select(), mksel();
- #endif
-
- /* if you don't use 'proto/diskfont.h', then you'll need this:
- extern long DiskfontBase;
- */
-
- struct AvailFontsHeader *afh;
-
- #ifdef FTS_LARGE
- struct selinfo { /* place to keep select options */
- short valid, type, style, flags, ysize, sort;
- char *name;
- };
- /* flag bits for 'valid' selections (things that the user set) */
- #define SEL_TYPE 0x01
- #define SEL_STYLE 0x02
- #define SEL_FLAGS 0x04
- #define SEL_YSIZE 0x08
- #define SEL_NAME 0x10
- #define SEL_SORT 0x20
- #endif
-
- #define FBUFSZ 24 /* length of flags string in the listing */
-
- void main(ac, av)
- int ac;
- char *av[];
- {
- register struct AvailFonts *af;
- register struct TextAttr *ta;
- unsigned short num ,i, cnt;
- char flagbuf[FBUFSZ];
- #ifdef FTS_LARGE
- struct selinfo selinfo;
- #endif
-
- afh = NULL; /* init for cleanup */
- onbreak(&brkclean); /* clean-up on ^C/^D */
-
- #ifdef FTS_LARGE
- selinfo.sort = 0; /* sort by name */
- selinfo.valid = 0; /* no others have been selected */
- selinfo.type = selinfo.style = selinfo.flags = 0;
- #endif
- afh = (struct AvailFontsHeader *) AllocMem(AFSIZE, MEMF_CLEAR);
- if ( afh == NULL ) {
- exit(10L);
- }
- if ( (DiskfontBase = OpenLibrary("diskfont.library",0L)) == (long)NULL ) {
- cleanup();
- exit(15L);
- }
- #ifdef FTS_LARGE
- doargs(ac, av, &selinfo); /* find out what they asked for */
- #endif
- if ( AvailFonts((char *)afh, AFSIZE, 0xffL) != 0 )
- printf("Some fonts not gotten...\n"); /* really should try again */
- num = afh->afh_NumEntries;
- af = (struct AvailFonts *) &afh[1]; /* trick from RKM */
-
- qsort(af, num, sizeof (struct AvailFonts), /* sort names/sizes */
- #ifdef FTS_LARGE
- (selinfo.sort == 0) ? fontcmpname : fontcmpsize );
- #else
- fontcmpname);
- #endif
- printf("Font Name Size Type Style Flags\n");
- cnt = 0;
- for ( i = 0; i < num; i++, af++ ) {
- ta = &af->af_Attr;
- if ( ta->ta_Name == NULL ) { /* when "combined" */
- continue;
- }
- if ( i < (num-1) ) { /* see if we can combine */
- combine(af);
- }
- fixname(ta->ta_Name); /* get rid of ".font" */
- #ifdef FTS_LARGE
- if ( !select(af, &selinfo) ) { /* if no match, skip it */
- continue;
- }
- #endif
- mkflags(flagbuf, af->af_Type, ta->ta_Style, ta->ta_Flags);
- printf("%-20s %3d %s\n", ta->ta_Name, ta->ta_YSize, flagbuf);
- cnt++;
- }
- printf("%d / %d fonts.\n", cnt, num);
- cleanup();
- exit(0L);
- }
-
- void cleanup()
- {
- if ( DiskfontBase != NULL )
- CloseLibrary(DiskfontBase);
- if ( afh != NULL )
- FreeMem((char *)afh, AFSIZE);
- }
-
- long brkclean()
- {
- cleanup();
- return 1L;
- }
-
- #ifdef FTS_LARGE
- /*
- * read command line args, fill in selinfo struct
- */
- void doargs(ac, av, sp)
- register int ac;
- register char **av;
- register struct selinfo *sp;
- {
- register char *p;
-
- while ( --ac > 0 ) {
- p = *++av;
- if ( *p != '-' )
- continue;
- ++p;
- switch ( (*p++) ) {
- case 't': /* set type */
- sp->type |= mksel(p, "dm", 0x2);
- sp->valid |= SEL_TYPE;
- break;
- case 's': /* set style */
- sp->style |= mksel(p, "eibu", 0x8);
- sp->valid |= SEL_STYLE;
- break;
- case 'f': /* set flags */
- sp->flags |= mksel(p, "xspwtbdr", 0x80);
- sp->valid |= SEL_FLAGS;
- break;
- case 'y': /* set ysize (only one!) */
- sp->ysize = atoi(p);
- sp->valid |= SEL_YSIZE;
- break;
- case 'n': /* set name (only one!) */
- sp->name = p;
- sp->valid |= SEL_NAME;
- break;
- case 'S': /* set sort by Size */
- sp->sort = 1;
- sp->valid |= SEL_SORT;
- break;
- default:
- showhelp();
- }
- }
- }
- #endif
-
- #ifdef FTS_LARGE
- /*
- * print help message, and cleanup and exit
- */
- void showhelp()
- {
- printf("Use: fts -t[dm] -s[eibu] -f[xspwtbdr] -y# -n(name) -S\n");
- printf(" Type: -t d = disk m = memory\n");
- printf(" Style: -s e = extended i = italics\n");
- printf(" b = bold u = underline\n");
- printf(" Flags: -f x = removed s = designed\n");
- printf(" p = proportional w = wide dot\n");
- printf(" t = tall dot b = backwards\n");
- printf(" d = disk font r = rom\n");
- printf(" Size: -y# where `#' is YSize of the font\n");
- printf(" Name: -n... where `...' is the font name\n");
- printf(" Sort: -S = sort by size instead of name\n");
- cleanup(); /* clean up and exit */
- exit(0);
- }
- #endif
-
- /*
- * compare two AvailFonts structs, to sort by name/ysize
- */
- short fontcmpname(f1, f2)
- struct AvailFonts *f1, *f2;
- {
- int stricmp();
- short r;
- register struct TextAttr *t1, *t2;
-
- t1 = &f1->af_Attr;
- t2 = &f2->af_Attr;
- if ( (r = stricmp(t1->ta_Name, t2->ta_Name)) == 0 ) {
- r = t1->ta_YSize - t2->ta_YSize;
- }
- return r;
- }
-
- #ifdef FTS_LARGE
- /*
- * compare two AvailFonts structs, to sort by ysize/name
- */
- short fontcmpsize(f1, f2)
- struct AvailFonts *f1, *f2;
- {
- int stricmp();
- short r;
- register struct TextAttr *t1, *t2;
-
- t1 = &f1->af_Attr;
- t2 = &f2->af_Attr;
- if ( (r = t1->ta_YSize - t2->ta_YSize) == 0 ) {
- r = stricmp(t1->ta_Name, t2->ta_Name);
- }
- return r;
- }
- #endif
-
- /*
- * see if the next (sorted) font has the same characteristics;
- * if so, combine that one's type with this one; mark it "empty"
- */
- void combine(ap)
- struct AvailFonts *ap;
- {
- struct AvailFonts *ap2;
- register struct TextAttr *t1, *t2;
-
- ap2 = ap + 1;
- t1 = &ap->af_Attr;
- t2 = &ap2->af_Attr;
- if ( (strcmp(t1->ta_Name, t2->ta_Name) == 0)
- && t1->ta_YSize == t2->ta_YSize
- && t1->ta_Style == t2->ta_Style
- && t1->ta_Flags == t2->ta_Flags ) { /* if TextAttr's are same, then combine avail-font types */
- ap->af_Type |= ap2->af_Type;
- t2->ta_Name = NULL; /* mark it "combined" */
- }
- }
-
- /*
- * fix up the font name to print - get rid of the training ".font"
- */
- void fixname(p)
- char *p;
- {
- register char *s, *d;
-
- /* if Lattice's "strrchr" did what UNIX's "strrchr" did, we wouldn't have to do this... */
- d = NULL;
- for ( s = p; *s; s++ ) {
- if ( *s == '.' )
- d = s;
- }
- if ( d != NULL )
- *d = '\0'; /* end the name at the last dot */
- }
-
- /*
- * fill a print buffer with some flags: mem/style/attributes
- */
- void mkflags(p, t, s, f)
- char *p; /* destination buffer */
- short t, s, f; /* type, style, flags */
- {
- /* Type Style Flags */
- strcpy (p, " -- ---- --------");
- shortbits(&p[1], t, "dm", '-', 0x2);
- shortbits(&p[5], s, "eibu", '-', 0x8);
- shortbits(&p[11], f, "xspwtbdr", '-', 0x80);
- }
-
- /* turn flag bits into series of characters */
- void shortbits(p, v, t, fc, b)
- char *p; /* output string */
- short v; /* value to be decoded */
- char *t; /* true char string */
- short fc; /* false char */
- short b; /* top (start) bit */
- {
- while ( b ) { /* for each bit */
- *p++ = ( b & v ) ? *t : fc; /* accum chars if bit is set */
- t++; /* next char, next bit */
- b >>= 1;
- }
- }
-
- #ifdef FTS_LARGE
- /* turn characters into flag bits */
- short mksel(p, r, b0)
- register char *p; /* input char string */
- char *r; /* reference flag characters */
- short b0; /* top (start) bit */
- {
- register short v; /* output value */
- register char *f; /* current flag char */
- register short b; /* current bit */
-
- v = 0;
- while ( *p ) { /* for each char in input */
- f = r;
- b = b0;
- while ( *f ) { /* for each char in reference */
- if ( *p == *f ) /* if char's match, set the bit */
- v |= b;
- f++; /* next char, next bit */
- b >>= 1;
- }
- p++; /* next input char */
- }
- return v;
- }
- #endif
-
- #ifdef FTS_LARGE
- /*
- * see if the given font structure matches what was asked for
- */
- short select(af, ps)
- register struct AvailFonts *af; /* what we're looking at */
- register struct selinfo *ps; /* what they want to see */
- {
- register short len;
-
- if ( (ps->valid & SEL_YSIZE) && (af->af_Attr.ta_YSize != ps->ysize) )
- return 0;
- len = strlen(ps->name);
- if ( (ps->valid & SEL_NAME)
- && (strnicmp(af->af_Attr.ta_Name, ps->name, len) != 0) )
- return 0;
- if ( (ps->valid & SEL_TYPE) && !(af->af_Type & ps->type) )
- return 0;
- if ( (ps->valid & SEL_STYLE) && !(af->af_Attr.ta_Style & ps->style) )
- return 0;
- if ( (ps->valid & SEL_FLAGS) && !(af->af_Attr.ta_Flags & ps->flags) )
- return 0;
- return 1;
- }
- #endif
-
-