TODO | 4 - src/hb-blob.cc | 5 - src/hb-blob.h | 3 src/hb-buffer.cc | 17 ++-- src/hb-buffer.h | 15 ++- src/hb-common.cc | 13 ++- src/hb-font-private.hh | 9 +- src/hb-font.cc | 100 ++++++++++++++++++------- src/hb-font.h | 34 ++++++-- src/hb-ft.cc | 10 +- src/hb-object-private.hh | 13 ++- src/hb-ot-layout-private.hh | 9 -- src/hb-ot-layout.cc | 23 ----- src/hb-private.hh | 16 ++-- src/hb-shape.cc | 78 ++++++++------------ src/hb-unicode.cc | 5 - src/hb-unicode.h | 3 src/hb-uniscribe-shape.cc | 170 +++++++++++++++++++++++++++++++++----------- src/main.cc | 1 test/Makefile.am | 8 ++ test/test-c.c | 10 +- test/test-object.c | 33 ++++---- 22 files changed, 357 insertions(+), 222 deletions(-)
New commits: commit 255f176fdcd42ab94f9c3c54e2bffb55d0b1a8f5 Author: Behdad Esfahbod <[email protected]> Date: Tue Aug 9 08:35:07 2011 +0200 Minor diff --git a/src/hb-uniscribe-shape.cc b/src/hb-uniscribe-shape.cc index 7962f3a..a0020ca 100644 --- a/src/hb-uniscribe-shape.cc +++ b/src/hb-uniscribe-shape.cc @@ -92,7 +92,7 @@ populate_log_font (LOGFONTW *lf, } -static struct hb_uniscribe_face_data_t{ +static struct hb_uniscribe_face_data_t { HANDLE fh; } _hb_uniscribe_face_data_nil = {0}; commit a9057eb3f38018faa1ece53c4aaeeba798b41fd1 Author: Behdad Esfahbod <[email protected]> Date: Tue Aug 9 00:47:55 2011 +0200 [uniscribe] Unbreak diff --git a/src/hb-uniscribe-shape.cc b/src/hb-uniscribe-shape.cc index b3653e7..7962f3a 100644 --- a/src/hb-uniscribe-shape.cc +++ b/src/hb-uniscribe-shape.cc @@ -219,11 +219,11 @@ hb_uniscribe_shape (hb_font_t *font, } HB_STMT_END; hb_uniscribe_face_data_t *face_data = _hb_uniscribe_face_get_data (font->face); - if (unlikely (!face_data)) + if (unlikely (!face_data->fh)) FAIL ("Couldn't get face data"); hb_uniscribe_font_data_t *font_data = _hb_uniscribe_font_get_data (font); - if (unlikely (!font_data)) + if (unlikely (!font_data->hfont)) FAIL ("Couldn't get font font"); if (unlikely (!buffer->len)) commit c0975e12315b7167b92411584d2f00a751bbc204 Author: Behdad Esfahbod <[email protected]> Date: Tue Aug 9 00:46:18 2011 +0200 Fix build again diff --git a/test/Makefile.am b/test/Makefile.am index 9e22b1f..07f3ccf 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -58,6 +58,9 @@ endif if HAVE_FREETYPE test_object_CPPFLAGS = $(AM_CPPFLAGS) $(FREETYPE_CFLAGS) test_object_LDADD = $(LDADD) $(FREETYPE_LIBS) +else +test_object_CPPFLAGS = $(AM_CPPFLAGS) +test_object_LDADD = $(LDADD) endif commit 33ccc77902660ed4b49184e5ec99f4fd0ef63175 Author: Behdad Esfahbod <[email protected]> Date: Tue Aug 9 00:43:24 2011 +0200 [API] Make set_user_data() functions take a replace parameter We need this to set data on objects safely without worrying that some other thread unsets it by setting it at the same time. diff --git a/src/hb-blob.cc b/src/hb-blob.cc index 7ed3812..58d7324 100644 --- a/src/hb-blob.cc +++ b/src/hb-blob.cc @@ -165,9 +165,10 @@ hb_bool_t hb_blob_set_user_data (hb_blob_t *blob, hb_user_data_key_t *key, void * data, - hb_destroy_func_t destroy) + hb_destroy_func_t destroy, + hb_bool_t replace) { - return hb_object_set_user_data (blob, key, data, destroy); + return hb_object_set_user_data (blob, key, data, destroy, replace); } void * diff --git a/src/hb-blob.h b/src/hb-blob.h index f2eaae9..50c9ae3 100644 --- a/src/hb-blob.h +++ b/src/hb-blob.h @@ -66,7 +66,8 @@ hb_bool_t hb_blob_set_user_data (hb_blob_t *blob, hb_user_data_key_t *key, void * data, - hb_destroy_func_t destroy); + hb_destroy_func_t destroy, + hb_bool_t replace); void * diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc index e0c86f5..3be3f44 100644 --- a/src/hb-buffer.cc +++ b/src/hb-buffer.cc @@ -532,9 +532,10 @@ hb_bool_t hb_buffer_set_user_data (hb_buffer_t *buffer, hb_user_data_key_t *key, void * data, - hb_destroy_func_t destroy) + hb_destroy_func_t destroy, + hb_bool_t replace) { - return hb_object_set_user_data (buffer, key, data, destroy); + return hb_object_set_user_data (buffer, key, data, destroy, replace); } void * diff --git a/src/hb-buffer.h b/src/hb-buffer.h index a43a8d1..a5efce3 100644 --- a/src/hb-buffer.h +++ b/src/hb-buffer.h @@ -75,7 +75,8 @@ hb_bool_t hb_buffer_set_user_data (hb_buffer_t *buffer, hb_user_data_key_t *key, void * data, - hb_destroy_func_t destroy); + hb_destroy_func_t destroy, + hb_bool_t replace); void * hb_buffer_get_user_data (hb_buffer_t *buffer, diff --git a/src/hb-common.cc b/src/hb-common.cc index afbe941..48382ca 100644 --- a/src/hb-common.cc +++ b/src/hb-common.cc @@ -301,17 +301,20 @@ static hb_static_mutex_t user_data_lock; bool hb_user_data_array_t::set (hb_user_data_key_t *key, void * data, - hb_destroy_func_t destroy) + hb_destroy_func_t destroy, + hb_bool_t replace) { if (!key) return false; - if (!data && !destroy) { - items.remove (key, user_data_lock); - return true; + if (replace) { + if (!data && !destroy) { + items.remove (key, user_data_lock); + return true; + } } hb_user_data_item_t item = {key, data, destroy}; - bool ret = !!items.replace_or_insert (item, user_data_lock); + bool ret = !!items.replace_or_insert (item, user_data_lock, replace); return ret; } diff --git a/src/hb-font.cc b/src/hb-font.cc index 4be2a2e..d3fbcbe 100644 --- a/src/hb-font.cc +++ b/src/hb-font.cc @@ -248,9 +248,10 @@ hb_bool_t hb_font_funcs_set_user_data (hb_font_funcs_t *ffuncs, hb_user_data_key_t *key, void * data, - hb_destroy_func_t destroy) + hb_destroy_func_t destroy, + hb_bool_t replace) { - return hb_object_set_user_data (ffuncs, key, data, destroy); + return hb_object_set_user_data (ffuncs, key, data, destroy, replace); } void * @@ -667,9 +668,10 @@ hb_bool_t hb_face_set_user_data (hb_face_t *face, hb_user_data_key_t *key, void * data, - hb_destroy_func_t destroy) + hb_destroy_func_t destroy, + hb_bool_t replace) { - return hb_object_set_user_data (face, key, data, destroy); + return hb_object_set_user_data (face, key, data, destroy, replace); } void * @@ -852,9 +854,10 @@ hb_bool_t hb_font_set_user_data (hb_font_t *font, hb_user_data_key_t *key, void * data, - hb_destroy_func_t destroy) + hb_destroy_func_t destroy, + hb_bool_t replace) { - return hb_object_set_user_data (font, key, data, destroy); + return hb_object_set_user_data (font, key, data, destroy, replace); } void * diff --git a/src/hb-font.h b/src/hb-font.h index 7f8cd5e..363ab55 100644 --- a/src/hb-font.h +++ b/src/hb-font.h @@ -65,7 +65,8 @@ hb_bool_t hb_face_set_user_data (hb_face_t *face, hb_user_data_key_t *key, void * data, - hb_destroy_func_t destroy); + hb_destroy_func_t destroy, + hb_bool_t replace); void * @@ -123,7 +124,8 @@ hb_bool_t hb_font_funcs_set_user_data (hb_font_funcs_t *ffuncs, hb_user_data_key_t *key, void * data, - hb_destroy_func_t destroy); + hb_destroy_func_t destroy, + hb_bool_t replace); void * @@ -338,7 +340,8 @@ hb_bool_t hb_font_set_user_data (hb_font_t *font, hb_user_data_key_t *key, void * data, - hb_destroy_func_t destroy); + hb_destroy_func_t destroy, + hb_bool_t replace); void * diff --git a/src/hb-object-private.hh b/src/hb-object-private.hh index c0a7bbe..adaa6e8 100644 --- a/src/hb-object-private.hh +++ b/src/hb-object-private.hh @@ -122,7 +122,8 @@ struct hb_user_data_array_t { HB_INTERNAL bool set (hb_user_data_key_t *key, void * data, - hb_destroy_func_t destroy); + hb_destroy_func_t destroy, + hb_bool_t replace); HB_INTERNAL void *get (hb_user_data_key_t *key); @@ -178,11 +179,12 @@ struct _hb_object_header_t { inline bool set_user_data (hb_user_data_key_t *key, void * data, - hb_destroy_func_t destroy_func) { + hb_destroy_func_t destroy_func, + hb_bool_t replace) { if (unlikely (!this || this->is_inert ())) return false; - return user_data.set (key, data, destroy_func); + return user_data.set (key, data, destroy_func, replace); } inline void *get_user_data (hb_user_data_key_t *key) { @@ -237,9 +239,10 @@ template <typename Type> static inline bool hb_object_set_user_data (Type *obj, hb_user_data_key_t *key, void * data, - hb_destroy_func_t destroy) + hb_destroy_func_t destroy, + hb_bool_t replace) { - return obj->header.set_user_data (key, data, destroy); + return obj->header.set_user_data (key, data, destroy, replace); } template <typename Type> diff --git a/src/hb-private.hh b/src/hb-private.hh index b2ef802..413becd 100644 --- a/src/hb-private.hh +++ b/src/hb-private.hh @@ -343,15 +343,21 @@ struct hb_lockable_set_t hb_array_t <item_t> items; template <typename T> - inline item_t *replace_or_insert (T v, lock_t &l) + inline item_t *replace_or_insert (T v, lock_t &l, bool replace) { l.lock (); item_t *item = items.find (v); if (item) { - item_t old = *item; - *item = v; - l.unlock (); - old.finish (); + if (replace) { + item_t old = *item; + *item = v; + l.unlock (); + old.finish (); + } + else { + item = NULL; + l.unlock (); + } } else { item = items.push (); if (likely (item)) diff --git a/src/hb-shape.cc b/src/hb-shape.cc index 4202302..9a4ebfe 100644 --- a/src/hb-shape.cc +++ b/src/hb-shape.cc @@ -76,7 +76,7 @@ static struct static_shaper_list_t end = p + strlen (p); for (unsigned int j = i; j < ARRAY_LENGTH (shapers); j++) - if (end - p == strlen (shapers[j].name) && + if (end - p == (int) strlen (shapers[j].name) && 0 == strncmp (shapers[j].name, p, end - p)) { /* Reorder this shaper to position i */ diff --git a/src/hb-unicode.cc b/src/hb-unicode.cc index 2286f7b..4b285c5 100644 --- a/src/hb-unicode.cc +++ b/src/hb-unicode.cc @@ -175,9 +175,10 @@ hb_bool_t hb_unicode_funcs_set_user_data (hb_unicode_funcs_t *ufuncs, hb_user_data_key_t *key, void * data, - hb_destroy_func_t destroy) + hb_destroy_func_t destroy, + hb_bool_t replace) { - return hb_object_set_user_data (ufuncs, key, data, destroy); + return hb_object_set_user_data (ufuncs, key, data, destroy, replace); } void * diff --git a/src/hb-unicode.h b/src/hb-unicode.h index 9aa97a6..13886df 100644 --- a/src/hb-unicode.h +++ b/src/hb-unicode.h @@ -66,7 +66,8 @@ hb_bool_t hb_unicode_funcs_set_user_data (hb_unicode_funcs_t *ufuncs, hb_user_data_key_t *key, void * data, - hb_destroy_func_t destroy); + hb_destroy_func_t destroy, + hb_bool_t replace); void * diff --git a/src/hb-uniscribe-shape.cc b/src/hb-uniscribe-shape.cc index fa29cde..b3653e7 100644 --- a/src/hb-uniscribe-shape.cc +++ b/src/hb-uniscribe-shape.cc @@ -129,10 +129,15 @@ _hb_uniscribe_face_get_data (hb_face_t *face) DEBUG_MSG (UNISCRIBE, face, "Face AddFontMemResourceEx() failed"); if (unlikely (!hb_face_set_user_data (face, &uniscribe_face_data_key, data, - (hb_destroy_func_t) _hb_uniscribe_face_data_destroy))) + (hb_destroy_func_t) _hb_uniscribe_face_data_destroy, + FALSE))) { _hb_uniscribe_face_data_destroy (data); - return &_hb_uniscribe_face_data_nil; + data = (hb_uniscribe_face_data_t *) hb_face_get_user_data (face, &uniscribe_face_data_key); + if (data) + return data; + else + return &_hb_uniscribe_face_data_nil; } return data; @@ -183,10 +188,15 @@ _hb_uniscribe_font_get_data (hb_font_t *font) } if (unlikely (!hb_font_set_user_data (font, &uniscribe_font_data_key, data, - (hb_destroy_func_t) _hb_uniscribe_font_data_destroy))) + (hb_destroy_func_t) _hb_uniscribe_font_data_destroy, + FALSE))) { _hb_uniscribe_font_data_destroy (data); - return &_hb_uniscribe_font_data_nil; + data = (hb_uniscribe_font_data_t *) hb_font_get_user_data (font, &uniscribe_font_data_key); + if (data) + return data; + else + return &_hb_uniscribe_font_data_nil; } return data; diff --git a/test/test-object.c b/test/test-object.c index d0145c5..07cf158 100644 --- a/test/test-object.c +++ b/test/test-object.c @@ -116,7 +116,7 @@ create_unicode_funcs_inert (void) 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); +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); @@ -247,7 +247,7 @@ test_object (void) if (o->is_immutable) g_assert (!o->is_immutable (obj)); - g_assert (o->set_user_data (obj, &key[0], &data[0], free_up0)); + g_assert (o->set_user_data (obj, &key[0], &data[0], free_up0, TRUE)); g_assert (o->get_user_data (obj, &key[0]) == &data[0]); if (o->is_immutable) { @@ -256,38 +256,39 @@ test_object (void) } /* Should still work even if object is made immutable */ - g_assert (o->set_user_data (obj, &key[1], &data[1], free_up1)); + g_assert (o->set_user_data (obj, &key[1], &data[1], free_up1, TRUE)); g_assert (o->get_user_data (obj, &key[1]) == &data[1]); - g_assert (!o->set_user_data (obj, NULL, &data[0], free_up0)); + g_assert (!o->set_user_data (obj, NULL, &data[0], free_up0, TRUE)); g_assert (o->get_user_data (obj, &key[0]) == &data[0]); - g_assert (o->set_user_data (obj, &key[0], &data[1], NULL)); + g_assert (o->set_user_data (obj, &key[0], &data[1], NULL, TRUE)); g_assert (data[0].freed); g_assert (o->get_user_data (obj, &key[0]) == &data[1]); g_assert (!data[1].freed); data[0].freed = FALSE; - g_assert (o->set_user_data (obj, &key[0], &data[0], free_up0)); + g_assert (o->set_user_data (obj, &key[0], &data[0], free_up0, TRUE)); g_assert (!data[0].freed); - g_assert (o->set_user_data (obj, &key[0], NULL, NULL)); + g_assert (o->set_user_data (obj, &key[0], NULL, NULL, TRUE)); g_assert (data[0].freed); data[0].freed = FALSE; global_data = 0; - g_assert (o->set_user_data (obj, &key[0], &data[0], free_up0)); + g_assert (o->set_user_data (obj, &key[0], &data[0], free_up0, TRUE)); + g_assert (!o->set_user_data (obj, &key[0], &data[0], free_up0, FALSE)); g_assert_cmpuint (global_data, ==, 0); - g_assert (o->set_user_data (obj, &key[0], NULL, global_free_up)); + g_assert (o->set_user_data (obj, &key[0], NULL, global_free_up, TRUE)); g_assert_cmpuint (global_data, ==, 0); - g_assert (o->set_user_data (obj, &key[0], NULL, NULL)); + g_assert (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 (o->set_user_data (obj, &key[j], &data[j], global_free_up)); + g_assert (o->set_user_data (obj, &key[j], &data[j], global_free_up, TRUE)); for (j = 2; j < 1000; j++) g_assert (o->get_user_data (obj, &key[j]) == &data[j]); for (j = 100; j < 1000; j++) - g_assert (o->set_user_data (obj, &key[j], NULL, NULL)); + g_assert (o->set_user_data (obj, &key[j], NULL, NULL, TRUE)); for (j = 2; j < 100; j++) g_assert (o->get_user_data (obj, &key[j]) == &data[j]); for (j = 100; j < 1000; j++) @@ -298,8 +299,8 @@ test_object (void) * Make sure it doesn't deadlock or corrupt memory. */ deadlock_test.klass = o; deadlock_test.object = obj; - g_assert (o->set_user_data (obj, &deadlock_test.key, &deadlock_test, free_deadlock_test)); - g_assert (o->set_user_data (obj, &deadlock_test.key, NULL, NULL)); + g_assert (o->set_user_data (obj, &deadlock_test.key, &deadlock_test, free_deadlock_test, TRUE)); + g_assert (o->set_user_data (obj, &deadlock_test.key, NULL, NULL, TRUE)); g_assert (!data[1].freed); o->destroy (obj); @@ -321,7 +322,7 @@ test_object (void) if (o->is_immutable) g_assert (o->is_immutable (obj)); - g_assert (!o->set_user_data (obj, &key[0], &data[0], free_up0)); + g_assert (!o->set_user_data (obj, &key[0], &data[0], free_up0, TRUE)); g_assert (!o->get_user_data (obj, &key[0])); o->destroy (obj); @@ -349,7 +350,7 @@ test_object (void) if (o->is_immutable) g_assert (o->is_immutable (obj)); - g_assert (!o->set_user_data (obj, &key[0], &data[0], free_up0)); + g_assert (!o->set_user_data (obj, &key[0], &data[0], free_up0, TRUE)); g_assert (!o->get_user_data (obj, &key[0])); o->destroy (obj); commit 944b2ba1ce076385f985212bbdf2df96a8a995f0 Author: Behdad Esfahbod <[email protected]> Date: Tue Aug 9 00:23:58 2011 +0200 [buffer] Make API take signed int length Since we already switched to accepting -1 as 'zero-terminated'. diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc index 53b3200..e0c86f5 100644 --- a/src/hb-buffer.cc +++ b/src/hb-buffer.cc @@ -776,9 +776,9 @@ hb_utf8_next (const uint8_t *text, void hb_buffer_add_utf8 (hb_buffer_t *buffer, const char *text, - unsigned int text_length HB_UNUSED, + int text_length, unsigned int item_offset, - unsigned int item_length) + int item_length) { #define UTF_NEXT(S, E, U) hb_utf8_next (S, E, &(U)) ADD_UTF (uint8_t); @@ -810,9 +810,9 @@ hb_utf16_next (const uint16_t *text, void hb_buffer_add_utf16 (hb_buffer_t *buffer, const uint16_t *text, - unsigned int text_length HB_UNUSED, + int text_length, unsigned int item_offset, - unsigned int item_length) + int item_length) { #define UTF_NEXT(S, E, U) hb_utf16_next (S, E, &(U)) ADD_UTF (uint16_t); @@ -822,9 +822,9 @@ hb_buffer_add_utf16 (hb_buffer_t *buffer, void hb_buffer_add_utf32 (hb_buffer_t *buffer, const uint32_t *text, - unsigned int text_length HB_UNUSED, + int text_length, unsigned int item_offset, - unsigned int item_length) + int item_length) { #define UTF_NEXT(S, E, U) ((U) = *(S), (S)+1) ADD_UTF (uint32_t); diff --git a/src/hb-buffer.h b/src/hb-buffer.h index 1c4a9a7..a43a8d1 100644 --- a/src/hb-buffer.h +++ b/src/hb-buffer.h @@ -147,23 +147,23 @@ hb_buffer_add (hb_buffer_t *buffer, void hb_buffer_add_utf8 (hb_buffer_t *buffer, const char *text, - unsigned int text_length, + int text_length, unsigned int item_offset, - unsigned int item_length); + int item_length); void hb_buffer_add_utf16 (hb_buffer_t *buffer, const uint16_t *text, - unsigned int text_length, + int text_length, unsigned int item_offset, - unsigned int item_length); + int item_length); void hb_buffer_add_utf32 (hb_buffer_t *buffer, const uint32_t *text, - unsigned int text_length, + int text_length, unsigned int item_offset, - unsigned int item_length); + int item_length); /* Clears any new items added at the end */ diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index d5829b0..b05e494 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -26,8 +26,6 @@ * Red Hat Author(s): Behdad Esfahbod */ -#define HB_OT_LAYOUT_CC - #include "hb-ot-layout-private.hh" #include "hb-ot-layout-gdef-private.hh" diff --git a/src/main.cc b/src/main.cc index 6fd5e1e..e13a40d 100644 --- a/src/main.cc +++ b/src/main.cc @@ -24,7 +24,6 @@ * Red Hat Author(s): Behdad Esfahbod */ -#define HB_OT_LAYOUT_CC #include "hb-mutex-private.hh" #include "hb-open-file-private.hh" #include "hb-ot-layout-gdef-private.hh" commit de1e1cf9bccfd116d495804e230dc2e12b733a2d Author: Behdad Esfahbod <[email protected]> Date: Tue Aug 9 00:19:38 2011 +0200 [FT] Adapt to new face API diff --git a/src/hb-ft.cc b/src/hb-ft.cc index 953f0a6..7152805 100644 --- a/src/hb-ft.cc +++ b/src/hb-ft.cc @@ -293,6 +293,9 @@ hb_ft_face_create (FT_Face ft_face, face = hb_face_create_for_tables (reference_table, ft_face, destroy); } + hb_face_set_index (face, ft_face->face_index); + hb_face_set_upem (face, ft_face->units_per_EM); + return face; } commit 458c89a85695220d43b69dbae36fc93e3fe78d89 Author: Behdad Esfahbod <[email protected]> Date: Tue Aug 9 00:19:19 2011 +0200 Minor diff --git a/test/test-c.c b/test/test-c.c index e72db27..7e7c502 100644 --- a/test/test-c.c +++ b/test/test-c.c @@ -31,23 +31,23 @@ #include <hb.h> -#if HAVE_GLIB +#ifdef HAVE_GLIB #include <hb-glib.h> #endif -#if HAVE_ICU +#ifdef HAVE_ICU #include <hb-icu.h> #endif -#if HAVE_FREETYPE +#ifdef HAVE_FREETYPE #include <hb-ft.h> #endif -#if HAVE_OT +#ifdef HAVE_OT #include <hb-ot.h> #endif -#if HAVE_UNISCRIBE +#ifdef HAVE_UNISCRIBE #include <hb-uniscribe.h> #endif commit bf3eef540f81fdeba1c36263d7d5b2ec4c5f07b1 Author: Behdad Esfahbod <[email protected]> Date: Tue Aug 9 00:13:24 2011 +0200 [uniscribe] Cleanup backend diff --git a/TODO b/TODO index 917f131..81a0afb 100644 --- a/TODO +++ b/TODO @@ -29,6 +29,8 @@ API issues to fix before 1.0: API to add (maybe after 1.0): ============================ +- Add Uniscribe face / font get API + - BCP 47 language handling / API (language_matches?) - Add hb_face_get_glyph_count()? diff --git a/src/hb-uniscribe-shape.cc b/src/hb-uniscribe-shape.cc index 4315d34..fa29cde 100644 --- a/src/hb-uniscribe-shape.cc +++ b/src/hb-uniscribe-shape.cc @@ -91,6 +91,108 @@ populate_log_font (LOGFONTW *lf, return TRUE; } + +static struct hb_uniscribe_face_data_t{ + HANDLE fh; +} _hb_uniscribe_face_data_nil = {0}; + +static hb_user_data_key_t uniscribe_face_data_key; + +static void +_hb_uniscribe_face_data_destroy (hb_uniscribe_face_data_t *data) +{ + if (data->fh) + RemoveFontMemResourceEx (data->fh); + free (data); +} + +static hb_uniscribe_face_data_t * +_hb_uniscribe_face_get_data (hb_face_t *face) +{ + hb_uniscribe_face_data_t *data = (hb_uniscribe_face_data_t *) hb_face_get_user_data (face, &uniscribe_face_data_key); + if (likely (data)) return data; + + data = (hb_uniscribe_face_data_t *) calloc (1, sizeof (hb_uniscribe_face_data_t)); + if (unlikely (!data)) + return &_hb_uniscribe_face_data_nil; + + hb_blob_t *blob = hb_face_reference_blob (face); + unsigned int blob_length; + const char *blob_data = hb_blob_get_data (blob, &blob_length); + if (unlikely (!blob_length)) + DEBUG_MSG (UNISCRIBE, face, "Face has empty blob"); + + DWORD num_fonts_installed; + data->fh = AddFontMemResourceEx ((void *) blob_data, blob_length, 0, &num_fonts_installed); + hb_blob_destroy (blob); + if (unlikely (!data->fh)) + DEBUG_MSG (UNISCRIBE, face, "Face AddFontMemResourceEx() failed"); + + if (unlikely (!hb_face_set_user_data (face, &uniscribe_face_data_key, data, + (hb_destroy_func_t) _hb_uniscribe_face_data_destroy))) + { + _hb_uniscribe_face_data_destroy (data); + return &_hb_uniscribe_face_data_nil; + } + + return data; +} + + +static struct hb_uniscribe_font_data_t { + HDC hdc; + HFONT hfont; + SCRIPT_CACHE script_cache; +} _hb_uniscribe_font_data_nil = {NULL, NULL, NULL}; + +static hb_user_data_key_t uniscribe_font_data_key; + +static void +_hb_uniscribe_font_data_destroy (hb_uniscribe_font_data_t *data) +{ + if (data->hdc) + ReleaseDC (NULL, data->hdc); + if (data->hfont) + DeleteObject (data->hfont); + if (data->script_cache) + ScriptFreeCache (&data->script_cache); + free (data); +} + +static hb_uniscribe_font_data_t * +_hb_uniscribe_font_get_data (hb_font_t *font) +{ + hb_uniscribe_font_data_t *data = (hb_uniscribe_font_data_t *) hb_font_get_user_data (font, &uniscribe_font_data_key); + if (likely (data)) return data; + + data = (hb_uniscribe_font_data_t *) calloc (1, sizeof (hb_uniscribe_font_data_t)); + if (unlikely (!data)) + return &_hb_uniscribe_font_data_nil; + + data->hdc = GetDC (NULL); + + LOGFONTW log_font; + if (unlikely (!populate_log_font (&log_font, data->hdc, font))) + DEBUG_MSG (UNISCRIBE, font, "Font populate_log_font() failed"); + else { + data->hfont = CreateFontIndirectW (&log_font); + if (unlikely (!data->hfont)) + DEBUG_MSG (UNISCRIBE, font, "Font CreateFontIndirectW() failed"); + if (!SelectObject (data->hdc, data->hfont)) + DEBUG_MSG (UNISCRIBE, font, "Font SelectObject() failed"); + } + + if (unlikely (!hb_font_set_user_data (font, &uniscribe_font_data_key, data, + (hb_destroy_func_t) _hb_uniscribe_font_data_destroy))) + { + _hb_uniscribe_font_data_destroy (data); + return &_hb_uniscribe_font_data_nil; + } + + return data; +} + + hb_bool_t hb_uniscribe_shape (hb_font_t *font, hb_buffer_t *buffer, @@ -100,11 +202,25 @@ hb_uniscribe_shape (hb_font_t *font, { buffer->guess_properties (); - HRESULT hr; +#define FAIL(...) \ + HB_STMT_START { \ + DEBUG_MSG (UNISCRIBE, NULL, __VA_ARGS__); \ + return FALSE; \ + } HB_STMT_END; + + hb_uniscribe_face_data_t *face_data = _hb_uniscribe_face_get_data (font->face); + if (unlikely (!face_data)) + FAIL ("Couldn't get face data"); + + hb_uniscribe_font_data_t *font_data = _hb_uniscribe_font_get_data (font); + if (unlikely (!font_data)) + FAIL ("Couldn't get font font"); if (unlikely (!buffer->len)) return TRUE; + HRESULT hr; + retry: unsigned int scratch_size; @@ -152,13 +268,6 @@ retry: ALLOCATE_ARRAY (uint32_t, vis_clusters, glyphs_size); -#define FAIL(...) \ - HB_STMT_START { \ - DEBUG_MSG (UNISCRIBE, NULL, __VA_ARGS__); \ - return FALSE; \ - } HB_STMT_END; - - #define MAX_ITEMS 10 SCRIPT_ITEM items[MAX_ITEMS + 1]; @@ -189,30 +298,6 @@ retry: /* XXX setup ranges */ } - hb_blob_t *blob = hb_face_reference_blob (font->face); - unsigned int blob_length; - const char *blob_data = hb_blob_get_data (blob, &blob_length); - if (unlikely (!blob_length)) - FAIL ("Empty font blob"); - - DWORD num_fonts_installed; - HANDLE fh = AddFontMemResourceEx ((void *) blob_data, blob_length, 0, &num_fonts_installed); - hb_blob_destroy (blob); - if (unlikely (!fh)) - FAIL ("AddFontMemResourceEx() failed"); - - /* FREE stuff, specially when taking fallback... */ - - HDC hdc = GetDC (NULL); /* XXX The DC should be cached on the face I guess? */ - - LOGFONTW log_font; - if (unlikely (!populate_log_font (&log_font, hdc, font))) - FAIL ("populate_log_font() failed"); - - HFONT hfont = CreateFontIndirectW (&log_font); - SelectObject (hdc, hfont); - - SCRIPT_CACHE script_cache = NULL; OPENTYPE_TAG language_tag = hb_ot_tag_from_language (buffer->props.language); unsigned int glyphs_offset = 0; @@ -223,8 +308,8 @@ retry: unsigned int item_chars_len = items[i + 1].iCharPos - chars_offset; OPENTYPE_TAG script_tag = script_tags[i]; /* XXX buffer->props.script */ - hr = ScriptShapeOpenType (hdc, - &script_cache, + hr = ScriptShapeOpenType (font_data->hdc, + &font_data->script_cache, &items[i].a, script_tag, language_tag, @@ -255,8 +340,8 @@ retry: if (unlikely (FAILED (hr))) FAIL ("ScriptShapeOpenType() failed: 0x%08xL", hr); - hr = ScriptPlaceOpenType (hdc, - &script_cache, + hr = ScriptPlaceOpenType (font_data->hdc, + &font_data->script_cache, &items[i].a, script_tag, language_tag, @@ -281,10 +366,6 @@ retry: } glyphs_len = glyphs_offset; - ReleaseDC (NULL, hdc); - DeleteObject (hfont); - RemoveFontMemResourceEx (fh); - /* Ok, we've got everything we need, now compose output buffer, * very, *very*, carefully! */ commit f1f848e2e46ac54ff08aca7cd83390af31c7c9ef Author: Behdad Esfahbod <[email protected]> Date: Mon Aug 8 23:41:06 2011 +0200 Fix build diff --git a/test/Makefile.am b/test/Makefile.am index b3c8cc2..9e22b1f 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -55,6 +55,11 @@ test_shape_complex_CPPFLAGS = $(AM_CPPFLAGS) $(FREETYPE_CFLAGS) test_shape_complex_LDADD = $(LDADD) $(FREETYPE_LIBS) endif +if HAVE_FREETYPE +test_object_CPPFLAGS = $(AM_CPPFLAGS) $(FREETYPE_CFLAGS) +test_object_LDADD = $(LDADD) $(FREETYPE_LIBS) +endif + # Default test running environment TESTS = $(TEST_PROGS) commit 3897335c7620c37e9a0224b0c42ade0dfdce4053 Author: Behdad Esfahbod <[email protected]> Date: Mon Aug 8 23:37:41 2011 +0200 [API] Sort out get_blob API hb_face_get_blob() renamed to hb_face_reference_blob(), returns a reference now. hb_face_[sg]et_index() added. hb_face_set_upem() added. diff --git a/src/hb-font-private.hh b/src/hb-font-private.hh index 06a5bc4..d896e72 100644 --- a/src/hb-font-private.hh +++ b/src/hb-font-private.hh @@ -94,6 +94,7 @@ struct _hb_face_t { struct hb_ot_layout_t *ot_layout; + unsigned int index; unsigned int upem; }; @@ -154,7 +155,7 @@ struct _hb_font_t { private: - inline hb_position_t em_scale (int16_t v, int scale) { return v * (int64_t) scale / this->face->upem; } + inline hb_position_t em_scale (int16_t v, int scale) { return v * (int64_t) scale / hb_face_get_upem (this->face); } }; diff --git a/src/hb-font.cc b/src/hb-font.cc index c795c8a..4be2a2e 100644 --- a/src/hb-font.cc +++ b/src/hb-font.cc @@ -31,6 +31,7 @@ #include "hb-font-private.hh" #include "hb-blob.h" #include "hb-open-file-private.hh" +#include "hb-ot-head-private.hh" #include <string.h> @@ -538,7 +539,8 @@ static hb_face_t _hb_face_nil = { NULL, /* ot_layout */ - 1000 + 0, /* index */ + 1000 /* upem */ }; @@ -561,7 +563,7 @@ hb_face_create_for_tables (hb_reference_table_func_t reference_table, face->ot_layout = _hb_ot_layout_create (face); - face->upem = _hb_ot_layout_get_upem (face); + face->upem = 0; return face; } @@ -599,6 +601,9 @@ _hb_face_for_data_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void { hb_face_for_data_closure_t *data = (hb_face_for_data_closure_t *) user_data; + if (tag == HB_TAG_NONE) + return hb_blob_reference (data->blob); + const OpenTypeFontFile &ot_file = *Sanitizer<OpenTypeFontFile>::lock_instance (data->blob); const OpenTypeFontFace &ot_face = ot_file.get_face (data->index); @@ -613,6 +618,8 @@ hb_face_t * hb_face_create (hb_blob_t *blob, unsigned int index) { + hb_face_t *face; + if (unlikely (!blob || !hb_blob_get_length (blob))) return &_hb_face_nil; @@ -621,9 +628,13 @@ hb_face_create (hb_blob_t *blob, if (unlikely (!closure)) return &_hb_face_nil; - return hb_face_create_for_tables (_hb_face_for_data_reference_table, + face = hb_face_create_for_tables (_hb_face_for_data_reference_table, closure, (hb_destroy_func_t) _hb_face_for_data_closure_destroy); + + hb_face_set_index (face, index); + + return face; } hb_face_t * @@ -685,16 +696,6 @@ hb_face_is_immutable (hb_face_t *face) hb_blob_t * -hb_face_get_blob (hb_face_t *face) -{ - if (face->destroy != (hb_destroy_func_t) _hb_face_for_data_closure_destroy) - return hb_blob_get_empty (); - - hb_face_for_data_closure_t *data = (hb_face_for_data_closure_t *) face->user_data; - return data->blob; -} - -hb_blob_t * hb_face_reference_table (hb_face_t *face, hb_tag_t tag) { @@ -710,10 +711,48 @@ hb_face_reference_table (hb_face_t *face, return blob; } +hb_blob_t * +hb_face_reference_blob (hb_face_t *face) +{ + return hb_face_reference_table (face, HB_TAG_NONE); +} + +void +hb_face_set_index (hb_face_t *face, + unsigned int index) +{ + if (hb_object_is_inert (face)) + return; + + face->index = 0; +} + +unsigned int +hb_face_get_index (hb_face_t *face) +{ + return face->index; +} + +void +hb_face_set_upem (hb_face_t *face, + unsigned int upem) +{ + if (hb_object_is_inert (face)) + return; + + face->upem = upem; +} + unsigned int hb_face_get_upem (hb_face_t *face) { - return _hb_ot_layout_get_upem (face); + if (unlikely (!face->upem)) { + hb_blob_t *head_blob = Sanitizer<head>::sanitize (hb_face_reference_table (face, HB_OT_TAG_head)); + const head *head_table = Sanitizer<head>::lock_instance (head_blob); + face->upem = head_table->get_upem (); + hb_blob_destroy (head_blob); + } + return face->upem; } diff --git a/src/hb-font.h b/src/hb-font.h index 187c156..7f8cd5e 100644 --- a/src/hb-font.h +++ b/src/hb-font.h @@ -80,12 +80,23 @@ hb_face_is_immutable (hb_face_t *face); hb_blob_t * -hb_face_get_blob (hb_face_t *face); - -hb_blob_t * hb_face_reference_table (hb_face_t *face, hb_tag_t tag); +hb_blob_t * +hb_face_reference_blob (hb_face_t *face); + +void +hb_face_set_index (hb_face_t *face, + unsigned int index); + +unsigned int +hb_face_get_index (hb_face_t *face); + +void +hb_face_set_upem (hb_face_t *face, + unsigned int upem); + unsigned int hb_face_get_upem (hb_face_t *face); diff --git a/src/hb-ft.cc b/src/hb-ft.cc index e757524..953f0a6 100644 --- a/src/hb-ft.cc +++ b/src/hb-ft.cc @@ -250,8 +250,7 @@ reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data) FT_ULong length = 0; FT_Error error; - if (unlikely (tag == HB_TAG_NONE)) - return NULL; + /* Note: FreeType like HarfBuzz uses the NONE tag for fetching the entire blob */ error = FT_Load_Sfnt_Table (ft_face, tag, 0, NULL, &length); if (error) diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh index 1f6e20b..bf7e43b 100644 --- a/src/hb-ot-layout-private.hh +++ b/src/hb-ot-layout-private.hh @@ -70,13 +70,6 @@ _hb_ot_layout_skip_mark (hb_face_t *face, unsigned int *property_out); -/* - * head - */ - -HB_INTERNAL unsigned int -_hb_ot_layout_get_upem (hb_face_t *face); - /* * hb_ot_layout_t @@ -87,12 +80,10 @@ struct hb_ot_layout_t hb_blob_t *gdef_blob; hb_blob_t *gsub_blob; hb_blob_t *gpos_blob; - hb_blob_t *head_blob; const struct GDEF *gdef; const struct GSUB *gsub; const struct GPOS *gpos; - const struct head *head; }; diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index ceae824..d5829b0 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -33,7 +33,6 @@ #include "hb-ot-layout-gdef-private.hh" #include "hb-ot-layout-gsub-private.hh" #include "hb-ot-layout-gpos-private.hh" -#include "hb-ot-head-private.hh" #include "hb-ot-maxp-private.hh" @@ -57,9 +56,6 @@ _hb_ot_layout_create (hb_face_t *face) layout->gpos_blob = Sanitizer<GPOS>::sanitize (hb_face_reference_table (face, HB_OT_TAG_GPOS)); layout->gpos = Sanitizer<GPOS>::lock_instance (layout->gpos_blob); - layout->head_blob = Sanitizer<head>::sanitize (hb_face_reference_table (face, HB_OT_TAG_head)); - layout->head = Sanitizer<head>::lock_instance (layout->head_blob); - return layout; } @@ -69,7 +65,6 @@ _hb_ot_layout_destroy (hb_ot_layout_t *layout) hb_blob_destroy (layout->gdef_blob); hb_blob_destroy (layout->gsub_blob); hb_blob_destroy (layout->gpos_blob); - hb_blob_destroy (layout->head_blob); free (layout); } @@ -89,11 +84,6 @@ _get_gpos (hb_face_t *face) { return likely (face->ot_layout && face->ot_layout->gpos) ? *face->ot_layout->gpos : Null(GPOS); } -static inline const head& -_get_head (hb_face_t *face) -{ - return likely (face->ot_layout && face->ot_layout->head) ? *face->ot_layout->head : Null(head); -} /* @@ -505,14 +495,3 @@ hb_ot_layout_position_finish (hb_buffer_t *buffer) } -/* - * head - */ - -unsigned int -_hb_ot_layout_get_upem (hb_face_t *face) -{ - return _get_head (face).get_upem (); -} - - diff --git a/src/hb-uniscribe-shape.cc b/src/hb-uniscribe-shape.cc index 82ef648..4315d34 100644 --- a/src/hb-uniscribe-shape.cc +++ b/src/hb-uniscribe-shape.cc @@ -189,7 +189,7 @@ retry: /* XXX setup ranges */ } - hb_blob_t *blob = hb_face_get_blob (font->face); + hb_blob_t *blob = hb_face_reference_blob (font->face); unsigned int blob_length; const char *blob_data = hb_blob_get_data (blob, &blob_length); if (unlikely (!blob_length)) @@ -197,6 +197,7 @@ retry: DWORD num_fonts_installed; HANDLE fh = AddFontMemResourceEx ((void *) blob_data, blob_length, 0, &num_fonts_installed); + hb_blob_destroy (blob); if (unlikely (!fh)) FAIL ("AddFontMemResourceEx() failed"); commit e715784be35f0846c0e084b7c53c7556ce933a45 Author: Behdad Esfahbod <[email protected]> Date: Mon Aug 8 21:42:02 2011 +0200 Rename get_table to reference_table in all API diff --git a/src/hb-font-private.hh b/src/hb-font-private.hh index 76024fd..06a5bc4 100644 --- a/src/hb-font-private.hh +++ b/src/hb-font-private.hh @@ -88,9 +88,9 @@ struct _hb_face_t { hb_bool_t immutable; - hb_get_table_func_t get_table; - void *user_data; - hb_destroy_func_t destroy; + hb_reference_table_func_t reference_table; + void *user_data; + hb_destroy_func_t destroy; struct hb_ot_layout_t *ot_layout; diff --git a/src/hb-font.cc b/src/hb-font.cc index 3c5e802..c795c8a 100644 --- a/src/hb-font.cc +++ b/src/hb-font.cc @@ -532,7 +532,7 @@ static hb_face_t _hb_face_nil = { TRUE, /* immutable */ - NULL, /* get_table */ + NULL, /* reference_table */ NULL, /* user_data */ NULL, /* destroy */ @@ -543,19 +543,19 @@ static hb_face_t _hb_face_nil = { hb_face_t * -hb_face_create_for_tables (hb_get_table_func_t get_table, - void *user_data, - hb_destroy_func_t destroy) +hb_face_create_for_tables (hb_reference_table_func_t reference_table, + void *user_data, + hb_destroy_func_t destroy) { hb_face_t *face; - if (!get_table || !(face = hb_object_create<hb_face_t> ())) { + if (!reference_table || !(face = hb_object_create<hb_face_t> ())) { if (destroy) destroy (user_data); return &_hb_face_nil; } - face->get_table = get_table; + face->reference_table = reference_table; face->user_data = user_data; face->destroy = destroy; @@ -595,7 +595,7 @@ _hb_face_for_data_closure_destroy (hb_face_for_data_closure_t *closure) } static hb_blob_t * -_hb_face_for_data_get_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data) +_hb_face_for_data_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data) { hb_face_for_data_closure_t *data = (hb_face_for_data_closure_t *) user_data; @@ -621,7 +621,7 @@ hb_face_create (hb_blob_t *blob, if (unlikely (!closure)) return &_hb_face_nil; - return hb_face_create_for_tables (_hb_face_for_data_get_table, + return hb_face_create_for_tables (_hb_face_for_data_reference_table, closure, (hb_destroy_func_t) _hb_face_for_data_closure_destroy); } @@ -700,10 +700,10 @@ hb_face_reference_table (hb_face_t *face, { hb_blob_t *blob; - if (unlikely (!face || !face->get_table)) + if (unlikely (!face || !face->reference_table)) return hb_blob_get_empty (); - blob = face->get_table (face, tag, face->user_data); + blob = face->reference_table (face, tag, face->user_data); if (unlikely (!blob)) return hb_blob_get_empty (); diff --git a/src/hb-font.h b/src/hb-font.h index 2675c6e..187c156 100644 --- a/src/hb-font.h +++ b/src/hb-font.h @@ -44,13 +44,13 @@ hb_face_t * hb_face_create (hb_blob_t *blob, unsigned int index); -typedef hb_blob_t * (*hb_get_table_func_t) (hb_face_t *face, hb_tag_t tag, void *user_data); +typedef hb_blob_t * (*hb_reference_table_func_t) (hb_face_t *face, hb_tag_t tag, void *user_data); /* calls destroy() when not needing user_data anymore */ hb_face_t * -hb_face_create_for_tables (hb_get_table_func_t get_table, - void *user_data, - hb_destroy_func_t destroy); +hb_face_create_for_tables (hb_reference_table_func_t reference_table, + void *user_data, + hb_destroy_func_t destroy); hb_face_t * hb_face_get_empty (void); diff --git a/src/hb-ft.cc b/src/hb-ft.cc index 7e0c19b..e757524 100644 --- a/src/hb-ft.cc +++ b/src/hb-ft.cc @@ -243,7 +243,7 @@ hb_ft_get_font_funcs (void) static hb_blob_t * -get_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data) +reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data) { FT_Face ft_face = (FT_Face) user_data; FT_Byte *buffer; @@ -291,7 +291,7 @@ hb_ft_face_create (FT_Face ft_face, face = hb_face_create (blob, ft_face->face_index); hb_blob_destroy (blob); } else { - face = hb_face_create_for_tables (get_table, ft_face, destroy); + face = hb_face_create_for_tables (reference_table, ft_face, destroy); } return face; commit 670c873499f7f03fdfc07b8a0567b041628c6ab0 Author: Behdad Esfahbod <[email protected]> Date: Mon Aug 8 21:36:24 2011 +0200 Fix shaper ordering logic diff --git a/src/hb-shape.cc b/src/hb-shape.cc index 02d29bd..4202302 100644 --- a/src/hb-shape.cc +++ b/src/hb-shape.cc @@ -45,8 +45,8 @@ typedef hb_bool_t (*hb_shape_func_t) (hb_font_t *font, const char *shaper_options); #define HB_SHAPER_IMPLEMENT(name) {#name, hb_##name##_shape} -static const struct hb_shaper_pair_t { - const char name[16]; +static struct hb_shaper_pair_t { + char name[16]; hb_shape_func_t func; } shapers[] = { /* v--- Add new shapers in the right place here */ @@ -65,49 +65,42 @@ static struct static_shaper_list_t static_shaper_list_t (void) { char *env = getenv ("HB_SHAPER_LIST"); - shaper_list = NULL; - if (!env || !*env) { - fallback: - ASSERT_STATIC ((ARRAY_LENGTH (shapers) + 1) * sizeof (*shaper_list) <= sizeof (static_buffer)); - shaper_list = (const char **) static_buffer; - unsigned int i; - for (i = 0; i < ARRAY_LENGTH (shapers); i++) - shaper_list[i] = shapers[i].name; - shaper_list[i] = NULL; - return; + if (env && *env) + { + /* Reorder shaper list to prefer requested shaper list. */ + unsigned int i = 0; + char *end, *p = env; + for (;;) { + end = strchr (p, ','); + if (!end) + end = p + strlen (p); + + for (unsigned int j = i; j < ARRAY_LENGTH (shapers); j++) + if (end - p == strlen (shapers[j].name) && + 0 == strncmp (shapers[j].name, p, end - p)) + { + /* Reorder this shaper to position i */ + struct hb_shaper_pair_t t = shapers[j]; + memmove (&shapers[i + 1], &shapers[i], sizeof (shapers[i]) * (j - i)); + shapers[i] = t; + i++; + } + + if (!*end) + break; + else + p = end + 1; + } } - unsigned int count = 3; /* initial, fallback, null */ - for (const char *p = env; (p = strchr (p, ',')) && p++; ) - count++; - - unsigned int len = strlen (env); - - if (count > 100 || len > 1000) - goto fallback; - - len += count * sizeof (*shaper_list) + 1; - char *buffer = len < sizeof (static_buffer) ? static_buffer : (char *) malloc (len); - shaper_list = (const char **) buffer; - buffer += count * sizeof (*shaper_list); - len -= count * sizeof (*shaper_list); - strncpy (buffer, env, len); - - count = 0; - shaper_list[count++] = buffer; - for (char *p = buffer; (p = strchr (p, ',')) && (*p = '\0', TRUE) && p++; ) - shaper_list[count++] = p; - shaper_list[count++] = "fallback"; - shaper_list[count] = NULL; - } - ~static_shaper_list_t (void) - { - if ((char *) shaper_list != static_buffer) - free (shaper_list); + ASSERT_STATIC ((ARRAY_LENGTH (shapers) + 1) * sizeof (*shaper_list) <= sizeof (shaper_list)); + unsigned int i; + for (i = 0; i < ARRAY_LENGTH (shapers); i++) + shaper_list[i] = shapers[i].name; + shaper_list[i] = NULL; } - const char **shaper_list; - char static_buffer[32]; + const char *shaper_list[ARRAY_LENGTH (shapers) + 1]; } static_shaper_list; const char ** @@ -124,11 +117,6 @@ hb_shape_full (hb_font_t *font, const char *shaper_options, const char **shaper_list) { - /* TODO - * This function, and shaper_list handling need to be redone. */ - if (likely (!shaper_list)) - shaper_list = static_shaper_list.shaper_list; - if (likely (!shaper_list)) { for (unsigned int i = 0; i < ARRAY_LENGTH (shapers); i++) if (likely (shapers[i].func (font, buffer, commit cc797e0d5368b2f5732d77eb3e3882283bd87cf7 Author: Behdad Esfahbod <[email protected]> Date: Mon Aug 8 03:49:30 2011 +0200 Minor diff --git a/TODO b/TODO index 577843f..917f131 100644 --- a/TODO +++ b/TODO @@ -41,8 +41,6 @@ API to add (maybe after 1.0): - SFNT api? get_num_faces? get_table_tags? (there's something in stash) -- Full matrix instead of scale? - - Add segmentation API - Add hb-fribidi? diff --git a/src/hb-shape.cc b/src/hb-shape.cc index 7833a39..02d29bd 100644 --- a/src/hb-shape.cc +++ b/src/hb-shape.cc @@ -124,6 +124,8 @@ hb_shape_full (hb_font_t *font, const char *shaper_options, const char **shaper_list) { + /* TODO + * This function, and shaper_list handling need to be redone. */ if (likely (!shaper_list)) shaper_list = static_shaper_list.shaper_list; _______________________________________________ HarfBuzz mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/harfbuzz
