[net.micro.amiga] setfont.c -- set your CLI's font

mcinerny@rochester.ARPA (Michael McInerny) (10/28/86)

Okay, here's my hacking contribution to the net.

Time after time I've been wanting to change the font of my console.  However,
there's no easy way to do it.  What I needed was a SetFont....

So, here it is.  It's a bit of a hack, taken mostly from C/A demo code.
Should work under 1.1, but haven't tried it.  Compiles with some warnings
that I don't feel like tracking down.  Not exactly user-friendly either.
"setfont ?" should give a simple usage line.  Unfortunately, must link
with Lettuce, which makes it much too big.  Oh well.

I wish it didn't have to clear the screen, but c'est la vie.

Also, porportional fonts (i.e.: most fonts) look horrible.  The console
device just doesn't like them.  I have a 5x7/5x8 font (in a 6x7/8/10
cell) that I call terminal, which gives (easily) 80+ cols and 25 rows
on a standard window (hence its name).  It's lacking a little readability,
but if there's demand (e-mail me, please), I'll try to post it.  I also
whipped up a "dotty" font (<sp> = 1 clear pixel, all else = 1 set pixel),
which has the interesting feature of approximating a "zoom" function:
you can use it to get an overview of a file, etc.  Heck:  in interlace mode,
use can "read" about 400 lines of text at once (at about 600 chars/line).
Really wierd....

Sorry, no uuencoded version.  Get a 'C' compiler!!

Please distribute source with executable, this is HackerWare, after all!
(HackerWare is software for the People--source included.)

-Michael

-----------*snip*----*snip*----------
/*
		Find CON: window pointer and set its font
		by A. Finkel, R. Burns, and M. McInerny
		)1986 by Commodore-Amiga and M. McInerny.
*/

#include	"exec/types.h"
#include	"exec/ports.h"
#include	"exec/io.h"
#include	"exec/memory.h"
#include	"devices/console.h"
#include	"devices/conunit.h"
#include	"libraries/dos.h"
#include	"libraries/dosextens.h"
#include	"intuition/intuitionbase.h"
#include	"workbench/startup.h"
#include	"workbench/workbench.h"
#include	"graphics/rastport.h"
#include	"graphics/text.h"
#include	"libraries/diskfont.h"

extern struct Library *OpenLibrary();
extern struct TextFont *OpenDiskFont();
struct IntuitionBase *IntuitionBase = 0;
long GfxBase=0;
long DiskfontBase = 0;

struct MsgPort iorp = {
	{0, 0, NT_MSGPORT, 0, 0}, 0,
	-1,				/* initialize signal to -1 */
	0,				/* start with empty list */
	{&iorp.mp_MsgList.lh_Tail, 0, &iorp.mp_MsgList.lh_Head, 0, 0}
};
struct IOStdReq ior = {
	{{0, 0, 0, 0, 0}, &iorp, 0},
	0				/* device is zero */
};

struct TextAttr ta;
struct TextFont *font;

/* Convert s to integer, from K&R p.39. */
/* int atoi(s)
char s[];
{
	int i, n = 0;

	for (i = 0; s[i] >= '0' && s[i] <= '9'; ++i)
		n = 10 * n + s[i] - '0';
	return(n);
}
*/

cleanup(code)
int code;
{
	if (ior.io_Device != 0) {
		if (iorp.mp_SigBit != -1) {
			FreeSignal(iorp.mp_SigBit);
		}
		CloseDevice(&ior);
	}
	if (font) CloseFont(font);
	if (DiskfontBase) CloseLibrary(DiskfontBase);
	if (IntuitionBase) CloseLibrary(IntuitionBase);
	if (GfxBase) CloseLibrary(GfxBase);

	exit(code);
}

