[glib] Add compose() and decompose() implementations with fallback
This commit is contained in:
parent
a54a5505a3
commit
22fdc66712
106
src/hb-glib.cc
106
src/hb-glib.cc
|
@ -177,7 +177,7 @@ hb_glib_script_from_script (hb_script_t script)
|
||||||
|
|
||||||
|
|
||||||
static unsigned int
|
static unsigned int
|
||||||
hb_glib_get_combining_class (hb_unicode_funcs_t *ufuncs HB_UNUSED,
|
hb_glib_unicode_combining_class (hb_unicode_funcs_t *ufuncs HB_UNUSED,
|
||||||
hb_codepoint_t unicode,
|
hb_codepoint_t unicode,
|
||||||
void *user_data HB_UNUSED)
|
void *user_data HB_UNUSED)
|
||||||
|
|
||||||
|
@ -186,7 +186,7 @@ hb_glib_get_combining_class (hb_unicode_funcs_t *ufuncs HB_UNUSED,
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned int
|
static unsigned int
|
||||||
hb_glib_get_eastasian_width (hb_unicode_funcs_t *ufuncs HB_UNUSED,
|
hb_glib_unicode_eastasian_width (hb_unicode_funcs_t *ufuncs HB_UNUSED,
|
||||||
hb_codepoint_t unicode,
|
hb_codepoint_t unicode,
|
||||||
void *user_data HB_UNUSED)
|
void *user_data HB_UNUSED)
|
||||||
{
|
{
|
||||||
|
@ -194,7 +194,7 @@ hb_glib_get_eastasian_width (hb_unicode_funcs_t *ufuncs HB_UNUSED,
|
||||||
}
|
}
|
||||||
|
|
||||||
static hb_unicode_general_category_t
|
static hb_unicode_general_category_t
|
||||||
hb_glib_get_general_category (hb_unicode_funcs_t *ufuncs HB_UNUSED,
|
hb_glib_unicode_general_category (hb_unicode_funcs_t *ufuncs HB_UNUSED,
|
||||||
hb_codepoint_t unicode,
|
hb_codepoint_t unicode,
|
||||||
void *user_data HB_UNUSED)
|
void *user_data HB_UNUSED)
|
||||||
|
|
||||||
|
@ -204,7 +204,7 @@ hb_glib_get_general_category (hb_unicode_funcs_t *ufuncs HB_UNUSED,
|
||||||
}
|
}
|
||||||
|
|
||||||
static hb_codepoint_t
|
static hb_codepoint_t
|
||||||
hb_glib_get_mirroring (hb_unicode_funcs_t *ufuncs HB_UNUSED,
|
hb_glib_unicode_mirroring (hb_unicode_funcs_t *ufuncs HB_UNUSED,
|
||||||
hb_codepoint_t unicode,
|
hb_codepoint_t unicode,
|
||||||
void *user_data HB_UNUSED)
|
void *user_data HB_UNUSED)
|
||||||
{
|
{
|
||||||
|
@ -213,13 +213,97 @@ hb_glib_get_mirroring (hb_unicode_funcs_t *ufuncs HB_UNUSED,
|
||||||
}
|
}
|
||||||
|
|
||||||
static hb_script_t
|
static hb_script_t
|
||||||
hb_glib_get_script (hb_unicode_funcs_t *ufuncs HB_UNUSED,
|
hb_glib_unicode_script (hb_unicode_funcs_t *ufuncs HB_UNUSED,
|
||||||
hb_codepoint_t unicode,
|
hb_codepoint_t unicode,
|
||||||
void *user_data HB_UNUSED)
|
void *user_data HB_UNUSED)
|
||||||
{
|
{
|
||||||
return hb_glib_script_to_script (g_unichar_get_script (unicode));
|
return hb_glib_script_to_script (g_unichar_get_script (unicode));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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. */
|
||||||
|
|
||||||
|
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 (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 (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));
|
||||||
|
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 hb_unicode_funcs_t _hb_unicode_funcs_glib;
|
extern HB_INTERNAL hb_unicode_funcs_t _hb_unicode_funcs_glib;
|
||||||
hb_unicode_funcs_t _hb_glib_unicode_funcs = {
|
hb_unicode_funcs_t _hb_glib_unicode_funcs = {
|
||||||
HB_OBJECT_HEADER_STATIC,
|
HB_OBJECT_HEADER_STATIC,
|
||||||
|
@ -227,15 +311,9 @@ hb_unicode_funcs_t _hb_glib_unicode_funcs = {
|
||||||
NULL, /* parent */
|
NULL, /* parent */
|
||||||
TRUE, /* immutable */
|
TRUE, /* immutable */
|
||||||
{
|
{
|
||||||
hb_glib_get_combining_class,
|
#define HB_UNICODE_FUNC_IMPLEMENT(name) hb_glib_unicode_##name,
|
||||||
hb_glib_get_eastasian_width,
|
HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
|
||||||
hb_glib_get_general_category,
|
#undef HB_UNICODE_FUNC_IMPLEMENT
|
||||||
hb_glib_get_mirroring,
|
|
||||||
hb_glib_get_script,
|
|
||||||
/* TODO
|
|
||||||
hb_glib_compose,
|
|
||||||
hb_glib_decompose,
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -80,7 +80,7 @@ hb_unicode_script_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED,
|
||||||
}
|
}
|
||||||
|
|
||||||
static hb_bool_t
|
static hb_bool_t
|
||||||
hb_unicode_compose_nil (hb_unicode_funcs_t *ufuncs,
|
hb_unicode_compose_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED,
|
||||||
hb_codepoint_t a HB_UNUSED,
|
hb_codepoint_t a HB_UNUSED,
|
||||||
hb_codepoint_t b HB_UNUSED,
|
hb_codepoint_t b HB_UNUSED,
|
||||||
hb_codepoint_t *ab HB_UNUSED,
|
hb_codepoint_t *ab HB_UNUSED,
|
||||||
|
@ -91,7 +91,7 @@ hb_unicode_compose_nil (hb_unicode_funcs_t *ufuncs,
|
||||||
}
|
}
|
||||||
|
|
||||||
static hb_bool_t
|
static hb_bool_t
|
||||||
hb_unicode_decompose_nil (hb_unicode_funcs_t *ufuncs,
|
hb_unicode_decompose_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED,
|
||||||
hb_codepoint_t ab HB_UNUSED,
|
hb_codepoint_t ab HB_UNUSED,
|
||||||
hb_codepoint_t *a HB_UNUSED,
|
hb_codepoint_t *a HB_UNUSED,
|
||||||
hb_codepoint_t *b HB_UNUSED,
|
hb_codepoint_t *b HB_UNUSED,
|
||||||
|
@ -257,6 +257,7 @@ hb_unicode_compose (hb_unicode_funcs_t *ufuncs,
|
||||||
hb_codepoint_t b,
|
hb_codepoint_t b,
|
||||||
hb_codepoint_t *ab)
|
hb_codepoint_t *ab)
|
||||||
{
|
{
|
||||||
|
*ab = 0;
|
||||||
return ufuncs->func.compose (ufuncs, a, b, ab, ufuncs->user_data.compose);
|
return ufuncs->func.compose (ufuncs, a, b, ab, ufuncs->user_data.compose);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -266,6 +267,7 @@ hb_unicode_decompose (hb_unicode_funcs_t *ufuncs,
|
||||||
hb_codepoint_t *a,
|
hb_codepoint_t *a,
|
||||||
hb_codepoint_t *b)
|
hb_codepoint_t *b)
|
||||||
{
|
{
|
||||||
|
*a = *b = 0;
|
||||||
return ufuncs->func.decompose (ufuncs, ab, a, b, ufuncs->user_data.decompose);
|
return ufuncs->func.decompose (ufuncs, ab, a, b, ufuncs->user_data.decompose);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue