diff options
| author | Charles.Forsyth <devnull@localhost> | 2006-12-22 17:07:39 +0000 |
|---|---|---|
| committer | Charles.Forsyth <devnull@localhost> | 2006-12-22 17:07:39 +0000 |
| commit | 37da2899f40661e3e9631e497da8dc59b971cbd0 (patch) | |
| tree | cbc6d4680e347d906f5fa7fca73214418741df72 /libinterp/freetype.c | |
| parent | 54bc8ff236ac10b3eaa928fd6bcfc0cdb2ba46ae (diff) | |
20060303a
Diffstat (limited to 'libinterp/freetype.c')
| -rw-r--r-- | libinterp/freetype.c | 231 |
1 files changed, 231 insertions, 0 deletions
diff --git a/libinterp/freetype.c b/libinterp/freetype.c new file mode 100644 index 00000000..860b119d --- /dev/null +++ b/libinterp/freetype.c @@ -0,0 +1,231 @@ +#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*); + +void +freetypemodinit(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)); +} + +void +Face_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(); +} + +void +Face_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; +} + +void +Freetype_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; +} + +void +Freetype_newmemface(void *fp) +{ + F_Freetype_newmemface *f = fp; + + destroy(*f->ret); + *f->ret = H; + + kwerrstr("not implemented"); +} + +void +Face_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); +} + +void +Face_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 void +freeface(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; +} + |
