#include <memory.h>
#include "log.h"
#include "os.h"
+#include "q.h"
#include "mem.h"
#include "ttf.h"
head->xmax = ttf->glyphs[0].xmax;
head->ymax = ttf->glyphs[0].ymax;
for(t=1;t<ttf->num_glyphs;t++) {
- if(ttf->glyphs[0].xmin < head->xmin) head->xmin = ttf->glyphs[0].xmin;
- if(ttf->glyphs[0].ymin < head->ymin) head->ymin = ttf->glyphs[0].ymin;
- if(ttf->glyphs[0].xmax > head->xmax) head->xmax = ttf->glyphs[0].xmax;
- if(ttf->glyphs[0].ymax > head->ymax) head->ymax = ttf->glyphs[0].ymax;
+ if(ttf->glyphs[t].xmin < head->xmin) head->xmin = ttf->glyphs[t].xmin;
+ if(ttf->glyphs[t].ymin < head->ymin) head->ymin = ttf->glyphs[t].ymin;
+ if(ttf->glyphs[t].xmax > head->xmax) head->xmax = ttf->glyphs[t].xmax;
+ if(ttf->glyphs[t].ymax > head->ymax) head->ymax = ttf->glyphs[t].ymax;
}
}
head->macStyle = 0;
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 < ttf->hea->minLeftSideBearing)
- ttf->hea->minLeftSideBearing = ttf->glyphs[t].xmin;
- if(ttf->glyphs[t].xmax < ttf->hea->minRightSideBearing)
- ttf->hea->minRightSideBearing = ttf->glyphs[t].xmax;
+ if(ttf->glyphs[t].xmin < hea->minLeftSideBearing)
+ hea->minLeftSideBearing = ttf->glyphs[t].xmin;
+ if(ttf->glyphs[t].xmax < hea->minRightSideBearing)
+ hea->minRightSideBearing = ttf->glyphs[t].xmax;
int width = ttf->glyphs[t].xmax - ttf->glyphs[t].xmin;
if(width > hea->xMaxExtent)
hea->xMaxExtent = width;
}
ttf->unicode_size=0;
}
+void name_parse(memreader_t*r, ttf_t*ttf)
+{
+ U16 format = readU16(r);
+ U16 count = readU16(r);
+ U16 offset = readU16(r);
+
+ int t;
+ for(t=0;t<count;t++) {
+ U16 platform = readU16(r);
+ U16 encoding = readU16(r);
+ U16 language = readU16(r);
+ U16 name_id = readU16(r);
+ U16 len = readU16(r);
+ U16 offset_2 = readU16(r);
+ if(name_id==4) {
+ if(ttf->name)
+ free(ttf->name);
+ ttf->name = strdup_n(&r->mem[offset+offset_2], len);
+ }
+ }
+}
+void name_write(ttf_t*ttf, ttf_table_t*table)
+{
+ writeU16(table, 0); //format
+ writeU16(table, 1); //count
+ int offset = 18;
+ writeU16(table, offset); //offset
+
+ writeU16(table, 1); //platform id
+ writeU16(table, 0); //encoding id
+ writeU16(table, 0); //language
+ writeU16(table, 4); //4: full name
+ int len = strlen(ttf->name);
+ writeU16(table, len);
+ writeU16(table, table->len+2 - offset);
+ int t;
+ for(t=0;t<len;t++) {
+ writeU8(table, ttf->name[t]);
+ }
+}
+void name_delete(ttf_t*ttf)
+{
+ if(ttf->name)
+ 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)
{
cmap_parse(&m, ttf);
ttf_table_delete(ttf, table);
}
+
+ table = ttf_find_table(ttf, TAG_NAME);
+ if(table) {
+ INIT_READ(m, table->data, table->len, 0);
+ name_parse(&m, 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;
}
loca_size = loca_write(ttf, table, locations);
free(locations);
}
+
+ if(ttf->name) {
+ table = ttf_addtable(ttf, TAG_NAME);
+ 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);
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)
{
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) {
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);
}
//msg("<notice> 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;