From f9843bbeaa52fe428420eed8d2c8992f763a8d68 Mon Sep 17 00:00:00 2001 From: Matthias Kramm Date: Fri, 19 Feb 2010 20:48:00 -0800 Subject: [PATCH] fixed bugs in ttf writer --- lib/Makefile.in | 2 +- lib/gfxfont.c | 14 +++++++--- lib/ttf.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++----- lib/ttf.h | 8 ++++++ 4 files changed, 88 insertions(+), 12 deletions(-) diff --git a/lib/Makefile.in b/lib/Makefile.in index 857d928..bdd208d 100644 --- a/lib/Makefile.in +++ b/lib/Makefile.in @@ -93,7 +93,7 @@ gfximage.$(O): gfximage.c gfximage.h gfxdevice.h $(top_builddir)/config.h $(C) gfximage.c -o $@ gfxtools.$(O): gfxtools.c gfxtools.h $(top_builddir)/config.h $(C) gfxtools.c -o $@ -gfxfont.$(O): gfxfont.c gfxfont.h $(top_builddir)/config.h +gfxfont.$(O): gfxfont.c gfxfont.h ttf.h $(top_builddir)/config.h $(C) gfxfont.c -o $@ gfxwindow.$(O): gfxwindow_win32.c gfxwindow_unix.c gfxwindow.c gfxwindow.h $(C) gfxwindow.c -o $@ diff --git a/lib/gfxfont.c b/lib/gfxfont.c index 5004e18..d1f5806 100644 --- a/lib/gfxfont.c +++ b/lib/gfxfont.c @@ -539,6 +539,7 @@ ttf_t* gfxfont_to_ttf(gfxfont_t*font) ttf->glyphs = rfx_calloc(num_glyphs*sizeof(ttfglyph_t)); double scale = 1.0; int max_unicode = font->max_unicode; + int remap_pos=0; for(t=0;tnum_glyphs;t++) { gfxglyph_t*src = &font->glyphs[t]; ttfglyph_t*dest = &ttf->glyphs[t+offset]; @@ -592,19 +593,24 @@ ttf_t* gfxfont_to_ttf(gfxfont_t*font) } dest->advance = src->advance*scale; - if(src->unicode > max_unicode) - max_unicode = src->unicode; + + int u = font->glyphs[t].unicode; + if(u<32 || (u>=0xe000 && u<0xf900)) { + u = 0xe000 + remap_pos++; + } + if(u > max_unicode) + max_unicode = u; } ttf->unicode_size = max_unicode+1; ttf->unicode = rfx_calloc(sizeof(unicode_t)*ttf->unicode_size); - int remap_pos=0; + remap_pos=0; for(t=0;tnum_glyphs;t++) { gfxglyph_t*src = &font->glyphs[t]; int u = font->glyphs[t].unicode; if(u<32 || (u>=0xe000 && u<0xf900)) { u = 0xe000 + remap_pos++; } - if(u>=0) + if(u>=0 && uunicode_size) ttf->unicode[u] = t+offset; } int u; diff --git a/lib/ttf.c b/lib/ttf.c index f389ff9..db8b945 100644 --- a/lib/ttf.c +++ b/lib/ttf.c @@ -24,6 +24,7 @@ #include #include "log.h" #include "os.h" +#include "q.h" #include "mem.h" #include "ttf.h" @@ -1453,12 +1454,11 @@ void name_parse(memreader_t*r, ttf_t*ttf) U16 name_id = readU16(r); U16 len = readU16(r); U16 offset_2 = readU16(r); - /*printf("%d %d %d %d at %d, %d bytes:", platform, encoding, language, name_id, offset+offset_2, len); - int s; - for(s=0;smem[offset+offset_2+s]); + if(name_id==4) { + if(ttf->name) + free(ttf->name); + ttf->name = strdup_n(&r->mem[offset+offset_2], len); } - printf("\n");*/ } } void name_write(ttf_t*ttf, ttf_table_t*table) @@ -1486,6 +1486,43 @@ void name_delete(ttf_t*ttf) free(ttf->name); } +static table_post_t*post_new(ttf_t*ttf) +{ + table_post_t*post = rfx_calloc(sizeof(table_post_t)); + return post; +} +void post_parse(memreader_t*r, ttf_t*ttf) +{ + table_post_t*post = ttf->post = rfx_calloc(sizeof(table_post_t)); + U16 format = readU16(r); + post->italic_angle = readU16(r); + post->underline_position = readU16(r); + post->underline_thickness = readU16(r); + U16 is_monospaced = readU16(r); + readU16(r); // min mem 42 + readU16(r); + readU16(r); // min mem 1 + readU16(r); +} +void post_write(ttf_t*ttf, ttf_table_t*table) +{ + table_post_t*post = ttf->post; + writeU32(table, 0x00030000); + writeU32(table, post->italic_angle); + writeU16(table, post->underline_position); + writeU16(table, post->underline_thickness); + writeU32(table, 0); //is monospaced TODO + writeU32(table, 0); //min mem 42 + writeU32(table, 0); + writeU32(table, 0); //min mem 1 + writeU32(table, 0); +} +void post_delete(ttf_t*ttf) +{ + if(ttf->post) + free(ttf->post); +} + static int ttf_parse_tables(ttf_t*ttf) { ttf_table_t*table; @@ -1579,6 +1616,13 @@ static int ttf_parse_tables(ttf_t*ttf) ttf_table_delete(ttf, table); } + table = ttf_find_table(ttf, TAG_POST); + if(table) { + INIT_READ(m, table->data, table->len, 0); + post_parse(&m, ttf); + ttf_table_delete(ttf, table); + } + return 1; } static void ttf_collapse_tables(ttf_t*ttf) @@ -1625,6 +1669,11 @@ static void ttf_collapse_tables(ttf_t*ttf) name_write(ttf, table); name_delete(ttf); } + if(ttf->post) { + table = ttf_addtable(ttf, TAG_POST); + post_write(ttf, table); + post_delete(ttf); + } table = ttf_addtable(ttf, TAG_HEAD); head_write(ttf, table, loca_size); @@ -1731,6 +1780,8 @@ void ttf_create_truetype_tables(ttf_t*ttf) ttf->hea = hea_new(ttf); if(!ttf->os2) ttf->os2 = os2_new(ttf); + if(!ttf->post) + ttf->post = post_new(ttf); } ttf_table_t* ttf_write(ttf_t*ttf) { @@ -1831,7 +1882,7 @@ void ttf_dump(ttf_t*ttf) maxp_dump(ttf); glyf_dump(ttf); } -void ttf_destroy(ttf_t*ttf) +void ttf_destroy_tables(ttf_t*ttf) { ttf_table_t*table = ttf->tables; while(table) { @@ -1840,11 +1891,21 @@ void ttf_destroy(ttf_t*ttf) free(table); table = next; } + ttf->tables = 0; +} +void ttf_reduce(ttf_t*ttf) +{ + ttf_destroy_tables(ttf); +} +void ttf_destroy(ttf_t*ttf) +{ + ttf_destroy_tables(ttf); maxp_delete(ttf); os2_delete(ttf); head_delete(ttf); hea_delete(ttf); glyf_delete(ttf); + post_delete(ttf); free(ttf); } @@ -1858,13 +1919,14 @@ int main(int argn, const char*argv[]) //msg(" Loading %s", filename); memfile_t*m = memfile_open(filename); ttf_t*ttf = ttf_load(m->data, m->len); + ttf_reduce(ttf); ttf->name = strdup("testfont"); if(!ttf) return 1; memfile_close(m); //ttf_dump(ttf); //printf("os2 version: %04x (%d), maxp size: %d\n", // ttf->os2->version, ttf->os2->size, ttf->maxp->size); - ttf_save(ttf, "output.ttf"); + ttf_save(ttf, "testfont.ttf"); ttf_destroy(ttf); return 0; diff --git a/lib/ttf.h b/lib/ttf.h index 104ac78..d37f745 100644 --- a/lib/ttf.h +++ b/lib/ttf.h @@ -139,6 +139,12 @@ typedef struct _table_head { S16 dir_hint; } table_head_t; +typedef struct _table_post { + U16 italic_angle; + U16 underline_position; + U16 underline_thickness; +} table_post_t; + typedef struct _ttf { char*name; @@ -148,6 +154,7 @@ typedef struct _ttf { table_maxp_t*maxp; table_os2_t*os2; table_hea_t*hea; + table_post_t*post; U16 flags; char is_vertical; @@ -167,6 +174,7 @@ typedef struct _ttf { ttf_t*ttf_new(); +void ttf_reduce(ttf_t*ttf); ttf_t*ttf_load(void*data, int length); ttf_table_t*ttf_addtable(ttf_t*ttf, U32 tag); void ttf_create_truetype_tables(ttf_t*ttf); -- 1.7.10.4