small bug in ttf reading
[swftools.git] / lib / ttf.c
index 46190ee..c1fd06d 100644 (file)
--- a/lib/ttf.c
+++ b/lib/ttf.c
@@ -404,7 +404,7 @@ static table_os2_t*os2_new(ttf_t*ttf)
        os2->yStrikeoutSize = ttf->head->units_per_em / 10;
        os2->yStrikeoutPosition = ymid;
        os2->usWinAscent = ttf->ascent;
-       os2->usWinDescent = -ttf->descent;
+       os2->usWinDescent = ttf->descent>0?0:-ttf->descent;
        os2->sxHeight = ymid;
        os2->sCapHeight = height*2/3;
     }
@@ -638,6 +638,7 @@ static table_maxp_t*maxp_new(ttf_t*ttf)
        maxp->maxComponentPoints = 0;
        maxp->maxComponentContours = 0;
     }
+    maxp->maxZones = 2; // we don't use the Z0 zone
     return maxp;
 }
 static table_maxp_t* maxp_parse(ttf_t*ttf, memreader_t*r)
@@ -726,8 +727,8 @@ static table_hea_t*hea_new(ttf_t*ttf)
        for(t=0;t<ttf->num_glyphs;t++) {
            if(ttf->glyphs[t].advance > hea->advanceWidthMax)
                hea->advanceWidthMax = ttf->glyphs[t].advance;
-           if(ttf->glyphs[t].xmin < hea->minLeftSideBearing)
-               hea->minLeftSideBearing = ttf->glyphs[t].xmin;
+           if(ttf->glyphs[t].bearing < hea->minLeftSideBearing)
+               hea->minLeftSideBearing = ttf->glyphs[t].bearing;
            if(ttf->glyphs[t].xmax < hea->minRightSideBearing)
                hea->minRightSideBearing = ttf->glyphs[t].xmax;
            int width = ttf->glyphs[t].xmax - ttf->glyphs[t].xmin;
@@ -849,10 +850,10 @@ static int mtx_write(ttf_t*ttf, ttf_table_t*w)
     int t;
     for(t=0;t<num_advances;t++) {
        writeU16(w, ttf->glyphs[t].advance);
-       writeU16(w, ttf->glyphs[t].bearing);
+       writeS16(w, ttf->glyphs[t].bearing);
     }
     for(;t<ttf->num_glyphs;t++) {
-       writeU16(w, ttf->glyphs[t].bearing);
+       writeS16(w, ttf->glyphs[t].bearing);
     }
     return num_advances;
 }
@@ -1418,11 +1419,12 @@ void cmap_write(ttf_t* ttf, ttf_table_t*w)
     w->data[num_segments_pos++]=(search_range*2);
     /* backpatch entry selector */
     int entry_selector = 0;
+    tmp = search_range;
     while(tmp>1) {tmp>>=1;entry_selector++;}
     w->data[num_segments_pos++]=entry_selector>>8;
     w->data[num_segments_pos++]=entry_selector;
     /* backpatch range shift */
-    int range_shift = num_segments*2 - search_range;
+    int range_shift = num_segments*2 - search_range*2;
     w->data[num_segments_pos++]=range_shift>>8;
     w->data[num_segments_pos++]=range_shift;
 
@@ -1636,15 +1638,15 @@ static table_post_t*post_new(ttf_t*ttf)
 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);
+    U32 format = readU32(r);
+    post->italic_angle = readU32(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);
+    U16 is_monospaced = readU32(r);
+    readU32(r); // min mem 42
+    readU32(r);
+    readU32(r); // min mem 1
+    readU32(r);
 }
 void post_write(ttf_t*ttf, ttf_table_t*table)
 {
@@ -1718,13 +1720,25 @@ void gasp_parse(memreader_t*r, ttf_t*ttf)
        gasp->records[t].behaviour = readU16(r);
     }
 }
