| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437 |
- /*____________________________________________________________________________
- Copyright 2000-2016 Adobe Systems Incorporated. All Rights Reserved.
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use these files except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- ____________________________________________________________________________*/
- #include "stdlib.h"
- #include "stdio.h"
- #include "string.h"
- #include "hb.h"
- #include "hb-ot.h"
- static const bool verbose = true;
- struct TestData
- {
- TestData(hb_buffer_t *buffer_,
- hb_face_t *face_,
- hb_font_t *font_,
- hb_feature_t *features_,
- int num_features_)
- : buffer(buffer_), face(face_), font(font_),
- features(features_), num_features(num_features_)
- { }
- ~TestData()
- {
- free (features);
- hb_face_destroy (face);
- hb_font_destroy (font);
- hb_buffer_destroy (buffer);
- }
- hb_buffer_t *buffer;
- hb_face_t *face;
- hb_font_t *font;
- hb_feature_t *features;
- int num_features;
- };
- TestData
- runTest(const char *testName,
- const char *fontfileName,
- unsigned int *in, int nbIn,
- unsigned int *select, int nbSelect)
- {
- FILE *f = fopen (fontfileName, "rb");
- fseek(f, 0, SEEK_END);
- long fontsize = ftell(f);
- fseek(f, 0, SEEK_SET);
- char *fontdata = (char *)malloc (fontsize);
- fread(fontdata, fontsize, 1, f);
- fclose(f);
- if (verbose) {
- printf ("------------------------------- %s\n", testName);
- }
- // setup font
- hb_blob_t *blob = hb_blob_create(fontdata, fontsize,
- HB_MEMORY_MODE_WRITABLE,
- 0, 0);
- hb_face_t *face = hb_face_create(blob, 0);
- hb_font_t *font = hb_font_create(face);
- unsigned int upem = hb_face_get_upem (face);
- hb_font_set_scale(font, upem, upem);
- hb_ot_font_set_funcs (font);
- // setup buffer
- hb_buffer_t *buffer = hb_buffer_create();
- hb_buffer_set_direction(buffer, HB_DIRECTION_LTR);
- hb_buffer_set_script(buffer, HB_SCRIPT_LATIN);
- hb_buffer_set_language(buffer, hb_language_from_string("en", 2));
- hb_buffer_add_utf32(buffer, in, nbIn, 0, nbIn);
- // setup features
- hb_feature_t *features;
- int nbFeatures;
- if (nbSelect == 0)
- {
- nbFeatures = 1;
- features = (hb_feature_t *) malloc (sizeof (*features));
- features[0].tag = HB_TAG('t', 'e', 's', 't');
- features[0].value = 1;
- features[0].start = HB_FEATURE_GLOBAL_START;
- features[0].end = HB_FEATURE_GLOBAL_END;
- }
- else
- {
- nbFeatures = 0;
- features = (hb_feature_t *) malloc (sizeof (*features) * nbSelect);
- for (int i = 0; i < nbSelect; i++) {
- if (select[i] != -1) {
- features[nbFeatures].tag = HB_TAG('t', 'e', 's', 't');
- features[nbFeatures].value = select[i];
- features[nbFeatures].start = i;
- features[nbFeatures].end = i + 1;
- nbFeatures++;
- }
- }
- }
- // shape
- hb_shape(font, buffer, features, nbFeatures);
- hb_blob_destroy(blob);
- return TestData(buffer, face, font, features, nbFeatures);
- }
- void printArray (const char* s, int *a, int n)
- {
- printf ("%s %d : ", s, n);
- for (int i = 0; i < n; i++) {
- printf (" %d", a[i]);
- }
- printf ("\n");
- }
- void printUArray (const char* s, unsigned int *a, int n)
- {
- printArray (s, (int *) a, n);
- }
- bool gsub_test(const char *testName,
- const char *fontfileName,
- int nbIn, unsigned int *in,
- int nbSelect, unsigned int *select,
- int nbExpected, unsigned int *expected)
- {
- TestData data = runTest(testName,
- fontfileName,
- in, nbIn,
- select, nbSelect);
- // verify
- hb_glyph_info_t *actual = hb_buffer_get_glyph_infos(data.buffer, 0);
- unsigned int nbActual = hb_buffer_get_length(data.buffer);
- bool ok = true;
- if (nbActual != nbExpected)
- ok = false;
- else {
- for (int i = 0; i < nbActual; i++) {
- if (actual[i].codepoint != expected [i]) {
- ok = false;
- break;
- }
- }
- }
- char test_name[255];
- sprintf (test_name, "../../tests/%.*s.tests", (int) (strrchr (testName, '_') - testName), testName);
- FILE *tests_file = fopen (test_name, "a+");
- if (!ok) fprintf (tests_file, "#");
- fprintf (tests_file, "../fonts/%s;--features=\"", fontfileName + 9);
- for (unsigned int i = 0; i < data.num_features; i++)
- {
- if (i != 0) fprintf (tests_file, ",");
- char buf[255];
- hb_feature_to_string (&data.features[i], buf, sizeof (buf));
- fprintf (tests_file, "%s", buf);
- }
- fprintf (tests_file, "\" --single-par --no-clusters --no-glyph-names --no-positions;");
- for (unsigned int i = 0; i < nbIn; i++)
- {
- if (i != 0) fprintf (tests_file, ",");
- fprintf (tests_file, "U+%04X", in[i]);
- }
- fprintf (tests_file, ";[");
- for (unsigned int i = 0; i < nbActual; i++)
- {
- if (i != 0) fprintf (tests_file, "|");
- fprintf (tests_file, "%d", expected[i]);
- }
- fprintf (tests_file, "]");
- fprintf (tests_file, "\n");
- fclose (tests_file);
- if (! ok) {
- printf ("******* GSUB %s\n", testName);
- printf ("expected %d:", nbExpected);
- for (int i = 0; i < nbExpected; i++) {
- printf (" %d", expected[i]); }
- printf ("\n");
- printf (" actual %d:", nbActual);
- for (int i = 0; i < nbActual; i++) {
- printf (" %d", actual[i].codepoint); }
- printf ("\n");
- }
- return ok;
- }
- bool cmap_test(const char *testName,
- const char *fontfileName,
- int nbIn, unsigned int *in,
- int nbSelect, unsigned int *select,
- int nbExpected, unsigned int *expected)
- {
- TestData data = runTest(testName,
- fontfileName,
- in, nbIn,
- select, nbSelect);
- // verify
- hb_glyph_info_t *actual = hb_buffer_get_glyph_infos(data.buffer, 0);
- unsigned int nbActual = hb_buffer_get_length(data.buffer);
- bool ok = true;
- if (nbActual != nbExpected)
- ok = false;
- else {
- for (int i = 0; i < nbActual; i++) {
- if (actual[i].codepoint != expected [i]) {
- ok = false;
- break;
- }
- }
- }
- char test_name[255];
- sprintf (test_name, "../../tests/%.*s.tests", (int) (strrchr (testName, '_') - testName), testName);
- FILE *tests_file = fopen (test_name, "a+");
- if (!ok) fprintf (tests_file, "#");
- fprintf (tests_file, "../fonts/%s;--features=\"", fontfileName + 9);
- for (unsigned int i = 0; i < data.num_features; i++)
- {
- if (i != 0) fprintf (tests_file, ",");
- char buf[255];
- hb_feature_to_string (&data.features[i], buf, sizeof (buf));
- fprintf (tests_file, "%s", buf);
- }
- fprintf (tests_file, "\" --single-par --no-clusters --no-glyph-names --no-positions --font-funcs=ot;");
- for (unsigned int i = 0; i < nbIn; i++)
- {
- if (i != 0) fprintf (tests_file, ",");
- fprintf (tests_file, "U+%04X", in[i]);
- }
- fprintf (tests_file, ";[");
- for (unsigned int i = 0; i < nbActual; i++)
- {
- if (i != 0) fprintf (tests_file, "|");
- fprintf (tests_file, "%d", expected[i]);
- }
- fprintf (tests_file, "]");
- fprintf (tests_file, "\n");
- fclose (tests_file);
- if (! ok) {
- printf ("******* cmap %s\n", testName);
- printf ("expected %d:", nbExpected);
- for (int i = 0; i < nbExpected; i++) {
- printf (" %d", expected[i]); }
- printf ("\n");
- printf (" actual %d:", nbActual);
- for (int i = 0; i < nbActual; i++) {
- printf (" %d", actual[i].codepoint); }
- printf ("\n");
- }
- return ok;
- }
- bool gpos_test(const char *testName,
- const char *fontfileName,
- int nbIn,
- unsigned int *in,
- int nbOut,
- unsigned int *out,
- int *x,
- int *y)
- {
- TestData data = runTest(testName,
- fontfileName,
- in, nbIn,
- 0, 0);
- // verify
- unsigned int nbActual;
- hb_glyph_info_t *actual = hb_buffer_get_glyph_infos(data.buffer, &nbActual);
- hb_glyph_position_t *pos = hb_buffer_get_glyph_positions (data.buffer, NULL);
- unsigned int *actualG = (unsigned int *) malloc(sizeof(*actualG) * nbActual);
- int *actualX = (int *) malloc(sizeof(*actualX) * nbActual);
- int *actualY = (int *) malloc(sizeof(*actualY) * nbActual);
- int curX = 0;
- int curY = 0;
- for (int i = 0; i < nbActual; i++) {
- actualG[i] = actual[i].codepoint;
- actualX[i] = curX + pos[i].x_offset;
- actualY[i] = curY + pos[i].y_offset;
- curX += pos[i].x_advance;
- if (hb_ot_layout_get_glyph_class (data.face, actualG[i]) != HB_OT_LAYOUT_GLYPH_CLASS_MARK)
- curX -= 1500;
- curY += pos[i].y_advance;
- }
- bool nbOk = true;
- bool xOk = true;
- bool yOk = true;
- if (nbActual != nbOut)
- nbOk = false;
- else {
- for (int i = 0; i < nbActual; i++) {
- if (actualX[i] != x[i]) {
- xOk = false;
- }
- if (actualY[i] != y[i]) {
- yOk = false;
- }
- }
- }
- bool ok = (nbOk && xOk && yOk);
- if (! ok) {
- printf ("******* GPOS %s\n", testName);
- if (! (nbOk && xOk)) {
- printArray ("expectedX", x, nbOut);
- printArray ("actualX ", actualX, nbActual);
- printf ("xadv/pos:");
- for (int i = 0; i < nbOut; i++) {
- printf (" %d/%d", pos[i].x_advance, pos[i].x_offset);
- }
- printf ("\n");
- }
- if (! (nbOk && yOk)) {
- printArray ("expectedY", y, nbOut);
- printArray ("actualY ", actualY, nbActual);
- printf ("yadv/pos:");
- for (int i = 0; i < nbOut; i++) {
- printf (" %d/%d", pos[i].y_advance, pos[i].y_offset);
- }
- printf ("\n");
- }
- }
- char test_name[255];
- sprintf (test_name, "../../tests/%.*s.tests", (int) (strrchr (testName, '_') - testName), testName);
- FILE *tests_file = fopen (test_name, "a+");
- if (!ok) fprintf (tests_file, "#");
- fprintf (tests_file, "../fonts/%s;--features=\"", fontfileName + 9);
- for (unsigned int i = 0; i < data.num_features; i++)
- {
- if (i != 0) fprintf (tests_file, ",");
- char buf[255];
- hb_feature_to_string (&data.features[i], buf, sizeof (buf));
- fprintf (tests_file, "%s", buf);
- }
- fprintf (tests_file, "\" --single-par --no-clusters --no-glyph-names --ned;");
- for (unsigned int i = 0; i < nbIn; i++)
- {
- if (i != 0) fprintf (tests_file, ",");
- fprintf (tests_file, "U+%04X", in[i]);
- }
- fprintf (tests_file, ";[");
- int accumlatedAdvance = 0;
- for (unsigned int i = 0; i < nbActual; i++)
- {
- if (i != 0) fprintf (tests_file, "|");
- fprintf (tests_file, "%d", /*it should be "out[i]"*/ actualG[i]);
- int expected_x = x[i] + accumlatedAdvance;
- int expected_y = y[i];
- if (expected_x || expected_y) fprintf (tests_file, "@%d,%d", expected_x, expected_y);
- if (hb_ot_layout_get_glyph_class (data.face, actualG[i]) != HB_OT_LAYOUT_GLYPH_CLASS_MARK)
- accumlatedAdvance += 1500;
- }
- fprintf (tests_file, "]");
- fprintf (tests_file, "\n");
- fclose (tests_file);
- free(actualG);
- free(actualX);
- free(actualY);
- return ok;
- }
- int main(int argc, char **argv)
- {
- int failures = 0;
- int pass = 0;
- #include "hb-aots-tester.h"
- printf ("%d failures, %d pass\n", failures, pass);
- }
|