Rename variable.
[ttfautohint.git] / src / ttfautohint.c
bloba5f30cdaf8bdd248112ab4decbda99cf569fee2d
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;
32 FT_ULong num_tables = 0;
34 FT_Byte* in_buf;
35 size_t in_len;
37 SFNT_Table* SFNT_Tables = NULL;
38 FT_ULong glyf_idx;
40 FT_Error error;
42 FT_ULong i;
45 /*** load font into memory ***/
47 fseek(in, 0, SEEK_END);
48 in_len = ftell(in);
49 fseek(in, 0, SEEK_SET);
51 /* a TTF can never be that small */
52 if (in_len < 100)
53 return FT_Err_Invalid_Argument;
55 in_buf = (FT_Byte*)malloc(in_len);
56 if (!in_buf)
57 return FT_Err_Out_Of_Memory;
59 if (fread(in_buf, 1, in_len, in) != in_len)
61 error = FT_Err_Invalid_Stream_Read;
62 goto Err;
65 error = FT_Init_FreeType(&lib);
66 if (error)
67 goto Err;
69 error = FT_New_Memory_Face(lib, in_buf, in_len, -1, &face);
70 if (error)
71 goto Err;
72 num_faces = face->num_faces;
73 FT_Done_Face(face);
75 error = FT_New_Memory_Face(lib, in_buf, in_len, 0, &face);
76 if (error)
77 goto Err;
79 /* check that font is TTF */
80 if (!FT_IS_SFNT(face))
82 error = FT_Err_Invalid_Argument;
83 goto Err;
86 error = FT_Sfnt_Table_Info(face, 0, NULL, &num_tables);
87 if (error)
88 goto Err;
90 SFNT_Tables = (SFNT_Table*)calloc(1, num_tables * sizeof (SFNT_Table));
91 if (!SFNT_Tables)
93 error = FT_Err_Out_Of_Memory;
94 goto Err;
97 /* collect SFNT table data */
98 glyf_idx = num_tables;
99 for (i = 0; i < num_tables; i++)
101 FT_ULong tag, len;
104 error = FT_Sfnt_Table_Info(face, i, &tag, &len);
105 if (error && error != FT_Err_Table_Missing)
106 goto Err;
108 if (!error)
110 if (tag == TTAG_glyf)
111 glyf_idx = i;
113 /* ignore tables which we are going to create by ourselves */
114 if (!(tag == TTAG_fpgm
115 || tag == TTAG_prep
116 || tag == TTAG_cvt))
118 SFNT_Tables[i].tag = tag;
119 SFNT_Tables[i].len = len;
124 /* no (non-empty) `glyf' table; this can't be a TTF with outlines */
125 if (glyf_idx == num_tables)
127 error = FT_Err_Invalid_Argument;
128 goto Err;
132 /*** split font into SFNT tables ***/
135 SFNT_Table* stp = SFNT_Tables;
138 for (i = 0; i < num_tables; i++)
140 if (stp->len)
142 stp->buf = (FT_Byte*)malloc(stp->len);
143 if (!stp->buf)
145 error = FT_Err_Out_Of_Memory;
146 goto Err;
149 error = FT_Load_Sfnt_Table(face, stp->tag, 0, stp->buf, &stp->len);
150 if (error)
151 goto Err;
153 stp++;
158 /* compute global hints */
159 /* construct `fpgm' table */
160 /* construct `prep' table */
161 /* construct `cvt ' table */
163 /* split `glyf' table */
164 /* handle all glyphs in a loop */
165 /* strip bytecode */
166 /* hint the glyph */
167 /* construct bytecode */
169 /* construct `glyf' table */
170 /* build font from SFNT tables */
171 /* write font from memory */
173 error = TA_Err_Ok;
175 Err:
176 /* in case of error it is expected that the unallocated pointers */
177 /* are NULL (and counters are zero) */
178 for (i = 0; i < num_tables; i++)
179 free(SFNT_Tables[i].buf);
180 free(SFNT_Tables);
181 FT_Done_Face(face);
182 FT_Done_FreeType(lib);
183 free(in_buf);
185 return error;
188 /* end of ttfautohint.c */