X-Git-Url: http://git.asbjorn.biz/?p=swftools.git;a=blobdiff_plain;f=lib%2Fgfxfont.c;h=8e392728b3fb343ea7fc656cb85c7e65d2adef18;hp=8b66e808bd832f7ead3735a100b33bc86fd42b43;hb=687def0f4060cf9e48dba017316314c05f7b0480;hpb=9f38802b3d854166ef4395ea18ba495f7d954ff7 diff --git a/lib/gfxfont.c b/lib/gfxfont.c index 8b66e80..8e39272 100644 --- a/lib/gfxfont.c +++ b/lib/gfxfont.c @@ -24,6 +24,8 @@ #include "../config.h" #include "gfxdevice.h" #include "gfxtools.h" +#include "gfxfont.h" +#include "ttf.h" static int loadfont_scale = 64; static int full_unicode = 1; @@ -136,7 +138,9 @@ static void glyph_clear(gfxglyph_t*g) static int errorno = 0; -gfxfont_t* gfxfont_load(char*id, char*filename, double quality) +//#define DEBUG 1 + +gfxfont_t* gfxfont_load(char*id, char*filename, unsigned int flags, double quality) { FT_Face face; FT_Error error; @@ -147,7 +151,6 @@ gfxfont_t* gfxfont_load(char*id, char*filename, double quality) int t; int*glyph2glyph = 0; int*glyph2unicode = 0; - FT_Size size; int max_unicode = 0; int charmap = -1; int isunicode = 1; @@ -162,17 +165,20 @@ gfxfont_t* gfxfont_load(char*id, char*filename, double quality) } error = FT_New_Face(ftlibrary, filename, 0, &face); FT_Set_Pixel_Sizes (face, 16*loadfont_scale, 16*loadfont_scale); +#ifdef DEBUG + printf("gfxfont_load(%s, %s, %f)\n", id, filename, quality); +#endif if(error) { fprintf(stderr, "Couldn't load file %s- not a TTF file? (error=%02x)\n", filename, error); return 0; } if(face->num_glyphs <= 0) { - fprintf(stderr, "File %s contains %d glyphs\n", face->num_glyphs); + fprintf(stderr, "File %s contains %d glyphs\n", filename, (int)face->num_glyphs); return 0; } - font = rfx_calloc(sizeof(gfxfont_t)); + font = (gfxfont_t*)rfx_calloc(sizeof(gfxfont_t)); //font->style = ((face->style_flags&FT_STYLE_FLAG_ITALIC)?FONT_STYLE_ITALIC:0) |((face->style_flags&FT_STYLE_FLAG_BOLD)?FONT_STYLE_BOLD:0); //font->ascent = abs(face->ascender)*FT_SCALE*loadfont_scale*20/FT_SUBPIXELS/2; //face->bbox.xMin; //font->descent = abs(face->descender)*FT_SCALE*loadfont_scale*20/FT_SUBPIXELS/2; //face->bbox.xMax; @@ -181,9 +187,9 @@ gfxfont_t* gfxfont_load(char*id, char*filename, double quality) font->max_unicode = 0; font->id = strdup(id); - font->glyphs = rfx_calloc(face->num_glyphs*sizeof(gfxglyph_t)); - glyph2unicode = rfx_calloc(face->num_glyphs*sizeof(int)); - glyph2glyph = rfx_calloc(face->num_glyphs*sizeof(int)); + font->glyphs = (gfxglyph_t*)rfx_calloc(face->num_glyphs*sizeof(gfxglyph_t)); + glyph2unicode = (int*)rfx_calloc(face->num_glyphs*sizeof(int)); + glyph2glyph = (int*)rfx_calloc(face->num_glyphs*sizeof(int)); if(FT_HAS_GLYPH_NAMES(face)) { //font->glyphnames = rfx_calloc(face->num_glyphs*sizeof(char*)); @@ -191,7 +197,8 @@ gfxfont_t* gfxfont_load(char*id, char*filename, double quality) fontname = FT_Get_Postscript_Name(face); - /*for(t=0;tnum_charmaps;t++) { +#ifdef DEBUG + for(t=0;tnum_charmaps;t++) { printf("possible encoding: %c%c%c%c (%d of %d)\n", (face->charmaps[t]->encoding >> 24)&255, (face->charmaps[t]->encoding >> 16)&255, @@ -199,26 +206,13 @@ gfxfont_t* gfxfont_load(char*id, char*filename, double quality) (face->charmaps[t]->encoding >> 0)&255, t+1, face->num_charmaps ); - }*/ + } +#endif while(1) { charcode = FT_Get_First_Char(face, &gindex); - /*if(face->charmap) { - printf("ENCODING: %c%c%c%c (%d of %d)\n", - (face->charmap->encoding >> 24)&255, - (face->charmap->encoding >> 16)&255, - (face->charmap->encoding >> 8)&255, - (face->charmap->encoding >> 0)&255, - charmap, face->num_charmaps - ); - } else { - printf("ENCODING: NONE (%d of %d)\n", - charmap, face->num_charmaps - ); - }*/ - while(gindex != 0) { if(gindex >= 0 && gindexnum_glyphs) { @@ -232,13 +226,29 @@ gfxfont_t* gfxfont_load(char*id, char*filename, double quality) charcode = FT_Get_Next_Char(face, charcode, &gindex); } +#ifdef DEBUG + if(face->charmap) { + printf("ENCODING: %c%c%c%c (%d of %d) max_unicode=%d\n", + (face->charmap->encoding >> 24)&255, + (face->charmap->encoding >> 16)&255, + (face->charmap->encoding >> 8)&255, + (face->charmap->encoding >> 0)&255, + charmap, face->num_charmaps, font->max_unicode + ); + } else { + printf("ENCODING: NONE (%d of %d) max_unicode=%d\n", + charmap, face->num_charmaps, font->max_unicode + ); + } +#endif + /* if we didn't find a single encoding character, try the font's charmaps instead. That usually means that the encoding is no longer unicode. TODO: find a way to convert the encoding to unicode */ - if(font->max_unicode == 0 && charmap < face->num_charmaps-1 && - face->charmaps[charmap+1]->encoding != 0x41444243 /* custom */ + if(font->max_unicode == 0 && charmap < face->num_charmaps-1 + && face->charmaps[charmap+1]->encoding != 0x41444243 /* adbc, custom */ && face->charmaps[charmap+1]->encoding != 0x61726d6e /* armn */ ) { @@ -254,7 +264,7 @@ gfxfont_t* gfxfont_load(char*id, char*filename, double quality) if(full_unicode) font->max_unicode = 65535; - font->unicode2glyph = rfx_calloc(font->max_unicode*sizeof(int)); + font->unicode2glyph = (int*)rfx_calloc(font->max_unicode*sizeof(int)); for(t=0;tmax_unicode;t++) { int g = FT_Get_Char_Index(face, t); @@ -262,6 +272,9 @@ gfxfont_t* gfxfont_load(char*id, char*filename, double quality) g = -1; font->unicode2glyph[t] = g; if(g>=0) { +#ifdef DEBUG + printf("u%d ->%d\n", t, g); +#endif max_unicode = t+1; if(!glyph2unicode[g]) { glyph2unicode[g] = t; @@ -286,12 +299,9 @@ gfxfont_t* gfxfont_load(char*id, char*filename, double quality) for(t=0; t < face->num_glyphs; t++) { FT_Glyph glyph; - FT_BBox bbox; - FT_Matrix matrix; char name[128]; gfxdrawer_t draw; gfxdrawinfo_t info; - int ret; char hasname = 0; int omit = 0; name[0]=0; @@ -324,9 +334,9 @@ gfxfont_t* gfxfont_load(char*id, char*filename, double quality) error = FT_Load_Glyph(face, t, FT_LOAD_NO_BITMAP); if(error) { if(hasname) - fprintf(stderr, "Warning: glyph %d/%d (unicode %d, name %s) has return code %d\n", t, face->num_glyphs, glyph2unicode[t], name, error); + fprintf(stderr, "Warning: glyph %d/%d (unicode %d, name %s) has return code %d\n", t, (int)face->num_glyphs, glyph2unicode[t], name, error); else - fprintf(stderr, "Warning: glyph %d/%d (unicode %d) has return code %d\n", t, face->num_glyphs, glyph2unicode[t], error); + fprintf(stderr, "Warning: glyph %d/%d (unicode %d) has return code %d\n", t, (int)face->num_glyphs, glyph2unicode[t], error); omit = 2; #if 0 @@ -349,7 +359,7 @@ gfxfont_t* gfxfont_load(char*id, char*filename, double quality) if(!omit) { error = FT_Get_Glyph(face->glyph, &glyph); if(error) { - fprintf(stderr, "Couldn't get glyph %d/%d, error:%d\n", t, face->num_glyphs, error); + fprintf(stderr, "Couldn't get glyph %d/%d, error:%d\n", t, (int)face->num_glyphs, error); omit = 3; } } @@ -430,7 +440,7 @@ gfxfont_t* gfxfont_load(char*id, char*filename, double quality) so that the encoding equals the char position, and remove the unicode table */ int t; - gfxglyph_t*newglyphs = rfx_calloc(font->max_unicode*sizeof(gfxglyph_t)); + gfxglyph_t*newglyphs = (gfxglyph_t*)rfx_calloc(font->max_unicode*sizeof(gfxglyph_t)); for(t=0;tunicode2glyph[t]; @@ -479,9 +489,10 @@ gfxfont_t* gfxfont_load(char*id, char*filename, double quality) } #else -gfxfont_t* gfxfont_load(char*filename) +gfxfont_t* gfxfont_load(char*id, char*filename, unsigned int flags, double quality) { fprintf(stderr, "No freetype support compiled in! Not able to load %s\n", filename); + return 0; } #endif @@ -499,6 +510,117 @@ void gfxfont_free(gfxfont_t*font) if(font->unicode2glyph) { free(font->unicode2glyph);font->unicode2glyph = 0; } + if(font->id) { + free((void*)font->id);font->id=0; + } + if(font->kerning) { + free(font->kerning);font->kerning=0; + } + free(font); } +ttf_t* gfxfont_to_ttf(gfxfont_t*font) +{ + ttf_t*ttf = ttf_new(); + int num_glyphs = font->num_glyphs; + int offset = 0; + int t; + char has_nondef_glyph = + font->num_glyphs && font->glyphs[0].unicode==-1 && + (!font->glyphs[0].line || !font->glyphs[0].line->next); + + if(!has_nondef_glyph) { + /* insert a new .nondef glyph at the start of the font */ + offset++; + num_glyphs++; + } + ttf->num_glyphs = num_glyphs; + ttf->glyphs = rfx_calloc(num_glyphs*sizeof(ttfglyph_t)); + double scale = 1.0; + int max_unicode = font->max_unicode; + for(t=0;tnum_glyphs;t++) { + gfxglyph_t*src = &font->glyphs[t]; + ttfglyph_t*dest = &ttf->glyphs[t+offset]; + gfxline_t*line = src->line; + int count = 0; + while(line) { + count++; + if(line->type == gfx_splineTo) + count++; + line=line->next; + } + dest->num_points = count; + dest->points = rfx_calloc(count*sizeof(ttfpoint_t)); + count = 0; + line = src->line; + while(line) { + if(line->type == gfx_splineTo) { + dest->points[count].x = line->sx*scale; + dest->points[count].y = line->sy*scale; + count++; + } + dest->points[count].x = line->x*scale; + dest->points[count].y = line->y*scale; + dest->points[count].flags |= GLYPH_ON_CURVE; + if(line->type == gfx_moveTo) { + dest->points[count].flags |= GLYPH_CONTOUR_START; + if(count) + dest->points[count-1].flags |= GLYPH_CONTOUR_END; + } + count++; + line=line->next; + } + if(count) + dest->points[count-1].flags |= GLYPH_CONTOUR_END; + + /* compute bounding box */ + int s; + if(count) { + dest->xmin = dest->xmax = dest->points[0].x; + dest->ymin = dest->ymax = dest->points[0].y; + for(s=1;spoints[s].x < dest->xmin) + dest->xmin = dest->points[s].x; + if(dest->points[s].y < dest->ymin) + dest->ymin = dest->points[s].y; + if(dest->points[s].x > dest->xmax) + dest->xmax = dest->points[s].x; + if(dest->points[s].y > dest->ymax) + dest->ymax = dest->points[s].y; + } + } + + dest->advance = src->advance*scale; + if(src->unicode > max_unicode) + max_unicode = src->unicode; + } + ttf->unicode_size = max_unicode+1; + ttf->unicode = rfx_calloc(sizeof(unicode_t)*ttf->unicode_size); + for(t=0;tnum_glyphs;t++) { + gfxglyph_t*src = &font->glyphs[t]; + int u = font->glyphs[t].unicode; + if(u>=0) + ttf->unicode[u] = t+offset; + } + int u; + for(u=0;umax_unicode;u++) { + int g = font->unicode2glyph[u]; + if(g>=0) { + ttf->unicode[u] = g+offset; + } + } + ttf->ascent = font->ascent; + ttf->descent = font->descent; + ttf->lineGap = font->ascent + font->descent; + + ttf_create_truetype_tables(ttf); + return ttf; +} + +void gfxfont_save(gfxfont_t*font, const char*filename) +{ + ttf_t*ttf = gfxfont_to_ttf(font); + ttf_save(ttf, filename); +} +