main(argc, argv)
int argc;
char *argv[];
{
	struct MsgPort *con;
	struct StandardPacket *packet = 0;
	struct InfoData *id = 0;
	struct Window *win;
	struct RastPort *rp;
	int fontsize = 8;
	char *fontname = "topaz.font\0\0\0\0\0\0\0\0\0\0";

	if (*argv[1] == '?')
	{	
		printf("Usage:  %s [fontname=topaz [fontsize=8]].\n",argv[0]);
		cleanup(10);
	}
	if (argc>1)
	{
		char *extension =  ".font";
		char *s, *t;

		s = fontname;
		t = argv[1];
		while ((*s++ = *t++) && ((s - fontname) < 15));
		--s;	/* exclude '\0' */
		t = extension;
		while (*s++ = *t++);
	}
	if (argc>2)
	{
		fontsize = atoi(argv[2]);
	}

	GfxBase = OpenLibrary("graphics.library", 0);
	if (GfxBase == NULL)
	{
		printf("Graphics library open failed.\n");
		cleanup(20);
	}

	if ((IntuitionBase = (struct IntuitionBase *)
				OpenLibrary("intuition.library", 0)) == 0) {
		cleanup(21);
	}

	DiskfontBase = OpenLibrary("diskfont.library", 0);
	if (DiskfontBase == NULL)
	{
		printf("Diskfont library open failed.\n");
		cleanup(25);
	}

	ta.ta_Name =  fontname;
	ta.ta_YSize = fontsize;
	ta.ta_Style = 0;
	ta.ta_Flags = FPF_DISKFONT;

	font = OpenDiskFont(&ta);
	if (font == 0)
	{
		printf("OpenDiskFont failed--font not found?\n");
 		cleanup(27);
	}

	/* open the console device, returns address of device handler */
	if ((OpenDevice("console.device", -1, &ior, 0)) != 0) {
		cleanup(30);
	}

	/* set up the message port in the I/O request */
	if ((iorp.mp_SigBit = AllocSignal(-1)) < 0) {
		cleanup(35);
	}

	/* which task am I? */
	iorp.mp_SigTask = (struct Task *) FindTask((char *) NULL);

	/* Try to find the console associated with calling process */
	if (iorp.mp_SigTask->tc_Node.ln_Type == NT_PROCESS) {
	   con = (struct MsgPort *)
		  ((struct Process *) iorp.mp_SigTask)->pr_ConsoleTask;
	   if (con != 0) {
 	     if ((packet = (struct StandardPacket *)
			   AllocMem(sizeof(*packet), MEMF_CLEAR))) {
	       if ((id = (struct id *) AllocMem(sizeof(*id), MEMF_CLEAR))) {
		 /* This is the console handlers packet port. */
		 packet->sp_Msg.mn_Node.ln_Name = &(packet->sp_Pkt);
		 packet->sp_Pkt.dp_Link = &(packet->sp_Pkt);
		 packet->sp_Pkt.dp_Port = &iorp;
		 packet->sp_Pkt.dp_Type = ACTION_DISK_INFO;
		 packet->sp_Pkt.dp_Arg1 = ((ULONG) id) >> 2; /* #@!% BPTR! */
		 PutMsg(con, packet);
		 WaitPort(&iorp);
		 win = (struct Window *) (id->id_VolumeNode);
		 rp = win->RPort;
		 SetFont(rp, font);
		 FreeMem(id, sizeof(*id));
	       }
	       FreeMem(packet, sizeof(*packet));
	     }
	  }
	}
	ior.io_Unit = (struct Unit *) -1;
	printf("\033c");
	cleanup(0);
}

gnu@hoptoad.uucp (John Gilmore) (10/29/86)

In article <21961@rochester.ARPA>, mcinerny@rochester.ARPA (Michael McInerny) writes:
>                                                                  I also
> whipped up a "dotty" font (<sp> = 1 clear pixel, all else = 1 set pixel),
> which has the interesting feature of approximating a "zoom" function:
> you can use it to get an overview of a file, etc.

LucasFilm used this idea in a window system they wrote.  The scroll bars
of text windows have the text appear in the "dotty" font *in the scroll bar*.
(You have to adjust so the window height shows dots for the whole file.)
This lets you easily see the paragraph structure of text, or the function
indentation in C, in the scroll bar, and makes it much easier to just zoom
down to where you want to go.

Since they couldn't necessarily spare one dot per character, they had to
adapt.  Each pixel represented some number of characters (could be 1, <1, 
or >1) in some number of lines.  If all the chars it represents are blank,
it is white; otherwise, it is black.  This will show gross structure even
with a large file displayed in a small scroll bar.
-- 
John Gilmore  {sun,ptsfa,lll-crg,ihnp4}!hoptoad!gnu   jgilmore@lll-crg.arpa
  Overheard at a funeral: "I know this may be an awkward time, but do
  you recall him ever mentioning source code?"		-- Charles Addams