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;
}
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)
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;
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;
}
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;
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)
{
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);
}
}
}
-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)
{
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);
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 {
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)
}
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);