CCL Home Page
Up Directory CCL ScianFontSystem
/*  ScianFontSystem.c
    Routines for font system and string utilities

    Jim Lyons
    7/26/91

    9/24/91  added support for raster fonts
    1/5/92   EMP added font counting for both types of fonts
    1/28/92  modified StrWidth and DrawString to handle tabs
    4/6/92   added PostScript drawing mode 
    9/14/92  changed DrawString to take alignment parameter
	     and changed name to DrawAString
    9/10/93  added SetUIFont
    11/19/93 implemented caching in SetupFont etc.
*/

#include "Scian.h"
#include "ScianStyle.h"
#include "ScianTypes.h"
#include "ScianFontSystem.h"
#include "ScianWindows.h"
#include "ScianDraw.h"
#include "ScianTextBoxes.h"

#ifdef GRAPHICS
#include "ScianPalatino18.h"
#include "ScianTitleFont.h"

#define NRASTERFONTS	4	/* NOT including system font or icon fonts */
#define SCIANTITLE	1
#define MAXFONTSUSED	10  /* max different fonts in window (for PS drawing) */
#endif

/*
	The font system handles font manager routines, if available, as
	well as raster fonts. A cache is kept of fonts and sizes used,  and
	when SetupFont is called, it is searched first; if new, fmfindfont 
	and fmscalefont are called to get a new handle which is cached for
	subsequent use. The handle is stored in currentFontHandle for use by 
	DrawAString, StringWidth, etc. If not found, (or if not FONTS4D), 
	currentFontHandle is set to NULL and the name is looked
	up in the raster font name table, rasterFont[]. (The size parameter
	is ignored.) If not found the system font is used.

	Note that icon fonts are not treated like text fonts, although they
	are initialized here in InitFonts.
*/

/* globals for font system */

#ifdef GRAPHICS

char *rasterFont[NRASTERFONTS + 1];	/* table of raster font name pointers */
int nFonts = 0;
char **fonts;	/* names of available fonts */
static int registeredFonts;
char curFontName[64];		/* remember which font is set */
int curFontSize;

#ifdef FONTS4D
fmfonthandle currentFontHandle = NIL;

struct fontinfo *cachedFontInfo;    /* pointer to font info table */
int fontInfoSize;   /* current size of font info table */ 
int nCachedFonts;   /* number of entries in font info table */
#else
int uiFontSize[NUIFONTTYPES];	/* table of UI font sizes if not FONTS4D */
#endif

int uiFontMap[NUIFONTS];

#endif

/* for PostScript output */
char *fontsUsed[MAXFONTSUSED];	/* list of fonts used in current file */
int numFontsUsed = 0;		/* number of fonts used = next index */
char showBuf[256];	/* string buffer for PostScript show */

#ifdef GRAPHICS

#ifdef HAVE_PROTOTYPES
int UIFontSize(int uiFontNum)
#else
int UIFontSize(uiFontNum)
int uiFontNum;
#endif
{
#ifdef FONTS4D
    return cachedFontInfo[uiFontMap[uiFontNum]].size;
#else
    return uiFontSize[uiFontMap[uiFontNum]];
#endif
}

void SetDemoFonts(void)
{
    uiFontMap[UISMALLFONT] = UIBOLDSMALLFONT;
    uiFontMap[UINORMALFONT] = UIBOLDNORMALFONT;
    uiFontMap[UILARGEFONT] = UIBOLDLARGEFONT;
    uiFontMap[UITITLEFONT] = UIBOLDTITLEFONT;
    uiFontMap[UIHELPFONT] = UIBOLDLARGEFONT;
    uiFontMap[UIINFOFONT] = UIBOLDNORMALFONT;
    uiFontMap[UICONTROLFONT] = UIBOLDNORMALFONT;
    uiFontMap[UISMALLCONTROLFONT] = UIBOLDSMALLFONT;
    uiFontMap[UIICONFONT] = UIBOLDNORMALFONT;
    uiFontMap[UIICONSUBFONT] = UIBOLDSMALLFONT;
}
#endif

static void CountFonts(s)
char *s;
/*Counts the fonts*/
{
#ifdef GRAPHICS
    ++nFonts;
#endif
}

static void RegisterFont(s)
char *s;
/*Puts the font names in a list, fonts[]*/
{
#ifdef GRAPHICS
    fonts[registeredFonts] = Alloc(strlen(s) + 1);	/* freed by KillFonts */
    strcpy(fonts[registeredFonts], s);
    ++registeredFonts;
#endif
}

#ifdef HAVE_PROTOTYPES
static int CompareFonts(const void *f1, const void *f2)
#else
static int CompareFonts(f1, f2)
void *f1;
void *f2;
#endif
/*Compares two font names*/
{
    return strcmp2(*(char **) f1, *(char **) f2);
}

#ifdef HAVE_PROTOTYPES
static void SortFonts(void)
#else
static void SortFonts()
#endif
{
    /*Sorts the fonts*/

    qsort(fonts, registeredFonts, sizeof(char *), CompareFonts);
}

