From: Matthias Kramm <kramm@quiss.org>
Date: Thu, 25 Feb 2010 01:48:36 +0000 (-0800)
Subject: more ttf bug fixes
X-Git-Tag: version-0-9-1~136
X-Git-Url: http://git.asbjorn.biz/?a=commitdiff_plain;h=219ea5ad983fc389d894c967528b451ea321b8c6;p=swftools.git

more ttf bug fixes
---

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;t<num;t++) {
 		gfxglyph_t*g = &font->glyphs[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;t<num;t++) {
+		font->glyphs[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;t<l+1;t++) {
 		fontname2[t*2+0] = fontname[t];
 		fontname2[t*2+1] = 0;
 	    }
-	    fontid = PDF_load_font(i->p, 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;u<font->max_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;u<ttf->unicode_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("<warning> 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;s<segment_count;s++) {
 		U16 start = readU16(&r_start);
@@ -1299,7 +1301,12 @@ void cmap_parse(memreader_t*r, ttf_t*ttf)
 			ttf->unicode[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("<warning> 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;t<num_segments;t++) {writeU16(w, 0);} //end array
@@ -1374,10 +1383,10 @@ void cmap_write(ttf_t* ttf, ttf_table_t*w)
     for(t=0;t<num_segments;t++) {writeU16(w, 0);} //delta array
     int range_pos = w->len;
     for(t=0;t<num_segments;t++) {writeU16(w, 0);} //range array
-    
+	    
     w->data[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("<notice> Loading %s", filename);
     memfile_t*m = memfile_open(filename);
     ttf_t*ttf = ttf_load(m->data, m->len);
+    if(!ttf) {
+	msg("<error> Couldn't load %s", filename);
+	return 1;
+    }
     ttf_reduce(ttf);
     ttf->name = strdup("testfont");
     if(!ttf) return 1;