Charles.Forsyth20060303a828770d19 years agoHistory
231 lines · 4.3 KB · C
RawDownload
#include <lib9.h>#include <kernel.h>#include "interp.h"#include "isa.h"#include "runt.h"#include "raise.h"#include "freetypemod.h"#include "freetype.h"  typedef struct Face Face;struct Face {	Freetype_Face	freetypeface;		/* limbo part */	FTface		ftface;			/* private parts */}; Type*	TMatrix;Type*	TVector;Type*	TFace;Type*	TGlyph; static uchar	Matrixmap[] = Freetype_Matrix_map;static uchar	Vectormap[] = Freetype_Vector_map;static uchar	Facemap[] = Freetype_Face_map;static uchar	Glyphmap[] = Freetype_Glyph_map; static void		freeface(Heap*, int);static Face*	ckface(Freetype_Face*); voidfreetypemodinit(void){	builtinmod("$Freetype", Freetypemodtab, Freetypemodlen);	TMatrix = dtype(freeheap, sizeof(Freetype_Matrix), Matrixmap, sizeof(Matrixmap));	TVector = dtype(freeheap, sizeof(Freetype_Vector), Vectormap, sizeof(Vectormap));	TFace = dtype(freeface, sizeof(Face), Facemap, sizeof(Facemap));	TGlyph = dtype(freeheap, sizeof(Freetype_Glyph), Glyphmap, sizeof(Glyphmap));} voidFace_haschar(void *fp){	F_Face_haschar *f = fp;	Face *face; 	*f->ret = 0;	face = ckface(f->face);	release();	*f->ret = fthaschar(face->ftface, f->c);	acquire();} voidFace_loadglyph(void *fp){	F_Face_loadglyph *f = fp;	Heap *h;	Face *face;	Freetype_Glyph *g;	FTglyph ftg;	int n, i, s1bpr, s2bpr;	char *err; 	face = ckface(f->face); 	destroy(*f->ret);	*f->ret = H; 	release();	err = ftloadglyph(face->ftface, f->c, &ftg);	acquire();	if (err != nil) {		kwerrstr(err);		return;	} 	h = heap(TGlyph);	if (h == H) {		kwerrstr(exNomem);		return;	}	g = H2D(Freetype_Glyph*, h);	n = ftg.width*ftg.height;	h = heaparray(&Tbyte, n);	if (h == H) {		destroy(g);		kwerrstr(exNomem);		return;	}	g->bitmap = H2D(Array*, h);	g->top = ftg.top;	g->left = ftg.left;	g->height = ftg.height;	g->width = ftg.width;	g->advance.x = ftg.advx;	g->advance.y = ftg.advy; 	s1bpr = ftg.width;	s2bpr = ftg.bpr;	for (i = 0; i < ftg.height; i++)		memcpy(g->bitmap->data+(i*s1bpr), ftg.bitmap+(i*s2bpr), s1bpr);	*f->ret = g;} voidFreetype_newface(void *fp){	F_Freetype_newface *f = fp;	Heap *h;	Face *face;	Freetype_Face *limboface;	FTfaceinfo finfo;	char *path;	char *err; 	destroy(*f->ret);	*f->ret = H; 	h = heapz(TFace);	if (h == H) {		kwerrstr(exNomem);		return;	} 	face = H2D(Face*, h);	limboface = (Freetype_Face*)face;	*f->ret = limboface;	path = strdup(string2c(f->path));	/* string2c() can call error() */	release();	err = ftnewface(path, f->index, &face->ftface, &finfo);	acquire();	free(path);	if (err != nil) {		*f->ret = H;		destroy(face);		kwerrstr(err);		return;	}	limboface->nfaces = finfo.nfaces;	limboface->index = finfo.index;	limboface->style = finfo.style;	limboface->height = finfo.height;	limboface->ascent = finfo.ascent;	limboface->familyname = c2string(finfo.familyname, strlen(finfo.familyname));	limboface->stylename = c2string(finfo.stylename, strlen(finfo.stylename));	*f->ret = limboface;} voidFreetype_newmemface(void *fp){	F_Freetype_newmemface *f = fp; 	destroy(*f->ret);	*f->ret = H; 	kwerrstr("not implemented");} voidFace_setcharsize(void *fp){	F_Face_setcharsize *f = fp;	Face *face;	Freetype_Face *limboface;	FTfaceinfo finfo;	char *err; 	face = ckface(f->face);	limboface = (Freetype_Face*)face;	release();	err = ftsetcharsize(face->ftface, f->pts, f->hdpi, f->vdpi, &finfo);	acquire();	if (err == nil) {		limboface->height = finfo.height;		limboface->ascent = finfo.ascent;	}	retstr(err, f->ret);} voidFace_settransform(void *fp){	F_Face_settransform *f = fp;	FTmatrix *m = nil;	FTvector *v = nil;	Face *face; 	face = ckface(f->face); 	/*	 * ftsettransform() has no error return	 * we have one for consistency - but always nil for now	 */	destroy(*f->ret);	*f->ret = H; 	if (f->m != H)		m = (FTmatrix*)(f->m);	if (f->v != H)		v = (FTvector*)(f->v);	release();	ftsettransform(face->ftface, m, v);	acquire();} static voidfreeface(Heap *h, int swept){	Face *face = H2D(Face*, h); 	if (!swept) {		destroy(face->freetypeface.familyname);		destroy(face->freetypeface.stylename);	}	release();	ftdoneface(face->ftface);	acquire();	memset(&face->ftface, 0, sizeof(face->ftface));} static Face*ckface(Freetype_Face *face){	if (face == nil || face == H)		error("nil Face");	if (D2H(face)->t != TFace)		error(exType);	return (Face*)face;}