+
+#define GASP_SYMMETRIC_GRIDFIT 0x0008
+#define GASP_SYMMETRIC_SMOOTHING 0x0004
+#define GASP_DOGRAY 0x0002
+#define GASP_GRIDFIT 0x0001
+
 void gasp_write(ttf_t*ttf, ttf_table_t*table)
 {
     table_gasp_t*gasp = ttf->gasp;
-    writeU16(table, 0);
-    writeU16(table, gasp->num);
+    int version = 0;
     int t;
     for(t=0;t<gasp->num;t++) {
+       if(gasp->records[t].behaviour & ~(GASP_GRIDFIT | GASP_DOGRAY)) {
+           version = 1;
+       }
+    }
+    writeU16(table, version);
+    writeU16(table, gasp->num);
+    for(t=0;t<gasp->num;t++) {
        writeU16(table, gasp->records[t].size);
        writeU16(table, gasp->records[t].behaviour);
     }
@@ -1739,9 +1753,21 @@ void gasp_delete(ttf_t*ttf)
     }
 }
 
-void fpgm_new(ttf_t*ttf)
+table_code_t*prep_new(ttf_t*ttf)
 {
-    table_code_t*fpgm = ttf->fpgm = rfx_calloc(sizeof(table_code_t));
+    table_code_t*prep = ttf->prep = rfx_calloc(sizeof(table_code_t));
+    ttf_table_t*t = ttf_table_new(0);
+    writeU8(t,0xb8);writeU16(t,0x1ff); // pushword(0x1ff)
+    writeU8(t,0x85); //scanctrl (always do dropout, for all sizes)
+    writeU8(t,0xb0);writeU8(t,1); // pushbyte(1)
+    writeU8(t,0x8d); //scantype (simple dropout control w/o stubs)
+    writeU8(t,0xb0);writeU8(t,5); // pushbyte(5)
+    writeU8(t,0x8d); //scantype (for windows) smart dropout control w/o stubs
+    prep->code = t->data;
+    prep->size = t->len;
+    free(t);
+    return prep;
+
 }
 void fpgm_parse(memreader_t*r, ttf_t*ttf)
 {
@@ -1994,6 +2020,16 @@ static void ttf_collapse_tables(ttf_t*ttf)
        gasp_write(ttf, table);
        gasp_delete(ttf);
     }
+    if(ttf->fpgm) {
+       table = ttf_addtable(ttf, TAG_FPGM);
+       fpgm_write(ttf, table);
+       fpgm_delete(ttf);
+    }
+    if(ttf->prep) {
+       table = ttf_addtable(ttf, TAG_PREP);
+       prep_write(ttf, table);
+       prep_delete(ttf);
+    }
 
     table = ttf_addtable(ttf, TAG_HEAD);
     head_write(ttf, table, loca_size);
@@ -2118,11 +2154,6 @@ ttf_t* ttf_load(void*data, int length)
        U32 pos = table_data[t*4+2];
        U32 len = table_data[t*4+3];
        
-       printf("TTF Table %02x%02x%02x%02x %c%c%c%c\n", 
-               (tag>>24)&0xff, (tag>>16)&0xff, (tag>>8)&0xff, (tag)&0xff, 
-               (tag>>24)&0xff, (tag>>16)&0xff, (tag>>8)&0xff, (tag)&0xff
-               );
-
        if(pos+len > length) {
            msg("<error> TTF Table %02x%02x%02x%02x outside of stream (pos %d)", (tag>>24)&0xff, (tag>>16)&0xff, (tag>>8)&0xff, (tag)&0xff, pos);
        } else {
@@ -2165,8 +2196,8 @@ void ttf_create_truetype_tables(ttf_t*ttf)
        ttf->post = post_new(ttf);
     if(!ttf->gasp)
        ttf->gasp = gasp_new(ttf);
-    if(!ttf->fpgm)
-       ttf->fpgm = fpgm_new(ttf);
+    if(!ttf->prep)
+       ttf->prep = prep_new(ttf);
 }
 
 ttf_table_t* ttf_write(ttf_t*ttf, U32*checksum_adjust)
@@ -2415,12 +2446,7 @@ int main(int argn, const char*argv[])
     }
     ttf_reduce(ttf);
 
-    ttf->full_name = strdup("Test-Normal");
-    ttf->family_name = strdup("Test");
-    ttf->subfamily_name = strdup("Normal");
-    ttf->version_string = strdup("Version 1.0");
-    ttf->font_uid = strdup("omguid");
-    ttf->postscript_name = strdup("Test-psname");
+    ttf_create_truetype_tables(ttf);
 
     if(!ttf) return 1;
     memfile_close(m);