* description.
*/
-#ifdef HAVE_FREETYPE
#include <hb-ft.h>
-#endif
typedef struct
{
/* TODO add min/max face version */
} font_data_t;
+static char *
+get_font_file (const font_data_t *font_data)
+{
+ return g_strdup_printf ("%s/fonts/%s", srcdir (), font_data->font_file);
+}
+
+
typedef struct
{
char comments[64];
typedef struct
{
const font_data_t font_data;
- const test_data_t tests[];
+ const test_data_t test_datas[];
} test_set_t;
typedef struct
{
- const font_data_t font_data;
- const test_data_t tests[];
+ const font_data_t *font_data;
+ const test_data_t *test_data;
} test_t;
-#if 0
-static bool decomposedShaping(FT_Face face, HB_Script script, const QChar &ch)
-{
- QString uc = QString().append(ch);
- Shaper shaper(face, script, uc);
-
- uc = uc.normalized(QString::NormalizationForm_D);
- Shaper decomposed(face, script, uc);
-
- if( shaper.shaper_item.num_glyphs != decomposed.shaper_item.num_glyphs )
- goto error;
-
- for (unsigned int i = 0; i < shaper.shaper_item.num_glyphs; ++i) {
- if ((shaper.shaper_item.glyphs[i]&0xffffff) != (decomposed.shaper_item.glyphs[i]&0xffffff))
- goto error;
- }
- return true;
- error:
- QString str = "";
- int i = 0;
- while (i < uc.length()) {
- str += QString("%1 ").arg(uc[i].unicode(), 4, 16);
- ++i;
- }
- qDebug("%s: decomposedShaping of char %4x failed\n decomposedString: %s\n nglyphs=%d, decomposed nglyphs %d",
- face->family_name,
- ch.unicode(), str.toLatin1().data(),
- shaper.shaper_item.num_glyphs,
- decomposed.shaper_item.num_glyphs);
-
- str = "";
- i = 0;
- while (i < shaper.shaper_item.num_glyphs) {
- str += QString("%1 ").arg(shaper.shaper_item.glyphs[i], 4, 16);
- ++i;
- }
- qDebug(" composed glyph result = %s", str.toLatin1().constData());
- str = "";
- i = 0;
- while (i < decomposed.shaper_item.num_glyphs) {
- str += QString("%1 ").arg(decomposed.shaper_item.glyphs[i], 4, 16);
- ++i;
- }
- qDebug(" decomposed glyph result = %s", str.toLatin1().constData());
- return false;
-}
-struct shape_test_t {
- unsigned short unicode[16];
- unsigned short glyphs[16];
-};
-
-void tst_QScriptEngine::greek()
-{
- "DejaVuSans.ttf",
- if (face) {
- for (int uc = 0x1f00; uc <= 0x1fff; ++uc) {
- QString str;
- str.append(uc);
- if (str.normalized(QString::NormalizationForm_D).normalized(QString::NormalizationForm_C) != str) {
- /* qDebug() << "skipping" << hex << uc; */
- continue;
- }
- if (uc == 0x1fc1 || uc == 0x1fed)
- continue;
- QVERIFY( decomposedShaping(face, HB_Script_Greek, QChar(uc)) );
- }
- FT_Done_Face(face);
- } else {
- QSKIP("couln't find DejaVu Sans", SkipAll);
- }
-
-
- face = loadFace("SBL_grk.ttf");
- if (face) {
- for (int uc = 0x1f00; uc <= 0x1fff; ++uc) {
- QString str;
- str.append(uc);
- if (str.normalized(QString::NormalizationForm_D).normalized(QString::NormalizationForm_C) != str) {
- /* qDebug() << "skipping" << hex << uc; */
- continue;
- }
- if (uc == 0x1fc1 || uc == 0x1fed)
- continue;
- QVERIFY( decomposedShaping(face, HB_Script_Greek, QChar(uc)) );
-
- }
-
- };
-}
-#endif
-
-static const test_set_t tests_greek = {
- {"DejaVuSans.ttf", 0},
- {
- { "",
- { 0x3b1, 0x300, 0x313, 0 },
- { 0xb8, 0x3d3, 0x3c7, 0 }
- },
- { "",
- { 0x3b1, 0x313, 0x300, 0 },
- { 0xd4, 0 }
- },
- {{0}}
- }
-};
-
-static const test_set_t tests_devanagari_1 = {
+static const test_set_t tests_devanagari1 = {
{"raghu.ttf", 0},
{
{ "Ka",
}
};
-static const test_set_t tests_devanagari_2 = {
+static const test_set_t tests_devanagari2 = {
{"mangal.ttf", 0},
{
{ "Ka",
}
};
-static const test_set_t tests_bengali_1 = {
+static const test_set_t tests_bengali1 = {
{"AkaashNormal.ttf", 0},
{
{ "Ka",
}
};
-static const test_set_t tests_bengali_2 = {
+static const test_set_t tests_bengali2 = {
{"MuktiNarrow.ttf", 0},
{
{ "Ka",
}
};
-static const test_set_t tests_bengali_3 = {
+static const test_set_t tests_bengali3 = {
{"LikhanNormal.ttf", 0},
{
{ "",
}
};
-static const test_set_t tests_kannada_1 = {
+static const test_set_t tests_kannada1 = {
{"Sampige.ttf", 0},
{
{ "",
}
};
-static const test_set_t tests_kannada_2 = {
+static const test_set_t tests_kannada2 = {
{"tunga.ttf", 0},
{
{ "",
}
};
-static const test_set_t tests_malayalam_1 = {
+static const test_set_t tests_malayalam1 = {
{"AkrutiMal2Normal.ttf", 0},
{
{ "",
}
};
-static const test_set_t tests_malayalam_2 = {
+static const test_set_t tests_malayalam2 = {
{"Rachana.ttf", 0},
{
{ "",
},
{ "",
{ 0x7ca, 0x7ca, 0 },
- { 0x14db, 0x14d9, 0 }
+ { 0x14d9, 0x14db, 0 }
},
{ "",
{ 0x7ca, 0x7fa, 0x7ca, 0 },
- { 0x14db, 0x5ec, 0x14d9, 0 }
+ { 0x14d9, 0x5ec, 0x14db, 0 }
},
{ "",
{ 0x7ca, 0x7f3, 0x7ca, 0 },
- { 0x14db, 0x5e7, 0x14d9, 0 }
+ { 0x14d9, 0x5e7, 0x14db, 0 }
},
{ "",
{ 0x7ca, 0x7f3, 0x7fa, 0x7ca, 0 },
- { 0x14db, 0x5e7, 0x5ec, 0x14d9, 0 }
+ { 0x14d9, 0x5ec, 0x5e7, 0x14db, 0 }
},
{{0}}
}
+
+
typedef struct {
FT_Library ft_library;
FT_Face ft_face;
static void
ft_fixture_init (ft_fixture_t *f, gconstpointer user_data)
{
- const test_set_t *test = user_data;
- char *font_file = g_strdup_printf ("%s/fonts/%s", srcdir (), test->font_data.font_file);
+ const test_t *test = user_data;
+ char *font_file = get_font_file (test->font_data);
+ FT_Error err;
FT_Init_FreeType (&f->ft_library);
- if (FT_New_Face (f->ft_library, font_file, test->font_data.face_index, &f->ft_face))
- g_test_message ("Font file %s not found. Skipping test.", font_file);
- else
- f->font = hb_ft_font_create (f->ft_face, NULL);
+ err = FT_New_Face (f->ft_library, font_file, test->font_data->face_index, &f->ft_face);
+ g_assert_cmpint (err, ==, 0);
+
+ f->font = hb_ft_font_create (f->ft_face, NULL);
g_free (font_file);
}
static void
test_shape_complex (ft_fixture_t *f, gconstpointer user_data)
{
- const test_set_t *test_set = user_data;
- const test_data_t *data;
-
- if (!f->font)
- return; /* Skip test */
+ const test_t *test = user_data;
+ const test_data_t *data = test->test_data;
+ hb_buffer_t *buffer;
+ unsigned int i, len, expected_len;
+ hb_glyph_info_t *glyphs;
+ hb_bool_t fail;
- for (data = test_set->tests; data->characters[0]; data++) {
- hb_buffer_t *buffer;
- unsigned int i, len, expected_len;
- hb_glyph_info_t *glyphs;
+ g_assert (f->font);
- if (data->comments[0])
- g_test_message ("Test comments: %s", data->comments);
+ if (data->comments[0])
+ g_test_message ("Test comments: %s", data->comments);
- buffer = hb_buffer_create (0);
- for (len = 0; data->characters[len]; len++) ;
- hb_buffer_add_utf32 (buffer, data->characters, len, 0, len);
+ buffer = hb_buffer_create (0);
+ for (len = 0; data->characters[len]; len++) ;
+ hb_buffer_add_utf32 (buffer, data->characters, len, 0, len);
- hb_shape (f->font, buffer, NULL, 0);
+ hb_shape (f->font, buffer, NULL, 0);
- for (len = 0; data->glyphs[len]; len++) ;
- expected_len = len;
+ for (len = 0; data->glyphs[len]; len++) ;
+ expected_len = len;
- glyphs = hb_buffer_get_glyph_infos (buffer, &len);
- g_assert_cmpint (len, ==, expected_len);
+ glyphs = hb_buffer_get_glyph_infos (buffer, &len);
+ fail = len != expected_len;
+ if (!fail)
+ for (i = 0; i < len; i++)
+ if (glyphs[i].codepoint != data->glyphs[i]) {
+ fail = TRUE;
+ break;
+ }
+
+ if (fail) {
+ GString *str = g_string_new ("");
+ for (i = 0; i < expected_len; i++)
+ g_string_append_printf (str, " %4d", data->glyphs[i]);
+ g_test_message ("Expected glyphs: %s", str->str);
+ g_string_truncate (str, 0);
for (i = 0; i < len; i++)
- g_assert_cmphex (glyphs[i].codepoint, ==, data->glyphs[i]);
+ g_string_append_printf (str, " %4d", glyphs[i].codepoint);
+ g_test_message ("Received glyphs: %s", str->str);
+ g_string_free (str, TRUE);
+
+ g_test_message ("FAIL");
+ /* The glib test framework is useless, lets not fail for now,
+ * we can grep for FAIL/PASS and count manually. Sigh... */
+ /*g_test_fail ();*/
+ } else
+ g_test_message ("PASS");
+
+ hb_buffer_destroy (buffer);
+}
- hb_buffer_destroy (buffer);
- }
+static void
+test_shape_complex_skipped (gconstpointer user_data)
+{
+ const test_t *test = user_data;
+ const test_data_t *data = test->test_data;
+
+ if (data->comments[0])
+ g_test_message ("Test comments: %s", data->comments);
+
+ g_test_message ("Skipping test");
}
+static void
+add_test_set (const test_set_t *test_set, const char *set_name)
+{
+ const test_data_t *data;
+ char *font_file;
+ hb_bool_t skip;
+
+ font_file = get_font_file (&test_set->font_data);
+ skip = !g_file_test (font_file, G_FILE_TEST_EXISTS);
+ g_free (font_file);
+
+ for (data = test_set->test_datas; data->characters[0]; data++) {
+ char *flavor;
+ GString *str;
+ const hb_codepoint_t *p;
+
+ test_t *test = g_slice_new0 (test_t);
+ test->font_data = &test_set->font_data;
+ test->test_data = data;
+
+ str = g_string_new ("<");
+ for (p = data->characters; *p; p++)
+ g_string_append_printf (str, "%04X,", *p);
+ str->str[str->len - 1] = '>';
+
+ flavor = g_strdup_printf ("%s/%s/%ld:%s", set_name, test_set->font_data.font_file, data - test_set->test_datas, str->str);
+
+ g_string_free (str, TRUE);
+
+ if (skip)
+ hb_test_add_data_flavor ((const void *) test, flavor, test_shape_complex_skipped);
+ else
+ hb_test_add_fixture_flavor (ft_fixture, (const void *) test, flavor, test_shape_complex);
+
+ g_free (flavor);
+ }
+}
int
{
hb_test_init (&argc, &argv);
-#define TEST_SET(name) hb_test_add_fixture_flavor (ft_fixture, (const void *) &tests_##name, #name, test_shape_complex)
-
- TEST_SET (greek);
+#define TEST_SET(name) add_test_set (&tests_##name, #name)
- TEST_SET (devanagari_1);
- TEST_SET (devanagari_2);
- TEST_SET (bengali_1);
- TEST_SET (bengali_2);
- TEST_SET (bengali_3);
+ TEST_SET (devanagari1);
+ TEST_SET (devanagari2);
+ TEST_SET (bengali1);
+ TEST_SET (bengali2);
+ TEST_SET (bengali3);
TEST_SET (gurmukhi);
TEST_SET (oriya);
TEST_SET (tamil);
TEST_SET (telugu);
- TEST_SET (kannada_1);
- TEST_SET (kannada_2);
- TEST_SET (malayalam_1);
- TEST_SET (malayalam_2);
+ TEST_SET (kannada1);
+ TEST_SET (kannada2);
+ TEST_SET (malayalam1);
+ TEST_SET (malayalam2);
TEST_SET (sinhala);
TEST_SET (khmer);