[API] unicode: rework virtual functions for subclassing
Unicode data providers can now be subclassed, including support for chain-up. The interface should now be nicely bindable, as well. Also fix glib unicode funcs that where broken after hb_script_t changes. Nicely caught by the test-unicode.c added in this commit.
This commit is contained in:
parent
f85faee9b3
commit
2fd0c577e3
186
src/hb-glib.c
186
src/hb-glib.c
|
@ -35,22 +35,188 @@
|
||||||
HB_BEGIN_DECLS
|
HB_BEGIN_DECLS
|
||||||
|
|
||||||
|
|
||||||
static hb_codepoint_t hb_glib_get_mirroring (hb_codepoint_t unicode) { g_unichar_get_mirror_char (unicode, &unicode); return unicode; }
|
static hb_codepoint_t
|
||||||
static hb_unicode_general_category_t hb_glib_get_general_category (hb_codepoint_t unicode) { return g_unichar_type (unicode); }
|
hb_glib_get_mirroring (hb_unicode_funcs_t *ufuncs,
|
||||||
static hb_script_t hb_glib_get_script (hb_codepoint_t unicode) { return g_unichar_get_script (unicode); }
|
hb_codepoint_t unicode,
|
||||||
static unsigned int hb_glib_get_combining_class (hb_codepoint_t unicode) { return g_unichar_combining_class (unicode); }
|
void *user_data)
|
||||||
static unsigned int hb_glib_get_eastasian_width (hb_codepoint_t unicode) { return g_unichar_iswide (unicode); }
|
{
|
||||||
|
g_unichar_get_mirror_char (unicode, &unicode);
|
||||||
|
return unicode;
|
||||||
|
}
|
||||||
|
|
||||||
|
static hb_unicode_general_category_t
|
||||||
|
hb_glib_get_general_category (hb_unicode_funcs_t *ufuncs,
|
||||||
|
hb_codepoint_t unicode,
|
||||||
|
void *user_data)
|
||||||
|
|
||||||
|
{
|
||||||
|
return g_unichar_type (unicode);
|
||||||
|
}
|
||||||
|
|
||||||
|
static hb_script_t
|
||||||
|
hb_glib_get_script (hb_unicode_funcs_t *ufuncs,
|
||||||
|
hb_codepoint_t unicode,
|
||||||
|
void *user_data)
|
||||||
|
{
|
||||||
|
GUnicodeScript script = g_unichar_get_script (unicode);
|
||||||
|
switch (script)
|
||||||
|
{
|
||||||
|
#define MATCH_SCRIPT(C) case G_UNICODE_SCRIPT_##C: return HB_SCRIPT_##C
|
||||||
|
#define MATCH_SCRIPT2(C1, C2) case G_UNICODE_SCRIPT_##C1: return HB_SCRIPT_##C2
|
||||||
|
|
||||||
|
MATCH_SCRIPT2(INVALID_CODE, INVALID);
|
||||||
|
|
||||||
|
MATCH_SCRIPT (COMMON); /* Zyyy */
|
||||||
|
MATCH_SCRIPT (INHERITED); /* Qaai */
|
||||||
|
MATCH_SCRIPT (ARABIC); /* Arab */
|
||||||
|
MATCH_SCRIPT (ARMENIAN); /* Armn */
|
||||||
|
MATCH_SCRIPT (BENGALI); /* Beng */
|
||||||
|
MATCH_SCRIPT (BOPOMOFO); /* Bopo */
|
||||||
|
MATCH_SCRIPT (CHEROKEE); /* Cher */
|
||||||
|
MATCH_SCRIPT (COPTIC); /* Qaac */
|
||||||
|
MATCH_SCRIPT (CYRILLIC); /* Cyrl (Cyrs) */
|
||||||
|
MATCH_SCRIPT (DESERET); /* Dsrt */
|
||||||
|
MATCH_SCRIPT (DEVANAGARI); /* Deva */
|
||||||
|
MATCH_SCRIPT (ETHIOPIC); /* Ethi */
|
||||||
|
MATCH_SCRIPT (GEORGIAN); /* Geor (Geon); Geoa) */
|
||||||
|
MATCH_SCRIPT (GOTHIC); /* Goth */
|
||||||
|
MATCH_SCRIPT (GREEK); /* Grek */
|
||||||
|
MATCH_SCRIPT (GUJARATI); /* Gujr */
|
||||||
|
MATCH_SCRIPT (GURMUKHI); /* Guru */
|
||||||
|
MATCH_SCRIPT (HAN); /* Hani */
|
||||||
|
MATCH_SCRIPT (HANGUL); /* Hang */
|
||||||
|
MATCH_SCRIPT (HEBREW); /* Hebr */
|
||||||
|
MATCH_SCRIPT (HIRAGANA); /* Hira */
|
||||||
|
MATCH_SCRIPT (KANNADA); /* Knda */
|
||||||
|
MATCH_SCRIPT (KATAKANA); /* Kana */
|
||||||
|
MATCH_SCRIPT (KHMER); /* Khmr */
|
||||||
|
MATCH_SCRIPT (LAO); /* Laoo */
|
||||||
|
MATCH_SCRIPT (LATIN); /* Latn (Latf); Latg) */
|
||||||
|
MATCH_SCRIPT (MALAYALAM); /* Mlym */
|
||||||
|
MATCH_SCRIPT (MONGOLIAN); /* Mong */
|
||||||
|
MATCH_SCRIPT (MYANMAR); /* Mymr */
|
||||||
|
MATCH_SCRIPT (OGHAM); /* Ogam */
|
||||||
|
MATCH_SCRIPT (OLD_ITALIC); /* Ital */
|
||||||
|
MATCH_SCRIPT (ORIYA); /* Orya */
|
||||||
|
MATCH_SCRIPT (RUNIC); /* Runr */
|
||||||
|
MATCH_SCRIPT (SINHALA); /* Sinh */
|
||||||
|
MATCH_SCRIPT (SYRIAC); /* Syrc (Syrj, Syrn); Syre) */
|
||||||
|
MATCH_SCRIPT (TAMIL); /* Taml */
|
||||||
|
MATCH_SCRIPT (TELUGU); /* Telu */
|
||||||
|
MATCH_SCRIPT (THAANA); /* Thaa */
|
||||||
|
MATCH_SCRIPT (THAI); /* Thai */
|
||||||
|
MATCH_SCRIPT (TIBETAN); /* Tibt */
|
||||||
|
MATCH_SCRIPT (CANADIAN_ABORIGINAL);/* Cans */
|
||||||
|
MATCH_SCRIPT (YI); /* Yiii */
|
||||||
|
MATCH_SCRIPT (TAGALOG); /* Tglg */
|
||||||
|
MATCH_SCRIPT (HANUNOO); /* Hano */
|
||||||
|
MATCH_SCRIPT (BUHID); /* Buhd */
|
||||||
|
MATCH_SCRIPT (TAGBANWA); /* Tagb */
|
||||||
|
|
||||||
|
/* Unicode-4.0 additions */
|
||||||
|
MATCH_SCRIPT (BRAILLE); /* Brai */
|
||||||
|
MATCH_SCRIPT (CYPRIOT); /* Cprt */
|
||||||
|
MATCH_SCRIPT (LIMBU); /* Limb */
|
||||||
|
MATCH_SCRIPT (OSMANYA); /* Osma */
|
||||||
|
MATCH_SCRIPT (SHAVIAN); /* Shaw */
|
||||||
|
MATCH_SCRIPT (LINEAR_B); /* Linb */
|
||||||
|
MATCH_SCRIPT (TAI_LE); /* Tale */
|
||||||
|
MATCH_SCRIPT (UGARITIC); /* Ugar */
|
||||||
|
|
||||||
|
/* Unicode-4.1 additions */
|
||||||
|
MATCH_SCRIPT (NEW_TAI_LUE); /* Talu */
|
||||||
|
MATCH_SCRIPT (BUGINESE); /* Bugi */
|
||||||
|
MATCH_SCRIPT (GLAGOLITIC); /* Glag */
|
||||||
|
MATCH_SCRIPT (TIFINAGH); /* Tfng */
|
||||||
|
MATCH_SCRIPT (SYLOTI_NAGRI); /* Sylo */
|
||||||
|
MATCH_SCRIPT (OLD_PERSIAN); /* Xpeo */
|
||||||
|
MATCH_SCRIPT (KHAROSHTHI); /* Khar */
|
||||||
|
|
||||||
|
/* Unicode-5.0 additions */
|
||||||
|
MATCH_SCRIPT (UNKNOWN); /* Zzzz */
|
||||||
|
MATCH_SCRIPT (BALINESE); /* Bali */
|
||||||
|
MATCH_SCRIPT (CUNEIFORM); /* Xsux */
|
||||||
|
MATCH_SCRIPT (PHOENICIAN); /* Phnx */
|
||||||
|
MATCH_SCRIPT (PHAGS_PA); /* Phag */
|
||||||
|
MATCH_SCRIPT (NKO); /* Nkoo */
|
||||||
|
|
||||||
|
/* Unicode-5.1 additions */
|
||||||
|
MATCH_SCRIPT (KAYAH_LI); /* Kali */
|
||||||
|
MATCH_SCRIPT (LEPCHA); /* Lepc */
|
||||||
|
MATCH_SCRIPT (REJANG); /* Rjng */
|
||||||
|
MATCH_SCRIPT (SUNDANESE); /* Sund */
|
||||||
|
MATCH_SCRIPT (SAURASHTRA); /* Saur */
|
||||||
|
MATCH_SCRIPT (CHAM); /* Cham */
|
||||||
|
MATCH_SCRIPT (OL_CHIKI); /* Olck */
|
||||||
|
MATCH_SCRIPT (VAI); /* Vaii */
|
||||||
|
MATCH_SCRIPT (CARIAN); /* Cari */
|
||||||
|
MATCH_SCRIPT (LYCIAN); /* Lyci */
|
||||||
|
MATCH_SCRIPT (LYDIAN); /* Lydi */
|
||||||
|
|
||||||
|
/* Unicode-5.2 additions */
|
||||||
|
#if GLIB_CHECK_VERSION(2,26,0)
|
||||||
|
MATCH_SCRIPT (AVESTAN); /* Avst */
|
||||||
|
MATCH_SCRIPT (BAMUM); /* Bamu */
|
||||||
|
MATCH_SCRIPT (EGYPTIAN_HIEROGLYPHS); /* Egyp */
|
||||||
|
MATCH_SCRIPT (IMPERIAL_ARAMAIC); /* Armi */
|
||||||
|
MATCH_SCRIPT (INSCRIPTIONAL_PAHLAVI); /* Phli */
|
||||||
|
MATCH_SCRIPT (INSCRIPTIONAL_PARTHIAN); /* Prti */
|
||||||
|
MATCH_SCRIPT (JAVANESE); /* Java */
|
||||||
|
MATCH_SCRIPT (KAITHI); /* Kthi */
|
||||||
|
MATCH_SCRIPT (TAI_THAM); /* Lana */
|
||||||
|
MATCH_SCRIPT (LISU); /* Lisu */
|
||||||
|
MATCH_SCRIPT (MEETEI_MAYEK); /* Mtei */
|
||||||
|
MATCH_SCRIPT (OLD_SOUTH_ARABIAN); /* Sarb */
|
||||||
|
#if GLIB_CHECK_VERSION(2,28,0)
|
||||||
|
MATCH_SCRIPT (OLD_TURKIC); /* Orkh */
|
||||||
|
#else
|
||||||
|
MATCH_SCRIPT2(OLD_TURKISH, OLD_TURKIC);/* Orkh */
|
||||||
|
#endif
|
||||||
|
MATCH_SCRIPT (SAMARITAN); /* Samr */
|
||||||
|
MATCH_SCRIPT (TAI_VIET); /* Tavt */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Unicode-6.0 additions */
|
||||||
|
#if GLIB_CHECK_VERSION(2,28,0)
|
||||||
|
MATCH_SCRIPT (BATAK); /* Batk */
|
||||||
|
MATCH_SCRIPT (BRAHMI); /* Brah */
|
||||||
|
MATCH_SCRIPT (MANDAIC); /* Mand */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#undef MATCH_SCRIPT
|
||||||
|
#undef MATCH_SCRIPT2
|
||||||
|
}
|
||||||
|
|
||||||
|
return HB_SCRIPT_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int
|
||||||
|
hb_glib_get_combining_class (hb_unicode_funcs_t *ufuncs,
|
||||||
|
hb_codepoint_t unicode,
|
||||||
|
void *user_data)
|
||||||
|
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
return g_unichar_iswide (unicode) ? 2 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
static hb_unicode_funcs_t glib_ufuncs = {
|
static hb_unicode_funcs_t glib_ufuncs = {
|
||||||
HB_REFERENCE_COUNT_INVALID, /* ref_count */
|
HB_REFERENCE_COUNT_INVALID, /* ref_count */
|
||||||
|
NULL,
|
||||||
TRUE, /* immutable */
|
TRUE, /* immutable */
|
||||||
{
|
{
|
||||||
hb_glib_get_general_category,
|
hb_glib_get_general_category, NULL, NULL,
|
||||||
hb_glib_get_combining_class,
|
hb_glib_get_combining_class, NULL, NULL,
|
||||||
hb_glib_get_mirroring,
|
hb_glib_get_mirroring, NULL, NULL,
|
||||||
hb_glib_get_script,
|
hb_glib_get_script, NULL, NULL,
|
||||||
hb_glib_get_eastasian_width
|
hb_glib_get_eastasian_width, NULL, NULL
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
45
src/hb-icu.c
45
src/hb-icu.c
|
@ -38,11 +38,27 @@
|
||||||
HB_BEGIN_DECLS
|
HB_BEGIN_DECLS
|
||||||
|
|
||||||
|
|
||||||
static hb_codepoint_t hb_icu_get_mirroring (hb_codepoint_t unicode) { return u_charMirror(unicode); }
|
static hb_codepoint_t
|
||||||
static unsigned int hb_icu_get_combining_class (hb_codepoint_t unicode) { return u_getCombiningClass (unicode); }
|
hb_icu_get_mirroring (hb_unicode_funcs_t *ufuncs,
|
||||||
|
hb_codepoint_t unicode,
|
||||||
|
void *user_data)
|
||||||
|
{
|
||||||
|
return u_charMirror(unicode);
|
||||||
|
}
|
||||||
|
|
||||||
static unsigned int
|
static unsigned int
|
||||||
hb_icu_get_eastasian_width (hb_codepoint_t unicode)
|
hb_icu_get_combining_class (hb_unicode_funcs_t *ufuncs,
|
||||||
|
hb_codepoint_t unicode,
|
||||||
|
void *user_data)
|
||||||
|
|
||||||
|
{
|
||||||
|
return u_getCombiningClass (unicode);
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int
|
||||||
|
hb_icu_get_eastasian_width (hb_unicode_funcs_t *ufuncs,
|
||||||
|
hb_codepoint_t unicode,
|
||||||
|
void *user_data)
|
||||||
{
|
{
|
||||||
switch (u_getIntPropertyValue(unicode, UCHAR_EAST_ASIAN_WIDTH))
|
switch (u_getIntPropertyValue(unicode, UCHAR_EAST_ASIAN_WIDTH))
|
||||||
{
|
{
|
||||||
|
@ -59,7 +75,9 @@ hb_icu_get_eastasian_width (hb_codepoint_t unicode)
|
||||||
}
|
}
|
||||||
|
|
||||||
static hb_unicode_general_category_t
|
static hb_unicode_general_category_t
|
||||||
hb_icu_get_general_category (hb_codepoint_t unicode)
|
hb_icu_get_general_category (hb_unicode_funcs_t *ufuncs,
|
||||||
|
hb_codepoint_t unicode,
|
||||||
|
void *user_data)
|
||||||
{
|
{
|
||||||
switch (u_getIntPropertyValue(unicode, UCHAR_GENERAL_CATEGORY))
|
switch (u_getIntPropertyValue(unicode, UCHAR_GENERAL_CATEGORY))
|
||||||
{
|
{
|
||||||
|
@ -108,7 +126,9 @@ hb_icu_get_general_category (hb_codepoint_t unicode)
|
||||||
}
|
}
|
||||||
|
|
||||||
static hb_script_t
|
static hb_script_t
|
||||||
hb_icu_get_script (hb_codepoint_t unicode)
|
hb_icu_get_script (hb_unicode_funcs_t *ufuncs,
|
||||||
|
hb_codepoint_t unicode,
|
||||||
|
void *user_data)
|
||||||
{
|
{
|
||||||
UErrorCode status = U_ZERO_ERROR;
|
UErrorCode status = U_ZERO_ERROR;
|
||||||
UScriptCode scriptCode = uscript_getScript(unicode, &status);
|
UScriptCode scriptCode = uscript_getScript(unicode, &status);
|
||||||
|
@ -234,19 +254,24 @@ hb_icu_get_script (hb_codepoint_t unicode)
|
||||||
MATCH_SCRIPT (BRAHMI); /* Brah */
|
MATCH_SCRIPT (BRAHMI); /* Brah */
|
||||||
MATCH_SCRIPT2(MANDAEAN, MANDAIC); /* Mand */
|
MATCH_SCRIPT2(MANDAEAN, MANDAIC); /* Mand */
|
||||||
|
|
||||||
|
#undef CHECK_ICU_VERSION
|
||||||
|
#undef MATCH_SCRIPT
|
||||||
|
#undef MATCH_SCRIPT2
|
||||||
}
|
}
|
||||||
|
|
||||||
return HB_SCRIPT_UNKNOWN;
|
return HB_SCRIPT_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
static hb_unicode_funcs_t icu_ufuncs = {
|
static hb_unicode_funcs_t icu_ufuncs = {
|
||||||
HB_REFERENCE_COUNT_INVALID, /* ref_count */
|
HB_REFERENCE_COUNT_INVALID, /* ref_count */
|
||||||
|
NULL,
|
||||||
TRUE, /* immutable */
|
TRUE, /* immutable */
|
||||||
{
|
{
|
||||||
hb_icu_get_general_category,
|
hb_icu_get_general_category, NULL, NULL,
|
||||||
hb_icu_get_combining_class,
|
hb_icu_get_combining_class, NULL, NULL,
|
||||||
hb_icu_get_mirroring,
|
hb_icu_get_mirroring, NULL, NULL,
|
||||||
hb_icu_get_script,
|
hb_icu_get_script, NULL, NULL,
|
||||||
hb_icu_get_eastasian_width
|
hb_icu_get_eastasian_width, NULL, NULL
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -149,8 +149,10 @@ hb_set_unicode_props (hb_ot_shape_context_t *c)
|
||||||
|
|
||||||
unsigned int count = c->buffer->len;
|
unsigned int count = c->buffer->len;
|
||||||
for (unsigned int i = 1; i < count; i++) {
|
for (unsigned int i = 1; i < count; i++) {
|
||||||
info[i].general_category() = get_general_category (info[i].codepoint);
|
info[i].general_category() = get_general_category (c->buffer->unicode, info[i].codepoint,
|
||||||
info[i].combining_class() = get_combining_class (info[i].codepoint);
|
c->buffer->unicode->v.get_general_category_data);
|
||||||
|
info[i].combining_class() = get_combining_class (c->buffer->unicode, info[i].codepoint,
|
||||||
|
c->buffer->unicode->v.get_combining_class_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,7 +202,8 @@ hb_mirror_chars (hb_ot_shape_context_t *c)
|
||||||
|
|
||||||
unsigned int count = c->buffer->len;
|
unsigned int count = c->buffer->len;
|
||||||
for (unsigned int i = 0; i < count; i++) {
|
for (unsigned int i = 0; i < count; i++) {
|
||||||
hb_codepoint_t codepoint = get_mirroring (c->buffer->info[i].codepoint);
|
hb_codepoint_t codepoint = get_mirroring (c->buffer->unicode, c->buffer->info[i].codepoint,
|
||||||
|
c->buffer->unicode->v.get_mirroring_data);
|
||||||
if (likely (codepoint == c->buffer->info[i].codepoint))
|
if (likely (codepoint == c->buffer->info[i].codepoint))
|
||||||
c->buffer->info[i].mask |= rtlm_mask; /* XXX this should be moved to before setting user-feature masks */
|
c->buffer->info[i].mask |= rtlm_mask; /* XXX this should be moved to before setting user-feature masks */
|
||||||
else
|
else
|
||||||
|
|
|
@ -77,7 +77,7 @@ hb_shape (hb_font_t *font,
|
||||||
hb_unicode_get_script_func_t get_script = buffer->unicode->v.get_script;
|
hb_unicode_get_script_func_t get_script = buffer->unicode->v.get_script;
|
||||||
unsigned int count = buffer->len;
|
unsigned int count = buffer->len;
|
||||||
for (unsigned int i = 0; i < count; i++) {
|
for (unsigned int i = 0; i < count; i++) {
|
||||||
hb_script_t script = get_script (buffer->info[i].codepoint);
|
hb_script_t script = get_script (buffer->unicode, buffer->info[i].codepoint, buffer->unicode->v.get_script_data);
|
||||||
if (likely (script != HB_SCRIPT_COMMON &&
|
if (likely (script != HB_SCRIPT_COMMON &&
|
||||||
script != HB_SCRIPT_INHERITED &&
|
script != HB_SCRIPT_INHERITED &&
|
||||||
script != HB_SCRIPT_UNKNOWN)) {
|
script != HB_SCRIPT_UNKNOWN)) {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2009 Red Hat, Inc.
|
* Copyright (C) 2009 Red Hat, Inc.
|
||||||
|
* Copyright © 2011 Codethink Limited
|
||||||
*
|
*
|
||||||
* This is part of HarfBuzz, a text shaping library.
|
* This is part of HarfBuzz, a text shaping library.
|
||||||
*
|
*
|
||||||
|
@ -22,6 +23,7 @@
|
||||||
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||||
*
|
*
|
||||||
* Red Hat Author(s): Behdad Esfahbod
|
* Red Hat Author(s): Behdad Esfahbod
|
||||||
|
* Codethink Author(s): Ryan Lortie
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef HB_UNICODE_PRIVATE_H
|
#ifndef HB_UNICODE_PRIVATE_H
|
||||||
|
@ -40,15 +42,30 @@ HB_BEGIN_DECLS
|
||||||
|
|
||||||
struct _hb_unicode_funcs_t {
|
struct _hb_unicode_funcs_t {
|
||||||
hb_reference_count_t ref_count;
|
hb_reference_count_t ref_count;
|
||||||
|
hb_unicode_funcs_t *parent;
|
||||||
|
|
||||||
hb_bool_t immutable;
|
hb_bool_t immutable;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
hb_unicode_get_general_category_func_t get_general_category;
|
hb_unicode_get_general_category_func_t get_general_category;
|
||||||
|
void *get_general_category_data;
|
||||||
|
hb_destroy_func_t get_general_category_destroy;
|
||||||
|
|
||||||
hb_unicode_get_combining_class_func_t get_combining_class;
|
hb_unicode_get_combining_class_func_t get_combining_class;
|
||||||
|
void *get_combining_class_data;
|
||||||
|
hb_destroy_func_t get_combining_class_destroy;
|
||||||
|
|
||||||
hb_unicode_get_mirroring_func_t get_mirroring;
|
hb_unicode_get_mirroring_func_t get_mirroring;
|
||||||
|
void *get_mirroring_data;
|
||||||
|
hb_destroy_func_t get_mirroring_destroy;
|
||||||
|
|
||||||
hb_unicode_get_script_func_t get_script;
|
hb_unicode_get_script_func_t get_script;
|
||||||
|
void *get_script_data;
|
||||||
|
hb_destroy_func_t get_script_destroy;
|
||||||
|
|
||||||
hb_unicode_get_eastasian_width_func_t get_eastasian_width;
|
hb_unicode_get_eastasian_width_func_t get_eastasian_width;
|
||||||
|
void *get_eastasian_width_data;
|
||||||
|
hb_destroy_func_t get_eastasian_width_destroy;
|
||||||
} v;
|
} v;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
229
src/hb-unicode.c
229
src/hb-unicode.c
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2009 Red Hat, Inc.
|
* Copyright (C) 2009 Red Hat, Inc.
|
||||||
|
* Copyright © 2011 Codethink Limited
|
||||||
*
|
*
|
||||||
* This is part of HarfBuzz, a text shaping library.
|
* This is part of HarfBuzz, a text shaping library.
|
||||||
*
|
*
|
||||||
|
@ -22,6 +23,7 @@
|
||||||
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||||
*
|
*
|
||||||
* Red Hat Author(s): Behdad Esfahbod
|
* Red Hat Author(s): Behdad Esfahbod
|
||||||
|
* Codethink Author(s): Ryan Lortie
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "hb-private.h"
|
#include "hb-private.h"
|
||||||
|
@ -35,33 +37,86 @@ HB_BEGIN_DECLS
|
||||||
* hb_unicode_funcs_t
|
* hb_unicode_funcs_t
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static hb_codepoint_t hb_unicode_get_mirroring_nil (hb_codepoint_t unicode) { return unicode; }
|
static hb_codepoint_t
|
||||||
static hb_unicode_general_category_t hb_unicode_get_general_category_nil (hb_codepoint_t unicode HB_UNUSED) { return HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER; }
|
hb_unicode_get_mirroring_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED,
|
||||||
static hb_script_t hb_unicode_get_script_nil (hb_codepoint_t unicode HB_UNUSED) { return HB_SCRIPT_UNKNOWN; }
|
hb_codepoint_t unicode HB_UNUSED,
|
||||||
static unsigned int hb_unicode_get_combining_class_nil (hb_codepoint_t unicode HB_UNUSED) { return 0; }
|
void *user_data HB_UNUSED)
|
||||||
static unsigned int hb_unicode_get_eastasian_width_nil (hb_codepoint_t unicode HB_UNUSED) { return 1; }
|
{
|
||||||
|
return unicode;
|
||||||
|
}
|
||||||
|
|
||||||
|
static hb_unicode_general_category_t
|
||||||
|
hb_unicode_get_general_category_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED,
|
||||||
|
hb_codepoint_t unicode HB_UNUSED,
|
||||||
|
void *user_data HB_UNUSED)
|
||||||
|
{
|
||||||
|
return HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
static hb_script_t
|
||||||
|
hb_unicode_get_script_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED,
|
||||||
|
hb_codepoint_t unicode HB_UNUSED,
|
||||||
|
void *user_data HB_UNUSED)
|
||||||
|
{
|
||||||
|
return HB_SCRIPT_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int
|
||||||
|
hb_unicode_get_combining_class_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED,
|
||||||
|
hb_codepoint_t unicode HB_UNUSED,
|
||||||
|
void *user_data HB_UNUSED)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int
|
||||||
|
hb_unicode_get_eastasian_width_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED,
|
||||||
|
hb_codepoint_t unicode HB_UNUSED,
|
||||||
|
void *user_data HB_UNUSED)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
hb_unicode_funcs_t _hb_unicode_funcs_nil = {
|
hb_unicode_funcs_t _hb_unicode_funcs_nil = {
|
||||||
HB_REFERENCE_COUNT_INVALID, /* ref_count */
|
HB_REFERENCE_COUNT_INVALID, /* ref_count */
|
||||||
|
NULL, /* parent */
|
||||||
TRUE, /* immutable */
|
TRUE, /* immutable */
|
||||||
{
|
{
|
||||||
hb_unicode_get_general_category_nil,
|
hb_unicode_get_general_category_nil, NULL, NULL,
|
||||||
hb_unicode_get_combining_class_nil,
|
hb_unicode_get_combining_class_nil, NULL, NULL,
|
||||||
hb_unicode_get_mirroring_nil,
|
hb_unicode_get_mirroring_nil, NULL, NULL,
|
||||||
hb_unicode_get_script_nil,
|
hb_unicode_get_script_nil, NULL, NULL,
|
||||||
hb_unicode_get_eastasian_width_nil
|
hb_unicode_get_eastasian_width_nil, NULL, NULL
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
hb_unicode_funcs_t *
|
hb_unicode_funcs_t *
|
||||||
hb_unicode_funcs_create (void)
|
hb_unicode_funcs_create (hb_unicode_funcs_t *parent)
|
||||||
{
|
{
|
||||||
hb_unicode_funcs_t *ufuncs;
|
hb_unicode_funcs_t *ufuncs;
|
||||||
|
|
||||||
if (!HB_OBJECT_DO_CREATE (hb_unicode_funcs_t, ufuncs))
|
if (!HB_OBJECT_DO_CREATE (hb_unicode_funcs_t, ufuncs))
|
||||||
return &_hb_unicode_funcs_nil;
|
return &_hb_unicode_funcs_nil;
|
||||||
|
|
||||||
|
if (parent != NULL) {
|
||||||
|
ufuncs->parent = hb_unicode_funcs_reference (parent);
|
||||||
|
hb_unicode_funcs_make_immutable (parent);
|
||||||
|
ufuncs->v = parent->v;
|
||||||
|
|
||||||
|
/* Clear out the destroy notifies from our parent.
|
||||||
|
*
|
||||||
|
* We don't want to destroy the user_data twice and since we hold a
|
||||||
|
* reference on our parent then we know that the user_data will
|
||||||
|
* survive for at least as long as we do anyway.
|
||||||
|
*/
|
||||||
|
ufuncs->v.get_general_category_destroy = NULL;
|
||||||
|
ufuncs->v.get_combining_class_destroy = NULL;
|
||||||
|
ufuncs->v.get_mirroring_destroy = NULL;
|
||||||
|
ufuncs->v.get_script_destroy = NULL;
|
||||||
|
ufuncs->v.get_eastasian_width_destroy = NULL;
|
||||||
|
} else {
|
||||||
ufuncs->v = _hb_unicode_funcs_nil.v;
|
ufuncs->v = _hb_unicode_funcs_nil.v;
|
||||||
|
}
|
||||||
|
|
||||||
return ufuncs;
|
return ufuncs;
|
||||||
}
|
}
|
||||||
|
@ -83,20 +138,31 @@ hb_unicode_funcs_destroy (hb_unicode_funcs_t *ufuncs)
|
||||||
{
|
{
|
||||||
HB_OBJECT_DO_DESTROY (ufuncs);
|
HB_OBJECT_DO_DESTROY (ufuncs);
|
||||||
|
|
||||||
|
if (ufuncs->parent != NULL)
|
||||||
|
hb_unicode_funcs_destroy (ufuncs->parent);
|
||||||
|
|
||||||
|
if (ufuncs->v.get_general_category_destroy != NULL)
|
||||||
|
ufuncs->v.get_general_category_destroy (ufuncs->v.get_general_category_data);
|
||||||
|
|
||||||
|
if (ufuncs->v.get_combining_class_destroy != NULL)
|
||||||
|
ufuncs->v.get_combining_class_destroy (ufuncs->v.get_combining_class_data);
|
||||||
|
|
||||||
|
if (ufuncs->v.get_mirroring_destroy != NULL)
|
||||||
|
ufuncs->v.get_mirroring_destroy (ufuncs->v.get_mirroring_data);
|
||||||
|
|
||||||
|
if (ufuncs->v.get_script_destroy != NULL)
|
||||||
|
ufuncs->v.get_script_destroy (ufuncs->v.get_script_data);
|
||||||
|
|
||||||
|
if (ufuncs->v.get_eastasian_width_destroy != NULL)
|
||||||
|
ufuncs->v.get_eastasian_width_destroy (ufuncs->v.get_eastasian_width_data);
|
||||||
|
|
||||||
free (ufuncs);
|
free (ufuncs);
|
||||||
}
|
}
|
||||||
|
|
||||||
hb_unicode_funcs_t *
|
hb_unicode_funcs_t *
|
||||||
hb_unicode_funcs_copy (hb_unicode_funcs_t *other_ufuncs)
|
hb_unicode_funcs_get_parent (hb_unicode_funcs_t *ufuncs)
|
||||||
{
|
{
|
||||||
hb_unicode_funcs_t *ufuncs;
|
return ufuncs->parent;
|
||||||
|
|
||||||
if (!HB_OBJECT_DO_CREATE (hb_unicode_funcs_t, ufuncs))
|
|
||||||
return &_hb_unicode_funcs_nil;
|
|
||||||
|
|
||||||
ufuncs->v = other_ufuncs->v;
|
|
||||||
|
|
||||||
return ufuncs;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -115,122 +181,75 @@ hb_unicode_funcs_is_immutable (hb_unicode_funcs_t *ufuncs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
#define SETTER(name) \
|
||||||
hb_unicode_funcs_set_mirroring_func (hb_unicode_funcs_t *ufuncs,
|
void \
|
||||||
hb_unicode_get_mirroring_func_t mirroring_func)
|
hb_unicode_funcs_set_##name##_func (hb_unicode_funcs_t *ufuncs, \
|
||||||
{
|
hb_unicode_get_##name##_func_t func, \
|
||||||
if (ufuncs->immutable)
|
void *user_data, \
|
||||||
return;
|
hb_destroy_func_t destroy) \
|
||||||
|
{ \
|
||||||
ufuncs->v.get_mirroring = mirroring_func ? mirroring_func : hb_unicode_get_mirroring_nil;
|
if (ufuncs->immutable) \
|
||||||
|
return; \
|
||||||
|
\
|
||||||
|
if (func != NULL) { \
|
||||||
|
ufuncs->v.get_##name = func; \
|
||||||
|
ufuncs->v.get_##name##_data = user_data; \
|
||||||
|
ufuncs->v.get_##name##_destroy = destroy; \
|
||||||
|
} else if (ufuncs->parent != NULL) { \
|
||||||
|
ufuncs->v.get_##name = ufuncs->parent->v.get_##name; \
|
||||||
|
ufuncs->v.get_##name##_data = ufuncs->parent->v.get_##name##_data;; \
|
||||||
|
ufuncs->v.get_##name##_destroy = NULL; \
|
||||||
|
} else { \
|
||||||
|
ufuncs->v.get_##name = hb_unicode_get_##name##_nil; \
|
||||||
|
ufuncs->v.get_##name##_data = NULL; \
|
||||||
|
ufuncs->v.get_##name##_destroy = NULL; \
|
||||||
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
SETTER(mirroring)
|
||||||
hb_unicode_funcs_set_general_category_func (hb_unicode_funcs_t *ufuncs,
|
SETTER(general_category)
|
||||||
hb_unicode_get_general_category_func_t general_category_func)
|
SETTER(script)
|
||||||
{
|
SETTER(combining_class)
|
||||||
if (ufuncs->immutable)
|
SETTER(eastasian_width)
|
||||||
return;
|
|
||||||
|
|
||||||
ufuncs->v.get_general_category = general_category_func ? general_category_func : hb_unicode_get_general_category_nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
hb_unicode_funcs_set_script_func (hb_unicode_funcs_t *ufuncs,
|
|
||||||
hb_unicode_get_script_func_t script_func)
|
|
||||||
{
|
|
||||||
if (ufuncs->immutable)
|
|
||||||
return;
|
|
||||||
|
|
||||||
ufuncs->v.get_script = script_func ? script_func : hb_unicode_get_script_nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
hb_unicode_funcs_set_combining_class_func (hb_unicode_funcs_t *ufuncs,
|
|
||||||
hb_unicode_get_combining_class_func_t combining_class_func)
|
|
||||||
{
|
|
||||||
if (ufuncs->immutable)
|
|
||||||
return;
|
|
||||||
|
|
||||||
ufuncs->v.get_combining_class = combining_class_func ? combining_class_func : hb_unicode_get_combining_class_nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
hb_unicode_funcs_set_eastasian_width_func (hb_unicode_funcs_t *ufuncs,
|
|
||||||
hb_unicode_get_eastasian_width_func_t eastasian_width_func)
|
|
||||||
{
|
|
||||||
if (ufuncs->immutable)
|
|
||||||
return;
|
|
||||||
|
|
||||||
ufuncs->v.get_eastasian_width = eastasian_width_func ? eastasian_width_func : hb_unicode_get_eastasian_width_nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
hb_unicode_get_mirroring_func_t
|
|
||||||
hb_unicode_funcs_get_mirroring_func (hb_unicode_funcs_t *ufuncs)
|
|
||||||
{
|
|
||||||
return ufuncs->v.get_mirroring;
|
|
||||||
}
|
|
||||||
|
|
||||||
hb_unicode_get_general_category_func_t
|
|
||||||
hb_unicode_funcs_get_general_category_func (hb_unicode_funcs_t *ufuncs)
|
|
||||||
{
|
|
||||||
return ufuncs->v.get_general_category;
|
|
||||||
}
|
|
||||||
|
|
||||||
hb_unicode_get_script_func_t
|
|
||||||
hb_unicode_funcs_get_script_func (hb_unicode_funcs_t *ufuncs)
|
|
||||||
{
|
|
||||||
return ufuncs->v.get_script;
|
|
||||||
}
|
|
||||||
|
|
||||||
hb_unicode_get_combining_class_func_t
|
|
||||||
hb_unicode_funcs_get_combining_class_func (hb_unicode_funcs_t *ufuncs)
|
|
||||||
{
|
|
||||||
return ufuncs->v.get_combining_class;
|
|
||||||
}
|
|
||||||
|
|
||||||
hb_unicode_get_eastasian_width_func_t
|
|
||||||
hb_unicode_funcs_get_eastasian_width_func (hb_unicode_funcs_t *ufuncs)
|
|
||||||
{
|
|
||||||
return ufuncs->v.get_eastasian_width;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
hb_codepoint_t
|
hb_codepoint_t
|
||||||
hb_unicode_get_mirroring (hb_unicode_funcs_t *ufuncs,
|
hb_unicode_get_mirroring (hb_unicode_funcs_t *ufuncs,
|
||||||
hb_codepoint_t unicode)
|
hb_codepoint_t unicode)
|
||||||
{
|
{
|
||||||
return ufuncs->v.get_mirroring (unicode);
|
return ufuncs->v.get_mirroring (ufuncs, unicode,
|
||||||
|
ufuncs->v.get_mirroring_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
hb_unicode_general_category_t
|
hb_unicode_general_category_t
|
||||||
hb_unicode_get_general_category (hb_unicode_funcs_t *ufuncs,
|
hb_unicode_get_general_category (hb_unicode_funcs_t *ufuncs,
|
||||||
hb_codepoint_t unicode)
|
hb_codepoint_t unicode)
|
||||||
{
|
{
|
||||||
return ufuncs->v.get_general_category (unicode);
|
return ufuncs->v.get_general_category (ufuncs, unicode,
|
||||||
|
ufuncs->v.get_general_category_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
hb_script_t
|
hb_script_t
|
||||||
hb_unicode_get_script (hb_unicode_funcs_t *ufuncs,
|
hb_unicode_get_script (hb_unicode_funcs_t *ufuncs,
|
||||||
hb_codepoint_t unicode)
|
hb_codepoint_t unicode)
|
||||||
{
|
{
|
||||||
return ufuncs->v.get_script (unicode);
|
return ufuncs->v.get_script (ufuncs, unicode,
|
||||||
|
ufuncs->v.get_script_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int
|
unsigned int
|
||||||
hb_unicode_get_combining_class (hb_unicode_funcs_t *ufuncs,
|
hb_unicode_get_combining_class (hb_unicode_funcs_t *ufuncs,
|
||||||
hb_codepoint_t unicode)
|
hb_codepoint_t unicode)
|
||||||
{
|
{
|
||||||
return ufuncs->v.get_combining_class (unicode);
|
return ufuncs->v.get_combining_class (ufuncs, unicode,
|
||||||
|
ufuncs->v.get_combining_class_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int
|
unsigned int
|
||||||
hb_unicode_get_eastasian_width (hb_unicode_funcs_t *ufuncs,
|
hb_unicode_get_eastasian_width (hb_unicode_funcs_t *ufuncs,
|
||||||
hb_codepoint_t unicode)
|
hb_codepoint_t unicode)
|
||||||
{
|
{
|
||||||
return ufuncs->v.get_eastasian_width (unicode);
|
return ufuncs->v.get_eastasian_width (ufuncs, unicode,
|
||||||
|
ufuncs->v.get_eastasian_width_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2009 Red Hat, Inc.
|
* Copyright (C) 2009 Red Hat, Inc.
|
||||||
|
* Copyright © 2011 Codethink Limited
|
||||||
*
|
*
|
||||||
* This is part of HarfBuzz, a text shaping library.
|
* This is part of HarfBuzz, a text shaping library.
|
||||||
*
|
*
|
||||||
|
@ -22,6 +23,7 @@
|
||||||
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||||
*
|
*
|
||||||
* Red Hat Author(s): Behdad Esfahbod
|
* Red Hat Author(s): Behdad Esfahbod
|
||||||
|
* Codethink Author(s): Ryan Lortie
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef HB_UNICODE_H
|
#ifndef HB_UNICODE_H
|
||||||
|
@ -39,7 +41,7 @@ HB_BEGIN_DECLS
|
||||||
typedef struct _hb_unicode_funcs_t hb_unicode_funcs_t;
|
typedef struct _hb_unicode_funcs_t hb_unicode_funcs_t;
|
||||||
|
|
||||||
hb_unicode_funcs_t *
|
hb_unicode_funcs_t *
|
||||||
hb_unicode_funcs_create (void);
|
hb_unicode_funcs_create (hb_unicode_funcs_t *parent_funcs);
|
||||||
|
|
||||||
hb_unicode_funcs_t *
|
hb_unicode_funcs_t *
|
||||||
hb_unicode_funcs_reference (hb_unicode_funcs_t *ufuncs);
|
hb_unicode_funcs_reference (hb_unicode_funcs_t *ufuncs);
|
||||||
|
@ -51,7 +53,7 @@ void
|
||||||
hb_unicode_funcs_destroy (hb_unicode_funcs_t *ufuncs);
|
hb_unicode_funcs_destroy (hb_unicode_funcs_t *ufuncs);
|
||||||
|
|
||||||
hb_unicode_funcs_t *
|
hb_unicode_funcs_t *
|
||||||
hb_unicode_funcs_copy (hb_unicode_funcs_t *ufuncs);
|
hb_unicode_funcs_get_parent (hb_unicode_funcs_t *ufuncs);
|
||||||
|
|
||||||
void
|
void
|
||||||
hb_unicode_funcs_make_immutable (hb_unicode_funcs_t *ufuncs);
|
hb_unicode_funcs_make_immutable (hb_unicode_funcs_t *ufuncs);
|
||||||
|
@ -63,57 +65,55 @@ hb_unicode_funcs_is_immutable (hb_unicode_funcs_t *ufuncs);
|
||||||
* funcs
|
* funcs
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/* typedefs */
|
/* typedefs */
|
||||||
|
|
||||||
typedef hb_codepoint_t (*hb_unicode_get_mirroring_func_t) (hb_codepoint_t unicode);
|
typedef hb_codepoint_t (*hb_unicode_get_mirroring_func_t) (hb_unicode_funcs_t *ufuncs,
|
||||||
typedef hb_unicode_general_category_t (*hb_unicode_get_general_category_func_t) (hb_codepoint_t unicode);
|
hb_codepoint_t unicode,
|
||||||
typedef hb_script_t (*hb_unicode_get_script_func_t) (hb_codepoint_t unicode);
|
void *user_data);
|
||||||
typedef unsigned int (*hb_unicode_get_combining_class_func_t) (hb_codepoint_t unicode);
|
typedef hb_unicode_general_category_t (*hb_unicode_get_general_category_func_t) (hb_unicode_funcs_t *ufuncs,
|
||||||
typedef unsigned int (*hb_unicode_get_eastasian_width_func_t) (hb_codepoint_t unicode);
|
hb_codepoint_t unicode,
|
||||||
|
void *user_data);
|
||||||
|
typedef hb_script_t (*hb_unicode_get_script_func_t) (hb_unicode_funcs_t *ufuncs,
|
||||||
|
hb_codepoint_t unicode,
|
||||||
|
void *user_data);
|
||||||
|
typedef unsigned int (*hb_unicode_get_combining_class_func_t) (hb_unicode_funcs_t *ufuncs,
|
||||||
|
hb_codepoint_t unicode,
|
||||||
|
void *user_data);
|
||||||
|
typedef unsigned int (*hb_unicode_get_eastasian_width_func_t) (hb_unicode_funcs_t *ufuncs,
|
||||||
|
hb_codepoint_t unicode,
|
||||||
|
void *user_data);
|
||||||
|
|
||||||
/* setters */
|
/* setters */
|
||||||
|
|
||||||
void
|
void
|
||||||
hb_unicode_funcs_set_mirroring_func (hb_unicode_funcs_t *ufuncs,
|
hb_unicode_funcs_set_mirroring_func (hb_unicode_funcs_t *ufuncs,
|
||||||
hb_unicode_get_mirroring_func_t mirroring_func);
|
hb_unicode_get_mirroring_func_t mirroring_func,
|
||||||
|
void *user_data,
|
||||||
|
hb_destroy_func_t destroy);
|
||||||
|
|
||||||
void
|
void
|
||||||
hb_unicode_funcs_set_general_category_func (hb_unicode_funcs_t *ufuncs,
|
hb_unicode_funcs_set_general_category_func (hb_unicode_funcs_t *ufuncs,
|
||||||
hb_unicode_get_general_category_func_t general_category_func);
|
hb_unicode_get_general_category_func_t general_category_func,
|
||||||
|
void *user_data,
|
||||||
|
hb_destroy_func_t destroy);
|
||||||
|
|
||||||
void
|
void
|
||||||
hb_unicode_funcs_set_script_func (hb_unicode_funcs_t *ufuncs,
|
hb_unicode_funcs_set_script_func (hb_unicode_funcs_t *ufuncs,
|
||||||
hb_unicode_get_script_func_t script_func);
|
hb_unicode_get_script_func_t script_func,
|
||||||
|
void *user_data,
|
||||||
|
hb_destroy_func_t destroy);
|
||||||
|
|
||||||
void
|
void
|
||||||
hb_unicode_funcs_set_combining_class_func (hb_unicode_funcs_t *ufuncs,
|
hb_unicode_funcs_set_combining_class_func (hb_unicode_funcs_t *ufuncs,
|
||||||
hb_unicode_get_combining_class_func_t combining_class_func);
|
hb_unicode_get_combining_class_func_t combining_class_func,
|
||||||
|
void *user_data,
|
||||||
|
hb_destroy_func_t destroy);
|
||||||
|
|
||||||
void
|
void
|
||||||
hb_unicode_funcs_set_eastasian_width_func (hb_unicode_funcs_t *ufuncs,
|
hb_unicode_funcs_set_eastasian_width_func (hb_unicode_funcs_t *ufuncs,
|
||||||
hb_unicode_get_eastasian_width_func_t eastasian_width_func);
|
hb_unicode_get_eastasian_width_func_t eastasian_width_func,
|
||||||
|
void *user_data,
|
||||||
|
hb_destroy_func_t destroy);
|
||||||
/* getters */
|
|
||||||
|
|
||||||
/* These never return NULL. Return fallback defaults instead. */
|
|
||||||
|
|
||||||
hb_unicode_get_mirroring_func_t
|
|
||||||
hb_unicode_funcs_get_mirroring_func (hb_unicode_funcs_t *ufuncs);
|
|
||||||
|
|
||||||
hb_unicode_get_general_category_func_t
|
|
||||||
hb_unicode_funcs_get_general_category_func (hb_unicode_funcs_t *ufuncs);
|
|
||||||
|
|
||||||
hb_unicode_get_script_func_t
|
|
||||||
hb_unicode_funcs_get_script_func (hb_unicode_funcs_t *ufuncs);
|
|
||||||
|
|
||||||
hb_unicode_get_combining_class_func_t
|
|
||||||
hb_unicode_funcs_get_combining_class_func (hb_unicode_funcs_t *ufuncs);
|
|
||||||
|
|
||||||
hb_unicode_get_eastasian_width_func_t
|
|
||||||
hb_unicode_funcs_get_eastasian_width_func (hb_unicode_funcs_t *ufuncs);
|
|
||||||
|
|
||||||
|
|
||||||
/* accessors */
|
/* accessors */
|
||||||
|
|
|
@ -11,6 +11,7 @@ check_PROGRAMS = $(TEST_PROGS)
|
||||||
TEST_PROGS += \
|
TEST_PROGS += \
|
||||||
test-buffer \
|
test-buffer \
|
||||||
test-types \
|
test-types \
|
||||||
|
test-unicode \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,215 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2011 Codethink Limited
|
||||||
|
*
|
||||||
|
* This is part of HarfBuzz, a text shaping library.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, without written agreement and without
|
||||||
|
* license or royalty fees, to use, copy, modify, and distribute this
|
||||||
|
* software and its documentation for any purpose, provided that the
|
||||||
|
* above copyright notice and the following two paragraphs appear in
|
||||||
|
* all copies of this software.
|
||||||
|
*
|
||||||
|
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
|
||||||
|
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
|
||||||
|
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||||
|
* DAMAGE.
|
||||||
|
*
|
||||||
|
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
|
||||||
|
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
|
||||||
|
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||||
|
*
|
||||||
|
* Codethink Author(s): Ryan Lortie
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "hb-test.h"
|
||||||
|
|
||||||
|
/* This file tests the unicode virtual functions interface */
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_nil (void)
|
||||||
|
{
|
||||||
|
hb_unicode_funcs_t *uf = hb_unicode_funcs_create (NULL);
|
||||||
|
|
||||||
|
g_assert_cmpint (hb_unicode_get_script (uf, 'd'), ==, HB_SCRIPT_UNKNOWN);
|
||||||
|
|
||||||
|
g_assert_cmpint (hb_unicode_funcs_get_reference_count (uf), ==, 1);
|
||||||
|
hb_unicode_funcs_destroy (uf);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_glib (void)
|
||||||
|
{
|
||||||
|
hb_unicode_funcs_t *uf = hb_glib_get_unicode_funcs ();
|
||||||
|
|
||||||
|
g_assert_cmpint (hb_unicode_get_script (uf, 'd'), ==, HB_SCRIPT_LATIN);
|
||||||
|
|
||||||
|
g_assert_cmpint (hb_unicode_funcs_get_reference_count (uf), ==, 0);
|
||||||
|
hb_unicode_funcs_destroy (uf);
|
||||||
|
g_assert_cmpint (hb_unicode_funcs_get_reference_count (uf), ==, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean freed0, freed1;
|
||||||
|
static int unique_pointer0[1];
|
||||||
|
static int unique_pointer1[1];
|
||||||
|
static void free_up (void *up)
|
||||||
|
{
|
||||||
|
if (up == unique_pointer0) {
|
||||||
|
g_assert (!freed0);
|
||||||
|
freed0 = TRUE;
|
||||||
|
} else if (up == unique_pointer1) {
|
||||||
|
g_assert (!freed1);
|
||||||
|
freed1 = TRUE;
|
||||||
|
} else {
|
||||||
|
g_assert_not_reached ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static hb_script_t
|
||||||
|
simple_get_script (hb_unicode_funcs_t *ufuncs,
|
||||||
|
hb_codepoint_t codepoint,
|
||||||
|
void *user_data)
|
||||||
|
{
|
||||||
|
g_assert (hb_unicode_funcs_get_parent (ufuncs) == NULL);
|
||||||
|
g_assert (unique_pointer0 == user_data);
|
||||||
|
|
||||||
|
if ('a' <= codepoint && codepoint <= 'z')
|
||||||
|
return HB_SCRIPT_LATIN;
|
||||||
|
else
|
||||||
|
return HB_SCRIPT_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_custom (void)
|
||||||
|
{
|
||||||
|
hb_unicode_funcs_t *uf = hb_unicode_funcs_create (NULL);
|
||||||
|
|
||||||
|
hb_unicode_funcs_set_script_func (uf, simple_get_script,
|
||||||
|
unique_pointer0, free_up);
|
||||||
|
|
||||||
|
g_assert_cmpint (hb_unicode_get_script (uf, 'a'), ==, HB_SCRIPT_LATIN);
|
||||||
|
g_assert_cmpint (hb_unicode_get_script (uf, '0'), ==, HB_SCRIPT_UNKNOWN);
|
||||||
|
|
||||||
|
g_assert_cmpint (hb_unicode_funcs_get_reference_count (uf), ==, 1);
|
||||||
|
g_assert (!freed0 && !freed1);
|
||||||
|
hb_unicode_funcs_destroy (uf);
|
||||||
|
g_assert (freed0 && !freed1);
|
||||||
|
freed0 = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static hb_script_t
|
||||||
|
a_is_for_arabic_get_script (hb_unicode_funcs_t *ufuncs,
|
||||||
|
hb_codepoint_t codepoint,
|
||||||
|
void *user_data)
|
||||||
|
{
|
||||||
|
g_assert (hb_unicode_funcs_get_parent (ufuncs) != NULL);
|
||||||
|
g_assert (user_data == unique_pointer1);
|
||||||
|
|
||||||
|
if (codepoint == 'a') {
|
||||||
|
return HB_SCRIPT_ARABIC;
|
||||||
|
} else {
|
||||||
|
hb_unicode_funcs_t *parent = hb_unicode_funcs_get_parent (ufuncs);
|
||||||
|
|
||||||
|
return hb_unicode_get_script (parent, codepoint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_subclassing_nil (void)
|
||||||
|
{
|
||||||
|
hb_unicode_funcs_t *uf = hb_unicode_funcs_create (NULL);
|
||||||
|
g_assert_cmpint (hb_unicode_funcs_get_reference_count (uf), ==, 1);
|
||||||
|
hb_unicode_funcs_t *aa = hb_unicode_funcs_create (uf);
|
||||||
|
g_assert_cmpint (hb_unicode_funcs_get_reference_count (uf), ==, 2);
|
||||||
|
hb_unicode_funcs_destroy (uf);
|
||||||
|
g_assert_cmpint (hb_unicode_funcs_get_reference_count (uf), ==, 1);
|
||||||
|
|
||||||
|
hb_unicode_funcs_set_script_func (aa, a_is_for_arabic_get_script,
|
||||||
|
unique_pointer1, free_up);
|
||||||
|
|
||||||
|
g_assert_cmpint (hb_unicode_get_script (aa, 'a'), ==, HB_SCRIPT_ARABIC);
|
||||||
|
g_assert_cmpint (hb_unicode_get_script (aa, 'b'), ==, HB_SCRIPT_UNKNOWN);
|
||||||
|
|
||||||
|
|
||||||
|
g_assert_cmpint (hb_unicode_funcs_get_reference_count (aa), ==, 1);
|
||||||
|
g_assert_cmpint (hb_unicode_funcs_get_reference_count (uf), ==, 1);
|
||||||
|
g_assert (!freed0 && !freed1);
|
||||||
|
hb_unicode_funcs_destroy (aa);
|
||||||
|
g_assert (!freed0 && freed1);
|
||||||
|
freed1 = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_subclassing_glib (void)
|
||||||
|
{
|
||||||
|
hb_unicode_funcs_t *uf = hb_glib_get_unicode_funcs ();
|
||||||
|
g_assert_cmpint (hb_unicode_funcs_get_reference_count (uf), ==, 0);
|
||||||
|
hb_unicode_funcs_t *aa = hb_unicode_funcs_create (uf);
|
||||||
|
g_assert_cmpint (hb_unicode_funcs_get_reference_count (uf), ==, 0);
|
||||||
|
hb_unicode_funcs_destroy (uf);
|
||||||
|
g_assert_cmpint (hb_unicode_funcs_get_reference_count (uf), ==, 0);
|
||||||
|
|
||||||
|
hb_unicode_funcs_set_script_func (aa, a_is_for_arabic_get_script,
|
||||||
|
unique_pointer1, free_up);
|
||||||
|
|
||||||
|
g_assert_cmpint (hb_unicode_get_script (aa, 'a'), ==, HB_SCRIPT_ARABIC);
|
||||||
|
g_assert_cmpint (hb_unicode_get_script (aa, 'b'), ==, HB_SCRIPT_LATIN);
|
||||||
|
|
||||||
|
g_assert_cmpint (hb_unicode_funcs_get_reference_count (aa), ==, 1);
|
||||||
|
g_assert (!freed0 && !freed1);
|
||||||
|
hb_unicode_funcs_destroy (aa);
|
||||||
|
g_assert (!freed0 && freed1);
|
||||||
|
freed1 = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_subclassing_deep (void)
|
||||||
|
{
|
||||||
|
hb_unicode_funcs_t *uf = hb_unicode_funcs_create (NULL);
|
||||||
|
g_assert_cmpint (hb_unicode_funcs_get_reference_count (uf), ==, 1);
|
||||||
|
|
||||||
|
hb_unicode_funcs_set_script_func (uf, simple_get_script,
|
||||||
|
unique_pointer0, free_up);
|
||||||
|
|
||||||
|
hb_unicode_funcs_t *aa = hb_unicode_funcs_create (uf);
|
||||||
|
g_assert_cmpint (hb_unicode_funcs_get_reference_count (aa), ==, 1);
|
||||||
|
g_assert_cmpint (hb_unicode_funcs_get_reference_count (uf), ==, 2);
|
||||||
|
|
||||||
|
hb_unicode_funcs_destroy (uf);
|
||||||
|
g_assert_cmpint (hb_unicode_funcs_get_reference_count (uf), ==, 1);
|
||||||
|
|
||||||
|
/* make sure the 'uf' didn't get freed, since 'aa' holds a ref */
|
||||||
|
g_assert (!freed0);
|
||||||
|
|
||||||
|
hb_unicode_funcs_set_script_func (aa, a_is_for_arabic_get_script,
|
||||||
|
unique_pointer1, free_up);
|
||||||
|
|
||||||
|
g_assert_cmpint (hb_unicode_get_script (aa, 'a'), ==, HB_SCRIPT_ARABIC);
|
||||||
|
g_assert_cmpint (hb_unicode_get_script (aa, 'b'), ==, HB_SCRIPT_LATIN);
|
||||||
|
g_assert_cmpint (hb_unicode_get_script (aa, '0'), ==, HB_SCRIPT_UNKNOWN);
|
||||||
|
|
||||||
|
g_assert_cmpint (hb_unicode_funcs_get_reference_count (aa), ==, 1);
|
||||||
|
g_assert_cmpint (hb_unicode_funcs_get_reference_count (uf), ==, 1);
|
||||||
|
g_assert (!freed0 && !freed1);
|
||||||
|
hb_unicode_funcs_destroy (aa);
|
||||||
|
g_assert (freed0 && freed1);
|
||||||
|
freed0 = freed1 = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc, char **argv)
|
||||||
|
{
|
||||||
|
g_test_init (&argc, &argv, NULL);
|
||||||
|
|
||||||
|
g_test_add_func ("/unicode/nil", test_nil);
|
||||||
|
g_test_add_func ("/unicode/glib", test_glib);
|
||||||
|
g_test_add_func ("/unicode/custom", test_custom);
|
||||||
|
g_test_add_func ("/unicode/subclassing/nil", test_subclassing_nil);
|
||||||
|
g_test_add_func ("/unicode/subclassing/glib", test_subclassing_glib);
|
||||||
|
g_test_add_func ("/unicode/subclassing/deep", test_subclassing_deep);
|
||||||
|
|
||||||
|
return g_test_run ();
|
||||||
|
}
|
Loading…
Reference in New Issue