summaryrefslogtreecommitdiff
path: root/src/intmetrics.c
blob: 6040008d5ac6fd91eb5974ec57df89f022eba9aa (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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#ifdef __riscos__
#include "swis.h"
#endif

#include "fm.h"
#include "glyph.h"
#include "intmetrics.h"
#include "utils.h"

struct intmetrics_header {
	char  name[40];
	int   a;
	int   b;
	char  nlo;
	char  version;
	char  flags;
	char  nhi;
};

static short mapsize;

static char *character_map = 0;

/* we don't use these */
// static short *x0;
// static short *y0;
// static short *x1;
// static short *y1;

static short *xwidthtab = 0;
// static short *ywidthtab;

struct extra_data_offsets {
	short misc;
	short kern;
	short res1;
	short res2;
};

struct misc_area {
	short x0;
	short y0;
	short x1;
	short y1;
	short default_x_offset;
	short default_y_offset;
	short italic_h_offset;
	char  underline_position;
	char  underline_thickness;
	short cap_height;
	short xheight;
	short descender;
	short ascender;
	int reserved;
};

struct kern_pair_8 {
	char  left;
	char  right;
	short x_kern;
	short y_kern;
	char  list_end;
	char  area_end;
};

struct kern_pair_16 {
	short left;
	short right;
	short x_kern;
	short y_kern;
	short list_end;
	short area_end;
};

/**
 * Write font metrics to file
 *
 * \param savein     Location to save in
 * \param name       Font name
 * \param glyph_list List of all glyphs in font
 * \param list_size  Size of glyph list
 * \param metrics    Global font metrics
 */
ttf2f_result write_intmetrics(const char *savein,
		const char *name,struct glyph *glyph_list, int list_size,
		struct font_metrics *metrics, void (*callback)(int progress))
{
	struct intmetrics_header header;
	int charmap_size = 0;
	unsigned int xwidthtab_size = 0;
	int i;
	struct glyph *g;
	char out[1024];
	FILE *output;

	UNUSED(metrics);

	/* allow for chunk 0 */
	xwidthtab = calloc(33, sizeof(short));
	if (xwidthtab == NULL)
		return TTF2F_RESULT_NOMEM;

	xwidthtab_size = 32;

	/* create xwidthtab - char code is now the index */
	for (i = 0; i != list_size; i++) {
		g = &glyph_list[i];

		callback((i * 100) / list_size);
		ttf2f_poll(1);

		xwidthtab_size++;
		xwidthtab[i+32] = g->width;
		xwidthtab = realloc(xwidthtab,
				(xwidthtab_size+1) * sizeof(short));
		if (xwidthtab == NULL)
			return TTF2F_RESULT_NOMEM;
	}

	/* fill in header */
	snprintf(header.name, 40, "%s", name);
	memset(header.name + (strlen(name) >= 40 ? 39 : strlen(name)), 0xD,
		40 - (strlen(name) >= 40 ? 39 : strlen(name)));
	header.a = header.b = 16;
	header.version = 0x2;
	header.flags = 0x25;
	header.nhi = xwidthtab_size / 256;
	header.nlo = xwidthtab_size % 256;

	mapsize = charmap_size;

	snprintf(out, 1024, "%s" DIR_SEP "IntMetrics", savein);
	if ((output = fopen(out, "wb+")) == NULL) {
		free(xwidthtab);
		return TTF2F_RESULT_OPEN;
	}

	if (fwrite((void*)&header, sizeof(struct intmetrics_header),
		   1, output) != 1) goto error_write;

	if (fputc(mapsize & 0xFF, output) == EOF) goto error_write;
	if (fputc((mapsize & 0xFF00) >> 8, output) == EOF) goto error_write;

	if (fwrite(character_map, sizeof(char), charmap_size, output)
		!= (size_t)charmap_size) goto error_write;
	
	if (fwrite(xwidthtab, sizeof(short), xwidthtab_size, output)
		!= xwidthtab_size) goto error_write;

	fclose(output);

#ifdef __riscos__
	/* set type */
	_swix(OS_File, _INR(0,2), 18, out, 0xFF6);
#endif

	if (character_map)
		free(character_map);
	free(xwidthtab);
	
	return TTF2F_RESULT_OK;

error_write:
	free(character_map);
	free(xwidthtab);
	fclose(output);

	return TTF2F_RESULT_WRITE;
}