• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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