From 219ea5ad983fc389d894c967528b451ea321b8c6 Mon Sep 17 00:00:00 2001 From: Matthias Kramm Date: Wed, 24 Feb 2010 17:48:36 -0800 Subject: [PATCH] more ttf bug fixes --- lib/devices/pdf.c | 24 +++++++++++++++--------- lib/gfxfont.c | 14 ++++++++------ lib/ttf.c | 32 +++++++++++++++++++++++++------- 3 files changed, 48 insertions(+), 22 deletions(-) diff --git a/lib/devices/pdf.c b/lib/devices/pdf.c index 1cfd6f8..8ecfa87 100644 --- a/lib/devices/pdf.c +++ b/lib/devices/pdf.c @@ -335,13 +335,14 @@ void pdf_fillgradient(gfxdevice_t*dev, gfxline_t*line, gfxgradient_t*gradient, g internal_t*i = (internal_t*)dev->internal; } -static const char type3 = 1; -static const char ttf = 0; +static const char type3 = 0; +static const char ttf = 1; void pdf_addfont(gfxdevice_t*dev, gfxfont_t*font) { internal_t*i = (internal_t*)dev->internal; + int num = font->num_glyphs<256-32?font->num_glyphs:256-32; if(type3) { int fontid = 0; if(!gfxfontlist_hasfont(i->fontlist, font)) { @@ -358,7 +359,6 @@ void pdf_addfont(gfxdevice_t*dev, gfxfont_t*font) } PDF_begin_font(i->p, fontname2, l*2, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, ""); - int num = font->num_glyphs<256-32?font->num_glyphs:256-32; for(t=0;tglyphs[t]; gfxbbox_t bbox = gfxline_getbbox(g->line); @@ -385,18 +385,21 @@ void pdf_addfont(gfxdevice_t*dev, gfxfont_t*font) fontnr++; const char*old_id = font->id; font->id = fontname; + int t; + for(t=0;tglyphs[t].unicode = 32+t; + } + font->unicode2glyph = 0; gfxfont_save(font, filename); font->id=old_id; int l = strlen(font->id); - int t; for(t=0;tp, fontname2, l*2, "host", ""); + fontid = PDF_load_font(i->p, fontname2, l*2, "host", "embedding=true"); i->fontlist = gfxfontlist_addfont2(i->fontlist, font, (void*)(ptroff_t)fontid); - unlink(fontname); } } } @@ -427,10 +430,15 @@ void pdf_drawchar(gfxdevice_t*dev, gfxfont_t*font, int glyphnr, gfxcolor_t*color int fontid = (int)(ptroff_t)gfxfontlist_getuserdata(i->fontlist, font->id); gfxmatrix_t m = *matrix; + m.m00*=64; m.m01*=64; m.m10*=64; m.m11*=64; + if(ttf) { + m.m10 = -m.m10; + m.m11 = -m.m11; + } if(!(fabs(m.m00 - i->m00) < 1e-6 && fabs(m.m01 - i->m01) < 1e-6 && @@ -441,8 +449,7 @@ void pdf_drawchar(gfxdevice_t*dev, gfxfont_t*font, int glyphnr, gfxcolor_t*color double tx, ty; transform_back(i, m.tx+i->config_xpad, m.ty+i->config_ypad, &tx, &ty); - //PDF_setfont(i->p, fontid, 1.0/64.0); // downscaling is done in glyph itself - PDF_setfont(i->p, fontid, 1.0); + PDF_setfont(i->p, fontid, ttf?16.0:1.0); PDF_setrgbcolor_fill(i->p, color->r/255.0, color->g/255.0, color->b/255.0); char name[32]; @@ -570,4 +577,3 @@ void gfxdevice_pdf_init(gfxdevice_t*dev) i->has_matrix = 0; i->p = PDF_new(); } - diff --git a/lib/gfxfont.c b/lib/gfxfont.c index d1f5806..dda20db 100644 --- a/lib/gfxfont.c +++ b/lib/gfxfont.c @@ -614,12 +614,14 @@ ttf_t* gfxfont_to_ttf(gfxfont_t*font) ttf->unicode[u] = t+offset; } int u; - for(u=0;umax_unicode;u++) { - int g = font->unicode2glyph[u]; - if(u<32 || (u>=0xe000 && u<0xf900)) - continue; - if(g>=0 && !ttf->unicode[u]) { - ttf->unicode[u] = g+offset; + if(font->unicode2glyph) { + for(u=0;uunicode_size;u++) { + int g = font->unicode2glyph[u]; + if(u<32 || (u>=0xe000 && u<0xf900)) + continue; + if(g>=0 && !ttf->unicode[u]) { + ttf->unicode[u] = g+offset; + } } } ttf->ascent = font->ascent; diff --git a/lib/ttf.c b/lib/ttf.c index db8b945..28bdee2 100644 --- a/lib/ttf.c +++ b/lib/ttf.c @@ -1220,6 +1220,7 @@ void cmap_parse(memreader_t*r, ttf_t*ttf) readU16(r); // version (0) int num_subtables = readU16(r); int t; + char warn=1; if(r->pos+num_subtables*8 > r->size) { msg(" CMap overflow"); num_subtables = (r->size-r->pos)/8; @@ -1277,6 +1278,7 @@ void cmap_parse(memreader_t*r, ttf_t*ttf) INIT_READ(r_delta, t.mem, t.size, t.pos+2+segment_count*4); INIT_READ(r_range, t.mem, t.size, t.pos+2+segment_count*6); int glyphmap_start = t.pos+2+segment_count*8; + int glyphmap_size = t.size - glyphmap_start; int s; for(s=0;sunicode[u] = (u + delta) & 0xffff; } } else { - INIT_READ(g, t.mem, t.size, r_range.pos-2+range); + int pos = r_range.pos-2+range; + if(warn && pos+end-start+1 > t.size) { + msg(" glyphmap index out of bounds (%d-%d/%d)", pos, pos+end-start, t.size); + warn=0; + } + INIT_READ(g, t.mem, t.size, pos); for(u=start;u<=end;u++) { ttf->unicode[u] = readU16(&g); } @@ -1364,6 +1371,8 @@ void cmap_write(ttf_t* ttf, ttf_table_t*w) num_segments++; // account for 0xffff mapping + int glyphmap_start = w->len+2+num_segments*8; + int t; int end_pos = w->len; for(t=0;tlen; for(t=0;tdata[num_segments_pos]=(num_segments*2)>>8; w->data[num_segments_pos+1]=(num_segments*2); - + pos=0; num_segments = 0; while(pos < ttf->unicode_size) { @@ -1394,7 +1403,7 @@ void cmap_write(ttf_t* ttf, ttf_table_t*w) U16 delta = ttf->unicode[pos]-pos; char do_delta=1; for(s=pos+1;s<=end;s++) { - U16 delta2 = ttf->unicode[pos]-pos; + U16 delta2 = ttf->unicode[s]-s; if(delta2!=delta) { do_delta=0; break; @@ -1405,7 +1414,7 @@ void cmap_write(ttf_t* ttf, ttf_table_t*w) range = 0; } else { delta = 0; - range = w->len - range_pos+num_segments*2; + range = w->len - range_pos; for(s=pos;s<=end;s++) { writeU16(w, ttf->unicode[s]); } @@ -1482,8 +1491,10 @@ void name_write(ttf_t*ttf, ttf_table_t*table) } void name_delete(ttf_t*ttf) { - if(ttf->name) + if(ttf->name) { free(ttf->name); + ttf->name=0; + } } static table_post_t*post_new(ttf_t*ttf) @@ -1519,8 +1530,10 @@ void post_write(ttf_t*ttf, ttf_table_t*table) } void post_delete(ttf_t*ttf) { - if(ttf->post) + if(ttf->post) { free(ttf->post); + ttf->post = 0; + } } static int ttf_parse_tables(ttf_t*ttf) @@ -1906,6 +1919,7 @@ void ttf_destroy(ttf_t*ttf) hea_delete(ttf); glyf_delete(ttf); post_delete(ttf); + name_delete(ttf); free(ttf); } @@ -1919,6 +1933,10 @@ 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); + if(!ttf) { + msg(" Couldn't load %s", filename); + return 1; + } ttf_reduce(ttf); ttf->name = strdup("testfont"); if(!ttf) return 1; -- 1.7.10.4