Another variable renaming.
[ttfautohint.git] / src / ttfautohint.c
blob901b7aaaed119d168e5d74e1cb1243e6d4e7b8d9
1 /* ttfautohint.c */
3 /* written 2011 by Werner Lemberg <wl@gnu.org> */
5 /* This file needs FreeType 2.4.5 or newer. */
8 #include <config.h>
9 #include <stdio.h>
11 #include <ft2build.h>
12 #include FT_FREETYPE_H
13 #include FT_TRUETYPE_TAGS_H
15 #include "ttfautohint.h"
18 typedef struct SFNT_Table_ {
19 FT_ULong tag;
20 FT_ULong len;
21 FT_Byte* buf;
22 } SFNT_Table;
25 TA_Error
26 TTF_autohint(FILE *in,
27 FILE *out)
29 FT_Library lib = NULL;
30 FT_Face face = NULL;
31 FT_Long num_faces = 0;
33 FT_Byte* in_buf;
34 size_t in_len;
36 SFNT_Table* SFNT_Table_Infos = NULL;
37 FT_ULong num_table_infos = 0;
39 FT_ULong glyf_idx;
41 FT_Error error;
43 FT_ULong j;
46 /*** load font into memory ***/
48 fseek(in, 0, SEEK_END);
49 in_len = ftell(in);
50 fseek(in, 0, SEEK_SET);
52 /* a TTF can never be that small */
53 if (in_len < 100)
54 return FT_Err_Invalid_Argument;
56 in_buf = (FT_Byte*)malloc(in_len);
57 if (!in_buf)
58 return FT_Err_Out_Of_Memory;
60 if (fread(in_buf, 1, in_len, in) != in_len)
62 error = FT_Err_Invalid_Stream_Read;
63 goto Err;
66 error = FT_Init_FreeType(&lib);
67 if (error)
68 goto Err;
70 error = FT_New_Memory_Face(lib, in_buf, in_len, -1, &face);
71 if (error)
72 goto Err;
73 num_faces = face->num_faces;
74 FT_Done_Face(face);
76 error = FT_New_Memory_Face(lib, in_buf, in_len, 0, &face);
77 if (error)
78 goto Err;
80 /* check that font is TTF */
81 if (!FT_IS_SFNT(face))
83 error = FT_Err_Invalid_Argument;
84 goto Err;
87 error = FT_Sfnt_Table_Info(face, 0, NULL, &num_table_infos);
88 if (error)
89 goto Err;
91 SFNT_Table_Infos =
92 (SFNT_Table*)calloc(1, num_table_infos * sizeof (SFNT_Table));
93 if (!SFNT_Table_Infos)
95 error = FT_Err_Out_Of_Memory;
96 goto Err;
99 /* collect SFNT table data */
100 glyf_idx = num_table_infos;
101 for (j = 0; j < num_table_infos; j++)
103 FT_ULong tag, len;
106 error = FT_Sfnt_Table_Info(face, j, &tag, &len);
107 if (error && error != FT_Err_Table_Missing)
108 goto Err;
110 if (!error)
112 if (tag == TTAG_glyf)
113 glyf_idx = j;
115 /* ignore tables which we are going to create by ourselves */
116 if (!(tag == TTAG_fpgm
117 || tag == TTAG_prep
118 || tag == TTAG_cvt))
120 SFNT_Table_Infos[j].tag = tag;
121 SFNT_Table_Infos[j].len = len;
126 /* no (non-empty) `glyf' table; this can't be a TTF with outlines */
127 if (glyf_idx == num_table_infos)
129 error = FT_Err_Invalid_Argument;
130 goto Err;
134 /*** split font into SFNT tables ***/
137 SFNT_Table* sti_p = SFNT_Table_Infos;
140 for (j = 0; j < num_table_infos; j++)
142 if (sti_p->len)
144 sti_p->buf = (FT_Byte*)malloc(sti_p->len);
145 if (!sti_p->buf)
147 error = FT_Err_Out_Of_Memory;
148 goto Err;
151 error = FT_Load_Sfnt_Table(face, sti_p->tag, 0,
152 sti_p->buf, &sti_p->len);
153 if (error)
154 goto Err;
156 sti_p++;
161 /* compute global hints */
162 /* construct `fpgm' table */
163 /* construct `prep' table */
164 /* construct `cvt ' table */
166 /* split `glyf' table */
167 /* handle all glyphs in a loop */
168 /* strip bytecode */
169 /* hint the glyph */
170 /* construct bytecode */
172 /* construct `glyf' table */
173 /* build font from SFNT tables */
174 /* write font from memory */
176 error = TA_Err_Ok;
178 Err:
179 /* in case of error it is expected that the unallocated pointers */
180 /* are NULL (and counters are zero) */
181 if (SFNT_Table_Infos)
183 for (j = 0; j < num_table_infos; j++)
184 free(SFNT_Table_Infos[j].buf);
185 free(SFNT_Table_Infos);
187 FT_Done_Face(face);
188 FT_Done_FreeType(lib);
189 free(in_buf);
191 return error;
194 /* end of ttfautohint.c */