home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
215.lha
/
FTS
/
fts.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-02-15
|
8KB
|
363 lines
/*
* 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