/* 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 }