home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
World of A1200
/
World_Of_A1200.iso
/
programs
/
misc
/
wingnuplot
/
source.lha
/
source
/
OutlineFont.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-05-22
|
6KB
|
286 lines
/* this defines some routines for handling of Outline-Fonts */
#include "struct.c"
#include "OutlineFont.h"
#define CW 80
#define CH 35
static int cwidth, cheight;
static ULONG XYdpi, PointSize;
struct Glyph
{
int top, left, width, height;
int basex, basey;
int bmsize, bpr;
UBYTE *bitmap;
};
static struct Glyph *HGlyphs[256], *VGlyphs[256];
struct Library *BulletBase = NULL;
static struct GlyphEngine *BulletEngine = NULL;
static BOOL IsOutlineFont(char *fontname)
{
BPTR FontsDir, Font;
char FullFontName[255];
BOOL h = FALSE;
struct FontContentsHeader *fch;
/* hack to get the real font-directory incase of MultiAssign !! */
strcpy(FullFontName, "FONTS:"); AddPart(FullFontName, fontname, 255);
if (Font = Lock(FullFontName, ACCESS_READ))
{
FontsDir = ParentDir(Font);
if (fch = NewFontContents(FontsDir, fontname))
{
if (fch->fch_FileID == OFCH_ID)
h = TRUE;
DisposeFontContents(fch);
}
UnLock(FontsDir);
UnLock(Font);
}
return h;
}
static struct GlyphEngine *GetEngine(char *fontname, struct TagItem **OTags)
{
BPTR f;
int l;
char enginename[80];
struct TagItem *Tags, *ti, *tstate;
struct GlyphEngine *Engine = NULL;
if (f = Open(fontname, MODE_OLDFILE))
{
Seek(f, 0, OFFSET_END);
l = Seek(f, 0, OFFSET_BEGINNING);
if (Tags = malloc(l))
{
Read(f, Tags, l);
tstate = Tags;
while (ti = NextTagItem(&tstate))
if (ti->ti_Tag & OT_Indirect)
ti->ti_Data += (ULONG)Tags;
if ((ti = FindTagItem(OT_FileIdent, Tags)) && ti->ti_Data == l)
{
if (ti = FindTagItem(OT_Engine, Tags))
{
strcpy(enginename, (char *)(ti->ti_Data));
strcat(enginename, ".library");
if (BulletBase = OpenLibrary(enginename, 0))
{
Engine = OpenEngine();
*OTags = Tags;
}
}
}
}
Close(f);
}
return Engine;
}
static struct Glyph *GetGlyph(char ch, BOOL Vertical)
{
struct GlyphMap *GlyphMap;
struct Glyph **glyphs;
glyphs = (Vertical) ? VGlyphs : HGlyphs;
if (!glyphs[ch])
{
glyphs[ch] = malloc(sizeof(struct Glyph));
SetInfo(BulletEngine,
OT_GlyphCode, ch,
OT_RotateSin, (Vertical) ? 0x00010000 : 0x00000000,
OT_RotateCos, (Vertical) ? 0x00000000 : 0x00010000,
OT_PointHeight, PointSize,
OT_DeviceDPI, XYdpi,
OT_DotSize, 0x00640064,
TAG_END);
if (ObtainInfo(BulletEngine,
OT_GlyphMap, &GlyphMap,
TAG_END) == OTERR_Success)
{
glyphs[ch]->top = GlyphMap->glm_BlackTop;
glyphs[ch]->left = GlyphMap->glm_BlackLeft;
glyphs[ch]->height = GlyphMap->glm_BlackHeight+1;
glyphs[ch]->width = GlyphMap->glm_BlackWidth+1;
glyphs[ch]->basey = GlyphMap->glm_Y0-GlyphMap->glm_BlackTop;
glyphs[ch]->basex = GlyphMap->glm_X0-GlyphMap->glm_BlackLeft;
glyphs[ch]->bpr = GlyphMap->glm_BMModulo;
glyphs[ch]->bmsize = GlyphMap->glm_BMModulo*GlyphMap->glm_BMRows;
if (glyphs[ch]->bitmap = AllocMem(glyphs[ch]->bmsize, MEMF_CHIP))
CopyMemQuick(GlyphMap->glm_BitMap, glyphs[ch]->bitmap, glyphs[ch]->bmsize);
ReleaseInfo(BulletEngine,
OT_GlyphMap, GlyphMap,
TAG_END);
}
else
{
glyphs[ch]->top = 0;
glyphs[ch]->left = 0;
glyphs[ch]->height = cheight;
glyphs[ch]->width = cwidth;
glyphs[ch]->basey = 0;
glyphs[ch]->basex = 0;
glyphs[ch]->bpr = (cwidth/32 + 1) * 4;
glyphs[ch]->bmsize = glyphs[ch]->bpr * cheight;
glyphs[ch]->bitmap = AllocMem(glyphs[ch]->bmsize, MEMF_CHIP|MEMF_CLEAR);
}
}
return glyphs[ch];
}
static void FreeGlyph(struct Glyph *glyph)
{
FreeMem(glyph->bitmap, glyph->bmsize);
}
static void FreeGlyphs(void)
{
int ch;
for(ch=0; ch <= 255; ch++)
{
if (HGlyphs[ch])
{
FreeGlyph(HGlyphs[ch]);
free(HGlyphs[ch]);
HGlyphs[ch] = NULL;
}
if (VGlyphs[ch])
{
FreeGlyph(VGlyphs[ch]);
free(VGlyphs[ch]);
VGlyphs[ch] = NULL;
}
}
}
BOOL OpenOutlineFont(char *font)
{
char fontname[80], otagname[80];
struct TagItem *OTags;
int ch;
strcpy(fontname, font); strcat(fontname, ".font");
if (IsOutlineFont(fontname))
{
strcpy(otagname, "FONTS:"); strcat(otagname, font); strcat(otagname, ".otag");
if (BulletEngine = GetEngine(otagname, &OTags))
{
strcpy(fontname, "FONTS:"); strcat(fontname, font); strcat(fontname, ".font");
SetInfo(BulletEngine,
OT_OTagPath, fontname,
OT_OTagList, OTags,
TAG_END);
for(ch=0; ch <= 255; ch++)
HGlyphs[ch] = VGlyphs[ch] = NULL;
return TRUE;
}
}
return FALSE;
}
void CloseOutlineFont(void)
{
FreeGlyphs();
if (BulletEngine) CloseEngine(BulletEngine);
if (BulletBase) CloseLibrary(BulletBase);
}
void PrintString(struct RastPort *rp, int x0, int y0, char *s, BOOL Vertical)
{
char *ch;
int x, y;
struct Glyph *glyph;
x = x0; y = y0;
for(ch = s; *ch; ch++)
{
glyph = GetGlyph(*ch, Vertical);
BltTemplate(glyph->bitmap+glyph->top*glyph->bpr,
glyph->left, glyph->bpr,
rp,
x-glyph->basex,
y-glyph->basey,
glyph->width, glyph->height);
WaitBlit();
if (Vertical)
y -= glyph->height;
else
x += glyph->width;
}
}
void SetFontSize(int w, int h)
{
static int last_x = 0, last_y = 0, last_p = 0;
int x, y, p;
cwidth = w/CW; cheight = h/CH;
if (w*CH < h*CW)
{
x = 100;
y = (100 * h * CW) / (w * CH);
p = (w * 65536L) / CW;
}
else
{
y = 100;
x = (100 * w * CH) / (h * CW);
p = (h * 65536L) / CH;
}
PointSize = p;
XYdpi = x<<16 | y;
if (last_x != x || last_y != y || last_p != PointSize)
{
FreeGlyphs();
last_x = x;
last_y = y;
last_p = PointSize;
}
}
int TextLen(char *s)
{
char *ch;
int txtlen = 0;
for(ch = s; *ch; ch++)
txtlen += (GetGlyph(*ch, FALSE))->width;
return txtlen;
}
static int _STI_10000_InitGlyphs(void)
{
char ch;
for(ch=0; ch <= 255; ch++)
HGlyphs[ch] = VGlyphs[ch] = NULL;
return 0;
}
static void _STD_10000_CloseOutlineFonts(void)
{
CloseOutlineFont();
}