void InitFonts(void) /*********************************** INITFONTS */
{
#ifdef GRAPHICS
    int i;
#ifdef FONTS4D
    fmfonthandle fh;
#endif

    nFonts = 2;

#ifdef FONTS4D
    fminit();
    fmenumerate(CountFonts);
#endif
    fonts = (char**) Alloc(sizeof(char *) * nFonts); /* freed in KillFonts */
#ifdef FONTS4D
    /* register fonts for font menu */
    registeredFonts = 0;
    fmenumerate(RegisterFont);
#endif

    /*Complete font menu with System and Palatino18*/
    RegisterFont("System");
    RegisterFont("Palatino18");

    SortFonts();

    rasterFont[0] = "System"; /* default */
    for (i=1; i= MAXFONTSUSED)
    {
        ReportError("RegisterFontUsed","Too many fonts in PostScript file!");
        return;
    }
    fontsUsed[numFontsUsed] = Alloc(strlen(name) + 1);
    /* string space will be freed by EndDrawing() in ScianDraw.c */
    if (fontsUsed[numFontsUsed])
    {
         strcpy(fontsUsed[numFontsUsed], name);
         ++numFontsUsed;
    }
    else OMErr();
#endif
    return;
}


#ifdef HAVE_PROTOTYPES
int ChrWidth(char c)
#else
int ChrWidth(c)
char c;
#endif
{
#ifdef GRAPHICS
	if (c < ' ') return 0;
#ifdef FONTS4D
	if (currentFontHandle)
	{
		return fmgetchrwidth(currentFontHandle, c);
	}
	else
	{
		char buf[2];

		buf[0] = c;
		buf[1] = '\0';
		return strwidth(buf);
	}
#else
	{	char buf[2];

	buf[0] = c;
	buf[1] = '\0';
	return strwidth(buf);
	}
#endif
#else
	return 0;
#endif
}

#ifdef HAVE_PROTOTYPES
int StrWidth(char *s)
#else
int StrWidth(s)
char *s;
#endif
/* handles tabs in string */
{
#ifdef GRAPHICS
	int nTabs=0;
	char *t=s;

	while (*t)
	{
		if (*t++ == '\t')
		{
			s = t; /* point to char following tab */
			++nTabs;   /* incr tab count */
		}
	}
	/* now return the indent plus the length of the string following last tab */
#ifdef FONTS4D
	if (currentFontHandle)
	{
		return nTabs*TABWID*ChrWidth('0') + fmgetstrwidth(currentFontHandle, s);
	}
	else
	{
		return nTabs*TABWID*ChrWidth('0') + strwidth(s);
	}
#else
	return nTabs*TABWID*ChrWidth('0') + strwidth(s);
#endif
#else
	return 0;
#endif
}

#ifdef HAVE_PROTOTYPES
char *PSShow(char *s)
#else
char *PSShow(s)
char *s;
#endif
{
    /*
     * Process any special characters in string for PostScript show.
     */

    char *p = showBuf;
    
    while (*s)
    {
	if (*s == '(' || *s == ')' || *s == '\\') *p++ = '\\';
	*p++ = *s++;
    }
    *p = '\0';
    return showBuf;
}

#ifdef HAVE_PROTOTYPES
void DrawAString(int align, long x, long y, char *s)
#else
void DrawAString(align, x, y, s)
int align;
long x, y;
char *s;
#endif
{
#ifdef GRAPHICS
    int left, right, bottom, top;
	int xx, yy, dxx, dyy;
    
    if (drawingMode == DRAW_SCREEN)
    {
    /* find starting point of string */
	switch (align)
	{
	    case RIGHTALIGN:
		    x -= StrWidth(s);
		    break;

	    case CENTERALIGN:
		    x -= StrWidth(s)/2;
		    break;

	    case LEFTALIGN:
	    default:
		    break;
    	}

    /* check to see if string starts out of window */
	GetWindowBounds(&left, &right, &bottom, &top);
	CurOffset(&xx, &yy);
	GetWindowOrigin(&dxx, &dyy);
	left -= xx - dxx;
	
    /* trim string if necessary */
	while (x < left)
	{
	    if (*s == '\0') return;
	    x += ChrWidth(*s++);
	}
	cmov2i(x, y);
    
#ifdef FONTS4D
	if (currentFontHandle)
	{
		fmprstr(s);
	}
	else
	{
		charstr(s);
	}
#else
	charstr(s);
#endif
    }
    else if (drawingMode == DRAW_POSTSCRIPT && psFile && *s != '\0')
    {
    /* write PostScript to file */
	fprintf(psFile, "%f setgray\n", PSColor());
	switch (align)
	{
		case RIGHTALIGN:
			fprintf(psFile,
	"(%s) dup %d exch stringwidth pop sub %d moveto show\n", PSShow(s), x, y);
			break;

		case CENTERALIGN:
			fprintf(psFile,
	"(%s) dup %d exch stringwidth pop 2 div sub %d moveto show\n", PSShow(s), x, y);
			break;

		case LEFTALIGN:
		default:
        		fprintf(psFile, "%d %d moveto (%s) show\n", x, y, PSShow(s));
			break;
	}
    }
#endif
}
Modified: Sun Nov 17 17:00:00 1996 GMT
Page accessed 4180 times since Sat Apr 17 21:55:01 1999 GMT