mirror of
https://github.com/harfbuzz/harfbuzz.git
synced 2025-04-18 11:13:49 +00:00
commit
a9e2c8f3aa
17 changed files with 506 additions and 439 deletions
|
@ -66,6 +66,8 @@ jobs:
|
|||
- run: apt update || true
|
||||
- run: DEBIAN_FRONTEND=noninteractive apt install -y python3 python3-pip python3-venv ninja-build clang lld git binutils pkg-config ragel libfreetype6-dev libglib2.0-dev libcairo2-dev libicu-dev libgraphite2-dev
|
||||
- run: |
|
||||
export ASAN_OPTIONS=log_path=stderr:halt_on_error=1:abort_on_error=1
|
||||
export UBSAN_OPTIONS=log_path=stderr:halt_on_error=1:abort_on_error=1:print_stacktrace=1
|
||||
python3 -m venv venv
|
||||
source venv/bin/activate
|
||||
pip3 install meson==0.60.0
|
||||
|
@ -81,6 +83,7 @@ jobs:
|
|||
- run: apt update || true
|
||||
- run: DEBIAN_FRONTEND=noninteractive apt install -y python3 python3-pip python3-venv ninja-build clang lld git binutils pkg-config ragel libfreetype6-dev libglib2.0-dev libcairo2-dev libicu-dev libgraphite2-dev
|
||||
- run: |
|
||||
export TSAN_OPTIONS=log_path=stderr:halt_on_error=1:abort_on_error=1
|
||||
python3 -m venv venv
|
||||
source venv/bin/activate
|
||||
pip3 install meson==0.60.0
|
||||
|
@ -96,6 +99,7 @@ jobs:
|
|||
- run: apt update || true
|
||||
- run: DEBIAN_FRONTEND=noninteractive apt install -y python3 python3-pip python3-venv ninja-build clang lld git binutils pkg-config ragel libfreetype6-dev libglib2.0-dev libcairo2-dev libicu-dev libgraphite2-dev
|
||||
- run: |
|
||||
export MSAN_OPTIONS=log_path=stderr:halt_on_error=1:abort_on_error=1:print_stacktrace=1
|
||||
python3 -m venv venv
|
||||
source venv/bin/activate
|
||||
pip3 install meson==0.60.0
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
#include "hb.hh"
|
||||
|
||||
|
||||
#line 36 "hb-buffer-deserialize-json.hh"
|
||||
#line 33 "hb-buffer-deserialize-json.hh"
|
||||
static const unsigned char _deserialize_json_trans_keys[] = {
|
||||
0u, 0u, 9u, 34u, 97u, 121u, 120u, 121u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u,
|
||||
9u, 125u, 9u, 125u, 9u, 93u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u,
|
||||
|
@ -597,12 +597,12 @@ _hb_buffer_deserialize_json (hb_buffer_t *buffer,
|
|||
hb_glyph_info_t info = {0};
|
||||
hb_glyph_position_t pos = {0};
|
||||
|
||||
#line 601 "hb-buffer-deserialize-json.hh"
|
||||
#line 594 "hb-buffer-deserialize-json.hh"
|
||||
{
|
||||
cs = deserialize_json_start;
|
||||
}
|
||||
|
||||
#line 606 "hb-buffer-deserialize-json.hh"
|
||||
#line 597 "hb-buffer-deserialize-json.hh"
|
||||
{
|
||||
int _slen;
|
||||
int _trans;
|
||||
|
@ -712,7 +712,7 @@ _resume:
|
|||
#line 56 "hb-buffer-deserialize-json.rl"
|
||||
{ if (unlikely (!buffer->ensure_unicode ())) return false; }
|
||||
break;
|
||||
#line 716 "hb-buffer-deserialize-json.hh"
|
||||
#line 689 "hb-buffer-deserialize-json.hh"
|
||||
}
|
||||
|
||||
_again:
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
#include "hb.hh"
|
||||
|
||||
|
||||
#line 36 "hb-buffer-deserialize-text-glyphs.hh"
|
||||
#line 33 "hb-buffer-deserialize-text-glyphs.hh"
|
||||
static const unsigned char _deserialize_text_glyphs_trans_keys[] = {
|
||||
0u, 0u, 35u, 124u, 48u, 57u, 60u, 124u, 45u, 57u, 48u, 57u, 44u, 44u, 45u, 57u,
|
||||
48u, 57u, 44u, 44u, 45u, 57u, 48u, 57u, 44u, 44u, 45u, 57u, 48u, 57u, 62u, 62u,
|
||||
|
@ -389,12 +389,12 @@ _hb_buffer_deserialize_text_glyphs (hb_buffer_t *buffer,
|
|||
hb_glyph_info_t info = {0};
|
||||
hb_glyph_position_t pos = {0};
|
||||
|
||||
#line 393 "hb-buffer-deserialize-text-glyphs.hh"
|
||||
#line 386 "hb-buffer-deserialize-text-glyphs.hh"
|
||||
{
|
||||
cs = deserialize_text_glyphs_start;
|
||||
}
|
||||
|
||||
#line 398 "hb-buffer-deserialize-text-glyphs.hh"
|
||||
#line 389 "hb-buffer-deserialize-text-glyphs.hh"
|
||||
{
|
||||
int _slen;
|
||||
int _trans;
|
||||
|
@ -552,7 +552,7 @@ _resume:
|
|||
return false;
|
||||
}
|
||||
break;
|
||||
#line 556 "hb-buffer-deserialize-text-glyphs.hh"
|
||||
#line 523 "hb-buffer-deserialize-text-glyphs.hh"
|
||||
}
|
||||
|
||||
_again:
|
||||
|
@ -573,7 +573,7 @@ _again:
|
|||
*end_ptr = p;
|
||||
}
|
||||
break;
|
||||
#line 577 "hb-buffer-deserialize-text-glyphs.hh"
|
||||
#line 542 "hb-buffer-deserialize-text-glyphs.hh"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -672,7 +672,7 @@ hb_face_make_immutable (hb_face_t *face)
|
|||
* Since: 0.9.2
|
||||
**/
|
||||
hb_bool_t
|
||||
hb_face_is_immutable (const hb_face_t *face)
|
||||
hb_face_is_immutable (hb_face_t *face)
|
||||
{
|
||||
return hb_object_is_immutable (face);
|
||||
}
|
||||
|
|
|
@ -131,7 +131,7 @@ HB_EXTERN void
|
|||
hb_face_make_immutable (hb_face_t *face);
|
||||
|
||||
HB_EXTERN hb_bool_t
|
||||
hb_face_is_immutable (const hb_face_t *face);
|
||||
hb_face_is_immutable (hb_face_t *face);
|
||||
|
||||
|
||||
HB_EXTERN hb_blob_t *
|
||||
|
|
|
@ -134,7 +134,7 @@ typedef GTestFixtureFunc hb_test_fixture_func_t;
|
|||
#else
|
||||
typedef void (*hb_test_func_t) (void);
|
||||
typedef void (*hb_test_data_func_t) (gconstpointer user_data);
|
||||
typedef void (*hb_test_fixture_func_t) (void);
|
||||
typedef void (*hb_test_fixture_func_t) (gpointer fixture, gconstpointer user_data);
|
||||
#endif
|
||||
|
||||
#if !GLIB_CHECK_VERSION(2,30,0)
|
||||
|
@ -226,16 +226,7 @@ hb_test_add_vtable (const char *test_path,
|
|||
}
|
||||
#define hb_test_add_fixture(FixturePrefix, UserData, Func) \
|
||||
G_STMT_START { \
|
||||
typedef G_PASTE (FixturePrefix, _t) Fixture; \
|
||||
void (*add_vtable) (const char*, gsize, gconstpointer, \
|
||||
void (*) (Fixture*, gconstpointer), \
|
||||
void (*) (Fixture*, gconstpointer), \
|
||||
void (*) (Fixture*, gconstpointer)) \
|
||||
= (void (*) (const gchar *, gsize, gconstpointer, \
|
||||
void (*) (Fixture*, gconstpointer), \
|
||||
void (*) (Fixture*, gconstpointer), \
|
||||
void (*) (Fixture*, gconstpointer))) hb_test_add_vtable; \
|
||||
add_vtable (#Func, sizeof (G_PASTE (FixturePrefix, _t)), UserData, \
|
||||
hb_test_add_vtable (#Func, sizeof (G_PASTE (FixturePrefix, _t)), UserData, \
|
||||
G_PASTE (FixturePrefix, _init), Func, G_PASTE (FixturePrefix, _finish)); \
|
||||
} G_STMT_END
|
||||
|
||||
|
@ -254,16 +245,7 @@ hb_test_add_vtable_flavor (const char *test_path,
|
|||
}
|
||||
#define hb_test_add_fixture_flavor(FixturePrefix, UserData, Flavor, Func) \
|
||||
G_STMT_START { \
|
||||
typedef G_PASTE (FixturePrefix, _t) Fixture; \
|
||||
void (*add_vtable) (const char*, const char *, gsize, gconstpointer, \
|
||||
void (*) (Fixture*, gconstpointer), \
|
||||
void (*) (Fixture*, gconstpointer), \
|
||||
void (*) (Fixture*, gconstpointer)) \
|
||||
= (void (*) (const gchar *, const char *, gsize, gconstpointer, \
|
||||
void (*) (Fixture*, gconstpointer), \
|
||||
void (*) (Fixture*, gconstpointer), \
|
||||
void (*) (Fixture*, gconstpointer))) hb_test_add_vtable_flavor; \
|
||||
add_vtable (#Func, Flavor, sizeof (G_PASTE (FixturePrefix, _t)), UserData, \
|
||||
hb_test_add_vtable_flavor (#Func, Flavor, sizeof (G_PASTE (FixturePrefix, _t)), UserData, \
|
||||
G_PASTE (FixturePrefix, _init), Func, G_PASTE (FixturePrefix, _finish)); \
|
||||
} G_STMT_END
|
||||
|
||||
|
|
|
@ -98,15 +98,17 @@ typedef struct
|
|||
} fixture_t;
|
||||
|
||||
static void
|
||||
free_up (fixture_t *fixture)
|
||||
free_up (void *fixture_)
|
||||
{
|
||||
fixture_t *fixture = (fixture_t *) fixture_;
|
||||
g_assert_cmpint (fixture->freed, ==, 0);
|
||||
fixture->freed++;
|
||||
}
|
||||
|
||||
static void
|
||||
free_up_free (fixture_t *fixture)
|
||||
free_up_free (void *fixture_)
|
||||
{
|
||||
fixture_t *fixture = (fixture_t *) fixture_;
|
||||
free_up (fixture);
|
||||
free (fixture->data);
|
||||
}
|
||||
|
@ -132,8 +134,9 @@ get_pagesize (void)
|
|||
}
|
||||
|
||||
static void
|
||||
free_up_munmap (fixture_t *fixture)
|
||||
free_up_munmap (void *fixture_)
|
||||
{
|
||||
fixture_t *fixture = (fixture_t *) fixture_;
|
||||
free_up (fixture);
|
||||
munmap (fixture->data, get_pagesize ());
|
||||
}
|
||||
|
@ -141,8 +144,9 @@ free_up_munmap (fixture_t *fixture)
|
|||
|
||||
#include <errno.h>
|
||||
static void
|
||||
fixture_init (fixture_t *fixture, gconstpointer user_data)
|
||||
fixture_init (gpointer fixture_, gconstpointer user_data)
|
||||
{
|
||||
fixture_t *fixture = (fixture_t *) fixture_;
|
||||
hb_memory_mode_t mm = (hb_memory_mode_t) GPOINTER_TO_INT (user_data);
|
||||
unsigned int len;
|
||||
const char *data;
|
||||
|
@ -153,13 +157,13 @@ fixture_init (fixture_t *fixture, gconstpointer user_data)
|
|||
case HB_MEMORY_MODE_DUPLICATE:
|
||||
data = test_data;
|
||||
len = sizeof (test_data);
|
||||
free_func = (hb_destroy_func_t) free_up;
|
||||
free_func = free_up;
|
||||
break;
|
||||
|
||||
case HB_MEMORY_MODE_READONLY:
|
||||
data = test_data;
|
||||
len = sizeof (test_data);
|
||||
free_func = (hb_destroy_func_t) free_up;
|
||||
free_func = free_up;
|
||||
break;
|
||||
|
||||
case HB_MEMORY_MODE_WRITABLE:
|
||||
|
@ -179,7 +183,7 @@ fixture_init (fixture_t *fixture, gconstpointer user_data)
|
|||
memcpy ((char *) data, test_data, sizeof (test_data));
|
||||
mprotect ((char *) data, pagesize, PROT_READ);
|
||||
len = sizeof (test_data);
|
||||
free_func = (hb_destroy_func_t) free_up_munmap;
|
||||
free_func = free_up_munmap;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
@ -195,16 +199,18 @@ fixture_init (fixture_t *fixture, gconstpointer user_data)
|
|||
}
|
||||
|
||||
static void
|
||||
fixture_finish (fixture_t *fixture, gconstpointer user_data HB_UNUSED)
|
||||
fixture_finish (gpointer fixture_, gconstpointer user_data HB_UNUSED)
|
||||
{
|
||||
fixture_t *fixture = (fixture_t *) fixture_;
|
||||
hb_blob_destroy (fixture->blob);
|
||||
g_assert_cmpint (fixture->freed, ==, 1);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
test_blob (fixture_t *fixture, gconstpointer user_data)
|
||||
test_blob (gpointer fixture_, gconstpointer user_data)
|
||||
{
|
||||
fixture_t *fixture = (fixture_t *) fixture_;
|
||||
hb_blob_t *b = fixture->blob;
|
||||
hb_memory_mode_t mm = GPOINTER_TO_INT (user_data);
|
||||
unsigned int len;
|
||||
|
@ -262,8 +268,9 @@ test_blob (fixture_t *fixture, gconstpointer user_data)
|
|||
}
|
||||
|
||||
static void
|
||||
test_blob_subblob (fixture_t *fixture, gconstpointer user_data)
|
||||
test_blob_subblob (gpointer fixture_, gconstpointer user_data)
|
||||
{
|
||||
fixture_t *fixture = (fixture_t *) fixture_;
|
||||
hb_blob_t *b = fixture->blob;
|
||||
hb_memory_mode_t mm = GPOINTER_TO_INT (user_data);
|
||||
unsigned int len;
|
||||
|
|
|
@ -57,8 +57,9 @@ typedef struct
|
|||
} fixture_t;
|
||||
|
||||
static void
|
||||
fixture_init (fixture_t *fixture, gconstpointer user_data)
|
||||
fixture_init (gpointer fixture_, gconstpointer user_data)
|
||||
{
|
||||
fixture_t *fixture = fixture_;
|
||||
hb_buffer_t *b;
|
||||
unsigned int i;
|
||||
|
||||
|
@ -92,15 +93,17 @@ fixture_init (fixture_t *fixture, gconstpointer user_data)
|
|||
}
|
||||
|
||||
static void
|
||||
fixture_finish (fixture_t *fixture, gconstpointer user_data HB_UNUSED)
|
||||
fixture_finish (gpointer fixture_, gconstpointer user_data HB_UNUSED)
|
||||
{
|
||||
fixture_t *fixture = fixture_;
|
||||
hb_buffer_destroy (fixture->buffer);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
test_buffer_properties (fixture_t *fixture, gconstpointer user_data HB_UNUSED)
|
||||
test_buffer_properties (gpointer fixture_, gconstpointer user_data HB_UNUSED)
|
||||
{
|
||||
fixture_t *fixture = fixture_;
|
||||
hb_buffer_t *b = fixture->buffer;
|
||||
hb_unicode_funcs_t *ufuncs;
|
||||
|
||||
|
@ -177,8 +180,9 @@ test_buffer_properties (fixture_t *fixture, gconstpointer user_data HB_UNUSED)
|
|||
}
|
||||
|
||||
static void
|
||||
test_buffer_contents (fixture_t *fixture, gconstpointer user_data)
|
||||
test_buffer_contents (gpointer fixture_, gconstpointer user_data)
|
||||
{
|
||||
fixture_t *fixture = fixture_;
|
||||
hb_buffer_t *b = fixture->buffer;
|
||||
unsigned int i, len, len2;
|
||||
buffer_type_t buffer_type = GPOINTER_TO_INT (user_data);
|
||||
|
@ -294,8 +298,9 @@ test_buffer_contents (fixture_t *fixture, gconstpointer user_data)
|
|||
}
|
||||
|
||||
static void
|
||||
test_buffer_positions (fixture_t *fixture, gconstpointer user_data HB_UNUSED)
|
||||
test_buffer_positions (gpointer fixture_, gconstpointer user_data HB_UNUSED)
|
||||
{
|
||||
fixture_t *fixture = fixture_;
|
||||
hb_buffer_t *b = fixture->buffer;
|
||||
unsigned int i, len, len2;
|
||||
hb_glyph_position_t *positions;
|
||||
|
@ -319,8 +324,9 @@ test_buffer_positions (fixture_t *fixture, gconstpointer user_data HB_UNUSED)
|
|||
}
|
||||
|
||||
static void
|
||||
test_buffer_allocation (fixture_t *fixture, gconstpointer user_data HB_UNUSED)
|
||||
test_buffer_allocation (gpointer fixture_, gconstpointer user_data HB_UNUSED)
|
||||
{
|
||||
fixture_t *fixture = fixture_;
|
||||
hb_buffer_t *b = fixture->buffer;
|
||||
|
||||
g_assert_cmpint (hb_buffer_get_length (b), ==, 0);
|
||||
|
|
|
@ -98,49 +98,54 @@ test_itoa (void)
|
|||
}
|
||||
|
||||
static void
|
||||
move_to (HB_UNUSED hb_draw_funcs_t *dfuncs, draw_data_t *draw_data,
|
||||
move_to (HB_UNUSED hb_draw_funcs_t *dfuncs, void *draw_data_,
|
||||
HB_UNUSED hb_draw_state_t *st,
|
||||
HB_UNUSED float to_x, HB_UNUSED float to_y,
|
||||
HB_UNUSED void *user_data)
|
||||
{
|
||||
draw_data_t *draw_data = (draw_data_t *) draw_data_;
|
||||
draw_data->move_to_count++;
|
||||
}
|
||||
|
||||
static void
|
||||
line_to (HB_UNUSED hb_draw_funcs_t *dfuncs, draw_data_t *draw_data,
|
||||
line_to (HB_UNUSED hb_draw_funcs_t *dfuncs, void *draw_data_,
|
||||
HB_UNUSED hb_draw_state_t *st,
|
||||
HB_UNUSED float to_x, HB_UNUSED float to_y,
|
||||
HB_UNUSED void *user_data)
|
||||
{
|
||||
draw_data_t *draw_data = (draw_data_t *) draw_data_;
|
||||
draw_data->line_to_count++;
|
||||
}
|
||||
|
||||
static void
|
||||
quadratic_to (HB_UNUSED hb_draw_funcs_t *dfuncs, draw_data_t *draw_data,
|
||||
quadratic_to (HB_UNUSED hb_draw_funcs_t *dfuncs, void *draw_data_,
|
||||
HB_UNUSED hb_draw_state_t *st,
|
||||
HB_UNUSED float control_x, HB_UNUSED float control_y,
|
||||
HB_UNUSED float to_x, HB_UNUSED float to_y,
|
||||
HB_UNUSED void *user_data)
|
||||
{
|
||||
draw_data_t *draw_data = (draw_data_t *) draw_data_;
|
||||
draw_data->quad_to_count++;
|
||||
}
|
||||
|
||||
static void
|
||||
cubic_to (HB_UNUSED hb_draw_funcs_t *dfuncs, draw_data_t *draw_data,
|
||||
cubic_to (HB_UNUSED hb_draw_funcs_t *dfuncs, void *draw_data_,
|
||||
HB_UNUSED hb_draw_state_t *st,
|
||||
HB_UNUSED float control1_x, HB_UNUSED float control1_y,
|
||||
HB_UNUSED float control2_x, HB_UNUSED float control2_y,
|
||||
HB_UNUSED float to_x, HB_UNUSED float to_y,
|
||||
HB_UNUSED void *user_data)
|
||||
{
|
||||
draw_data_t *draw_data = (draw_data_t *) draw_data_;
|
||||
draw_data->cubic_to_count++;
|
||||
}
|
||||
|
||||
static void
|
||||
close_path (HB_UNUSED hb_draw_funcs_t *dfuncs, draw_data_t *draw_data,
|
||||
close_path (HB_UNUSED hb_draw_funcs_t *dfuncs, void *draw_data_,
|
||||
HB_UNUSED hb_draw_state_t *st,
|
||||
HB_UNUSED void *user_data)
|
||||
{
|
||||
draw_data_t *draw_data = (draw_data_t *) draw_data_;
|
||||
draw_data->close_path_count++;
|
||||
}
|
||||
|
||||
|
@ -249,11 +254,11 @@ int
|
|||
main (int argc, char **argv)
|
||||
{
|
||||
funcs = hb_draw_funcs_create ();
|
||||
hb_draw_funcs_set_move_to_func (funcs, (hb_draw_move_to_func_t) move_to, NULL, NULL);
|
||||
hb_draw_funcs_set_line_to_func (funcs, (hb_draw_line_to_func_t) line_to, NULL, NULL);
|
||||
hb_draw_funcs_set_quadratic_to_func (funcs, (hb_draw_quadratic_to_func_t) quadratic_to, NULL, NULL);
|
||||
hb_draw_funcs_set_cubic_to_func (funcs, (hb_draw_cubic_to_func_t) cubic_to, NULL, NULL);
|
||||
hb_draw_funcs_set_close_path_func (funcs, (hb_draw_close_path_func_t) close_path, NULL, NULL);
|
||||
hb_draw_funcs_set_move_to_func (funcs, move_to, NULL, NULL);
|
||||
hb_draw_funcs_set_line_to_func (funcs, line_to, NULL, NULL);
|
||||
hb_draw_funcs_set_quadratic_to_func (funcs, quadratic_to, NULL, NULL);
|
||||
hb_draw_funcs_set_cubic_to_func (funcs, cubic_to, NULL, NULL);
|
||||
hb_draw_funcs_set_close_path_func (funcs, close_path, NULL, NULL);
|
||||
hb_draw_funcs_make_immutable (funcs);
|
||||
|
||||
hb_test_init (&argc, &argv);
|
||||
|
|
|
@ -96,11 +96,12 @@ test_itoa (void)
|
|||
}
|
||||
|
||||
static void
|
||||
move_to (HB_UNUSED hb_draw_funcs_t *dfuncs, draw_data_t *draw_data,
|
||||
move_to (HB_UNUSED hb_draw_funcs_t *dfuncs, void *draw_data_,
|
||||
HB_UNUSED hb_draw_state_t *st,
|
||||
float to_x, float to_y,
|
||||
HB_UNUSED void *user_data)
|
||||
{
|
||||
draw_data_t *draw_data = (draw_data_t *) draw_data_;
|
||||
/* 4 = command character space + comma + array starts with 0 index + nul character space */
|
||||
if (draw_data->consumed + 2 * ITOA_BUF_SIZE + 4 > draw_data->size) return;
|
||||
draw_data->str[draw_data->consumed++] = 'M';
|
||||
|
@ -110,11 +111,12 @@ move_to (HB_UNUSED hb_draw_funcs_t *dfuncs, draw_data_t *draw_data,
|
|||
}
|
||||
|
||||
static void
|
||||
line_to (HB_UNUSED hb_draw_funcs_t *dfuncs, draw_data_t *draw_data,
|
||||
line_to (HB_UNUSED hb_draw_funcs_t *dfuncs, void *draw_data_,
|
||||
HB_UNUSED hb_draw_state_t *st,
|
||||
float to_x, float to_y,
|
||||
HB_UNUSED void *user_data)
|
||||
{
|
||||
draw_data_t *draw_data = (draw_data_t *) draw_data_;
|
||||
if (draw_data->consumed + 2 * ITOA_BUF_SIZE + 4 > draw_data->size) return;
|
||||
draw_data->str[draw_data->consumed++] = 'L';
|
||||
draw_data->consumed += _hb_itoa (to_x, draw_data->str + draw_data->consumed);
|
||||
|
@ -123,13 +125,13 @@ line_to (HB_UNUSED hb_draw_funcs_t *dfuncs, draw_data_t *draw_data,
|
|||
}
|
||||
|
||||
static void
|
||||
quadratic_to (HB_UNUSED hb_draw_funcs_t *dfuncs, draw_data_t *draw_data,
|
||||
quadratic_to (HB_UNUSED hb_draw_funcs_t *dfuncs, void *draw_data_,
|
||||
HB_UNUSED hb_draw_state_t *st,
|
||||
float control_x, float control_y,
|
||||
float to_x, float to_y,
|
||||
HB_UNUSED void *user_data)
|
||||
{
|
||||
|
||||
draw_data_t *draw_data = (draw_data_t *) draw_data_;
|
||||
if (draw_data->consumed + 4 * ITOA_BUF_SIZE + 6 > draw_data->size) return;
|
||||
draw_data->str[draw_data->consumed++] = 'Q';
|
||||
draw_data->consumed += _hb_itoa (control_x, draw_data->str + draw_data->consumed);
|
||||
|
@ -142,13 +144,14 @@ quadratic_to (HB_UNUSED hb_draw_funcs_t *dfuncs, draw_data_t *draw_data,
|
|||
}
|
||||
|
||||
static void
|
||||
cubic_to (HB_UNUSED hb_draw_funcs_t *dfuncs, draw_data_t *draw_data,
|
||||
cubic_to (HB_UNUSED hb_draw_funcs_t *dfuncs, void *draw_data_,
|
||||
HB_UNUSED hb_draw_state_t *st,
|
||||
float control1_x, float control1_y,
|
||||
float control2_x, float control2_y,
|
||||
float to_x, float to_y,
|
||||
HB_UNUSED void *user_data)
|
||||
{
|
||||
draw_data_t *draw_data = (draw_data_t *) draw_data_;
|
||||
if (draw_data->consumed + 6 * ITOA_BUF_SIZE + 8 > draw_data->size) return;
|
||||
draw_data->str[draw_data->consumed++] = 'C';
|
||||
draw_data->consumed += _hb_itoa (control1_x, draw_data->str + draw_data->consumed);
|
||||
|
@ -165,10 +168,11 @@ cubic_to (HB_UNUSED hb_draw_funcs_t *dfuncs, draw_data_t *draw_data,
|
|||
}
|
||||
|
||||
static void
|
||||
close_path (HB_UNUSED hb_draw_funcs_t *dfuncs, draw_data_t *draw_data,
|
||||
close_path (HB_UNUSED hb_draw_funcs_t *dfuncs, void *draw_data_,
|
||||
HB_UNUSED hb_draw_state_t *st,
|
||||
HB_UNUSED void *user_data)
|
||||
{
|
||||
draw_data_t *draw_data = (draw_data_t *) draw_data_;
|
||||
if (draw_data->consumed + 2 > draw_data->size) return;
|
||||
draw_data->str[draw_data->consumed++] = 'Z';
|
||||
}
|
||||
|
@ -1156,18 +1160,18 @@ int
|
|||
main (int argc, char **argv)
|
||||
{
|
||||
funcs = hb_draw_funcs_create ();
|
||||
hb_draw_funcs_set_move_to_func (funcs, (hb_draw_move_to_func_t) move_to, NULL, NULL);
|
||||
hb_draw_funcs_set_line_to_func (funcs, (hb_draw_line_to_func_t) line_to, NULL, NULL);
|
||||
hb_draw_funcs_set_quadratic_to_func (funcs, (hb_draw_quadratic_to_func_t) quadratic_to, NULL, NULL);
|
||||
hb_draw_funcs_set_cubic_to_func (funcs, (hb_draw_cubic_to_func_t) cubic_to, NULL, NULL);
|
||||
hb_draw_funcs_set_close_path_func (funcs, (hb_draw_close_path_func_t) close_path, NULL, NULL);
|
||||
hb_draw_funcs_set_move_to_func (funcs, move_to, NULL, NULL);
|
||||
hb_draw_funcs_set_line_to_func (funcs, line_to, NULL, NULL);
|
||||
hb_draw_funcs_set_quadratic_to_func (funcs, quadratic_to, NULL, NULL);
|
||||
hb_draw_funcs_set_cubic_to_func (funcs, cubic_to, NULL, NULL);
|
||||
hb_draw_funcs_set_close_path_func (funcs, close_path, NULL, NULL);
|
||||
hb_draw_funcs_make_immutable (funcs);
|
||||
|
||||
funcs2 = hb_draw_funcs_create ();
|
||||
hb_draw_funcs_set_move_to_func (funcs2, (hb_draw_move_to_func_t) move_to, NULL, NULL);
|
||||
hb_draw_funcs_set_line_to_func (funcs2, (hb_draw_line_to_func_t) line_to, NULL, NULL);
|
||||
hb_draw_funcs_set_cubic_to_func (funcs2, (hb_draw_cubic_to_func_t) cubic_to, NULL, NULL);
|
||||
hb_draw_funcs_set_close_path_func (funcs2, (hb_draw_close_path_func_t) close_path, NULL, NULL);
|
||||
hb_draw_funcs_set_move_to_func (funcs2, move_to, NULL, NULL);
|
||||
hb_draw_funcs_set_line_to_func (funcs2, line_to, NULL, NULL);
|
||||
hb_draw_funcs_set_cubic_to_func (funcs2, cubic_to, NULL, NULL);
|
||||
hb_draw_funcs_set_close_path_func (funcs2, close_path, NULL, NULL);
|
||||
hb_draw_funcs_make_immutable (funcs2);
|
||||
|
||||
hb_test_init (&argc, &argv);
|
||||
|
|
|
@ -29,41 +29,52 @@
|
|||
/* Unit tests for hb-object-private.h */
|
||||
|
||||
|
||||
static void *
|
||||
static hb_blob_t *
|
||||
create_blob (void)
|
||||
{
|
||||
static char data[] = "test data";
|
||||
return hb_blob_create (data, sizeof (data), HB_MEMORY_MODE_READONLY, NULL, NULL);
|
||||
}
|
||||
static void *
|
||||
static hb_blob_t *
|
||||
create_blob_from_inert (void)
|
||||
{
|
||||
return hb_blob_create (NULL, 0, HB_MEMORY_MODE_DUPLICATE, NULL, NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void *
|
||||
static hb_buffer_t *
|
||||
create_buffer (void)
|
||||
{
|
||||
return hb_buffer_create ();
|
||||
}
|
||||
static void *
|
||||
static hb_buffer_t *
|
||||
create_buffer_from_inert (void)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void *
|
||||
static hb_map_t *
|
||||
create_map (void)
|
||||
{
|
||||
return hb_map_create ();
|
||||
}
|
||||
static hb_map_t *
|
||||
create_map_from_inert (void)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static hb_set_t *
|
||||
create_set (void)
|
||||
{
|
||||
return hb_set_create ();
|
||||
}
|
||||
static void *
|
||||
static hb_set_t *
|
||||
create_set_from_inert (void)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void *
|
||||
static hb_face_t *
|
||||
create_face (void)
|
||||
{
|
||||
hb_blob_t *blob = (hb_blob_t *) create_blob ();
|
||||
|
@ -71,13 +82,13 @@ create_face (void)
|
|||
hb_blob_destroy (blob);
|
||||
return face;
|
||||
}
|
||||
static void *
|
||||
static hb_face_t *
|
||||
create_face_from_inert (void)
|
||||
{
|
||||
return hb_face_create (hb_blob_get_empty (), 0);
|
||||
}
|
||||
|
||||
static void *
|
||||
static hb_font_t *
|
||||
create_font (void)
|
||||
{
|
||||
hb_face_t *face = (hb_face_t *) create_face ();
|
||||
|
@ -85,96 +96,51 @@ create_font (void)
|
|||
hb_face_destroy (face);
|
||||
return font;
|
||||
}
|
||||
static void *
|
||||
static hb_font_t *
|
||||
create_font_from_inert (void)
|
||||
{
|
||||
return hb_font_create (hb_face_get_empty ());
|
||||
}
|
||||
|
||||
static void *
|
||||
static hb_font_funcs_t *
|
||||
create_font_funcs (void)
|
||||
{
|
||||
return hb_font_funcs_create ();
|
||||
}
|
||||
static void *
|
||||
static hb_font_funcs_t *
|
||||
create_font_funcs_from_inert (void)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void *
|
||||
static hb_shape_plan_t *
|
||||
create_shape_plan (void)
|
||||
{
|
||||
hb_segment_properties_t props = HB_SEGMENT_PROPERTIES_DEFAULT;
|
||||
props.direction = HB_DIRECTION_LTR;
|
||||
hb_face_t *face = (hb_face_t *) create_face ();
|
||||
hb_shape_plan_t *shape_plan = hb_shape_plan_create (face, &props, NULL, 0, NULL);
|
||||
hb_face_destroy (face);
|
||||
return shape_plan;
|
||||
}
|
||||
static hb_shape_plan_t *
|
||||
create_shape_plan_from_inert (void)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static hb_unicode_funcs_t *
|
||||
create_unicode_funcs (void)
|
||||
{
|
||||
return hb_unicode_funcs_create (NULL);
|
||||
}
|
||||
static void *
|
||||
static hb_unicode_funcs_t *
|
||||
create_unicode_funcs_from_inert (void)
|
||||
{
|
||||
return hb_unicode_funcs_create (hb_unicode_funcs_get_empty ());
|
||||
}
|
||||
|
||||
|
||||
|
||||
typedef void *(*create_func_t) (void);
|
||||
typedef void *(*reference_func_t) (void *obj);
|
||||
typedef void (*destroy_func_t) (void *obj);
|
||||
typedef hb_bool_t (*set_user_data_func_t) (void *obj, hb_user_data_key_t *key, void *data, hb_destroy_func_t destroy, hb_bool_t replace);
|
||||
typedef void * (*get_user_data_func_t) (void *obj, hb_user_data_key_t *key);
|
||||
typedef void (*make_immutable_func_t) (void *obj);
|
||||
typedef hb_bool_t (*is_immutable_func_t) (void *obj);
|
||||
|
||||
typedef struct {
|
||||
create_func_t create;
|
||||
create_func_t create_from_inert;
|
||||
create_func_t get_empty;
|
||||
reference_func_t reference;
|
||||
destroy_func_t destroy;
|
||||
set_user_data_func_t set_user_data;
|
||||
get_user_data_func_t get_user_data;
|
||||
make_immutable_func_t make_immutable;
|
||||
is_immutable_func_t is_immutable;
|
||||
const char *name;
|
||||
} object_t;
|
||||
|
||||
#define OBJECT_WITHOUT_IMMUTABILITY(name) \
|
||||
{ \
|
||||
(create_func_t) create_##name, \
|
||||
(create_func_t) create_##name##_from_inert, \
|
||||
(create_func_t) hb_##name##_get_empty, \
|
||||
(reference_func_t) hb_##name##_reference, \
|
||||
(destroy_func_t) hb_##name##_destroy, \
|
||||
(set_user_data_func_t) hb_##name##_set_user_data, \
|
||||
(get_user_data_func_t) hb_##name##_get_user_data, \
|
||||
(make_immutable_func_t) NULL, \
|
||||
(is_immutable_func_t) NULL, \
|
||||
#name, \
|
||||
}
|
||||
#define OBJECT_WITH_IMMUTABILITY(name) \
|
||||
{ \
|
||||
(create_func_t) create_##name, \
|
||||
(create_func_t) create_##name##_from_inert, \
|
||||
(create_func_t) hb_##name##_get_empty, \
|
||||
(reference_func_t) hb_##name##_reference, \
|
||||
(destroy_func_t) hb_##name##_destroy, \
|
||||
(set_user_data_func_t) hb_##name##_set_user_data, \
|
||||
(get_user_data_func_t) hb_##name##_get_user_data, \
|
||||
(make_immutable_func_t) hb_##name##_make_immutable, \
|
||||
(is_immutable_func_t) hb_##name##_is_immutable, \
|
||||
#name, \
|
||||
}
|
||||
static const object_t objects[] =
|
||||
{
|
||||
OBJECT_WITHOUT_IMMUTABILITY (buffer),
|
||||
OBJECT_WITHOUT_IMMUTABILITY (set),
|
||||
OBJECT_WITH_IMMUTABILITY (blob),
|
||||
OBJECT_WITH_IMMUTABILITY (face),
|
||||
OBJECT_WITH_IMMUTABILITY (font),
|
||||
OBJECT_WITH_IMMUTABILITY (font_funcs),
|
||||
OBJECT_WITH_IMMUTABILITY (unicode_funcs)
|
||||
};
|
||||
#undef OBJECT
|
||||
|
||||
|
||||
#define MAGIC0 0x12345678
|
||||
#define MAGIC1 0x76543210
|
||||
|
||||
|
@ -208,168 +174,198 @@ static void free_up1 (void *p)
|
|||
data->freed = TRUE;
|
||||
}
|
||||
|
||||
|
||||
typedef struct {
|
||||
const object_t *klass;
|
||||
void *object;
|
||||
hb_user_data_key_t key;
|
||||
} deadlock_test_t;
|
||||
|
||||
static void free_deadlock_test (void *p)
|
||||
{
|
||||
deadlock_test_t *t = (deadlock_test_t *) p;
|
||||
|
||||
g_assert_true (NULL == t->klass->get_user_data (t->object, &t->key));
|
||||
#define OBJECT(name, _hb_object_make_immutable, _hb_object_is_immutable) \
|
||||
static void \
|
||||
test_object_##name (void) \
|
||||
{ \
|
||||
typedef hb_##name##_t type_t; \
|
||||
typedef type_t *(*create_func_t) (void); \
|
||||
typedef type_t *(*reference_func_t) (type_t *obj); \
|
||||
typedef void (*destroy_func_t) (type_t *obj); \
|
||||
typedef hb_bool_t (*set_user_data_func_t) (type_t *obj, hb_user_data_key_t *key, void *data, hb_destroy_func_t destroy, hb_bool_t replace); \
|
||||
typedef void * (*get_user_data_func_t) (const type_t *obj, hb_user_data_key_t *key); \
|
||||
typedef void (*make_immutable_func_t) (type_t *obj); \
|
||||
typedef hb_bool_t (*is_immutable_func_t) (type_t *obj); \
|
||||
\
|
||||
struct object_t { \
|
||||
create_func_t create; \
|
||||
create_func_t create_from_inert; \
|
||||
create_func_t get_empty; \
|
||||
reference_func_t reference; \
|
||||
destroy_func_t destroy; \
|
||||
set_user_data_func_t set_user_data; \
|
||||
get_user_data_func_t get_user_data; \
|
||||
make_immutable_func_t make_immutable; \
|
||||
is_immutable_func_t is_immutable; \
|
||||
const char *name; \
|
||||
} o[1] = {{\
|
||||
create_##name, \
|
||||
create_##name##_from_inert, \
|
||||
hb_##name##_get_empty, \
|
||||
hb_##name##_reference, \
|
||||
hb_##name##_destroy, \
|
||||
hb_##name##_set_user_data, \
|
||||
hb_##name##_get_user_data, \
|
||||
_hb_object_make_immutable, \
|
||||
_hb_object_is_immutable, \
|
||||
#name, \
|
||||
}}; \
|
||||
\
|
||||
void *obj; \
|
||||
hb_user_data_key_t key[1001]; \
|
||||
\
|
||||
{ \
|
||||
unsigned int j; \
|
||||
data_t data[1000] = {{MAGIC0, FALSE}, {MAGIC1, FALSE}}; \
|
||||
\
|
||||
g_test_message ("Testing object %s", o->name); \
|
||||
\
|
||||
g_test_message ("->create()"); \
|
||||
obj = o->create (); \
|
||||
g_assert_true (obj); \
|
||||
\
|
||||
g_assert_true (obj == o->reference (obj)); \
|
||||
o->destroy (obj); \
|
||||
\
|
||||
if (o->is_immutable) \
|
||||
g_assert_true (!o->is_immutable (obj)); \
|
||||
\
|
||||
g_assert_true (o->set_user_data (obj, &key[0], &data[0], free_up0, TRUE)); \
|
||||
g_assert_true (o->get_user_data (obj, &key[0]) == &data[0]); \
|
||||
\
|
||||
if (o->is_immutable) { \
|
||||
o->make_immutable (obj); \
|
||||
g_assert_true (o->is_immutable (obj)); \
|
||||
} \
|
||||
\
|
||||
/* Should still work even if object is made immutable */ \
|
||||
g_assert_true (o->set_user_data (obj, &key[1], &data[1], free_up1, TRUE)); \
|
||||
g_assert_true (o->get_user_data (obj, &key[1]) == &data[1]); \
|
||||
\
|
||||
g_assert_true (!o->set_user_data (obj, NULL, &data[0], free_up0, TRUE)); \
|
||||
g_assert_true (o->get_user_data (obj, &key[0]) == &data[0]); \
|
||||
g_assert_true (o->set_user_data (obj, &key[0], &data[1], NULL, TRUE)); \
|
||||
g_assert_true (data[0].freed); \
|
||||
g_assert_true (o->get_user_data (obj, &key[0]) == &data[1]); \
|
||||
g_assert_true (!data[1].freed); \
|
||||
\
|
||||
data[0].freed = FALSE; \
|
||||
g_assert_true (o->set_user_data (obj, &key[0], &data[0], free_up0, TRUE)); \
|
||||
g_assert_true (!data[0].freed); \
|
||||
g_assert_true (o->set_user_data (obj, &key[0], NULL, NULL, TRUE)); \
|
||||
g_assert_true (data[0].freed); \
|
||||
\
|
||||
data[0].freed = FALSE; \
|
||||
global_data = 0; \
|
||||
g_assert_true (o->set_user_data (obj, &key[0], &data[0], free_up0, TRUE)); \
|
||||
g_assert_true (!o->set_user_data (obj, &key[0], &data[0], free_up0, FALSE)); \
|
||||
g_assert_cmpuint (global_data, ==, 0); \
|
||||
g_assert_true (o->set_user_data (obj, &key[0], NULL, global_free_up, TRUE)); \
|
||||
g_assert_cmpuint (global_data, ==, 0); \
|
||||
g_assert_true (o->set_user_data (obj, &key[0], NULL, NULL, TRUE)); \
|
||||
g_assert_cmpuint (global_data, ==, 1); \
|
||||
\
|
||||
global_data = 0; \
|
||||
for (j = 2; j < 1000; j++) \
|
||||
g_assert_true (o->set_user_data (obj, &key[j], &data[j], global_free_up, TRUE)); \
|
||||
for (j = 2; j < 1000; j++) \
|
||||
g_assert_true (o->get_user_data (obj, &key[j]) == &data[j]); \
|
||||
for (j = 100; j < 1000; j++) \
|
||||
g_assert_true (o->set_user_data (obj, &key[j], NULL, NULL, TRUE)); \
|
||||
for (j = 2; j < 100; j++) \
|
||||
g_assert_true (o->get_user_data (obj, &key[j]) == &data[j]); \
|
||||
for (j = 100; j < 1000; j++) \
|
||||
g_assert_true (!o->get_user_data (obj, &key[j])); \
|
||||
g_assert_cmpuint (global_data, ==, 900); \
|
||||
\
|
||||
g_assert_true (!data[1].freed); \
|
||||
o->destroy (obj); \
|
||||
g_assert_true (data[0].freed); \
|
||||
g_assert_true (data[1].freed); \
|
||||
g_assert_cmpuint (global_data, ==, 1000-2); \
|
||||
} \
|
||||
\
|
||||
{ \
|
||||
data_t data[2] = {{MAGIC0, FALSE}, {MAGIC1, FALSE}}; \
|
||||
\
|
||||
g_test_message ("->get_empty()"); \
|
||||
obj = o->get_empty (); \
|
||||
g_assert_true (obj); \
|
||||
\
|
||||
g_assert_true (obj == o->reference (obj)); \
|
||||
o->destroy (obj); \
|
||||
\
|
||||
if (o->is_immutable) \
|
||||
g_assert_true (o->is_immutable (obj)); \
|
||||
\
|
||||
g_assert_true (!o->set_user_data (obj, &key[0], &data[0], free_up0, TRUE)); \
|
||||
g_assert_true (!o->get_user_data (obj, &key[0])); \
|
||||
\
|
||||
o->destroy (obj); \
|
||||
o->destroy (obj); \
|
||||
o->destroy (obj); \
|
||||
o->destroy (obj); \
|
||||
o->destroy (obj); \
|
||||
\
|
||||
g_assert_true (!data[0].freed); \
|
||||
} \
|
||||
\
|
||||
{ \
|
||||
data_t data[2] = {{MAGIC0, FALSE}, {MAGIC1, FALSE}}; \
|
||||
\
|
||||
g_test_message ("->create_from_inert()"); \
|
||||
obj = o->create_from_inert (); \
|
||||
if (!obj) \
|
||||
return; \
|
||||
g_assert_true (obj != o->get_empty ()); \
|
||||
\
|
||||
g_assert_true (obj == o->reference (obj)); \
|
||||
o->destroy (obj); \
|
||||
\
|
||||
if (o->is_immutable) \
|
||||
g_assert_true (!o->is_immutable (obj)); \
|
||||
\
|
||||
g_assert_true (o->set_user_data (obj, &key[0], &data[0], free_up0, TRUE)); \
|
||||
g_assert_true (o->get_user_data (obj, &key[0])); \
|
||||
\
|
||||
o->destroy (obj); \
|
||||
\
|
||||
g_assert_true (data[0].freed); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define OBJECT_WITH_IMMUTABILITY(name) \
|
||||
OBJECT (name, hb_##name##_make_immutable, hb_##name##_is_immutable)
|
||||
#define OBJECT_WITHOUT_IMMUTABILITY(name) \
|
||||
OBJECT (name, NULL, NULL)
|
||||
|
||||
static void
|
||||
test_object (void)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (objects); i++) {
|
||||
const object_t *o = &objects[i];
|
||||
void *obj;
|
||||
hb_user_data_key_t key[1001];
|
||||
|
||||
{
|
||||
unsigned int j;
|
||||
data_t data[1000] = {{MAGIC0, FALSE}, {MAGIC1, FALSE}};
|
||||
deadlock_test_t deadlock_test;
|
||||
|
||||
g_test_message ("Testing object %s", o->name);
|
||||
|
||||
g_test_message ("->create()");
|
||||
obj = o->create ();
|
||||
g_assert_true (obj);
|
||||
|
||||
g_assert_true (obj == o->reference (obj));
|
||||
o->destroy (obj);
|
||||
|
||||
if (o->is_immutable)
|
||||
g_assert_true (!o->is_immutable (obj));
|
||||
|
||||
g_assert_true (o->set_user_data (obj, &key[0], &data[0], free_up0, TRUE));
|
||||
g_assert_true (o->get_user_data (obj, &key[0]) == &data[0]);
|
||||
|
||||
if (o->is_immutable) {
|
||||
o->make_immutable (obj);
|
||||
g_assert_true (o->is_immutable (obj));
|
||||
}
|
||||
|
||||
/* Should still work even if object is made immutable */
|
||||
g_assert_true (o->set_user_data (obj, &key[1], &data[1], free_up1, TRUE));
|
||||
g_assert_true (o->get_user_data (obj, &key[1]) == &data[1]);
|
||||
|
||||
g_assert_true (!o->set_user_data (obj, NULL, &data[0], free_up0, TRUE));
|
||||
g_assert_true (o->get_user_data (obj, &key[0]) == &data[0]);
|
||||
g_assert_true (o->set_user_data (obj, &key[0], &data[1], NULL, TRUE));
|
||||
g_assert_true (data[0].freed);
|
||||
g_assert_true (o->get_user_data (obj, &key[0]) == &data[1]);
|
||||
g_assert_true (!data[1].freed);
|
||||
|
||||
data[0].freed = FALSE;
|
||||
g_assert_true (o->set_user_data (obj, &key[0], &data[0], free_up0, TRUE));
|
||||
g_assert_true (!data[0].freed);
|
||||
g_assert_true (o->set_user_data (obj, &key[0], NULL, NULL, TRUE));
|
||||
g_assert_true (data[0].freed);
|
||||
|
||||
data[0].freed = FALSE;
|
||||
global_data = 0;
|
||||
g_assert_true (o->set_user_data (obj, &key[0], &data[0], free_up0, TRUE));
|
||||
g_assert_true (!o->set_user_data (obj, &key[0], &data[0], free_up0, FALSE));
|
||||
g_assert_cmpuint (global_data, ==, 0);
|
||||
g_assert_true (o->set_user_data (obj, &key[0], NULL, global_free_up, TRUE));
|
||||
g_assert_cmpuint (global_data, ==, 0);
|
||||
g_assert_true (o->set_user_data (obj, &key[0], NULL, NULL, TRUE));
|
||||
g_assert_cmpuint (global_data, ==, 1);
|
||||
|
||||
global_data = 0;
|
||||
for (j = 2; j < 1000; j++)
|
||||
g_assert_true (o->set_user_data (obj, &key[j], &data[j], global_free_up, TRUE));
|
||||
for (j = 2; j < 1000; j++)
|
||||
g_assert_true (o->get_user_data (obj, &key[j]) == &data[j]);
|
||||
for (j = 100; j < 1000; j++)
|
||||
g_assert_true (o->set_user_data (obj, &key[j], NULL, NULL, TRUE));
|
||||
for (j = 2; j < 100; j++)
|
||||
g_assert_true (o->get_user_data (obj, &key[j]) == &data[j]);
|
||||
for (j = 100; j < 1000; j++)
|
||||
g_assert_true (!o->get_user_data (obj, &key[j]));
|
||||
g_assert_cmpuint (global_data, ==, 900);
|
||||
|
||||
/* Test set_user_data where the destroy() func calls user_data functions.
|
||||
* Make sure it doesn't deadlock or corrupt memory. */
|
||||
deadlock_test.klass = o;
|
||||
deadlock_test.object = obj;
|
||||
g_assert_true (o->set_user_data (obj, &deadlock_test.key, &deadlock_test, free_deadlock_test, TRUE));
|
||||
g_assert_true (o->set_user_data (obj, &deadlock_test.key, NULL, NULL, TRUE));
|
||||
|
||||
g_assert_true (!data[1].freed);
|
||||
o->destroy (obj);
|
||||
g_assert_true (data[0].freed);
|
||||
g_assert_true (data[1].freed);
|
||||
g_assert_cmpuint (global_data, ==, 1000-2);
|
||||
}
|
||||
|
||||
{
|
||||
data_t data[2] = {{MAGIC0, FALSE}, {MAGIC1, FALSE}};
|
||||
|
||||
g_test_message ("->get_empty()");
|
||||
obj = o->get_empty ();
|
||||
g_assert_true (obj);
|
||||
|
||||
g_assert_true (obj == o->reference (obj));
|
||||
o->destroy (obj);
|
||||
|
||||
if (o->is_immutable)
|
||||
g_assert_true (o->is_immutable (obj));
|
||||
|
||||
g_assert_true (!o->set_user_data (obj, &key[0], &data[0], free_up0, TRUE));
|
||||
g_assert_true (!o->get_user_data (obj, &key[0]));
|
||||
|
||||
o->destroy (obj);
|
||||
o->destroy (obj);
|
||||
o->destroy (obj);
|
||||
o->destroy (obj);
|
||||
o->destroy (obj);
|
||||
|
||||
g_assert_true (!data[0].freed);
|
||||
}
|
||||
|
||||
{
|
||||
data_t data[2] = {{MAGIC0, FALSE}, {MAGIC1, FALSE}};
|
||||
|
||||
g_test_message ("->create_from_inert()");
|
||||
obj = o->create_from_inert ();
|
||||
if (!obj)
|
||||
continue;
|
||||
if (obj == o->get_empty ())
|
||||
continue; /* Tested already */
|
||||
|
||||
g_assert_true (obj == o->reference (obj));
|
||||
o->destroy (obj);
|
||||
|
||||
if (o->is_immutable)
|
||||
g_assert_true (!o->is_immutable (obj));
|
||||
|
||||
g_assert_true (o->set_user_data (obj, &key[0], &data[0], free_up0, TRUE));
|
||||
g_assert_true (o->get_user_data (obj, &key[0]));
|
||||
|
||||
o->destroy (obj);
|
||||
|
||||
g_assert_true (data[0].freed);
|
||||
}
|
||||
}
|
||||
}
|
||||
OBJECT_WITHOUT_IMMUTABILITY (buffer)
|
||||
OBJECT_WITHOUT_IMMUTABILITY (map)
|
||||
OBJECT_WITHOUT_IMMUTABILITY (set)
|
||||
OBJECT_WITHOUT_IMMUTABILITY (shape_plan)
|
||||
|
||||
OBJECT_WITH_IMMUTABILITY (blob)
|
||||
OBJECT_WITH_IMMUTABILITY (face)
|
||||
OBJECT_WITH_IMMUTABILITY (font)
|
||||
OBJECT_WITH_IMMUTABILITY (font_funcs)
|
||||
OBJECT_WITH_IMMUTABILITY (unicode_funcs)
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
hb_test_init (&argc, &argv);
|
||||
|
||||
hb_test_add (test_object);
|
||||
hb_test_add (test_object_buffer);
|
||||
hb_test_add (test_object_map);
|
||||
hb_test_add (test_object_shape_plan);
|
||||
hb_test_add (test_object_set);
|
||||
|
||||
hb_test_add (test_object_blob);
|
||||
hb_test_add (test_object_face);
|
||||
hb_test_add (test_object_font);
|
||||
hb_test_add (test_object_font_funcs);
|
||||
hb_test_add (test_object_unicode_funcs);
|
||||
|
||||
return hb_test_run ();
|
||||
}
|
||||
|
|
|
@ -577,13 +577,22 @@ typedef struct {
|
|||
unsigned int default_value;
|
||||
} property_t;
|
||||
|
||||
static unsigned _hb_unicode_combining_class (hb_unicode_funcs_t *ufuncs, hb_codepoint_t unicode)
|
||||
{ return (unsigned) hb_unicode_combining_class (ufuncs, unicode); }
|
||||
static unsigned _hb_unicode_general_category (hb_unicode_funcs_t *ufuncs, hb_codepoint_t unicode)
|
||||
{ return (unsigned) hb_unicode_general_category (ufuncs, unicode); }
|
||||
static unsigned _hb_unicode_mirroring (hb_unicode_funcs_t *ufuncs, hb_codepoint_t unicode)
|
||||
{ return (unsigned) hb_unicode_mirroring (ufuncs, unicode); }
|
||||
static unsigned _hb_unicode_script (hb_unicode_funcs_t *ufuncs, hb_codepoint_t unicode)
|
||||
{ return (unsigned) hb_unicode_script (ufuncs, unicode); }
|
||||
|
||||
#define RETURNS_UNICODE_ITSELF ((unsigned int) -1)
|
||||
|
||||
#define PROPERTY(name, DEFAULT) \
|
||||
{ \
|
||||
#name, \
|
||||
(func_setter_func_t) hb_unicode_funcs_set_##name##_func, \
|
||||
(getter_func_t) hb_unicode_##name, \
|
||||
_hb_unicode_##name, \
|
||||
name##_tests, \
|
||||
G_N_ELEMENTS (name##_tests), \
|
||||
name##_tests_more, \
|
||||
|
@ -785,19 +794,21 @@ typedef struct {
|
|||
} data_fixture_t;
|
||||
|
||||
static void
|
||||
data_fixture_init (data_fixture_t *f, gconstpointer user_data HB_UNUSED)
|
||||
data_fixture_init (gpointer fixture, gconstpointer user_data HB_UNUSED)
|
||||
{
|
||||
data_fixture_t *f = (data_fixture_t *) fixture;
|
||||
f->data[0].value = MAGIC0;
|
||||
f->data[1].value = MAGIC1;
|
||||
}
|
||||
static void
|
||||
data_fixture_finish (data_fixture_t *f HB_UNUSED, gconstpointer user_data HB_UNUSED)
|
||||
data_fixture_finish (gpointer fixture HB_UNUSED, gconstpointer user_data HB_UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
test_unicode_subclassing_nil (data_fixture_t *f, gconstpointer user_data HB_UNUSED)
|
||||
test_unicode_subclassing_nil (gpointer fixture, gconstpointer user_data HB_UNUSED)
|
||||
{
|
||||
data_fixture_t *f = (data_fixture_t *) fixture;
|
||||
hb_unicode_funcs_t *uf, *aa;
|
||||
|
||||
uf = hb_unicode_funcs_create (NULL);
|
||||
|
@ -818,8 +829,9 @@ test_unicode_subclassing_nil (data_fixture_t *f, gconstpointer user_data HB_UNUS
|
|||
}
|
||||
|
||||
static void
|
||||
test_unicode_subclassing_default (data_fixture_t *f, gconstpointer user_data HB_UNUSED)
|
||||
test_unicode_subclassing_default (gpointer fixture, gconstpointer user_data HB_UNUSED)
|
||||
{
|
||||
data_fixture_t *f = (data_fixture_t *) fixture;
|
||||
hb_unicode_funcs_t *uf, *aa;
|
||||
|
||||
uf = hb_unicode_funcs_get_default ();
|
||||
|
@ -837,8 +849,9 @@ test_unicode_subclassing_default (data_fixture_t *f, gconstpointer user_data HB_
|
|||
}
|
||||
|
||||
static void
|
||||
test_unicode_subclassing_deep (data_fixture_t *f, gconstpointer user_data HB_UNUSED)
|
||||
test_unicode_subclassing_deep (gpointer fixture, gconstpointer user_data HB_UNUSED)
|
||||
{
|
||||
data_fixture_t *f = (data_fixture_t *) fixture;
|
||||
hb_unicode_funcs_t *uf, *aa;
|
||||
|
||||
uf = hb_unicode_funcs_create (NULL);
|
||||
|
@ -999,6 +1012,9 @@ test_unicode_normalization (gconstpointer user_data)
|
|||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
char *ubsan_obtions = getenv ("UBSAN_OPTIONS");
|
||||
int ubsan = ubsan_obtions && strstr (ubsan_obtions, "halt_on_error=1");
|
||||
|
||||
hb_test_init (&argc, &argv);
|
||||
|
||||
hb_test_add (test_unicode_properties_nil);
|
||||
|
@ -1020,7 +1036,8 @@ main (int argc, char **argv)
|
|||
|
||||
hb_test_add (test_unicode_chainup);
|
||||
|
||||
hb_test_add (test_unicode_setters);
|
||||
if (!ubsan)
|
||||
hb_test_add (test_unicode_setters);
|
||||
|
||||
hb_test_add_fixture (data_fixture, NULL, test_unicode_subclassing_nil);
|
||||
hb_test_add_fixture (data_fixture, NULL, test_unicode_subclassing_default);
|
||||
|
|
|
@ -38,7 +38,8 @@ def cmd(command):
|
|||
command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True
|
||||
)
|
||||
(stdoutdata, stderrdata) = p.communicate()
|
||||
print(stderrdata, end="", file=sys.stderr)
|
||||
if stderrdata:
|
||||
print(stderrdata, file=sys.stderr)
|
||||
return stdoutdata, p.returncode
|
||||
|
||||
|
||||
|
@ -52,9 +53,9 @@ def fail_test(test, cli_args, message):
|
|||
print(" test.test_path %s" % os.path.abspath(test.test_path))
|
||||
print("not ok -", test)
|
||||
print(" ---", file=sys.stderr)
|
||||
print(" message: \"%s\"" % message, file=sys.stderr)
|
||||
print(" test.font_name: \"%s\"" % test.font_name)
|
||||
print(" test.test_path: \"%s\"" % os.path.abspath(test.test_path))
|
||||
print(' message: "%s"' % message, file=sys.stderr)
|
||||
print(' test.font_name: "%s"' % test.font_name, file=sys.stderr)
|
||||
print(' test.test_path: "%s"' % os.path.abspath(test.test_path), file=sys.stderr)
|
||||
print(" ...", file=sys.stderr)
|
||||
return False
|
||||
|
||||
|
|
|
@ -40,25 +40,29 @@ def cmd(command):
|
|||
command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True
|
||||
)
|
||||
(stdoutdata, stderrdata) = p.communicate()
|
||||
print(stderrdata, end="", file=sys.stderr)
|
||||
if stderrdata:
|
||||
print(stderrdata, file=sys.stderr)
|
||||
return stdoutdata, p.returncode
|
||||
|
||||
|
||||
def fail_test(test, cli_args, message):
|
||||
global fails
|
||||
global fails, number
|
||||
fails += 1
|
||||
|
||||
expected_file = os.path.join(
|
||||
test_suite.get_output_directory(), test.get_font_name()
|
||||
)
|
||||
|
||||
print("not ok -", test)
|
||||
print("not ok %d - %s" % (number, test))
|
||||
print(" ---", file=sys.stderr)
|
||||
print(" message: \"%s\"" % message, file=sys.stderr)
|
||||
print(" test.font_path: \"%s\"" % os.path.abspath(test.font_path), file=sys.stderr)
|
||||
print(" test.profile_path: \"%s\"" % os.path.abspath(test.profile_path), file=sys.stderr)
|
||||
print(" test.unicodes: \"%s\"" % test.unicodes(), file=sys.stderr)
|
||||
print(" expected_file: \"%s\"" % os.path.abspath(expected_file), file=sys.stderr)
|
||||
print(' message: "%s"' % message, file=sys.stderr)
|
||||
print(' test.font_path: "%s"' % os.path.abspath(test.font_path), file=sys.stderr)
|
||||
print(
|
||||
' test.profile_path: "%s"' % os.path.abspath(test.profile_path),
|
||||
file=sys.stderr,
|
||||
)
|
||||
print(' test.unicodes: "%s"' % test.unicodes(), file=sys.stderr)
|
||||
print(' expected_file: "%s"' % os.path.abspath(expected_file), file=sys.stderr)
|
||||
print(" ...", file=sys.stderr)
|
||||
return False
|
||||
|
||||
|
@ -214,7 +218,7 @@ for path in args:
|
|||
print("ok %d - %s" % (number, test))
|
||||
|
||||
if fails != 0:
|
||||
print("# %d test(s) failed; output left in %s" % (fails, out_dir), file=sys.stderr)
|
||||
print("# %d test(s) failed; output left in %s" % (fails, out_dir))
|
||||
else:
|
||||
print("# All tests passed.")
|
||||
shutil.rmtree(out_dir)
|
||||
|
|
|
@ -2,143 +2,180 @@
|
|||
|
||||
import os
|
||||
|
||||
|
||||
# A single test in a subset test suite. Identifies a font
|
||||
# a subsetting profile, and a subset to be cut.
|
||||
class Test:
|
||||
def __init__(self, font_path, profile_path, subset, instance, iup_optimize, options):
|
||||
self.font_path = font_path
|
||||
self.profile_path = profile_path
|
||||
self.subset = subset
|
||||
self.instance = instance
|
||||
self.iup_optimize = iup_optimize
|
||||
self.options = options
|
||||
def __init__(
|
||||
self, font_path, profile_path, subset, instance, iup_optimize, options
|
||||
):
|
||||
self.font_path = font_path
|
||||
self.profile_path = profile_path
|
||||
self.subset = subset
|
||||
self.instance = instance
|
||||
self.iup_optimize = iup_optimize
|
||||
self.options = options
|
||||
|
||||
def unicodes(self):
|
||||
import re
|
||||
if self.subset == '*':
|
||||
return self.subset[0]
|
||||
elif self.subset == "no-unicodes":
|
||||
return ""
|
||||
elif re.match("^U\+", self.subset):
|
||||
s = re.sub (r"U\+", "", self.subset)
|
||||
return s
|
||||
else:
|
||||
return ",".join("%X" % ord(c) for (i, c) in enumerate(self.subset))
|
||||
def __str__(self):
|
||||
# Don't print self.subset as contains non-ASCII and some CI's don't like it
|
||||
return "Test: %s %s %s %s %s" % (
|
||||
self.font_path,
|
||||
self.profile_path,
|
||||
self.instance,
|
||||
self.iup_optimize,
|
||||
self.options,
|
||||
)
|
||||
|
||||
def instance_name(self):
|
||||
if not self.instance:
|
||||
return self.instance
|
||||
else:
|
||||
s = "." + self.instance.replace(':', '-')
|
||||
if self.iup_optimize:
|
||||
s += ".iup_optimize"
|
||||
return s
|
||||
def unicodes(self):
|
||||
import re
|
||||
|
||||
def get_profile_flags(self):
|
||||
with open (self.profile_path, mode="r", encoding="utf-8") as f:
|
||||
return f.read().splitlines()
|
||||
if self.subset == "*":
|
||||
return self.subset[0]
|
||||
elif self.subset == "no-unicodes":
|
||||
return ""
|
||||
elif re.match(r"^U\+", self.subset):
|
||||
s = re.sub(r"U\+", "", self.subset)
|
||||
return s
|
||||
else:
|
||||
return ",".join("%X" % ord(c) for (i, c) in enumerate(self.subset))
|
||||
|
||||
def get_instance_flags(self):
|
||||
if not self.instance:
|
||||
return []
|
||||
else:
|
||||
return self.instance.split(',')
|
||||
def instance_name(self):
|
||||
if not self.instance:
|
||||
return self.instance
|
||||
else:
|
||||
s = "." + self.instance.replace(":", "-")
|
||||
if self.iup_optimize:
|
||||
s += ".iup_optimize"
|
||||
return s
|
||||
|
||||
def get_font_name(self):
|
||||
font_base_name = os.path.basename(self.font_path)
|
||||
font_base_name_parts = os.path.splitext(font_base_name)
|
||||
profile_name = os.path.splitext(os.path.basename(self.profile_path))[0]
|
||||
def get_profile_flags(self):
|
||||
with open(self.profile_path, mode="r", encoding="utf-8") as f:
|
||||
return f.read().splitlines()
|
||||
|
||||
if self.unicodes() == "*":
|
||||
return "%s.%s.all%s%s" % (font_base_name_parts[0],
|
||||
profile_name,
|
||||
self.instance_name(),
|
||||
font_base_name_parts[1])
|
||||
elif self.unicodes() == "":
|
||||
return "%s.%s.no-unicodes%s%s" % (font_base_name_parts[0],
|
||||
profile_name,
|
||||
self.instance_name(),
|
||||
font_base_name_parts[1])
|
||||
else:
|
||||
return "%s.%s.%s%s%s" % (font_base_name_parts[0],
|
||||
profile_name,
|
||||
self.unicodes(),
|
||||
self.instance_name(),
|
||||
font_base_name_parts[1])
|
||||
def get_instance_flags(self):
|
||||
if not self.instance:
|
||||
return []
|
||||
else:
|
||||
return self.instance.split(",")
|
||||
|
||||
def get_font_name(self):
|
||||
font_base_name = os.path.basename(self.font_path)
|
||||
font_base_name_parts = os.path.splitext(font_base_name)
|
||||
profile_name = os.path.splitext(os.path.basename(self.profile_path))[0]
|
||||
|
||||
if self.unicodes() == "*":
|
||||
return "%s.%s.all%s%s" % (
|
||||
font_base_name_parts[0],
|
||||
profile_name,
|
||||
self.instance_name(),
|
||||
font_base_name_parts[1],
|
||||
)
|
||||
elif self.unicodes() == "":
|
||||
return "%s.%s.no-unicodes%s%s" % (
|
||||
font_base_name_parts[0],
|
||||
profile_name,
|
||||
self.instance_name(),
|
||||
font_base_name_parts[1],
|
||||
)
|
||||
else:
|
||||
return "%s.%s.%s%s%s" % (
|
||||
font_base_name_parts[0],
|
||||
profile_name,
|
||||
self.unicodes(),
|
||||
self.instance_name(),
|
||||
font_base_name_parts[1],
|
||||
)
|
||||
|
||||
def get_font_extension(self):
|
||||
font_base_name = os.path.basename(self.font_path)
|
||||
font_base_name_parts = os.path.splitext(font_base_name)
|
||||
return font_base_name_parts[1]
|
||||
|
||||
def get_font_extension(self):
|
||||
font_base_name = os.path.basename(self.font_path)
|
||||
font_base_name_parts = os.path.splitext(font_base_name)
|
||||
return font_base_name_parts[1]
|
||||
|
||||
# A group of tests to perform on the subsetter. Each test
|
||||
# Identifies a font a subsetting profile, and a subset to be cut.
|
||||
class SubsetTestSuite:
|
||||
|
||||
def __init__(self, test_path, definition):
|
||||
self.test_path = test_path
|
||||
self.fonts = []
|
||||
self.profiles = []
|
||||
self.subsets = []
|
||||
self.instances = []
|
||||
self.options = []
|
||||
self.iup_options = []
|
||||
self._parse(definition)
|
||||
def __init__(self, test_path, definition):
|
||||
self.test_path = test_path
|
||||
self.fonts = []
|
||||
self.profiles = []
|
||||
self.subsets = []
|
||||
self.instances = []
|
||||
self.options = []
|
||||
self.iup_options = []
|
||||
self._parse(definition)
|
||||
|
||||
def get_output_directory(self):
|
||||
test_name = os.path.splitext(os.path.basename(self.test_path))[0]
|
||||
data_dir = os.path.join(os.path.dirname(self.test_path), "..")
|
||||
def get_output_directory(self):
|
||||
test_name = os.path.splitext(os.path.basename(self.test_path))[0]
|
||||
data_dir = os.path.join(os.path.dirname(self.test_path), "..")
|
||||
|
||||
output_dir = os.path.normpath(os.path.join(data_dir, "expected", test_name))
|
||||
if not os.path.exists(output_dir):
|
||||
os.mkdir(output_dir)
|
||||
if not os.path.isdir(output_dir):
|
||||
raise Exception("%s is not a directory." % output_dir)
|
||||
output_dir = os.path.normpath(os.path.join(data_dir, "expected", test_name))
|
||||
if not os.path.exists(output_dir):
|
||||
os.mkdir(output_dir)
|
||||
if not os.path.isdir(output_dir):
|
||||
raise Exception("%s is not a directory." % output_dir)
|
||||
|
||||
return output_dir
|
||||
return output_dir
|
||||
|
||||
def tests(self):
|
||||
for font in self.fonts:
|
||||
font = os.path.join(self._base_path(), "fonts", font)
|
||||
for profile in self.profiles:
|
||||
profile = os.path.join(self._base_path(), "profiles", profile)
|
||||
for subset in self.subsets:
|
||||
if self.instances:
|
||||
for instance in self.instances:
|
||||
if self.iup_options:
|
||||
for iup_option in self.iup_options:
|
||||
yield Test(font, profile, subset, instance, iup_option == 'Yes', options=self.options)
|
||||
else:
|
||||
yield Test(font, profile, subset, instance, False, options=self.options)
|
||||
else:
|
||||
yield Test(font, profile, subset, "", False, options=self.options)
|
||||
def tests(self):
|
||||
for font in self.fonts:
|
||||
font = os.path.join(self._base_path(), "fonts", font)
|
||||
for profile in self.profiles:
|
||||
profile = os.path.join(self._base_path(), "profiles", profile)
|
||||
for subset in self.subsets:
|
||||
if self.instances:
|
||||
for instance in self.instances:
|
||||
if self.iup_options:
|
||||
for iup_option in self.iup_options:
|
||||
yield Test(
|
||||
font,
|
||||
profile,
|
||||
subset,
|
||||
instance,
|
||||
iup_option == "Yes",
|
||||
options=self.options,
|
||||
)
|
||||
else:
|
||||
yield Test(
|
||||
font,
|
||||
profile,
|
||||
subset,
|
||||
instance,
|
||||
False,
|
||||
options=self.options,
|
||||
)
|
||||
else:
|
||||
yield Test(
|
||||
font, profile, subset, "", False, options=self.options
|
||||
)
|
||||
|
||||
def _base_path(self):
|
||||
return os.path.dirname(os.path.dirname(self.test_path))
|
||||
def _base_path(self):
|
||||
return os.path.dirname(os.path.dirname(self.test_path))
|
||||
|
||||
def _parse(self, definition):
|
||||
destinations = {
|
||||
"FONTS:": self.fonts,
|
||||
"PROFILES:": self.profiles,
|
||||
"SUBSETS:": self.subsets,
|
||||
"INSTANCES:": self.instances,
|
||||
"OPTIONS:": self.options,
|
||||
"IUP_OPTIONS:": self.iup_options,
|
||||
}
|
||||
def _parse(self, definition):
|
||||
destinations = {
|
||||
"FONTS:": self.fonts,
|
||||
"PROFILES:": self.profiles,
|
||||
"SUBSETS:": self.subsets,
|
||||
"INSTANCES:": self.instances,
|
||||
"OPTIONS:": self.options,
|
||||
"IUP_OPTIONS:": self.iup_options,
|
||||
}
|
||||
|
||||
current_destination = None
|
||||
for line in definition.splitlines():
|
||||
line = line.strip()
|
||||
current_destination = None
|
||||
for line in definition.splitlines():
|
||||
line = line.strip()
|
||||
|
||||
if line.startswith("#"):
|
||||
continue
|
||||
if line.startswith("#"):
|
||||
continue
|
||||
|
||||
if not line:
|
||||
continue
|
||||
if not line:
|
||||
continue
|
||||
|
||||
if line in destinations:
|
||||
current_destination = destinations[line]
|
||||
elif current_destination is not None:
|
||||
current_destination.append(line)
|
||||
else:
|
||||
raise Exception("Failed to parse test suite file.")
|
||||
if line in destinations:
|
||||
current_destination = destinations[line]
|
||||
elif current_destination is not None:
|
||||
current_destination.append(line)
|
||||
else:
|
||||
raise Exception("Failed to parse test suite file.")
|
||||
|
|
|
@ -33,12 +33,16 @@ struct face_options_t
|
|||
{
|
||||
~face_options_t ()
|
||||
{
|
||||
g_free (face_loader);
|
||||
g_free (font_file);
|
||||
g_free (face_loader);
|
||||
hb_face_destroy (face);
|
||||
}
|
||||
|
||||
void set_face (hb_face_t *face_)
|
||||
{ face = face_; }
|
||||
{
|
||||
hb_face_destroy (face);
|
||||
face = hb_face_reference (face_);
|
||||
}
|
||||
|
||||
void add_options (option_parser_t *parser);
|
||||
|
||||
|
@ -116,7 +120,7 @@ face_options_t::post_parse (GError **error)
|
|||
}
|
||||
}
|
||||
|
||||
face = cache.face;
|
||||
set_face (cache.face);
|
||||
}
|
||||
|
||||
static G_GNUC_NORETURN gboolean
|
||||
|
|
|
@ -71,7 +71,7 @@ struct subset_main_t : option_parser_t, face_options_t, output_options_t<false>
|
|||
main2.option_parser_t::parse (&argc, &args);
|
||||
g_free (args);
|
||||
|
||||
set_face (hb_face_reference (main2.face));
|
||||
set_face (main2.face);
|
||||
}
|
||||
|
||||
void parse (int argc, char **argv)
|
||||
|
|
Loading…
Add table
Reference in a new issue