1 /*____________________________________________________________________________
2
3 Copyright 2000-2016 Adobe Systems Incorporated. All Rights Reserved.
4
5 Licensed under the Apache License, Version 2.0 (the "License");
6 you may not use these files except in compliance with the License.
7 You may obtain a copy of the License at
8
9 http://www.apache.org/licenses/LICENSE-2.0
10
11 Unless required by applicable law or agreed to in writing, software
12 distributed under the License is distributed on an "AS IS" BASIS,
13 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 See the License for the specific language governing permissions and
15 limitations under the License.
16 ____________________________________________________________________________*/
17
18 #include "stdlib.h"
19 #include "stdio.h"
20 #include "string.h"
21 #include "hb.h"
22 #include "hb-ot.h"
23
24 static const bool verbose = true;
25
26
27 hb_feature_t *gFeatures;
28 int gNbFeatures;
29
runTest(const char * testName,const char * fontfileName,unsigned int * in,int nbIn,unsigned int * select,int nbSelect)30 hb_buffer_t *runTest(const char *testName,
31 const char *fontfileName,
32 unsigned int *in, int nbIn,
33 unsigned int *select, int nbSelect)
34 {
35 FILE *f = fopen (fontfileName, "rb");
36 fseek(f, 0, SEEK_END);
37 long fontsize = ftell(f);
38 fseek(f, 0, SEEK_SET);
39 char *fontdata = (char *)malloc (fontsize);
40 fread(fontdata, fontsize, 1, f);
41 fclose(f);
42
43 if (verbose) {
44 printf ("------------------------------- %s\n", testName);
45 }
46
47 // setup font
48 hb_blob_t *blob = hb_blob_create(fontdata, fontsize,
49 HB_MEMORY_MODE_WRITABLE,
50 0, 0);
51 hb_face_t *face = hb_face_create(blob, 0);
52 hb_font_t *font = hb_font_create(face);
53 unsigned int upem = hb_face_get_upem (face);
54
55 hb_font_set_scale(font, upem, upem);
56 hb_ot_font_set_funcs (font);
57
58 // setup buffer
59 hb_buffer_t *buffer = hb_buffer_create();
60 hb_buffer_set_direction(buffer, HB_DIRECTION_LTR);
61 hb_buffer_set_script(buffer, HB_SCRIPT_LATIN);
62 hb_buffer_set_language(buffer, hb_language_from_string("en", 2));
63
64 hb_buffer_add_utf32(buffer, in, nbIn, 0, nbIn);
65
66 // setup features
67 hb_feature_t *features;
68 int nbFeatures;
69
70 if (nbSelect == 0)
71 {
72 nbFeatures = 1;
73
74 features = (hb_feature_t *) malloc (sizeof (*features));
75 features[0].tag = HB_TAG('t', 'e', 's', 't');
76 features[0].value = 1;
77 features[0].start = 0;
78 features[0].end = 0xffffffff;
79 }
80 else
81 {
82 nbFeatures = 0;
83
84 features = (hb_feature_t *) malloc (sizeof (*features) * nbSelect);
85 for (int i = 0; i < nbSelect; i++) {
86 if (select[i] != -1) {
87 features[nbFeatures].tag = HB_TAG('t', 'e', 's', 't');
88 features[nbFeatures].value = select[i];
89 features[nbFeatures].start = i;
90 features[nbFeatures].end = i + 1;
91 nbFeatures++;
92 }
93 }
94 }
95 gFeatures = features;
96 gNbFeatures = nbFeatures;
97
98 // shape
99 hb_shape(font, buffer, features, nbFeatures);
100
101 hb_blob_destroy(blob);
102 hb_font_destroy(font);
103 hb_face_destroy(face);
104 //free(features);
105
106 return buffer;
107 }
108
109
printArray(const char * s,int * a,int n)110 void printArray (const char* s, int *a, int n)
111 {
112 printf ("%s %d : ", s, n);
113 for (int i = 0; i < n; i++) {
114 printf (" %d", a[i]);
115 }
116 printf ("\n");
117 }
118
printUArray(const char * s,unsigned int * a,int n)119 void printUArray (const char* s, unsigned int *a, int n)
120 {
121 printArray (s, (int *) a, n);
122 }
123
gsub_test(const char * testName,const char * fontfileName,int nbIn,unsigned int * in,int nbSelect,unsigned int * select,int nbExpected,unsigned int * expected)124 bool gsub_test(const char *testName,
125 const char *fontfileName,
126 int nbIn, unsigned int *in,
127 int nbSelect, unsigned int *select,
128 int nbExpected, unsigned int *expected)
129 {
130 hb_buffer_t *buffer = runTest(testName,
131 fontfileName,
132 in, nbIn,
133 select, nbSelect);
134
135 // verify
136 hb_glyph_info_t *actual = hb_buffer_get_glyph_infos(buffer, 0);
137 unsigned int nbActual = hb_buffer_get_length(buffer);
138
139 bool ok = true;
140
141 if (nbActual != nbExpected)
142 ok = false;
143 else {
144 for (int i = 0; i < nbActual; i++) {
145 if (actual[i].codepoint != expected [i]) {
146 ok = false;
147 break;
148 }
149 }
150 }
151
152
153 char test_name[255];
154 sprintf (test_name, "../../tests/%.*s.tests", (int) (strrchr (testName, '_') - testName), testName);
155 FILE *tests_file = fopen (test_name, "a+");
156 if (!ok) fprintf (tests_file, "#");
157 fprintf (tests_file, "../fonts/%s:--features=\"", fontfileName + 9);
158 for (unsigned int i = 0; i < gNbFeatures; i++)
159 {
160 if (i != 0) fprintf (tests_file, ",");
161 char buf[255];
162 hb_feature_to_string (&gFeatures[i], buf, sizeof (buf));
163 fprintf (tests_file, "%s", buf);
164 }
165 free (gFeatures);
166 fprintf (tests_file, "\" --no-clusters --no-glyph-names --no-positions:");
167
168 for (unsigned int i = 0; i < nbIn; i++)
169 {
170 if (i != 0) fprintf (tests_file, ",");
171 fprintf (tests_file, "U+%04X", in[i]);
172 }
173
174 fprintf (tests_file, ":[");
175 for (unsigned int i = 0; i < nbActual; i++)
176 {
177 if (i != 0) fprintf (tests_file, "|");
178 fprintf (tests_file, "%d", expected[i]);
179 }
180 fprintf (tests_file, "]");
181
182 fprintf (tests_file, "\n");
183 fclose (tests_file);
184
185
186 if (! ok) {
187 printf ("******* GSUB %s\n", testName);
188
189 printf ("expected %d:", nbExpected);
190 for (int i = 0; i < nbExpected; i++) {
191 printf (" %d", expected[i]); }
192 printf ("\n");
193
194 printf (" actual %d:", nbActual);
195 for (int i = 0; i < nbActual; i++) {
196 printf (" %d", actual[i].codepoint); }
197 printf ("\n");
198
199 }
200
201 hb_buffer_destroy(buffer);
202
203 return ok;
204 }
205
gpos_test(const char * testName,const char * fontfileName,int nbIn,unsigned int * in,int nbOut,unsigned int * out,int * x,int * y)206 bool gpos_test(const char *testName,
207 const char *fontfileName,
208 int nbIn,
209 unsigned int *in,
210 int nbOut,
211 unsigned int *out,
212 int *x,
213 int *y)
214 {
215 hb_buffer_t *buffer = runTest(testName,
216 fontfileName,
217 in, nbIn,
218 0, 0);
219
220 // verify
221 unsigned int nbActual;
222 hb_glyph_info_t *actual = hb_buffer_get_glyph_infos(buffer, &nbActual);
223 hb_glyph_position_t *pos = hb_buffer_get_glyph_positions (buffer, NULL);
224
225 unsigned int *actualG = (unsigned int *) malloc(sizeof(*actualG) * nbActual);
226 int *actualX = (int *) malloc(sizeof(*actualX) * nbActual);
227 int *actualY = (int *) malloc(sizeof(*actualY) * nbActual);
228 int curX = 0;
229 int curY = 0;
230 for (int i = 0; i < nbActual; i++) {
231 actualG[i] = actual[i].codepoint;
232 actualX[i] = curX + pos[i].x_offset;
233 actualY[i] = curY + pos[i].y_offset;
234
235 actualX[i] -= 1500 * i;
236
237 curX += pos[i].x_advance;
238 curY += pos[i].y_advance;
239 }
240
241 bool nbOk = true;
242 bool xOk = true;
243 bool yOk = true;
244
245 if (nbActual != nbOut)
246 nbOk = false;
247 else {
248 for (int i = 0; i < nbActual; i++) {
249 if (actualX[i] != x[i]) {
250 xOk = false;
251 }
252 if (actualY[i] != y[i]) {
253 yOk = false;
254 }
255 }
256 }
257
258 bool ok = (nbOk && xOk && yOk);
259 if (! ok) {
260 printf ("******* GPOS %s\n", testName);
261
262 if (! (nbOk && xOk)) {
263 printArray ("expectedX", x, nbOut);
264 printArray ("actualX ", actualX, nbActual);
265
266 printf ("xadv/pos:");
267 for (int i = 0; i < nbOut; i++) {
268 printf (" %d/%d", pos[i].x_advance, pos[i].x_offset);
269 }
270 printf ("\n");
271 }
272
273 if (! (nbOk && yOk)) {
274 printArray ("expectedY", y, nbOut);
275 printArray ("actualY ", actualY, nbActual);
276
277 printf ("yadv/pos:");
278 for (int i = 0; i < nbOut; i++) {
279 printf (" %d/%d", pos[i].y_advance, pos[i].y_offset);
280 }
281 printf ("\n");
282 }
283 }
284
285
286 char test_name[255];
287 sprintf (test_name, "../../tests/%.*s.tests", (int) (strrchr (testName, '_') - testName), testName);
288 FILE *tests_file = fopen (test_name, "a+");
289 if (!ok) fprintf (tests_file, "#");
290 fprintf (tests_file, "../fonts/%s:--features=\"", fontfileName + 9);
291 for (unsigned int i = 0; i < gNbFeatures; i++)
292 {
293 if (i != 0) fprintf (tests_file, ",");
294 char buf[255];
295 hb_feature_to_string (&gFeatures[i], buf, sizeof (buf));
296 fprintf (tests_file, "%s", buf);
297 }
298 free (gFeatures);
299 fprintf (tests_file, "\" --no-clusters --no-glyph-names --ned:");
300
301 for (unsigned int i = 0; i < nbIn; i++)
302 {
303 if (i != 0) fprintf (tests_file, ",");
304 fprintf (tests_file, "U+%04X", in[i]);
305 }
306
307 fprintf (tests_file, ":[");
308 for (unsigned int i = 0; i < nbActual; i++)
309 {
310 if (i != 0) fprintf (tests_file, "|");
311 fprintf (tests_file, "%d", /*it should be "out[i]"*/ actualG[i]);
312
313 int expected_x = x[i] + 1500*i;
314 int expected_y = y[i];
315 if (expected_x || expected_y) fprintf (tests_file, "@%d,%d", expected_x, expected_y);
316 }
317 fprintf (tests_file, "]");
318
319 fprintf (tests_file, "\n");
320 fclose (tests_file);
321
322
323 hb_buffer_destroy(buffer);
324
325 free(actualG);
326 free(actualX);
327 free(actualY);
328
329 return ok;
330 }
331
332
main(int argc,char ** argv)333 int main(int argc, char **argv)
334 {
335 int failures = 0;
336 int pass = 0;
337
338 #include "hb-aots-tester.h"
339
340 printf ("%d failures, %d pass\n", failures, pass);
341 }
342
343
344
345