summaryrefslogtreecommitdiff
path: root/misc/ttf2woff/genttf.c
blob: ad87be45b82fb262803d6d8c5b109861ed3a9c48 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
/*
 *	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 <stdlib.h>
#include <string.h>
#include <strings.h>
#include <assert.h>
#include "ttf2woff.h"

u8 *put_ttf_header(u8 buf[12], struct ttf *ttf)
{
	u8 *p = buf;
	int n = ttf->ntables;
	p = p32(p, ttf->flavor);
	p = p16(p, n);
	while(n & n-1) n &= n-1;
	p = p16(p, n<<4);
	p = p16(p, ffs(n)-1);
	p = p16(p, ttf->ntables-n << 4);
	return p;
}

void gen_ttf(struct buf *out, struct ttf *ttf)
{
	unsigned sfnt_size;
	u8 *buf, *p;
	int i;

	sfnt_size = 12 + 16*ttf->ntables;
	for(i=0; i<ttf->ntables; i++) {
		struct table *t = ttf->tab_pos[i];
		t->pos = sfnt_size; // remember offset in output file
		sfnt_size += t->buf.len+3 & ~3;
	}

	buf = my_alloc(sfnt_size);
	p = put_ttf_header(buf, ttf);

	for(i=0; i<ttf->ntables; i++) {
		struct table *t = &ttf->tables[i];
		p = p32(p, t->tag);
		p = p32(p, t->csum);
		p = p32(p, t->pos);
		p = p32(p, t->buf.len);
	}

	for(i=0; i<ttf->ntables; i++) {
		struct table *t = ttf->tab_pos[i];
		unsigned sz = t->buf.len;
		p = append(p, t->buf.ptr, sz);
		while(sz&3) *p++=0, sz++;
	}

	assert(p == buf+sfnt_size);

	out->ptr = buf;
	out->len = sfnt_size;
}