diff options
author | Rasmus Andersson <rasmus@notion.se> | 2017-08-22 10:05:20 +0300 |
---|---|---|
committer | Rasmus Andersson <rasmus@notion.se> | 2017-08-22 12:23:08 +0300 |
commit | 3b1fffade1473f20f2558733fbd218f4580fc7c3 (patch) | |
tree | ea4f80b43b08744d493bb86ab646444ec04ddc7f /misc/ttf2woff/genwoff.c | |
download | inter-3b1fffade1473f20f2558733fbd218f4580fc7c3.tar.xz |
Initial public commitv1.0
Diffstat (limited to 'misc/ttf2woff/genwoff.c')
-rw-r--r-- | misc/ttf2woff/genwoff.c | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/misc/ttf2woff/genwoff.c b/misc/ttf2woff/genwoff.c new file mode 100644 index 000000000..7b6b746a7 --- /dev/null +++ b/misc/ttf2woff/genwoff.c @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2013 Jan Bobrowski <jb@wizard.ae.krakow.pl> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + */ + +#include <string.h> +#include <stdlib.h> +#include <assert.h> +#include "ttf2woff.h" + +#define MIN_COMPR 16 + +void gen_woff(struct buf *out, struct ttf *ttf) +{ + unsigned woff_size, sfnt_size; + struct buf meta_comp={0}; + u32 meta_off, priv_off; + u8 *buf, *p; + int i; + + woff_size = 44 + 20*ttf->ntables; + sfnt_size = 12 + 16*ttf->ntables; + for(i=0; i<ttf->ntables; i++) { + struct table *t = ttf->tab_pos[i]; + t->pos = woff_size; // remember offset in output file + t->zbuf = t->buf; + if(t->buf.len >= MIN_COMPR) + zlib_compress(&t->zbuf, &t->buf); + sfnt_size += t->buf.len+3 & ~3; + woff_size += t->zbuf.len+3 & ~3; + } + + meta_off = 0; + if(ttf->woff_meta.len >= MIN_COMPR) { + meta_comp = ttf->woff_meta; + zlib_compress(&meta_comp, &ttf->woff_meta); + meta_off = woff_size; + woff_size += meta_comp.len; + } + + priv_off = 0; + if(ttf->woff_priv.len) { + priv_off = woff_size; + woff_size += ttf->woff_priv.len; + } + + buf = my_alloc(woff_size); + + p32(buf, 0x774F4646); + p32(buf+4, ttf->flavor); + p32(buf+8, woff_size); + p16(buf+12, ttf->ntables); + p16(buf+14, 0); + p32(buf+16, sfnt_size); + p32(buf+20, 0); // version ? + p32(buf+24, meta_off); + p32(buf+28, meta_comp.len); // meta len + p32(buf+32, ttf->woff_meta.len); // meta orig len + p32(buf+36, priv_off); + p32(buf+40, ttf->woff_priv.len); + + p = buf + 44; + for(i=0; i<ttf->ntables; i++) { + struct table *t = &ttf->tables[i]; + p32(p, t->tag); + p32(p+4, t->pos); + p32(p+8, t->zbuf.len); + p32(p+12, t->buf.len); + p32(p+16, t->csum); + p += 20; + } + + for(i=0; i<ttf->ntables; i++) { + struct table *t = ttf->tab_pos[i]; + u32 sz = t->zbuf.len; + p = append(p, t->zbuf.ptr, sz); + while(sz&3) *p++=0, sz++; +// if(t->zbuf.ptr != t->buf.ptr) +// my_free(t->zbuf.ptr); + } + + if(meta_comp.len) + p = append(p, meta_comp.ptr, meta_comp.len); + + if(ttf->woff_priv.len) + p = append(p, ttf->woff_priv.ptr, ttf->woff_priv.len); + + assert(p == buf+woff_size); + + out->ptr = buf; + out->len = woff_size; +} |