X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fhb-glib.cc;h=6b655dd130bdcfa86b2557f483951b6b7e5ae3fc;hb=b08254dad51328fed58b3c0999a1eb7a25f53efc;hp=2bce1f9c26d068acbd35ffc7a81954cb3fb4ad16;hpb=d4bee9f813bb299b1c4aab7c33d588be2a7d354b;p=framework%2Fuifw%2Fharfbuzz.git diff --git a/src/hb-glib.cc b/src/hb-glib.cc index 2bce1f9..6b655dd 100644 --- a/src/hb-glib.cc +++ b/src/hb-glib.cc @@ -32,10 +32,8 @@ #include "hb-unicode-private.hh" -#include - -HB_BEGIN_DECLS +#if !GLIB_CHECK_VERSION(2,29,14) static const hb_script_t glib_script_to_script[] = { @@ -146,12 +144,25 @@ glib_script_to_script[] = /* Unicode-6.0 additions */ HB_SCRIPT_BATAK, HB_SCRIPT_BRAHMI, - HB_SCRIPT_MANDAIC + HB_SCRIPT_MANDAIC, + + /* Unicode-6.1 additions */ + HB_SCRIPT_CHAKMA, + HB_SCRIPT_MEROITIC_CURSIVE, + HB_SCRIPT_MEROITIC_HIEROGLYPHS, + HB_SCRIPT_MIAO, + HB_SCRIPT_SHARADA, + HB_SCRIPT_SORA_SOMPENG, + HB_SCRIPT_TAKRI }; +#endif hb_script_t hb_glib_script_to_script (GUnicodeScript script) { +#if GLIB_CHECK_VERSION(2,29,14) + return (hb_script_t) g_unicode_script_to_iso15924 (script); +#else if (likely ((unsigned int) script < ARRAY_LENGTH (glib_script_to_script))) return glib_script_to_script[script]; @@ -159,11 +170,15 @@ hb_glib_script_to_script (GUnicodeScript script) return HB_SCRIPT_INVALID; return HB_SCRIPT_UNKNOWN; +#endif } GUnicodeScript hb_glib_script_from_script (hb_script_t script) { +#if GLIB_CHECK_VERSION(2,29,14) + return g_unicode_script_from_iso15924 (script); +#else unsigned int count = ARRAY_LENGTH (glib_script_to_script); for (unsigned int i = 0; i < count; i++) if (glib_script_to_script[i] == script) @@ -173,30 +188,31 @@ hb_glib_script_from_script (hb_script_t script) return G_UNICODE_SCRIPT_INVALID_CODE; return G_UNICODE_SCRIPT_UNKNOWN; +#endif } static unsigned int -hb_glib_get_combining_class (hb_unicode_funcs_t *ufuncs, - hb_codepoint_t unicode, - void *user_data) +hb_glib_unicode_combining_class (hb_unicode_funcs_t *ufuncs HB_UNUSED, + hb_codepoint_t unicode, + void *user_data HB_UNUSED) { return g_unichar_combining_class (unicode); } static unsigned int -hb_glib_get_eastasian_width (hb_unicode_funcs_t *ufuncs, - hb_codepoint_t unicode, - void *user_data) +hb_glib_unicode_eastasian_width (hb_unicode_funcs_t *ufuncs HB_UNUSED, + hb_codepoint_t unicode, + void *user_data HB_UNUSED) { return g_unichar_iswide (unicode) ? 2 : 1; } static hb_unicode_general_category_t -hb_glib_get_general_category (hb_unicode_funcs_t *ufuncs, - hb_codepoint_t unicode, - void *user_data) +hb_glib_unicode_general_category (hb_unicode_funcs_t *ufuncs HB_UNUSED, + hb_codepoint_t unicode, + void *user_data HB_UNUSED) { /* hb_unicode_general_category_t and GUnicodeType are identical */ @@ -204,42 +220,139 @@ hb_glib_get_general_category (hb_unicode_funcs_t *ufuncs, } static hb_codepoint_t -hb_glib_get_mirroring (hb_unicode_funcs_t *ufuncs, - hb_codepoint_t unicode, - void *user_data) +hb_glib_unicode_mirroring (hb_unicode_funcs_t *ufuncs HB_UNUSED, + hb_codepoint_t unicode, + void *user_data HB_UNUSED) { g_unichar_get_mirror_char (unicode, &unicode); return unicode; } static hb_script_t -hb_glib_get_script (hb_unicode_funcs_t *ufuncs, - hb_codepoint_t unicode, - void *user_data) +hb_glib_unicode_script (hb_unicode_funcs_t *ufuncs HB_UNUSED, + hb_codepoint_t unicode, + void *user_data HB_UNUSED) { return hb_glib_script_to_script (g_unichar_get_script (unicode)); } -extern HB_INTERNAL hb_unicode_funcs_t _hb_unicode_funcs_glib; -hb_unicode_funcs_t _hb_glib_unicode_funcs = { +static hb_bool_t +hb_glib_unicode_compose (hb_unicode_funcs_t *ufuncs HB_UNUSED, + hb_codepoint_t a, + hb_codepoint_t b, + hb_codepoint_t *ab, + void *user_data HB_UNUSED) +{ +#if GLIB_CHECK_VERSION(2,29,12) + return g_unichar_compose (a, b, ab); +#endif + + /* We don't ifdef-out the fallback code such that compiler always + * sees it and makes sure it's compilable. */ + + if (!a || !b) + return false; + + gchar utf8[12]; + gchar *normalized; + gint len; + hb_bool_t ret; + + len = g_unichar_to_utf8 (a, utf8); + len += g_unichar_to_utf8 (b, utf8 + len); + normalized = g_utf8_normalize (utf8, len, G_NORMALIZE_NFC); + len = g_utf8_strlen (normalized, -1); + if (unlikely (!len)) + return false; + + if (len == 1) { + *ab = g_utf8_get_char (normalized); + ret = true; + } else { + ret = false; + } + + g_free (normalized); + return ret; +} + +static hb_bool_t +hb_glib_unicode_decompose (hb_unicode_funcs_t *ufuncs HB_UNUSED, + hb_codepoint_t ab, + hb_codepoint_t *a, + hb_codepoint_t *b, + void *user_data HB_UNUSED) +{ +#if GLIB_CHECK_VERSION(2,29,12) + return g_unichar_decompose (ab, a, b); +#endif + + /* We don't ifdef-out the fallback code such that compiler always + * sees it and makes sure it's compilable. */ + + gchar utf8[6]; + gchar *normalized; + gint len; + hb_bool_t ret; + + len = g_unichar_to_utf8 (ab, utf8); + normalized = g_utf8_normalize (utf8, len, G_NORMALIZE_NFD); + len = g_utf8_strlen (normalized, -1); + if (unlikely (!len)) + return false; + + if (len == 1) { + *a = g_utf8_get_char (normalized); + *b = 0; + ret = *a != ab; + } else if (len == 2) { + *a = g_utf8_get_char (normalized); + *b = g_utf8_get_char (g_utf8_next_char (normalized)); + /* Here's the ugly part: if ab decomposes to a single character and + * that character decomposes again, we have to detect that and undo + * the second part :-(. */ + gchar *recomposed = g_utf8_normalize (normalized, -1, G_NORMALIZE_NFC); + hb_codepoint_t c = g_utf8_get_char (recomposed); + if (c != ab && c != *a) { + *a = c; + *b = 0; + } + g_free (recomposed); + ret = true; + } else { + /* If decomposed to more than two characters, take the last one, + * and recompose the rest to get the first component. */ + gchar *end = g_utf8_offset_to_pointer (normalized, len - 1); + gchar *recomposed; + *b = g_utf8_get_char (end); + recomposed = g_utf8_normalize (normalized, end - normalized, G_NORMALIZE_NFC); + /* We expect that recomposed has exactly one character now. */ + *a = g_utf8_get_char (recomposed); + g_free (recomposed); + ret = true; + } + + g_free (normalized); + return ret; +} + + +extern HB_INTERNAL const hb_unicode_funcs_t _hb_glib_unicode_funcs; +const hb_unicode_funcs_t _hb_glib_unicode_funcs = { HB_OBJECT_HEADER_STATIC, NULL, /* parent */ - TRUE, /* immutable */ + true, /* immutable */ { - hb_glib_get_combining_class, - hb_glib_get_eastasian_width, - hb_glib_get_general_category, - hb_glib_get_mirroring, - hb_glib_get_script +#define HB_UNICODE_FUNC_IMPLEMENT(name) hb_glib_unicode_##name, + HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS +#undef HB_UNICODE_FUNC_IMPLEMENT } }; hb_unicode_funcs_t * hb_glib_get_unicode_funcs (void) { - return &_hb_glib_unicode_funcs; + return const_cast (&_hb_glib_unicode_funcs); } - -HB_END_DECLS