[HarfBuzz] harfbuzz-ng: Branch 'master' - 15 commits
Behdad Esfahbod
behdad at kemper.freedesktop.org
Thu Apr 21 13:59:40 PDT 2011
TODO | 22 -
src/Makefile.am | 19
src/hb-blob-private.h | 59 --
src/hb-blob-private.hh | 59 ++
src/hb-blob.c | 362 -----------------
src/hb-blob.cc | 356 ++++++++++++++++
src/hb-blob.h | 3
src/hb-buffer-private.hh | 2
src/hb-buffer.cc | 6
src/hb-buffer.h | 3
src/hb-common.c | 222 ----------
src/hb-common.cc | 222 ++++++++++
src/hb-font-private.h | 97 ----
src/hb-font-private.hh | 97 ++++
src/hb-font.cc | 38 -
src/hb-font.h | 24 -
src/hb-ft.c | 262 ------------
src/hb-ft.cc | 261 ++++++++++++
src/hb-ft.h | 2
src/hb-glib.cc | 2
src/hb-icu.cc | 139 ------
src/hb-object-private.h | 141 ------
src/hb-object-private.hh | 130 ++++++
src/hb-open-type-private.hh | 5
src/hb-ot-layout-common-private.hh | 6
src/hb-ot-layout-gdef-private.hh | 2
src/hb-ot-layout-private.hh | 6
src/hb-ot-layout.cc | 6
src/hb-ot-shape-complex-arabic-table.h | 674 -------------------------------
src/hb-ot-shape-complex-arabic-table.hh | 674 +++++++++++++++++++++++++++++++
src/hb-ot-shape-complex-arabic.cc | 2
src/hb-ot-shape-complex-private.hh | 2
src/hb-ot-shape-private.hh | 2
src/hb-ot-tag.c | 677 --------------------------------
src/hb-ot-tag.cc | 677 ++++++++++++++++++++++++++++++++
src/hb-private.h | 301 --------------
src/hb-private.hh | 303 ++++++++++++++
src/hb-shape.cc | 4
src/hb-unicode-private.hh | 2
src/hb-unicode.cc | 8
src/hb-unicode.h | 3
src/hb-view.c | 12
test/test-unicode.c | 24 -
43 files changed, 2847 insertions(+), 3071 deletions(-)
New commits:
commit 08da7a3841ca7dfcb627314cae1c3a668b9c7236
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Apr 21 16:59:10 2011 -0400
[hb-view] Accept numbers in feature tag name
Reported by Adam Twardoch.
diff --git a/src/hb-view.c b/src/hb-view.c
index ac55908..41adf20 100644
--- a/src/hb-view.c
+++ b/src/hb-view.c
@@ -233,10 +233,10 @@ parse_feature_tag (char **pp, hb_feature_t *feature)
parse_space (pp);
-#define ISALPHA(c) (('a' <= (c) && (c) <= 'z') || ('A' <= (c) && (c) <= 'Z'))
- while (c = **pp, ISALPHA(c))
+#define ISALNUM(c) (('a' <= (c) && (c) <= 'z') || ('A' <= (c) && (c) <= 'Z') || ('0' <= (c) && (c) <= '9'))
+ while (c = **pp, ISALNUM(c))
(*pp)++;
-#undef ISALPHA
+#undef ISALNUM
if (p == *pp)
return FALSE;
commit 24229eb13268a422efffbcb28a094b726824c7f0
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Apr 21 16:55:17 2011 -0400
Remove obsolete comment
Talking to Ryan Lortie, he thinks my comment doesn't make sense.
So I'm making the getter const. Note that g_atomic_int_get()
casts that away itself, so we don't need to worry about that
(which kinda makes me uncomfortable actually).
diff --git a/src/hb-object-private.hh b/src/hb-object-private.hh
index 74bc3ad..0a055e9 100644
--- a/src/hb-object-private.hh
+++ b/src/hb-object-private.hh
@@ -46,20 +46,8 @@ typedef struct {
inline int dec (void) { return hb_atomic_int_fetch_and_add (ref_count, -1); }
inline void set (int v) { return hb_atomic_int_set (ref_count, v); }
- /* XXX
- *
- * One thing I'm not sure. The following two methods should be declared
- * const. However, that assumes that hb_atomic_int_get() is const. I have
- * a vague memory hearing from Chris Wilson or Jeff Muizelaar that atomic get
- * is implemented as a fetch_and_add(0). In which case it does write to the
- * memory, and hence cannot be called on .rodata section. But that's how we
- * use it.
- *
- * If that is indeed the case, then perhaps is_invalid() should do a
- * non-protected read of the location.
- */
- inline int get (void) { return hb_atomic_int_get (ref_count); }
- inline bool is_invalid (void) { return get () == HB_REFERENCE_COUNT_INVALID_VALUE; }
+ inline int get (void) const { return hb_atomic_int_get (ref_count); }
+ inline bool is_invalid (void) const { return get () == HB_REFERENCE_COUNT_INVALID_VALUE; }
} hb_reference_count_t;
commit dcb7026f33cbcdf60e9b7fcdd44c64cc08702c74
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Apr 21 16:34:22 2011 -0400
Add ASSERT_STATIC_EXPR macro
Unused right now.
diff --git a/src/hb-private.hh b/src/hb-private.hh
index ae52889..85561d2 100644
--- a/src/hb-private.hh
+++ b/src/hb-private.hh
@@ -78,6 +78,8 @@ HB_BEGIN_DECLS
#define _ASSERT_STATIC0(_line, _cond) _ASSERT_STATIC1 (_line, (_cond))
#define ASSERT_STATIC(_cond) _ASSERT_STATIC0 (__LINE__, (_cond))
+#define ASSERT_STATIC_EXPR(_cond) ((void) sizeof (char[(_cond) ? 1 : -1]))
+
/* Lets assert int types. Saves trouble down the road. */
commit 3e8bdbf9414291da5cf61213d5f4275c1ae23ae5
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Apr 21 16:16:21 2011 -0400
Cleanup hb_refrence_count_t
diff --git a/src/hb-object-private.hh b/src/hb-object-private.hh
index 930f616..74bc3ad 100644
--- a/src/hb-object-private.hh
+++ b/src/hb-object-private.hh
@@ -38,18 +38,31 @@ HB_BEGIN_DECLS
typedef struct {
hb_atomic_int_t ref_count;
+#define HB_REFERENCE_COUNT_INVALID_VALUE ((hb_atomic_int_t) -1)
+#define HB_REFERENCE_COUNT_INVALID {HB_REFERENCE_COUNT_INVALID_VALUE}
+
inline void init (int v) { ref_count = v; /* non-atomic is fine */ }
inline int inc (void) { return hb_atomic_int_fetch_and_add (ref_count, 1); }
inline int dec (void) { return hb_atomic_int_fetch_and_add (ref_count, -1); }
inline void set (int v) { return hb_atomic_int_set (ref_count, v); }
+
+ /* XXX
+ *
+ * One thing I'm not sure. The following two methods should be declared
+ * const. However, that assumes that hb_atomic_int_get() is const. I have
+ * a vague memory hearing from Chris Wilson or Jeff Muizelaar that atomic get
+ * is implemented as a fetch_and_add(0). In which case it does write to the
+ * memory, and hence cannot be called on .rodata section. But that's how we
+ * use it.
+ *
+ * If that is indeed the case, then perhaps is_invalid() should do a
+ * non-protected read of the location.
+ */
inline int get (void) { return hb_atomic_int_get (ref_count); }
+ inline bool is_invalid (void) { return get () == HB_REFERENCE_COUNT_INVALID_VALUE; }
} hb_reference_count_t;
-#define HB_REFERENCE_COUNT_INVALID_VALUE ((hb_atomic_int_t) -1)
-#define HB_REFERENCE_COUNT_INVALID {HB_REFERENCE_COUNT_INVALID_VALUE}
-
-#define HB_REFERENCE_COUNT_IS_INVALID(RC) ((RC).get () == HB_REFERENCE_COUNT_INVALID_VALUE)
/* Debug */
@@ -77,7 +90,7 @@ _hb_trace_object (const void *obj,
/* Object allocation and lifecycle manamgement macros */
#define HB_OBJECT_IS_INERT(obj) \
- (unlikely (HB_REFERENCE_COUNT_IS_INVALID ((obj)->ref_count)))
+ (unlikely ((obj)->ref_count.is_invalid ()))
#define HB_OBJECT_DO_INIT_EXPR(obj) \
obj->ref_count.init (1)
diff --git a/src/hb-private.hh b/src/hb-private.hh
index d08a4d0..ae52889 100644
--- a/src/hb-private.hh
+++ b/src/hb-private.hh
@@ -212,7 +212,7 @@ typedef int (*hb_compare_func_t) (const void *, const void *);
#include <glib.h>
-typedef int hb_atomic_int_t;
+typedef volatile int hb_atomic_int_t;
#define hb_atomic_int_fetch_and_add(AI, V) g_atomic_int_exchange_and_add (&(AI), V)
#define hb_atomic_int_get(AI) g_atomic_int_get (&(AI))
#define hb_atomic_int_set(AI, V) g_atomic_int_set (&(AI), V)
@@ -235,12 +235,12 @@ typedef GStaticMutex hb_mutex_t;
#warning "Could not find any system to define platform macros, library will NOT be thread-safe"
#endif
-typedef int hb_atomic_int_t;
+typedef volatile int hb_atomic_int_t;
#define hb_atomic_int_fetch_and_add(AI, V) ((AI) += (V), (AI) - (V))
#define hb_atomic_int_get(AI) (AI)
#define hb_atomic_int_set(AI, V) HB_STMT_START { (AI) = (V); } HB_STMT_END
-typedef int hb_mutex_t;
+typedef volatile int hb_mutex_t;
#define HB_MUTEX_INIT 0
#define hb_mutex_init(M) HB_STMT_START { (M) = 0; } HB_STMT_END
#define hb_mutex_lock(M) HB_STMT_START { (M) = 1; } HB_STMT_END
commit 783a7d69696bf0b1502ec9c1495e482e491c78e0
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Apr 21 16:03:59 2011 -0400
[TODO] Remove finished items
diff --git a/TODO b/TODO
index b5eb3be..c90857e 100644
--- a/TODO
+++ b/TODO
@@ -9,8 +9,6 @@ General fixes:
- Remove fixed-size feature/lookup arrays in hb-ot-map
-- Use size_t in sanitize
-
- Use templates instead of macros for objects?
API issues to fix before 1.0:
@@ -18,8 +16,6 @@ API issues to fix before 1.0:
- Figure out how many .so objects, how to link, etc
-- Shall y axis progress downward instead of upward?
-
- User-data support ala cairo
- Real subclassing support for vfunc vectors
@@ -28,7 +24,7 @@ API issues to fix before 1.0:
- Fix blob, remove mutex, etc.
-- Add sanitize API (since may affect blob API)
+- Add sanitize API
- Add glib GBoxedType stuff
diff --git a/src/hb-ft.cc b/src/hb-ft.cc
index f583ce5..f792ba0 100644
--- a/src/hb-ft.cc
+++ b/src/hb-ft.cc
@@ -178,7 +178,6 @@ get_table (hb_tag_t tag, void *user_data)
if (error)
return NULL;
- /* TODO Use FT_Memory? */
buffer = (FT_Byte *) malloc (length);
if (buffer == NULL)
return NULL;
commit da975419884a535281745f30f4b32fee0bc8a7a1
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Apr 21 15:08:01 2011 -0400
[API] Allow negative font x_scale/y_scale
I was reconsidering whether y should grow down, since all three/four
times I've used this API I was tricked and got that wrong in my use.
So I was very inclined to make y grow down instead of up. However,
considering that the font space has y up and it would be very confusing
for callbacks to work against that, I decided that what I really want
is for the user to be able to set y_scale to a negative number to imply
that user-space y grows down.
Changing x_scale/y_scale from unsigned int to int allows that, and I've
made pango to use that instead of negating glyph y_offset later. hb-ft
however still has y group up. I *guess* that's how FreeType works?
I'm not sure, FreeType docs don't make this clear...
I'm happy with the resolution :-).
diff --git a/src/hb-font.cc b/src/hb-font.cc
index a84dde4..733eb3b 100644
--- a/src/hb-font.cc
+++ b/src/hb-font.cc
@@ -523,8 +523,8 @@ hb_font_unset_funcs (hb_font_t *font,
void
hb_font_set_scale (hb_font_t *font,
- unsigned int x_scale,
- unsigned int y_scale)
+ int x_scale,
+ int y_scale)
{
if (HB_OBJECT_IS_INERT (font))
return;
@@ -535,8 +535,8 @@ hb_font_set_scale (hb_font_t *font,
void
hb_font_get_scale (hb_font_t *font,
- unsigned int *x_scale,
- unsigned int *y_scale)
+ int *x_scale,
+ int *y_scale)
{
if (x_scale) *x_scale = font->x_scale;
if (y_scale) *y_scale = font->y_scale;
diff --git a/src/hb-font.h b/src/hb-font.h
index 397b586..d9d6090 100644
--- a/src/hb-font.h
+++ b/src/hb-font.h
@@ -231,13 +231,13 @@ hb_font_unset_funcs (hb_font_t *font,
*/
void
hb_font_set_scale (hb_font_t *font,
- unsigned int x_scale,
- unsigned int y_scale);
+ int x_scale,
+ int y_scale);
void
hb_font_get_scale (hb_font_t *font,
- unsigned int *x_scale,
- unsigned int *y_scale);
+ int *x_scale,
+ int *y_scale);
/*
* A zero value means "no hinting in that direction"
diff --git a/src/hb-ot-layout-common-private.hh b/src/hb-ot-layout-common-private.hh
index 9ff5ca9..00a1432 100644
--- a/src/hb-ot-layout-common-private.hh
+++ b/src/hb-ot-layout-common-private.hh
@@ -532,7 +532,7 @@ struct Device
inline hb_position_t get_y_delta (hb_ot_layout_context_t *c) const
{ return get_delta (c->font->y_ppem, c->font->y_scale); }
- inline int get_delta (unsigned int ppem, unsigned int scale) const
+ inline int get_delta (unsigned int ppem, int scale) const
{
if (!ppem) return 0;
@@ -540,10 +540,6 @@ struct Device
if (!pixels) return 0;
- /* pixels is at most in the -8..7 range. So 64-bit arithmetic is
- * not really necessary here. A simple cast to int may just work
- * as well. But since this code is not reached that often and
- * for the sake of correctness, we do a 64bit operation. */
return pixels * (int64_t) scale / ppem;
}
diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh
index a802c63..b032a7a 100644
--- a/src/hb-ot-layout-private.hh
+++ b/src/hb-ot-layout-private.hh
@@ -77,7 +77,7 @@ struct hb_ot_layout_context_t
inline hb_position_t scale_y (int16_t v) { return scale (v, this->font->y_scale); }
private:
- inline hb_position_t scale (int16_t v, unsigned int scale) { return v * (int64_t) scale / this->face->head_table->get_upem (); }
+ inline hb_position_t scale (int16_t v, int scale) { return v * (int64_t) scale / this->face->head_table->get_upem (); }
};
commit 4d559cddbb3b3a5c12c5167eba69598618a9f283
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Apr 21 14:58:23 2011 -0400
[icu] Remove big script switch(), rely on reverse-lookup
diff --git a/src/hb-icu.cc b/src/hb-icu.cc
index 2f31a07..5ff3d0f 100644
--- a/src/hb-icu.cc
+++ b/src/hb-icu.cc
@@ -40,140 +40,21 @@ HB_BEGIN_DECLS
hb_script_t
hb_icu_script_to_script (UScriptCode script)
{
+ if (unlikely (script == USCRIPT_INVALID_CODE))
+ return HB_SCRIPT_INVALID;
+
return hb_script_from_string (uscript_getShortName (script));
}
UScriptCode
hb_icu_script_from_script (hb_script_t script)
{
- switch ((int) script)
- {
-#define CHECK_ICU_VERSION(major, minor) \
- U_ICU_VERSION_MAJOR_NUM > (major) || (U_ICU_VERSION_MAJOR_NUM == (major) && U_ICU_VERSION_MINOR_NUM >= (minor))
-#define MATCH_SCRIPT(C) case HB_SCRIPT_##C: return USCRIPT_##C
-#define MATCH_SCRIPT2(C1, C2) case HB_SCRIPT_##C2: return USCRIPT_##C1
-
- MATCH_SCRIPT2(INVALID_CODE, INVALID);
-
- MATCH_SCRIPT (COMMON);
- MATCH_SCRIPT (INHERITED);
- MATCH_SCRIPT (ARABIC);
- MATCH_SCRIPT (ARMENIAN);
- MATCH_SCRIPT (BENGALI);
- MATCH_SCRIPT (BOPOMOFO);
- MATCH_SCRIPT (CHEROKEE);
- MATCH_SCRIPT (COPTIC);
- MATCH_SCRIPT (CYRILLIC);
- MATCH_SCRIPT (DESERET);
- MATCH_SCRIPT (DEVANAGARI);
- MATCH_SCRIPT (ETHIOPIC);
- MATCH_SCRIPT (GEORGIAN);
- MATCH_SCRIPT (GOTHIC);
- MATCH_SCRIPT (GREEK);
- MATCH_SCRIPT (GUJARATI);
- MATCH_SCRIPT (GURMUKHI);
- MATCH_SCRIPT (HAN);
- MATCH_SCRIPT (HANGUL);
- MATCH_SCRIPT (HEBREW);
- MATCH_SCRIPT (HIRAGANA);
- MATCH_SCRIPT (KANNADA);
- MATCH_SCRIPT (KATAKANA);
- MATCH_SCRIPT (KHMER);
- MATCH_SCRIPT (LAO);
- MATCH_SCRIPT (LATIN);
- MATCH_SCRIPT (MALAYALAM);
- MATCH_SCRIPT (MONGOLIAN);
- MATCH_SCRIPT (MYANMAR);
- MATCH_SCRIPT (OGHAM);
- MATCH_SCRIPT (OLD_ITALIC);
- MATCH_SCRIPT (ORIYA);
- MATCH_SCRIPT (RUNIC);
- MATCH_SCRIPT (SINHALA);
- MATCH_SCRIPT (SYRIAC);
- MATCH_SCRIPT (TAMIL);
- MATCH_SCRIPT (TELUGU);
- MATCH_SCRIPT (THAANA);
- MATCH_SCRIPT (THAI);
- MATCH_SCRIPT (TIBETAN);
- MATCH_SCRIPT (CANADIAN_ABORIGINAL);
- MATCH_SCRIPT (YI);
- MATCH_SCRIPT (TAGALOG);
- MATCH_SCRIPT (HANUNOO);
- MATCH_SCRIPT (BUHID);
- MATCH_SCRIPT (TAGBANWA);
-
- /* Unicode-4.0 additions */
- MATCH_SCRIPT (BRAILLE);
- MATCH_SCRIPT (CYPRIOT);
- MATCH_SCRIPT (LIMBU);
- MATCH_SCRIPT (OSMANYA);
- MATCH_SCRIPT (SHAVIAN);
- MATCH_SCRIPT (LINEAR_B);
- MATCH_SCRIPT (TAI_LE);
- MATCH_SCRIPT (UGARITIC);
-
- /* Unicode-4.1 additions */
- MATCH_SCRIPT (NEW_TAI_LUE);
- MATCH_SCRIPT (BUGINESE);
- MATCH_SCRIPT (GLAGOLITIC);
- MATCH_SCRIPT (TIFINAGH);
- MATCH_SCRIPT (SYLOTI_NAGRI);
- MATCH_SCRIPT (OLD_PERSIAN);
- MATCH_SCRIPT (KHAROSHTHI);
-
- /* Unicode-5.0 additions */
- MATCH_SCRIPT (UNKNOWN);
- MATCH_SCRIPT (BALINESE);
- MATCH_SCRIPT (CUNEIFORM);
- MATCH_SCRIPT (PHOENICIAN);
- MATCH_SCRIPT (PHAGS_PA);
- MATCH_SCRIPT (NKO);
-
- /* Unicode-5.1 additions */
- MATCH_SCRIPT (KAYAH_LI);
- MATCH_SCRIPT (LEPCHA);
- MATCH_SCRIPT (REJANG);
- MATCH_SCRIPT (SUNDANESE);
- MATCH_SCRIPT (SAURASHTRA);
- MATCH_SCRIPT (CHAM);
- MATCH_SCRIPT (OL_CHIKI);
- MATCH_SCRIPT (VAI);
- MATCH_SCRIPT (CARIAN);
- MATCH_SCRIPT (LYCIAN);
- MATCH_SCRIPT (LYDIAN);
-
- /* Unicode-5.2 additions */
- MATCH_SCRIPT (AVESTAN);
-#if CHECK_ICU_VERSION (4, 4)
- MATCH_SCRIPT (BAMUM);
-#endif
- MATCH_SCRIPT (EGYPTIAN_HIEROGLYPHS);
- MATCH_SCRIPT (IMPERIAL_ARAMAIC);
- MATCH_SCRIPT (INSCRIPTIONAL_PAHLAVI);
- MATCH_SCRIPT (INSCRIPTIONAL_PARTHIAN);
- MATCH_SCRIPT (JAVANESE);
- MATCH_SCRIPT (KAITHI);
- MATCH_SCRIPT2(LANNA, TAI_THAM);
-#if CHECK_ICU_VERSION (4, 4)
- MATCH_SCRIPT (LISU);
-#endif
- MATCH_SCRIPT2(MEITEI_MAYEK, MEETEI_MAYEK);
-#if CHECK_ICU_VERSION (4, 4)
- MATCH_SCRIPT (OLD_SOUTH_ARABIAN);
-#endif
- MATCH_SCRIPT2(ORKHON, OLD_TURKIC);
- MATCH_SCRIPT (SAMARITAN);
- MATCH_SCRIPT (TAI_VIET);
-
- /* Unicode-6.0 additions */
- MATCH_SCRIPT (BATAK);
- MATCH_SCRIPT (BRAHMI);
- MATCH_SCRIPT2(MANDAEAN, MANDAIC);
-
-#undef CHECK_ICU_VERSION
-#undef MATCH_SCRIPT
-#undef MATCH_SCRIPT2
- }
+ if (unlikely (script == HB_SCRIPT_INVALID))
+ return USCRIPT_INVALID_CODE;
+
+ for (unsigned int i = 0; i < USCRIPT_CODE_LIMIT; i++)
+ if (unlikely (hb_icu_script_to_script ((UScriptCode) i) == script))
+ return (UScriptCode) i;
return USCRIPT_UNKNOWN;
}
commit d18431b4cd8c1b14523733cd60a62b862f5b471f
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Wed Apr 20 18:59:10 2011 -0400
Move hb_reference_count_t from macros to inline methods
diff --git a/src/hb-object-private.hh b/src/hb-object-private.hh
index 8f0d5ae..930f616 100644
--- a/src/hb-object-private.hh
+++ b/src/hb-object-private.hh
@@ -35,24 +35,21 @@
HB_BEGIN_DECLS
-/* Encapsulate operations on the object's reference count */
typedef struct {
hb_atomic_int_t ref_count;
-} hb_reference_count_t;
-
-#define hb_reference_count_inc(RC) hb_atomic_int_fetch_and_add ((RC).ref_count, 1)
-#define hb_reference_count_dec(RC) hb_atomic_int_fetch_and_add ((RC).ref_count, -1)
-#define HB_REFERENCE_COUNT_INIT(RC, VALUE) ((RC).ref_count = (VALUE))
+ inline void init (int v) { ref_count = v; /* non-atomic is fine */ }
+ inline int inc (void) { return hb_atomic_int_fetch_and_add (ref_count, 1); }
+ inline int dec (void) { return hb_atomic_int_fetch_and_add (ref_count, -1); }
+ inline void set (int v) { return hb_atomic_int_set (ref_count, v); }
+ inline int get (void) { return hb_atomic_int_get (ref_count); }
-#define HB_REFERENCE_COUNT_GET_VALUE(RC) hb_atomic_int_get ((RC).ref_count)
-#define HB_REFERENCE_COUNT_SET_VALUE(RC, VALUE) hb_atomic_int_set ((RC).ref_count, (VALUE))
+} hb_reference_count_t;
#define HB_REFERENCE_COUNT_INVALID_VALUE ((hb_atomic_int_t) -1)
#define HB_REFERENCE_COUNT_INVALID {HB_REFERENCE_COUNT_INVALID_VALUE}
-#define HB_REFERENCE_COUNT_IS_INVALID(RC) (HB_REFERENCE_COUNT_GET_VALUE (RC) == HB_REFERENCE_COUNT_INVALID_VALUE)
-
+#define HB_REFERENCE_COUNT_IS_INVALID(RC) ((RC).get () == HB_REFERENCE_COUNT_INVALID_VALUE)
/* Debug */
@@ -69,7 +66,7 @@ _hb_trace_object (const void *obj,
(void) (HB_DEBUG_OBJECT &&
fprintf (stderr, "OBJECT(%p) refcount=%d %s\n",
obj,
- HB_REFERENCE_COUNT_GET_VALUE (*ref_count),
+ ref_count->get (),
function));
}
@@ -83,7 +80,7 @@ _hb_trace_object (const void *obj,
(unlikely (HB_REFERENCE_COUNT_IS_INVALID ((obj)->ref_count)))
#define HB_OBJECT_DO_INIT_EXPR(obj) \
- HB_REFERENCE_COUNT_INIT (obj->ref_count, 1)
+ obj->ref_count.init (1)
#define HB_OBJECT_DO_INIT(obj) \
HB_STMT_START { \
@@ -109,7 +106,7 @@ _hb_trace_object (const void *obj,
if (unlikely (!(obj) || HB_OBJECT_IS_INERT (obj))) \
return obj; \
TRACE_OBJECT (obj); \
- old_count = hb_reference_count_inc (obj->ref_count); \
+ old_count = obj->ref_count.inc (); \
assert (old_count > 0); \
return obj; \
} HB_STMT_END
@@ -120,7 +117,7 @@ _hb_trace_object (const void *obj,
if (unlikely (!(obj) || HB_OBJECT_IS_INERT (obj))) \
return; \
TRACE_OBJECT (obj); \
- old_count = hb_reference_count_dec (obj->ref_count); \
+ old_count = obj->ref_count.dec (); \
assert (old_count > 0); \
if (old_count != 1) \
return; \
commit c57d454accff66e5f2c58006e8fb40bc020b6182
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Wed Apr 20 18:50:27 2011 -0400
Rename all private sources and headers to C++ files
So we can liberally use the simple features of C++ that parts of the
codebase is already using.
diff --git a/src/Makefile.am b/src/Makefile.am
index 845c24a..1069307 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -12,17 +12,17 @@ HBCFLAGS =
HBLIBS =
HBSOURCES = \
hb-blob.cc \
- hb-blob-private.h \
+ hb-blob-private.hh \
hb-buffer.cc \
hb-buffer-private.hh \
- hb-common.c \
+ hb-common.cc \
hb-font.cc \
- hb-font-private.h \
- hb-object-private.h \
+ hb-font-private.hh \
+ hb-object-private.hh \
hb-open-file-private.hh \
hb-open-type-private.hh \
hb-ot-head-private.hh \
- hb-private.h \
+ hb-private.hh \
hb-shape.cc \
hb-unicode.cc \
hb-unicode-private.hh \
@@ -49,10 +49,10 @@ HBSOURCES += \
hb-ot-map-private.hh \
hb-ot-shape.cc \
hb-ot-shape-complex-arabic.cc \
- hb-ot-shape-complex-arabic-table.h \
+ hb-ot-shape-complex-arabic-table.hh \
hb-ot-shape-complex-private.hh \
hb-ot-shape-private.hh \
- hb-ot-tag.c \
+ hb-ot-tag.cc \
$(NULL)
HBHEADERS += \
hb-ot.h \
@@ -87,7 +87,7 @@ if HAVE_FREETYPE
HBCFLAGS += $(FREETYPE_CFLAGS)
HBLIBS += $(FREETYPE_LIBS)
HBSOURCES += \
- hb-ft.c \
+ hb-ft.cc \
$(NULL)
HBHEADERS += \
hb-ft.h \
@@ -142,5 +142,6 @@ else
dist_check_SCRIPTS += check-libstdc++.sh
endif
+TESTS = $(dist_check_SCRIPTS)
-include $(top_srcdir)/git.mk
diff --git a/src/hb-blob-private.h b/src/hb-blob-private.h
deleted file mode 100644
index cdc9b2f..0000000
--- a/src/hb-blob-private.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2010 Red Hat, Inc.
- *
- * 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.
- *
- * Red Hat Author(s): Behdad Esfahbod
- */
-
-#ifndef HB_BLOB_PRIVATE_H
-#define HB_BLOB_PRIVATE_H
-
-#include "hb-private.h"
-
-#include "hb-blob.h"
-
-HB_BEGIN_DECLS
-
-
-struct _hb_blob_t {
- hb_reference_count_t ref_count;
-
- unsigned int length;
-
- hb_mutex_t lock;
- /* the rest are protected by lock */
-
- unsigned int lock_count;
- hb_memory_mode_t mode;
-
- const char *data;
-
- void *user_data;
- hb_destroy_func_t destroy;
-};
-
-extern HB_INTERNAL hb_blob_t _hb_blob_nil;
-
-
-HB_END_DECLS
-
-#endif /* HB_BLOB_PRIVATE_H */
diff --git a/src/hb-blob-private.hh b/src/hb-blob-private.hh
new file mode 100644
index 0000000..4b421da
--- /dev/null
+++ b/src/hb-blob-private.hh
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * 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.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_BLOB_PRIVATE_HH
+#define HB_BLOB_PRIVATE_HH
+
+#include "hb-private.hh"
+
+#include "hb-blob.h"
+
+HB_BEGIN_DECLS
+
+
+struct _hb_blob_t {
+ hb_reference_count_t ref_count;
+
+ unsigned int length;
+
+ hb_mutex_t lock;
+ /* the rest are protected by lock */
+
+ unsigned int lock_count;
+ hb_memory_mode_t mode;
+
+ const char *data;
+
+ void *user_data;
+ hb_destroy_func_t destroy;
+};
+
+extern HB_INTERNAL hb_blob_t _hb_blob_nil;
+
+
+HB_END_DECLS
+
+#endif /* HB_BLOB_PRIVATE_HH */
diff --git a/src/hb-blob.cc b/src/hb-blob.cc
index 511455b..e2af8b7 100644
--- a/src/hb-blob.cc
+++ b/src/hb-blob.cc
@@ -24,9 +24,9 @@
* Red Hat Author(s): Behdad Esfahbod
*/
-#include "hb-private.h"
+#include "hb-private.hh"
-#include "hb-blob-private.h"
+#include "hb-blob-private.hh"
#ifdef HAVE_SYS_MMAN_H
#ifdef HAVE_UNISTD_H
diff --git a/src/hb-buffer-private.hh b/src/hb-buffer-private.hh
index dfcc45d..4c2a3e6 100644
--- a/src/hb-buffer-private.hh
+++ b/src/hb-buffer-private.hh
@@ -28,7 +28,7 @@
#ifndef HB_BUFFER_PRIVATE_HH
#define HB_BUFFER_PRIVATE_HH
-#include "hb-private.h"
+#include "hb-private.hh"
#include "hb-buffer.h"
#include "hb-unicode-private.hh"
diff --git a/src/hb-common.c b/src/hb-common.c
deleted file mode 100644
index c1c4c54..0000000
--- a/src/hb-common.c
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * Copyright (C) 2009,2010 Red Hat, Inc.
- *
- * 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.
- *
- * Red Hat Author(s): Behdad Esfahbod
- */
-
-#include "hb-private.h"
-
-HB_BEGIN_DECLS
-
-
-/* hb_tag_t */
-
-hb_tag_t
-hb_tag_from_string (const char *s)
-{
- char tag[4];
- unsigned int i;
-
- if (!s || !*s)
- return HB_TAG_NONE;
-
- for (i = 0; i < 4 && s[i]; i++)
- tag[i] = s[i];
- for (; i < 4; i++)
- tag[i] = ' ';
-
- return HB_TAG_CHAR4 (tag);
-}
-
-
-/* hb_language_t */
-
-struct _hb_language_t {
- const char s[1];
-};
-
-static const char canon_map[256] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '-', 0, 0,
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 0, 0, 0, 0, 0, 0,
- '-', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
- 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 0, 0, 0, 0, '-',
- 0, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
- 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 0, 0, 0, 0, 0
-};
-
-static hb_bool_t
-lang_equal (const void *v1,
- const void *v2)
-{
- const unsigned char *p1 = v1;
- const unsigned char *p2 = v2;
-
- while (canon_map[*p1] && canon_map[*p1] == canon_map[*p2])
- {
- p1++, p2++;
- }
-
- return (canon_map[*p1] == canon_map[*p2]);
-}
-
-#if 0
-static unsigned int
-lang_hash (const void *key)
-{
- const unsigned char *p = key;
- unsigned int h = 0;
- while (canon_map[*p])
- {
- h = (h << 5) - h + canon_map[*p];
- p++;
- }
-
- return h;
-}
-#endif
-
-
-hb_language_t
-hb_language_from_string (const char *str)
-{
- static unsigned int num_langs;
- static unsigned int num_alloced;
- static hb_language_t *langs;
- unsigned int i;
- unsigned char *p;
-
- /* TODO Use a hash table or something */
-
- if (!str || !*str)
- return NULL;
-
- for (i = 0; i < num_langs; i++)
- if (lang_equal (str, langs[i]->s))
- return langs[i];
-
- if (unlikely (num_langs == num_alloced)) {
- unsigned int new_alloced = 2 * (8 + num_alloced);
- hb_language_t *new_langs = realloc (langs, new_alloced * sizeof (langs[0]));
- if (!new_langs)
- return NULL;
- num_alloced = new_alloced;
- langs = new_langs;
- }
-
- langs[i] = (hb_language_t) strdup (str);
- for (p = (unsigned char *) langs[i]->s; *p; p++)
- *p = canon_map[*p];
-
- num_langs++;
-
- return langs[i];
-}
-
-const char *
-hb_language_to_string (hb_language_t language)
-{
- return language->s;
-}
-
-
-/* hb_script_t */
-
-hb_script_t
-hb_script_from_iso15924_tag (hb_tag_t tag)
-{
- if (unlikely (tag == HB_TAG_NONE))
- return HB_SCRIPT_INVALID;
-
- /* Be lenient, adjust case (one capital letter followed by three small letters) */
- tag = (tag & 0xDFDFDFDF) | 0x00202020;
-
- switch (tag) {
- case HB_TAG('C','y','r','s'): return HB_SCRIPT_CYRILLIC;
- case HB_TAG('G','e','o','a'): return HB_SCRIPT_GEORGIAN;
- case HB_TAG('G','e','o','n'): return HB_SCRIPT_GEORGIAN;
- case HB_TAG('L','a','t','f'): return HB_SCRIPT_LATIN;
- case HB_TAG('L','a','t','g'): return HB_SCRIPT_LATIN;
- case HB_TAG('S','y','r','e'): return HB_SCRIPT_SYRIAC;
- case HB_TAG('S','y','r','j'): return HB_SCRIPT_SYRIAC;
- case HB_TAG('S','y','r','n'): return HB_SCRIPT_SYRIAC;
- }
-
- /* If it looks right, just use the tag as a script */
- if (((uint32_t) tag & 0xE0E0E0E0) == 0x40606060)
- return (hb_script_t) tag;
-
- /* Otherwise, return unknown */
- return HB_SCRIPT_UNKNOWN;
-}
-
-hb_script_t
-hb_script_from_string (const char *s)
-{
- return hb_script_from_iso15924_tag (hb_tag_from_string (s));
-}
-
-hb_tag_t
-hb_script_to_iso15924_tag (hb_script_t script)
-{
- return (hb_tag_t) script;
-}
-
-hb_direction_t
-hb_script_get_horizontal_direction (hb_script_t script)
-{
- switch ((hb_tag_t) script)
- {
- case HB_SCRIPT_ARABIC:
- case HB_SCRIPT_HEBREW:
- case HB_SCRIPT_SYRIAC:
- case HB_SCRIPT_THAANA:
-
- /* Unicode-4.0 additions */
- case HB_SCRIPT_CYPRIOT:
-
- /* Unicode-5.0 additions */
- case HB_SCRIPT_PHOENICIAN:
- case HB_SCRIPT_NKO:
-
- /* Unicode-5.2 additions */
- case HB_SCRIPT_AVESTAN:
- case HB_SCRIPT_IMPERIAL_ARAMAIC:
- case HB_SCRIPT_INSCRIPTIONAL_PAHLAVI:
- case HB_SCRIPT_INSCRIPTIONAL_PARTHIAN:
- case HB_SCRIPT_OLD_SOUTH_ARABIAN:
- case HB_SCRIPT_OLD_TURKIC:
- case HB_SCRIPT_SAMARITAN:
-
- /* Unicode-6.0 additions */
- case HB_SCRIPT_MANDAIC:
-
- return HB_DIRECTION_RTL;
- }
-
- return HB_DIRECTION_LTR;
-}
-
-
-HB_END_DECLS
diff --git a/src/hb-common.cc b/src/hb-common.cc
new file mode 100644
index 0000000..ece0980
--- /dev/null
+++ b/src/hb-common.cc
@@ -0,0 +1,222 @@
+/*
+ * Copyright (C) 2009,2010 Red Hat, Inc.
+ *
+ * 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.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ */
+
+#include "hb-private.hh"
+
+HB_BEGIN_DECLS
+
+
+/* hb_tag_t */
+
+hb_tag_t
+hb_tag_from_string (const char *s)
+{
+ char tag[4];
+ unsigned int i;
+
+ if (!s || !*s)
+ return HB_TAG_NONE;
+
+ for (i = 0; i < 4 && s[i]; i++)
+ tag[i] = s[i];
+ for (; i < 4; i++)
+ tag[i] = ' ';
+
+ return HB_TAG_CHAR4 (tag);
+}
+
+
+/* hb_language_t */
+
+struct _hb_language_t {
+ const char s[1];
+};
+
+static const char canon_map[256] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '-', 0, 0,
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 0, 0, 0, 0, 0, 0,
+ '-', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
+ 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 0, 0, 0, 0, '-',
+ 0, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
+ 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 0, 0, 0, 0, 0
+};
+
+static hb_bool_t
+lang_equal (const void *v1,
+ const void *v2)
+{
+ const unsigned char *p1 = (const unsigned char *) v1;
+ const unsigned char *p2 = (const unsigned char *) v2;
+
+ while (canon_map[*p1] && canon_map[*p1] == canon_map[*p2])
+ {
+ p1++, p2++;
+ }
+
+ return (canon_map[*p1] == canon_map[*p2]);
+}
+
+#if 0
+static unsigned int
+lang_hash (const void *key)
+{
+ const unsigned char *p = key;
+ unsigned int h = 0;
+ while (canon_map[*p])
+ {
+ h = (h << 5) - h + canon_map[*p];
+ p++;
+ }
+
+ return h;
+}
+#endif
+
+
+hb_language_t
+hb_language_from_string (const char *str)
+{
+ static unsigned int num_langs;
+ static unsigned int num_alloced;
+ static hb_language_t *langs;
+ unsigned int i;
+ unsigned char *p;
+
+ /* TODO Use a hash table or something */
+
+ if (!str || !*str)
+ return NULL;
+
+ for (i = 0; i < num_langs; i++)
+ if (lang_equal (str, langs[i]->s))
+ return langs[i];
+
+ if (unlikely (num_langs == num_alloced)) {
+ unsigned int new_alloced = 2 * (8 + num_alloced);
+ hb_language_t *new_langs = (hb_language_t *) realloc (langs, new_alloced * sizeof (langs[0]));
+ if (!new_langs)
+ return NULL;
+ num_alloced = new_alloced;
+ langs = new_langs;
+ }
+
+ langs[i] = (hb_language_t) strdup (str);
+ for (p = (unsigned char *) langs[i]->s; *p; p++)
+ *p = canon_map[*p];
+
+ num_langs++;
+
+ return langs[i];
+}
+
+const char *
+hb_language_to_string (hb_language_t language)
+{
+ return language->s;
+}
+
+
+/* hb_script_t */
+
+hb_script_t
+hb_script_from_iso15924_tag (hb_tag_t tag)
+{
+ if (unlikely (tag == HB_TAG_NONE))
+ return HB_SCRIPT_INVALID;
+
+ /* Be lenient, adjust case (one capital letter followed by three small letters) */
+ tag = (tag & 0xDFDFDFDF) | 0x00202020;
+
+ switch (tag) {
+ case HB_TAG('C','y','r','s'): return HB_SCRIPT_CYRILLIC;
+ case HB_TAG('G','e','o','a'): return HB_SCRIPT_GEORGIAN;
+ case HB_TAG('G','e','o','n'): return HB_SCRIPT_GEORGIAN;
+ case HB_TAG('L','a','t','f'): return HB_SCRIPT_LATIN;
+ case HB_TAG('L','a','t','g'): return HB_SCRIPT_LATIN;
+ case HB_TAG('S','y','r','e'): return HB_SCRIPT_SYRIAC;
+ case HB_TAG('S','y','r','j'): return HB_SCRIPT_SYRIAC;
+ case HB_TAG('S','y','r','n'): return HB_SCRIPT_SYRIAC;
+ }
+
+ /* If it looks right, just use the tag as a script */
+ if (((uint32_t) tag & 0xE0E0E0E0) == 0x40606060)
+ return (hb_script_t) tag;
+
+ /* Otherwise, return unknown */
+ return HB_SCRIPT_UNKNOWN;
+}
+
+hb_script_t
+hb_script_from_string (const char *s)
+{
+ return hb_script_from_iso15924_tag (hb_tag_from_string (s));
+}
+
+hb_tag_t
+hb_script_to_iso15924_tag (hb_script_t script)
+{
+ return (hb_tag_t) script;
+}
+
+hb_direction_t
+hb_script_get_horizontal_direction (hb_script_t script)
+{
+ switch ((hb_tag_t) script)
+ {
+ case HB_SCRIPT_ARABIC:
+ case HB_SCRIPT_HEBREW:
+ case HB_SCRIPT_SYRIAC:
+ case HB_SCRIPT_THAANA:
+
+ /* Unicode-4.0 additions */
+ case HB_SCRIPT_CYPRIOT:
+
+ /* Unicode-5.0 additions */
+ case HB_SCRIPT_PHOENICIAN:
+ case HB_SCRIPT_NKO:
+
+ /* Unicode-5.2 additions */
+ case HB_SCRIPT_AVESTAN:
+ case HB_SCRIPT_IMPERIAL_ARAMAIC:
+ case HB_SCRIPT_INSCRIPTIONAL_PAHLAVI:
+ case HB_SCRIPT_INSCRIPTIONAL_PARTHIAN:
+ case HB_SCRIPT_OLD_SOUTH_ARABIAN:
+ case HB_SCRIPT_OLD_TURKIC:
+ case HB_SCRIPT_SAMARITAN:
+
+ /* Unicode-6.0 additions */
+ case HB_SCRIPT_MANDAIC:
+
+ return HB_DIRECTION_RTL;
+ }
+
+ return HB_DIRECTION_LTR;
+}
+
+
+HB_END_DECLS
diff --git a/src/hb-font-private.h b/src/hb-font-private.h
deleted file mode 100644
index 46686b7..0000000
--- a/src/hb-font-private.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2009 Red Hat, Inc.
- *
- * 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.
- *
- * Red Hat Author(s): Behdad Esfahbod
- */
-
-#ifndef HB_FONT_PRIVATE_H
-#define HB_FONT_PRIVATE_H
-
-#include "hb-private.h"
-
-#include "hb-font.h"
-
-HB_BEGIN_DECLS
-
-
-/*
- * hb_font_funcs_t
- */
-
-struct _hb_font_funcs_t {
- hb_reference_count_t ref_count;
-
- hb_bool_t immutable;
-
- struct {
- hb_font_get_glyph_func_t get_glyph;
- hb_font_get_glyph_advance_func_t get_glyph_advance;
- hb_font_get_glyph_extents_func_t get_glyph_extents;
- hb_font_get_contour_point_func_t get_contour_point;
- hb_font_get_kerning_func_t get_kerning;
- } v;
-};
-
-extern HB_INTERNAL hb_font_funcs_t _hb_font_funcs_nil;
-
-
-/*
- * hb_face_t
- */
-
-struct _hb_face_t {
- hb_reference_count_t ref_count;
-
- hb_get_table_func_t get_table;
- void *user_data;
- hb_destroy_func_t destroy;
-
- hb_blob_t *head_blob;
- const struct head *head_table;
-
- struct hb_ot_layout_t *ot_layout;
-};
-
-
-/*
- * hb_font_t
- */
-
-struct _hb_font_t {
- hb_reference_count_t ref_count;
-
- unsigned int x_scale;
- unsigned int y_scale;
-
- unsigned int x_ppem;
- unsigned int y_ppem;
-
- hb_font_funcs_t *klass;
- void *user_data;
- hb_destroy_func_t destroy;
-};
-
-
-HB_END_DECLS
-
-#endif /* HB_FONT_PRIVATE_H */
diff --git a/src/hb-font-private.hh b/src/hb-font-private.hh
new file mode 100644
index 0000000..da7255a
--- /dev/null
+++ b/src/hb-font-private.hh
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2009 Red Hat, Inc.
+ *
+ * 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.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_FONT_PRIVATE_HH
+#define HB_FONT_PRIVATE_HH
+
+#include "hb-private.hh"
+
+#include "hb-font.h"
+
+HB_BEGIN_DECLS
+
+
+/*
+ * hb_font_funcs_t
+ */
+
+struct _hb_font_funcs_t {
+ hb_reference_count_t ref_count;
+
+ hb_bool_t immutable;
+
+ struct {
+ hb_font_get_glyph_func_t get_glyph;
+ hb_font_get_glyph_advance_func_t get_glyph_advance;
+ hb_font_get_glyph_extents_func_t get_glyph_extents;
+ hb_font_get_contour_point_func_t get_contour_point;
+ hb_font_get_kerning_func_t get_kerning;
+ } v;
+};
+
+extern HB_INTERNAL hb_font_funcs_t _hb_font_funcs_nil;
+
+
+/*
+ * hb_face_t
+ */
+
+struct _hb_face_t {
+ hb_reference_count_t ref_count;
+
+ hb_get_table_func_t get_table;
+ void *user_data;
+ hb_destroy_func_t destroy;
+
+ hb_blob_t *head_blob;
+ const struct head *head_table;
+
+ struct hb_ot_layout_t *ot_layout;
+};
+
+
+/*
+ * hb_font_t
+ */
+
+struct _hb_font_t {
+ hb_reference_count_t ref_count;
+
+ unsigned int x_scale;
+ unsigned int y_scale;
+
+ unsigned int x_ppem;
+ unsigned int y_ppem;
+
+ hb_font_funcs_t *klass;
+ void *user_data;
+ hb_destroy_func_t destroy;
+};
+
+
+HB_END_DECLS
+
+#endif /* HB_FONT_PRIVATE_HH */
diff --git a/src/hb-font.cc b/src/hb-font.cc
index 96ff4f5..a84dde4 100644
--- a/src/hb-font.cc
+++ b/src/hb-font.cc
@@ -24,10 +24,10 @@
* Red Hat Author(s): Behdad Esfahbod
*/
-#include "hb-private.h"
+#include "hb-private.hh"
-#include "hb-font-private.h"
-#include "hb-blob-private.h"
+#include "hb-font-private.hh"
+#include "hb-blob-private.hh"
#include "hb-open-file-private.hh"
#include "hb-ot-layout-private.hh"
diff --git a/src/hb-ft.c b/src/hb-ft.c
deleted file mode 100644
index 96c035a..0000000
--- a/src/hb-ft.c
+++ /dev/null
@@ -1,262 +0,0 @@
-/*
- * Copyright (C) 2009 Red Hat, Inc.
- * Copyright (C) 2009 Keith Stribley
- *
- * 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.
- *
- * Red Hat Author(s): Behdad Esfahbod
- */
-
-#include "hb-private.h"
-
-#include "hb-ft.h"
-
-#include "hb-font-private.h"
-
-#include FT_TRUETYPE_TABLES_H
-
-HB_BEGIN_DECLS
-
-
-static hb_codepoint_t
-hb_ft_get_glyph (hb_font_t *font HB_UNUSED,
- hb_face_t *face HB_UNUSED,
- const void *user_data,
- hb_codepoint_t unicode,
- hb_codepoint_t variation_selector)
-{
- FT_Face ft_face = (FT_Face) user_data;
-
-#ifdef HAVE_FT_FACE_GETCHARVARIANTINDEX
- if (unlikely (variation_selector)) {
- hb_codepoint_t glyph = FT_Face_GetCharVariantIndex (ft_face, unicode, variation_selector);
- if (glyph)
- return glyph;
- }
-#endif
-
- return FT_Get_Char_Index (ft_face, unicode);
-}
-
-static void
-hb_ft_get_glyph_advance (hb_font_t *font HB_UNUSED,
- hb_face_t *face HB_UNUSED,
- const void *user_data,
- hb_codepoint_t glyph,
- hb_position_t *x_advance,
- hb_position_t *y_advance)
-{
- FT_Face ft_face = (FT_Face) user_data;
- int load_flags = FT_LOAD_DEFAULT;
-
- /* TODO: load_flags, embolden, etc */
-
- if (likely (!FT_Load_Glyph (ft_face, glyph, load_flags)))
- {
- *x_advance = ft_face->glyph->advance.x;
- *y_advance = ft_face->glyph->advance.y;
- }
-}
-
-static void
-hb_ft_get_glyph_extents (hb_font_t *font HB_UNUSED,
- hb_face_t *face HB_UNUSED,
- const void *user_data,
- hb_codepoint_t glyph,
- hb_glyph_extents_t *extents)
-{
- FT_Face ft_face = (FT_Face) user_data;
- int load_flags = FT_LOAD_DEFAULT;
-
- /* TODO: load_flags, embolden, etc */
-
- if (likely (!FT_Load_Glyph (ft_face, glyph, load_flags)))
- {
- /* XXX: A few negations should be in order here, not sure. */
- extents->x_bearing = ft_face->glyph->metrics.horiBearingX;
- extents->y_bearing = ft_face->glyph->metrics.horiBearingY;
- extents->width = ft_face->glyph->metrics.width;
- extents->height = ft_face->glyph->metrics.height;
- }
-}
-
-static hb_bool_t
-hb_ft_get_contour_point (hb_font_t *font HB_UNUSED,
- hb_face_t *face HB_UNUSED,
- const void *user_data,
- unsigned int point_index,
- hb_codepoint_t glyph,
- hb_position_t *x,
- hb_position_t *y)
-{
- FT_Face ft_face = (FT_Face) user_data;
- int load_flags = FT_LOAD_DEFAULT;
-
- /* TODO: load_flags, embolden, etc */
-
- if (unlikely (FT_Load_Glyph (ft_face, glyph, load_flags)))
- return FALSE;
-
- if (unlikely (ft_face->glyph->format != FT_GLYPH_FORMAT_OUTLINE))
- return FALSE;
-
- if (unlikely (point_index >= (unsigned int) ft_face->glyph->outline.n_points))
- return FALSE;
-
- *x = ft_face->glyph->outline.points[point_index].x;
- *y = ft_face->glyph->outline.points[point_index].y;
-
- return TRUE;
-}
-
-static hb_position_t
-hb_ft_get_kerning (hb_font_t *font HB_UNUSED,
- hb_face_t *face HB_UNUSED,
- const void *user_data,
- hb_codepoint_t first_glyph,
- hb_codepoint_t second_glyph)
-{
- FT_Face ft_face = (FT_Face) user_data;
- FT_Vector kerning;
-
- /* TODO: Kern type? */
- if (FT_Get_Kerning (ft_face, first_glyph, second_glyph, FT_KERNING_DEFAULT, &kerning))
- return 0;
-
- return kerning.x;
-}
-
-static hb_font_funcs_t ft_ffuncs = {
- HB_REFERENCE_COUNT_INVALID, /* ref_count */
- TRUE, /* immutable */
- {
- hb_ft_get_glyph,
- hb_ft_get_glyph_advance,
- hb_ft_get_glyph_extents,
- hb_ft_get_contour_point,
- hb_ft_get_kerning
- }
-};
-
-hb_font_funcs_t *
-hb_ft_get_font_funcs (void)
-{
- return &ft_ffuncs;
-}
-
-
-static hb_blob_t *
-get_table (hb_tag_t tag, void *user_data)
-{
- FT_Face ft_face = (FT_Face) user_data;
- FT_Byte *buffer;
- FT_ULong length = 0;
- FT_Error error;
-
- if (unlikely (tag == HB_TAG_NONE))
- return NULL;
-
- error = FT_Load_Sfnt_Table (ft_face, tag, 0, NULL, &length);
- if (error)
- return NULL;
-
- /* TODO Use FT_Memory? */
- buffer = (FT_Byte *) malloc (length);
- if (buffer == NULL)
- return NULL;
-
- error = FT_Load_Sfnt_Table (ft_face, tag, 0, buffer, &length);
- if (error)
- return NULL;
-
- return hb_blob_create ((const char *) buffer, length,
- HB_MEMORY_MODE_WRITABLE,
- buffer, free);
-}
-
-
-hb_face_t *
-hb_ft_face_create (FT_Face ft_face,
- hb_destroy_func_t destroy)
-{
- hb_face_t *face;
-
- if (ft_face->stream->read == NULL) {
- hb_blob_t *blob;
-
- blob = hb_blob_create ((const char *) ft_face->stream->base,
- (unsigned int) ft_face->stream->size,
- /* TODO: Check FT_FACE_FLAG_EXTERNAL_STREAM? */
- HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE,
- ft_face, destroy);
- face = hb_face_create_for_data (blob, ft_face->face_index);
- hb_blob_destroy (blob);
- } else {
- face = hb_face_create_for_tables (get_table, ft_face, destroy);
- }
-
- return face;
-}
-
-static void
-hb_ft_face_finalize (FT_Face ft_face)
-{
- hb_face_destroy ((hb_face_t *) ft_face->generic.data);
-}
-
-hb_face_t *
-hb_ft_face_create_cached (FT_Face ft_face)
-{
- if (unlikely (!ft_face->generic.data || ft_face->generic.finalizer != (FT_Generic_Finalizer) hb_ft_face_finalize))
- {
- if (ft_face->generic.finalizer)
- ft_face->generic.finalizer (ft_face);
-
- ft_face->generic.data = hb_ft_face_create (ft_face, NULL);
- ft_face->generic.finalizer = (FT_Generic_Finalizer) hb_ft_face_finalize;
- }
-
- return hb_face_reference ((hb_face_t *) ft_face->generic.data);
-}
-
-
-hb_font_t *
-hb_ft_font_create (FT_Face ft_face,
- hb_destroy_func_t destroy)
-{
- hb_font_t *font;
-
- font = hb_font_create ();
- hb_font_set_funcs (font,
- hb_ft_get_font_funcs (),
- ft_face, destroy);
- hb_font_set_scale (font,
- ((uint64_t) ft_face->size->metrics.x_scale * (uint64_t) ft_face->units_per_EM) >> 16,
- ((uint64_t) ft_face->size->metrics.y_scale * (uint64_t) ft_face->units_per_EM) >> 16);
- hb_font_set_ppem (font,
- ft_face->size->metrics.x_ppem,
- ft_face->size->metrics.y_ppem);
-
- return font;
-}
-
-
-HB_END_DECLS
diff --git a/src/hb-ft.cc b/src/hb-ft.cc
new file mode 100644
index 0000000..f583ce5
--- /dev/null
+++ b/src/hb-ft.cc
@@ -0,0 +1,262 @@
+/*
+ * Copyright (C) 2009 Red Hat, Inc.
+ * Copyright (C) 2009 Keith Stribley
+ *
+ * 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.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ */
+
+#include "hb-private.hh"
+
+#include "hb-ft.h"
+
+#include "hb-font-private.hh"
+
+#include FT_TRUETYPE_TABLES_H
+
+HB_BEGIN_DECLS
+
+
+static hb_codepoint_t
+hb_ft_get_glyph (hb_font_t *font HB_UNUSED,
+ hb_face_t *face HB_UNUSED,
+ const void *user_data,
+ hb_codepoint_t unicode,
+ hb_codepoint_t variation_selector)
+{
+ FT_Face ft_face = (FT_Face) user_data;
+
+#ifdef HAVE_FT_FACE_GETCHARVARIANTINDEX
+ if (unlikely (variation_selector)) {
+ hb_codepoint_t glyph = FT_Face_GetCharVariantIndex (ft_face, unicode, variation_selector);
+ if (glyph)
+ return glyph;
+ }
+#endif
+
+ return FT_Get_Char_Index (ft_face, unicode);
+}
+
+static void
+hb_ft_get_glyph_advance (hb_font_t *font HB_UNUSED,
+ hb_face_t *face HB_UNUSED,
+ const void *user_data,
+ hb_codepoint_t glyph,
+ hb_position_t *x_advance,
+ hb_position_t *y_advance)
+{
+ FT_Face ft_face = (FT_Face) user_data;
+ int load_flags = FT_LOAD_DEFAULT;
+
+ /* TODO: load_flags, embolden, etc */
+
+ if (likely (!FT_Load_Glyph (ft_face, glyph, load_flags)))
+ {
+ *x_advance = ft_face->glyph->advance.x;
+ *y_advance = ft_face->glyph->advance.y;
+ }
+}
+
+static void
+hb_ft_get_glyph_extents (hb_font_t *font HB_UNUSED,
+ hb_face_t *face HB_UNUSED,
+ const void *user_data,
+ hb_codepoint_t glyph,
+ hb_glyph_extents_t *extents)
+{
+ FT_Face ft_face = (FT_Face) user_data;
+ int load_flags = FT_LOAD_DEFAULT;
+
+ /* TODO: load_flags, embolden, etc */
+
+ if (likely (!FT_Load_Glyph (ft_face, glyph, load_flags)))
+ {
+ /* XXX: A few negations should be in order here, not sure. */
+ extents->x_bearing = ft_face->glyph->metrics.horiBearingX;
+ extents->y_bearing = ft_face->glyph->metrics.horiBearingY;
+ extents->width = ft_face->glyph->metrics.width;
+ extents->height = ft_face->glyph->metrics.height;
+ }
+}
+
+static hb_bool_t
+hb_ft_get_contour_point (hb_font_t *font HB_UNUSED,
+ hb_face_t *face HB_UNUSED,
+ const void *user_data,
+ unsigned int point_index,
+ hb_codepoint_t glyph,
+ hb_position_t *x,
+ hb_position_t *y)
+{
+ FT_Face ft_face = (FT_Face) user_data;
+ int load_flags = FT_LOAD_DEFAULT;
+
+ /* TODO: load_flags, embolden, etc */
+
+ if (unlikely (FT_Load_Glyph (ft_face, glyph, load_flags)))
+ return FALSE;
+
+ if (unlikely (ft_face->glyph->format != FT_GLYPH_FORMAT_OUTLINE))
+ return FALSE;
+
+ if (unlikely (point_index >= (unsigned int) ft_face->glyph->outline.n_points))
+ return FALSE;
+
+ *x = ft_face->glyph->outline.points[point_index].x;
+ *y = ft_face->glyph->outline.points[point_index].y;
+
+ return TRUE;
+}
+
+static hb_position_t
+hb_ft_get_kerning (hb_font_t *font HB_UNUSED,
+ hb_face_t *face HB_UNUSED,
+ const void *user_data,
+ hb_codepoint_t first_glyph,
+ hb_codepoint_t second_glyph)
+{
+ FT_Face ft_face = (FT_Face) user_data;
+ FT_Vector kerning;
+
+ /* TODO: Kern type? */
+ if (FT_Get_Kerning (ft_face, first_glyph, second_glyph, FT_KERNING_DEFAULT, &kerning))
+ return 0;
+
+ return kerning.x;
+}
+
+static hb_font_funcs_t ft_ffuncs = {
+ HB_REFERENCE_COUNT_INVALID, /* ref_count */
+ TRUE, /* immutable */
+ {
+ hb_ft_get_glyph,
+ hb_ft_get_glyph_advance,
+ hb_ft_get_glyph_extents,
+ hb_ft_get_contour_point,
+ hb_ft_get_kerning
+ }
+};
+
+hb_font_funcs_t *
+hb_ft_get_font_funcs (void)
+{
+ return &ft_ffuncs;
+}
+
+
+static hb_blob_t *
+get_table (hb_tag_t tag, void *user_data)
+{
+ FT_Face ft_face = (FT_Face) user_data;
+ FT_Byte *buffer;
+ FT_ULong length = 0;
+ FT_Error error;
+
+ if (unlikely (tag == HB_TAG_NONE))
+ return NULL;
+
+ error = FT_Load_Sfnt_Table (ft_face, tag, 0, NULL, &length);
+ if (error)
+ return NULL;
+
+ /* TODO Use FT_Memory? */
+ buffer = (FT_Byte *) malloc (length);
+ if (buffer == NULL)
+ return NULL;
+
+ error = FT_Load_Sfnt_Table (ft_face, tag, 0, buffer, &length);
+ if (error)
+ return NULL;
+
+ return hb_blob_create ((const char *) buffer, length,
+ HB_MEMORY_MODE_WRITABLE,
+ buffer, free);
+}
+
+
+hb_face_t *
+hb_ft_face_create (FT_Face ft_face,
+ hb_destroy_func_t destroy)
+{
+ hb_face_t *face;
+
+ if (ft_face->stream->read == NULL) {
+ hb_blob_t *blob;
+
+ blob = hb_blob_create ((const char *) ft_face->stream->base,
+ (unsigned int) ft_face->stream->size,
+ /* TODO: Check FT_FACE_FLAG_EXTERNAL_STREAM? */
+ HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE,
+ ft_face, destroy);
+ face = hb_face_create_for_data (blob, ft_face->face_index);
+ hb_blob_destroy (blob);
+ } else {
+ face = hb_face_create_for_tables (get_table, ft_face, destroy);
+ }
+
+ return face;
+}
+
+static void
+hb_ft_face_finalize (FT_Face ft_face)
+{
+ hb_face_destroy ((hb_face_t *) ft_face->generic.data);
+}
+
+hb_face_t *
+hb_ft_face_create_cached (FT_Face ft_face)
+{
+ if (unlikely (!ft_face->generic.data || ft_face->generic.finalizer != (FT_Generic_Finalizer) hb_ft_face_finalize))
+ {
+ if (ft_face->generic.finalizer)
+ ft_face->generic.finalizer (ft_face);
+
+ ft_face->generic.data = hb_ft_face_create (ft_face, NULL);
+ ft_face->generic.finalizer = (FT_Generic_Finalizer) hb_ft_face_finalize;
+ }
+
+ return hb_face_reference ((hb_face_t *) ft_face->generic.data);
+}
+
+
+hb_font_t *
+hb_ft_font_create (FT_Face ft_face,
+ hb_destroy_func_t destroy)
+{
+ hb_font_t *font;
+
+ font = hb_font_create ();
+ hb_font_set_funcs (font,
+ hb_ft_get_font_funcs (),
+ ft_face, destroy);
+ hb_font_set_scale (font,
+ ((uint64_t) ft_face->size->metrics.x_scale * (uint64_t) ft_face->units_per_EM) >> 16,
+ ((uint64_t) ft_face->size->metrics.y_scale * (uint64_t) ft_face->units_per_EM) >> 16);
+ hb_font_set_ppem (font,
+ ft_face->size->metrics.x_ppem,
+ ft_face->size->metrics.y_ppem);
+
+ return font;
+}
+
+
+HB_END_DECLS
diff --git a/src/hb-glib.cc b/src/hb-glib.cc
index 158a210..0f94f52 100644
--- a/src/hb-glib.cc
+++ b/src/hb-glib.cc
@@ -24,7 +24,7 @@
* Red Hat Author(s): Behdad Esfahbod
*/
-#include "hb-private.h"
+#include "hb-private.hh"
#include "hb-glib.h"
diff --git a/src/hb-icu.cc b/src/hb-icu.cc
index 8fc8c81..2f31a07 100644
--- a/src/hb-icu.cc
+++ b/src/hb-icu.cc
@@ -25,7 +25,7 @@
* Red Hat Author(s): Behdad Esfahbod
*/
-#include "hb-private.h"
+#include "hb-private.hh"
#include "hb-icu.h"
diff --git a/src/hb-object-private.h b/src/hb-object-private.h
deleted file mode 100644
index c1787c5..0000000
--- a/src/hb-object-private.h
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright (C) 2007 Chris Wilson
- * Copyright (C) 2009,2010 Red Hat, Inc.
- *
- * 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.
- *
- * Contributor(s):
- * Chris Wilson <chris at chris-wilson.co.uk>
- * Red Hat Author(s): Behdad Esfahbod
- */
-
-#ifndef HB_OBJECT_PRIVATE_H
-#define HB_OBJECT_PRIVATE_H
-
-#include "hb-private.h"
-
-HB_BEGIN_DECLS
-
-
-/* Encapsulate operations on the object's reference count */
-typedef struct {
- hb_atomic_int_t ref_count;
-} hb_reference_count_t;
-
-#define hb_reference_count_inc(RC) hb_atomic_int_fetch_and_add ((RC).ref_count, 1)
-#define hb_reference_count_dec(RC) hb_atomic_int_fetch_and_add ((RC).ref_count, -1)
-
-#define HB_REFERENCE_COUNT_INIT(RC, VALUE) ((RC).ref_count = (VALUE))
-
-#define HB_REFERENCE_COUNT_GET_VALUE(RC) hb_atomic_int_get ((RC).ref_count)
-#define HB_REFERENCE_COUNT_SET_VALUE(RC, VALUE) hb_atomic_int_set ((RC).ref_count, (VALUE))
-
-#define HB_REFERENCE_COUNT_INVALID_VALUE ((hb_atomic_int_t) -1)
-#define HB_REFERENCE_COUNT_INVALID {HB_REFERENCE_COUNT_INVALID_VALUE}
-
-#define HB_REFERENCE_COUNT_IS_INVALID(RC) (HB_REFERENCE_COUNT_GET_VALUE (RC) == HB_REFERENCE_COUNT_INVALID_VALUE)
-
-#define HB_REFERENCE_COUNT_HAS_REFERENCE(RC) (HB_REFERENCE_COUNT_GET_VALUE (RC) > 0)
-
-
-
-/* Debug */
-
-#ifndef HB_DEBUG_OBJECT
-#define HB_DEBUG_OBJECT (HB_DEBUG+0)
-#endif
-
-static inline void
-_hb_trace_object (const void *obj,
- hb_reference_count_t *ref_count,
- const char *function)
-{
- (void) (HB_DEBUG_OBJECT &&
- fprintf (stderr, "OBJECT(%p) refcount=%d %s\n",
- obj,
- HB_REFERENCE_COUNT_GET_VALUE (*ref_count),
- function));
-}
-
-#define TRACE_OBJECT(obj) _hb_trace_object (obj, &obj->ref_count, __FUNCTION__)
-
-
-
-/* Object allocation and lifecycle manamgement macros */
-
-#define HB_OBJECT_IS_INERT(obj) \
- (unlikely (HB_REFERENCE_COUNT_IS_INVALID ((obj)->ref_count)))
-
-#define HB_OBJECT_DO_INIT_EXPR(obj) \
- HB_REFERENCE_COUNT_INIT (obj->ref_count, 1)
-
-#define HB_OBJECT_DO_INIT(obj) \
- HB_STMT_START { \
- HB_OBJECT_DO_INIT_EXPR (obj); \
- } HB_STMT_END
-
-#define HB_OBJECT_DO_CREATE(Type, obj) \
- likely (( \
- (void) ( \
- ((obj) = (Type *) calloc (1, sizeof (Type))) && \
- ( \
- HB_OBJECT_DO_INIT_EXPR (obj), \
- TRACE_OBJECT (obj), \
- TRUE \
- ) \
- ), \
- (obj) \
- ))
-
-#define HB_OBJECT_DO_REFERENCE(obj) \
- HB_STMT_START { \
- int old_count; \
- if (unlikely (!(obj) || HB_OBJECT_IS_INERT (obj))) \
- return obj; \
- TRACE_OBJECT (obj); \
- old_count = hb_reference_count_inc (obj->ref_count); \
- assert (old_count > 0); \
- return obj; \
- } HB_STMT_END
-
-#define HB_OBJECT_DO_DESTROY(obj) \
- HB_STMT_START { \
- int old_count; \
- if (unlikely (!(obj) || HB_OBJECT_IS_INERT (obj))) \
- return; \
- TRACE_OBJECT (obj); \
- old_count = hb_reference_count_dec (obj->ref_count); \
- assert (old_count > 0); \
- if (old_count != 1) \
- return; \
- } HB_STMT_END
-
-
-HB_END_DECLS
-
-#endif /* HB_OBJECT_PRIVATE_H */
diff --git a/src/hb-object-private.hh b/src/hb-object-private.hh
new file mode 100644
index 0000000..8f0d5ae
--- /dev/null
+++ b/src/hb-object-private.hh
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2007 Chris Wilson
+ * Copyright (C) 2009,2010 Red Hat, Inc.
+ *
+ * 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.
+ *
+ * Contributor(s):
+ * Chris Wilson <chris at chris-wilson.co.uk>
+ * Red Hat Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_OBJECT_PRIVATE_HH
+#define HB_OBJECT_PRIVATE_HH
+
+#include "hb-private.hh"
+
+HB_BEGIN_DECLS
+
+
+/* Encapsulate operations on the object's reference count */
+typedef struct {
+ hb_atomic_int_t ref_count;
+} hb_reference_count_t;
+
+#define hb_reference_count_inc(RC) hb_atomic_int_fetch_and_add ((RC).ref_count, 1)
+#define hb_reference_count_dec(RC) hb_atomic_int_fetch_and_add ((RC).ref_count, -1)
+
+#define HB_REFERENCE_COUNT_INIT(RC, VALUE) ((RC).ref_count = (VALUE))
+
+#define HB_REFERENCE_COUNT_GET_VALUE(RC) hb_atomic_int_get ((RC).ref_count)
+#define HB_REFERENCE_COUNT_SET_VALUE(RC, VALUE) hb_atomic_int_set ((RC).ref_count, (VALUE))
+
+#define HB_REFERENCE_COUNT_INVALID_VALUE ((hb_atomic_int_t) -1)
+#define HB_REFERENCE_COUNT_INVALID {HB_REFERENCE_COUNT_INVALID_VALUE}
+
+#define HB_REFERENCE_COUNT_IS_INVALID(RC) (HB_REFERENCE_COUNT_GET_VALUE (RC) == HB_REFERENCE_COUNT_INVALID_VALUE)
+
+
+
+/* Debug */
+
+#ifndef HB_DEBUG_OBJECT
+#define HB_DEBUG_OBJECT (HB_DEBUG+0)
+#endif
+
+static inline void
+_hb_trace_object (const void *obj,
+ hb_reference_count_t *ref_count,
+ const char *function)
+{
+ (void) (HB_DEBUG_OBJECT &&
+ fprintf (stderr, "OBJECT(%p) refcount=%d %s\n",
+ obj,
+ HB_REFERENCE_COUNT_GET_VALUE (*ref_count),
+ function));
+}
+
+#define TRACE_OBJECT(obj) _hb_trace_object (obj, &obj->ref_count, __FUNCTION__)
+
+
+
+/* Object allocation and lifecycle manamgement macros */
+
+#define HB_OBJECT_IS_INERT(obj) \
+ (unlikely (HB_REFERENCE_COUNT_IS_INVALID ((obj)->ref_count)))
+
+#define HB_OBJECT_DO_INIT_EXPR(obj) \
+ HB_REFERENCE_COUNT_INIT (obj->ref_count, 1)
+
+#define HB_OBJECT_DO_INIT(obj) \
+ HB_STMT_START { \
+ HB_OBJECT_DO_INIT_EXPR (obj); \
+ } HB_STMT_END
+
+#define HB_OBJECT_DO_CREATE(Type, obj) \
+ likely (( \
+ (void) ( \
+ ((obj) = (Type *) calloc (1, sizeof (Type))) && \
+ ( \
+ HB_OBJECT_DO_INIT_EXPR (obj), \
+ TRACE_OBJECT (obj), \
+ TRUE \
+ ) \
+ ), \
+ (obj) \
+ ))
+
+#define HB_OBJECT_DO_REFERENCE(obj) \
+ HB_STMT_START { \
+ int old_count; \
+ if (unlikely (!(obj) || HB_OBJECT_IS_INERT (obj))) \
+ return obj; \
+ TRACE_OBJECT (obj); \
+ old_count = hb_reference_count_inc (obj->ref_count); \
+ assert (old_count > 0); \
+ return obj; \
+ } HB_STMT_END
+
+#define HB_OBJECT_DO_DESTROY(obj) \
+ HB_STMT_START { \
+ int old_count; \
+ if (unlikely (!(obj) || HB_OBJECT_IS_INERT (obj))) \
+ return; \
+ TRACE_OBJECT (obj); \
+ old_count = hb_reference_count_dec (obj->ref_count); \
+ assert (old_count > 0); \
+ if (old_count != 1) \
+ return; \
+ } HB_STMT_END
+
+
+HB_END_DECLS
+
+#endif /* HB_OBJECT_PRIVATE_HH */
diff --git a/src/hb-open-type-private.hh b/src/hb-open-type-private.hh
index 241c5a0..490ea3a 100644
--- a/src/hb-open-type-private.hh
+++ b/src/hb-open-type-private.hh
@@ -27,7 +27,7 @@
#ifndef HB_OPEN_TYPE_PRIVATE_HH
#define HB_OPEN_TYPE_PRIVATE_HH
-#include "hb-private.h"
+#include "hb-private.hh"
#include "hb-blob.h"
diff --git a/src/hb-ot-layout-gdef-private.hh b/src/hb-ot-layout-gdef-private.hh
index 4172a7c..242b33a 100644
--- a/src/hb-ot-layout-gdef-private.hh
+++ b/src/hb-ot-layout-gdef-private.hh
@@ -31,7 +31,7 @@
#include "hb-ot-layout-common-private.hh"
-#include "hb-font-private.h"
+#include "hb-font-private.hh"
HB_BEGIN_DECLS
diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh
index b0088fb..a802c63 100644
--- a/src/hb-ot-layout-private.hh
+++ b/src/hb-ot-layout-private.hh
@@ -27,12 +27,12 @@
#ifndef HB_OT_LAYOUT_PRIVATE_HH
#define HB_OT_LAYOUT_PRIVATE_HH
-#include "hb-private.h"
+#include "hb-private.hh"
#include "hb-ot-layout.h"
#include "hb-ot-head-private.hh"
-#include "hb-font-private.h"
+#include "hb-font-private.hh"
#include "hb-buffer-private.hh"
HB_BEGIN_DECLS
diff --git a/src/hb-ot-shape-complex-arabic-table.h b/src/hb-ot-shape-complex-arabic-table.h
deleted file mode 100644
index 523fc84..0000000
--- a/src/hb-ot-shape-complex-arabic-table.h
+++ /dev/null
@@ -1,674 +0,0 @@
-/*
- * Copyright (C) 2010 Google, Inc.
- *
- * 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.
- *
- * Google Author(s): Behdad Esfahbod
- */
-
-#ifndef HB_OT_SHAPE_COMPLEX_ARABIC_TABLE_H
-#define HB_OT_SHAPE_COMPLEX_ARABIC_TABLE_H
-
-#include "hb-private.h"
-
-HB_BEGIN_DECLS
-
-/* == Start of generated table == */
-/*
- * The following table is generated by running:
- *
- * ./gen-arabic-joining-table.py < ArabicShaping.txt
- *
- * on the ArabicShaping.txt file with the header:
- *
- * # ArabicShaping-6.1.0.txt
- * # Date: 2010-11-09, 12:10:00 PST [KW]
- */
-static const uint8_t joining_table[] =
-{
-
- /* Arabic characters */
-
- JOINING_TYPE_U, /* 0600; ARABIC NUMBER SIGN; U; No_Joining_Group */
- JOINING_TYPE_U, /* 0601; ARABIC SIGN SANAH; U; No_Joining_Group */
- JOINING_TYPE_U, /* 0602; ARABIC FOOTNOTE MARKER; U; No_Joining_Group */
- JOINING_TYPE_U, /* 0603; ARABIC SIGN SAFHA; U; No_Joining_Group */
- JOINING_TYPE_X, /* 0604 */
- JOINING_TYPE_X, /* 0605 */
- JOINING_TYPE_X, /* 0606 */
- JOINING_TYPE_X, /* 0607 */
- JOINING_TYPE_U, /* 0608; ARABIC RAY; U; No_Joining_Group */
- JOINING_TYPE_X, /* 0609 */
- JOINING_TYPE_X, /* 060A */
- JOINING_TYPE_U, /* 060B; AFGHANI SIGN; U; No_Joining_Group */
- JOINING_TYPE_X, /* 060C */
- JOINING_TYPE_X, /* 060D */
- JOINING_TYPE_X, /* 060E */
- JOINING_TYPE_X, /* 060F */
- JOINING_TYPE_X, /* 0610 */
- JOINING_TYPE_X, /* 0611 */
- JOINING_TYPE_X, /* 0612 */
- JOINING_TYPE_X, /* 0613 */
- JOINING_TYPE_X, /* 0614 */
- JOINING_TYPE_X, /* 0615 */
- JOINING_TYPE_X, /* 0616 */
- JOINING_TYPE_X, /* 0617 */
- JOINING_TYPE_X, /* 0618 */
- JOINING_TYPE_X, /* 0619 */
- JOINING_TYPE_X, /* 061A */
- JOINING_TYPE_X, /* 061B */
- JOINING_TYPE_X, /* 061C */
- JOINING_TYPE_X, /* 061D */
- JOINING_TYPE_X, /* 061E */
- JOINING_TYPE_X, /* 061F */
- JOINING_TYPE_D, /* 0620; YEH WITH RING; D; YEH */
- JOINING_TYPE_U, /* 0621; HAMZA; U; No_Joining_Group */
- JOINING_TYPE_R, /* 0622; MADDA ON ALEF; R; ALEF */
- JOINING_TYPE_R, /* 0623; HAMZA ON ALEF; R; ALEF */
- JOINING_TYPE_R, /* 0624; HAMZA ON WAW; R; WAW */
- JOINING_TYPE_R, /* 0625; HAMZA UNDER ALEF; R; ALEF */
- JOINING_TYPE_D, /* 0626; HAMZA ON YEH; D; YEH */
- JOINING_TYPE_R, /* 0627; ALEF; R; ALEF */
- JOINING_TYPE_D, /* 0628; BEH; D; BEH */
- JOINING_TYPE_R, /* 0629; TEH MARBUTA; R; TEH MARBUTA */
- JOINING_TYPE_D, /* 062A; TEH; D; BEH */
- JOINING_TYPE_D, /* 062B; THEH; D; BEH */
- JOINING_TYPE_D, /* 062C; JEEM; D; HAH */
- JOINING_TYPE_D, /* 062D; HAH; D; HAH */
- JOINING_TYPE_D, /* 062E; KHAH; D; HAH */
- JOINING_TYPE_R, /* 062F; DAL; R; DAL */
- JOINING_TYPE_R, /* 0630; THAL; R; DAL */
- JOINING_TYPE_R, /* 0631; REH; R; REH */
- JOINING_TYPE_R, /* 0632; ZAIN; R; REH */
- JOINING_TYPE_D, /* 0633; SEEN; D; SEEN */
- JOINING_TYPE_D, /* 0634; SHEEN; D; SEEN */
- JOINING_TYPE_D, /* 0635; SAD; D; SAD */
- JOINING_TYPE_D, /* 0636; DAD; D; SAD */
- JOINING_TYPE_D, /* 0637; TAH; D; TAH */
- JOINING_TYPE_D, /* 0638; ZAH; D; TAH */
- JOINING_TYPE_D, /* 0639; AIN; D; AIN */
- JOINING_TYPE_D, /* 063A; GHAIN; D; AIN */
- JOINING_TYPE_D, /* 063B; KEHEH WITH 2 DOTS ABOVE; D; GAF */
- JOINING_TYPE_D, /* 063C; KEHEH WITH 3 DOTS BELOW; D; GAF */
- JOINING_TYPE_D, /* 063D; FARSI YEH WITH INVERTED V; D; FARSI YEH */
- JOINING_TYPE_D, /* 063E; FARSI YEH WITH 2 DOTS ABOVE; D; FARSI YEH */
- JOINING_TYPE_D, /* 063F; FARSI YEH WITH 3 DOTS ABOVE; D; FARSI YEH */
- JOINING_TYPE_C, /* 0640; TATWEEL; C; No_Joining_Group */
- JOINING_TYPE_D, /* 0641; FEH; D; FEH */
- JOINING_TYPE_D, /* 0642; QAF; D; QAF */
- JOINING_TYPE_D, /* 0643; KAF; D; KAF */
- JOINING_TYPE_D, /* 0644; LAM; D; LAM */
- JOINING_TYPE_D, /* 0645; MEEM; D; MEEM */
- JOINING_TYPE_D, /* 0646; NOON; D; NOON */
- JOINING_TYPE_D, /* 0647; HEH; D; HEH */
- JOINING_TYPE_R, /* 0648; WAW; R; WAW */
- JOINING_TYPE_D, /* 0649; ALEF MAKSURA; D; YEH */
- JOINING_TYPE_D, /* 064A; YEH; D; YEH */
- JOINING_TYPE_X, /* 064B */
- JOINING_TYPE_X, /* 064C */
- JOINING_TYPE_X, /* 064D */
- JOINING_TYPE_X, /* 064E */
- JOINING_TYPE_X, /* 064F */
- JOINING_TYPE_X, /* 0650 */
- JOINING_TYPE_X, /* 0651 */
- JOINING_TYPE_X, /* 0652 */
- JOINING_TYPE_X, /* 0653 */
- JOINING_TYPE_X, /* 0654 */
- JOINING_TYPE_X, /* 0655 */
- JOINING_TYPE_X, /* 0656 */
- JOINING_TYPE_X, /* 0657 */
- JOINING_TYPE_X, /* 0658 */
- JOINING_TYPE_X, /* 0659 */
- JOINING_TYPE_X, /* 065A */
- JOINING_TYPE_X, /* 065B */
- JOINING_TYPE_X, /* 065C */
- JOINING_TYPE_X, /* 065D */
- JOINING_TYPE_X, /* 065E */
- JOINING_TYPE_X, /* 065F */
- JOINING_TYPE_X, /* 0660 */
- JOINING_TYPE_X, /* 0661 */
- JOINING_TYPE_X, /* 0662 */
- JOINING_TYPE_X, /* 0663 */
- JOINING_TYPE_X, /* 0664 */
- JOINING_TYPE_X, /* 0665 */
- JOINING_TYPE_X, /* 0666 */
- JOINING_TYPE_X, /* 0667 */
- JOINING_TYPE_X, /* 0668 */
- JOINING_TYPE_X, /* 0669 */
- JOINING_TYPE_X, /* 066A */
- JOINING_TYPE_X, /* 066B */
- JOINING_TYPE_X, /* 066C */
- JOINING_TYPE_X, /* 066D */
- JOINING_TYPE_D, /* 066E; DOTLESS BEH; D; BEH */
- JOINING_TYPE_D, /* 066F; DOTLESS QAF; D; QAF */
- JOINING_TYPE_X, /* 0670 */
- JOINING_TYPE_R, /* 0671; HAMZAT WASL ON ALEF; R; ALEF */
- JOINING_TYPE_R, /* 0672; WAVY HAMZA ON ALEF; R; ALEF */
- JOINING_TYPE_R, /* 0673; WAVY HAMZA UNDER ALEF; R; ALEF */
- JOINING_TYPE_U, /* 0674; HIGH HAMZA; U; No_Joining_Group */
- JOINING_TYPE_R, /* 0675; HIGH HAMZA ALEF; R; ALEF */
- JOINING_TYPE_R, /* 0676; HIGH HAMZA WAW; R; WAW */
- JOINING_TYPE_R, /* 0677; HIGH HAMZA WAW WITH DAMMA; R; WAW */
- JOINING_TYPE_D, /* 0678; HIGH HAMZA YEH; D; YEH */
- JOINING_TYPE_D, /* 0679; TEH WITH SMALL TAH; D; BEH */
- JOINING_TYPE_D, /* 067A; TEH WITH 2 DOTS VERTICAL ABOVE; D; BEH */
- JOINING_TYPE_D, /* 067B; BEH WITH 2 DOTS VERTICAL BELOW; D; BEH */
- JOINING_TYPE_D, /* 067C; TEH WITH RING; D; BEH */
- JOINING_TYPE_D, /* 067D; TEH WITH 3 DOTS ABOVE DOWNWARD; D; BEH */
- JOINING_TYPE_D, /* 067E; TEH WITH 3 DOTS BELOW; D; BEH */
- JOINING_TYPE_D, /* 067F; TEH WITH 4 DOTS ABOVE; D; BEH */
- JOINING_TYPE_D, /* 0680; BEH WITH 4 DOTS BELOW; D; BEH */
- JOINING_TYPE_D, /* 0681; HAMZA ON HAH; D; HAH */
- JOINING_TYPE_D, /* 0682; HAH WITH 2 DOTS VERTICAL ABOVE; D; HAH */
- JOINING_TYPE_D, /* 0683; HAH WITH MIDDLE 2 DOTS; D; HAH */
- JOINING_TYPE_D, /* 0684; HAH WITH MIDDLE 2 DOTS VERTICAL; D; HAH */
- JOINING_TYPE_D, /* 0685; HAH WITH 3 DOTS ABOVE; D; HAH */
- JOINING_TYPE_D, /* 0686; HAH WITH MIDDLE 3 DOTS DOWNWARD; D; HAH */
- JOINING_TYPE_D, /* 0687; HAH WITH MIDDLE 4 DOTS; D; HAH */
- JOINING_TYPE_R, /* 0688; DAL WITH SMALL TAH; R; DAL */
- JOINING_TYPE_R, /* 0689; DAL WITH RING; R; DAL */
- JOINING_TYPE_R, /* 068A; DAL WITH DOT BELOW; R; DAL */
- JOINING_TYPE_R, /* 068B; DAL WITH DOT BELOW AND SMALL TAH; R; DAL */
- JOINING_TYPE_R, /* 068C; DAL WITH 2 DOTS ABOVE; R; DAL */
- JOINING_TYPE_R, /* 068D; DAL WITH 2 DOTS BELOW; R; DAL */
- JOINING_TYPE_R, /* 068E; DAL WITH 3 DOTS ABOVE; R; DAL */
- JOINING_TYPE_R, /* 068F; DAL WITH 3 DOTS ABOVE DOWNWARD; R; DAL */
- JOINING_TYPE_R, /* 0690; DAL WITH 4 DOTS ABOVE; R; DAL */
- JOINING_TYPE_R, /* 0691; REH WITH SMALL TAH; R; REH */
- JOINING_TYPE_R, /* 0692; REH WITH SMALL V; R; REH */
- JOINING_TYPE_R, /* 0693; REH WITH RING; R; REH */
- JOINING_TYPE_R, /* 0694; REH WITH DOT BELOW; R; REH */
- JOINING_TYPE_R, /* 0695; REH WITH SMALL V BELOW; R; REH */
- JOINING_TYPE_R, /* 0696; REH WITH DOT BELOW AND DOT ABOVE; R; REH */
- JOINING_TYPE_R, /* 0697; REH WITH 2 DOTS ABOVE; R; REH */
- JOINING_TYPE_R, /* 0698; REH WITH 3 DOTS ABOVE; R; REH */
- JOINING_TYPE_R, /* 0699; REH WITH 4 DOTS ABOVE; R; REH */
- JOINING_TYPE_D, /* 069A; SEEN WITH DOT BELOW AND DOT ABOVE; D; SEEN */
- JOINING_TYPE_D, /* 069B; SEEN WITH 3 DOTS BELOW; D; SEEN */
- JOINING_TYPE_D, /* 069C; SEEN WITH 3 DOTS BELOW AND 3 DOTS ABOVE; D; SEEN */
- JOINING_TYPE_D, /* 069D; SAD WITH 2 DOTS BELOW; D; SAD */
- JOINING_TYPE_D, /* 069E; SAD WITH 3 DOTS ABOVE; D; SAD */
- JOINING_TYPE_D, /* 069F; TAH WITH 3 DOTS ABOVE; D; TAH */
- JOINING_TYPE_D, /* 06A0; AIN WITH 3 DOTS ABOVE; D; AIN */
- JOINING_TYPE_D, /* 06A1; DOTLESS FEH; D; FEH */
- JOINING_TYPE_D, /* 06A2; FEH WITH DOT MOVED BELOW; D; FEH */
- JOINING_TYPE_D, /* 06A3; FEH WITH DOT BELOW; D; FEH */
- JOINING_TYPE_D, /* 06A4; FEH WITH 3 DOTS ABOVE; D; FEH */
- JOINING_TYPE_D, /* 06A5; FEH WITH 3 DOTS BELOW; D; FEH */
- JOINING_TYPE_D, /* 06A6; FEH WITH 4 DOTS ABOVE; D; FEH */
- JOINING_TYPE_D, /* 06A7; QAF WITH DOT ABOVE; D; QAF */
- JOINING_TYPE_D, /* 06A8; QAF WITH 3 DOTS ABOVE; D; QAF */
- JOINING_TYPE_D, /* 06A9; KEHEH; D; GAF */
- JOINING_TYPE_D, /* 06AA; SWASH KAF; D; SWASH KAF */
- JOINING_TYPE_D, /* 06AB; KAF WITH RING; D; GAF */
- JOINING_TYPE_D, /* 06AC; KAF WITH DOT ABOVE; D; KAF */
- JOINING_TYPE_D, /* 06AD; KAF WITH 3 DOTS ABOVE; D; KAF */
- JOINING_TYPE_D, /* 06AE; KAF WITH 3 DOTS BELOW; D; KAF */
- JOINING_TYPE_D, /* 06AF; GAF; D; GAF */
- JOINING_TYPE_D, /* 06B0; GAF WITH RING; D; GAF */
- JOINING_TYPE_D, /* 06B1; GAF WITH 2 DOTS ABOVE; D; GAF */
- JOINING_TYPE_D, /* 06B2; GAF WITH 2 DOTS BELOW; D; GAF */
- JOINING_TYPE_D, /* 06B3; GAF WITH 2 DOTS VERTICAL BELOW; D; GAF */
- JOINING_TYPE_D, /* 06B4; GAF WITH 3 DOTS ABOVE; D; GAF */
- JOINING_TYPE_D, /* 06B5; LAM WITH SMALL V; D; LAM */
- JOINING_TYPE_D, /* 06B6; LAM WITH DOT ABOVE; D; LAM */
- JOINING_TYPE_D, /* 06B7; LAM WITH 3 DOTS ABOVE; D; LAM */
- JOINING_TYPE_D, /* 06B8; LAM WITH 3 DOTS BELOW; D; LAM */
- JOINING_TYPE_D, /* 06B9; NOON WITH DOT BELOW; D; NOON */
- JOINING_TYPE_D, /* 06BA; DOTLESS NOON; D; NOON */
- JOINING_TYPE_D, /* 06BB; DOTLESS NOON WITH SMALL TAH; D; NOON */
- JOINING_TYPE_D, /* 06BC; NOON WITH RING; D; NOON */
- JOINING_TYPE_D, /* 06BD; NYA; D; NYA */
- JOINING_TYPE_D, /* 06BE; KNOTTED HEH; D; KNOTTED HEH */
- JOINING_TYPE_D, /* 06BF; HAH WITH MIDDLE 3 DOTS DOWNWARD AND DOT ABOVE; D; HAH */
- JOINING_TYPE_R, /* 06C0; HAMZA ON HEH; R; TEH MARBUTA */
- JOINING_TYPE_D, /* 06C1; HEH GOAL; D; HEH GOAL */
- JOINING_TYPE_D, /* 06C2; HAMZA ON HEH GOAL; D; HEH GOAL */
- JOINING_TYPE_R, /* 06C3; TEH MARBUTA GOAL; R; TEH MARBUTA GOAL */
- JOINING_TYPE_R, /* 06C4; WAW WITH RING; R; WAW */
- JOINING_TYPE_R, /* 06C5; WAW WITH BAR; R; WAW */
- JOINING_TYPE_R, /* 06C6; WAW WITH SMALL V; R; WAW */
- JOINING_TYPE_R, /* 06C7; WAW WITH DAMMA; R; WAW */
- JOINING_TYPE_R, /* 06C8; WAW WITH ALEF ABOVE; R; WAW */
- JOINING_TYPE_R, /* 06C9; WAW WITH INVERTED SMALL V; R; WAW */
- JOINING_TYPE_R, /* 06CA; WAW WITH 2 DOTS ABOVE; R; WAW */
- JOINING_TYPE_R, /* 06CB; WAW WITH 3 DOTS ABOVE; R; WAW */
- JOINING_TYPE_D, /* 06CC; FARSI YEH; D; FARSI YEH */
- JOINING_TYPE_R, /* 06CD; YEH WITH TAIL; R; YEH WITH TAIL */
- JOINING_TYPE_D, /* 06CE; FARSI YEH WITH SMALL V; D; FARSI YEH */
- JOINING_TYPE_R, /* 06CF; WAW WITH DOT ABOVE; R; WAW */
- JOINING_TYPE_D, /* 06D0; YEH WITH 2 DOTS VERTICAL BELOW; D; YEH */
- JOINING_TYPE_D, /* 06D1; YEH WITH 3 DOTS BELOW; D; YEH */
- JOINING_TYPE_R, /* 06D2; YEH BARREE; R; YEH BARREE */
- JOINING_TYPE_R, /* 06D3; HAMZA ON YEH BARREE; R; YEH BARREE */
- JOINING_TYPE_X, /* 06D4 */
- JOINING_TYPE_R, /* 06D5; AE; R; TEH MARBUTA */
- JOINING_TYPE_X, /* 06D6 */
- JOINING_TYPE_X, /* 06D7 */
- JOINING_TYPE_X, /* 06D8 */
- JOINING_TYPE_X, /* 06D9 */
- JOINING_TYPE_X, /* 06DA */
- JOINING_TYPE_X, /* 06DB */
- JOINING_TYPE_X, /* 06DC */
- JOINING_TYPE_U, /* 06DD; ARABIC END OF AYAH; U; No_Joining_Group */
- JOINING_TYPE_X, /* 06DE */
- JOINING_TYPE_X, /* 06DF */
- JOINING_TYPE_X, /* 06E0 */
- JOINING_TYPE_X, /* 06E1 */
- JOINING_TYPE_X, /* 06E2 */
- JOINING_TYPE_X, /* 06E3 */
- JOINING_TYPE_X, /* 06E4 */
- JOINING_TYPE_X, /* 06E5 */
- JOINING_TYPE_X, /* 06E6 */
- JOINING_TYPE_X, /* 06E7 */
- JOINING_TYPE_X, /* 06E8 */
- JOINING_TYPE_X, /* 06E9 */
- JOINING_TYPE_X, /* 06EA */
- JOINING_TYPE_X, /* 06EB */
- JOINING_TYPE_X, /* 06EC */
- JOINING_TYPE_X, /* 06ED */
- JOINING_TYPE_R, /* 06EE; DAL WITH INVERTED V; R; DAL */
- JOINING_TYPE_R, /* 06EF; REH WITH INVERTED V; R; REH */
- JOINING_TYPE_X, /* 06F0 */
- JOINING_TYPE_X, /* 06F1 */
- JOINING_TYPE_X, /* 06F2 */
- JOINING_TYPE_X, /* 06F3 */
- JOINING_TYPE_X, /* 06F4 */
- JOINING_TYPE_X, /* 06F5 */
- JOINING_TYPE_X, /* 06F6 */
- JOINING_TYPE_X, /* 06F7 */
- JOINING_TYPE_X, /* 06F8 */
- JOINING_TYPE_X, /* 06F9 */
- JOINING_TYPE_D, /* 06FA; SEEN WITH DOT BELOW AND 3 DOTS ABOVE; D; SEEN */
- JOINING_TYPE_D, /* 06FB; DAD WITH DOT BELOW; D; SAD */
- JOINING_TYPE_D, /* 06FC; GHAIN WITH DOT BELOW; D; AIN */
- JOINING_TYPE_X, /* 06FD */
- JOINING_TYPE_X, /* 06FE */
- JOINING_TYPE_D, /* 06FF; HEH WITH INVERTED V; D; KNOTTED HEH */
-
- /* Syriac characters */
-
- JOINING_TYPE_X, /* 0700 */
- JOINING_TYPE_X, /* 0701 */
- JOINING_TYPE_X, /* 0702 */
- JOINING_TYPE_X, /* 0703 */
- JOINING_TYPE_X, /* 0704 */
- JOINING_TYPE_X, /* 0705 */
- JOINING_TYPE_X, /* 0706 */
- JOINING_TYPE_X, /* 0707 */
- JOINING_TYPE_X, /* 0708 */
- JOINING_TYPE_X, /* 0709 */
- JOINING_TYPE_X, /* 070A */
- JOINING_TYPE_X, /* 070B */
- JOINING_TYPE_X, /* 070C */
- JOINING_TYPE_X, /* 070D */
- JOINING_TYPE_X, /* 070E */
- JOINING_TYPE_X, /* 070F */
- JOINING_GROUP_ALAPH, /* 0710; ALAPH; R; ALAPH */
- JOINING_TYPE_X, /* 0711 */
- JOINING_TYPE_D, /* 0712; BETH; D; BETH */
- JOINING_TYPE_D, /* 0713; GAMAL; D; GAMAL */
- JOINING_TYPE_D, /* 0714; GAMAL GARSHUNI; D; GAMAL */
- JOINING_GROUP_DALATH_RISH, /* 0715; DALATH; R; DALATH RISH */
- JOINING_GROUP_DALATH_RISH, /* 0716; DOTLESS DALATH RISH; R; DALATH RISH */
- JOINING_TYPE_R, /* 0717; HE; R; HE */
- JOINING_TYPE_R, /* 0718; WAW; R; SYRIAC WAW */
- JOINING_TYPE_R, /* 0719; ZAIN; R; ZAIN */
- JOINING_TYPE_D, /* 071A; HETH; D; HETH */
- JOINING_TYPE_D, /* 071B; TETH; D; TETH */
- JOINING_TYPE_D, /* 071C; TETH GARSHUNI; D; TETH */
- JOINING_TYPE_D, /* 071D; YUDH; D; YUDH */
- JOINING_TYPE_R, /* 071E; YUDH HE; R; YUDH HE */
- JOINING_TYPE_D, /* 071F; KAPH; D; KAPH */
- JOINING_TYPE_D, /* 0720; LAMADH; D; LAMADH */
- JOINING_TYPE_D, /* 0721; MIM; D; MIM */
- JOINING_TYPE_D, /* 0722; NUN; D; NUN */
- JOINING_TYPE_D, /* 0723; SEMKATH; D; SEMKATH */
- JOINING_TYPE_D, /* 0724; FINAL SEMKATH; D; FINAL SEMKATH */
- JOINING_TYPE_D, /* 0725; E; D; E */
- JOINING_TYPE_D, /* 0726; PE; D; PE */
- JOINING_TYPE_D, /* 0727; REVERSED PE; D; REVERSED PE */
- JOINING_TYPE_R, /* 0728; SADHE; R; SADHE */
- JOINING_TYPE_D, /* 0729; QAPH; D; QAPH */
- JOINING_GROUP_DALATH_RISH, /* 072A; RISH; R; DALATH RISH */
- JOINING_TYPE_D, /* 072B; SHIN; D; SHIN */
- JOINING_TYPE_R, /* 072C; TAW; R; TAW */
- JOINING_TYPE_D, /* 072D; PERSIAN BHETH; D; BETH */
- JOINING_TYPE_D, /* 072E; PERSIAN GHAMAL; D; GAMAL */
- JOINING_GROUP_DALATH_RISH, /* 072F; PERSIAN DHALATH; R; DALATH RISH */
- JOINING_TYPE_X, /* 0730 */
- JOINING_TYPE_X, /* 0731 */
- JOINING_TYPE_X, /* 0732 */
- JOINING_TYPE_X, /* 0733 */
- JOINING_TYPE_X, /* 0734 */
- JOINING_TYPE_X, /* 0735 */
- JOINING_TYPE_X, /* 0736 */
- JOINING_TYPE_X, /* 0737 */
- JOINING_TYPE_X, /* 0738 */
- JOINING_TYPE_X, /* 0739 */
- JOINING_TYPE_X, /* 073A */
- JOINING_TYPE_X, /* 073B */
- JOINING_TYPE_X, /* 073C */
- JOINING_TYPE_X, /* 073D */
- JOINING_TYPE_X, /* 073E */
- JOINING_TYPE_X, /* 073F */
- JOINING_TYPE_X, /* 0740 */
- JOINING_TYPE_X, /* 0741 */
- JOINING_TYPE_X, /* 0742 */
- JOINING_TYPE_X, /* 0743 */
- JOINING_TYPE_X, /* 0744 */
- JOINING_TYPE_X, /* 0745 */
- JOINING_TYPE_X, /* 0746 */
- JOINING_TYPE_X, /* 0747 */
- JOINING_TYPE_X, /* 0748 */
- JOINING_TYPE_X, /* 0749 */
- JOINING_TYPE_X, /* 074A */
- JOINING_TYPE_X, /* 074B */
- JOINING_TYPE_X, /* 074C */
- JOINING_TYPE_R, /* 074D; SOGDIAN ZHAIN; R; ZHAIN */
- JOINING_TYPE_D, /* 074E; SOGDIAN KHAPH; D; KHAPH */
- JOINING_TYPE_D, /* 074F; SOGDIAN FE; D; FE */
-
- /* Arabic supplement characters */
-
- JOINING_TYPE_D, /* 0750; BEH WITH 3 DOTS HORIZONTALLY BELOW; D; BEH */
- JOINING_TYPE_D, /* 0751; BEH WITH DOT BELOW AND 3 DOTS ABOVE; D; BEH */
- JOINING_TYPE_D, /* 0752; BEH WITH 3 DOTS POINTING UPWARDS BELOW; D; BEH */
- JOINING_TYPE_D, /* 0753; BEH WITH 3 DOTS POINTING UPWARDS BELOW AND 2 DOTS ABOVE; D; BEH */
- JOINING_TYPE_D, /* 0754; BEH WITH 2 DOTS BELOW AND DOT ABOVE; D; BEH */
- JOINING_TYPE_D, /* 0755; BEH WITH INVERTED SMALL V BELOW; D; BEH */
- JOINING_TYPE_D, /* 0756; BEH WITH SMALL V; D; BEH */
- JOINING_TYPE_D, /* 0757; HAH WITH 2 DOTS ABOVE; D; HAH */
- JOINING_TYPE_D, /* 0758; HAH WITH 3 DOTS POINTING UPWARDS BELOW; D; HAH */
- JOINING_TYPE_R, /* 0759; DAL WITH 2 DOTS VERTICALLY BELOW AND SMALL TAH; R; DAL */
- JOINING_TYPE_R, /* 075A; DAL WITH INVERTED SMALL V BELOW; R; DAL */
- JOINING_TYPE_R, /* 075B; REH WITH STROKE; R; REH */
- JOINING_TYPE_D, /* 075C; SEEN WITH 4 DOTS ABOVE; D; SEEN */
- JOINING_TYPE_D, /* 075D; AIN WITH 2 DOTS ABOVE; D; AIN */
- JOINING_TYPE_D, /* 075E; AIN WITH 3 DOTS POINTING DOWNWARDS ABOVE; D; AIN */
- JOINING_TYPE_D, /* 075F; AIN WITH 2 DOTS VERTICALLY ABOVE; D; AIN */
- JOINING_TYPE_D, /* 0760; FEH WITH 2 DOTS BELOW; D; FEH */
- JOINING_TYPE_D, /* 0761; FEH WITH 3 DOTS POINTING UPWARDS BELOW; D; FEH */
- JOINING_TYPE_D, /* 0762; KEHEH WITH DOT ABOVE; D; GAF */
- JOINING_TYPE_D, /* 0763; KEHEH WITH 3 DOTS ABOVE; D; GAF */
- JOINING_TYPE_D, /* 0764; KEHEH WITH 3 DOTS POINTING UPWARDS BELOW; D; GAF */
- JOINING_TYPE_D, /* 0765; MEEM WITH DOT ABOVE; D; MEEM */
- JOINING_TYPE_D, /* 0766; MEEM WITH DOT BELOW; D; MEEM */
- JOINING_TYPE_D, /* 0767; NOON WITH 2 DOTS BELOW; D; NOON */
- JOINING_TYPE_D, /* 0768; NOON WITH SMALL TAH; D; NOON */
- JOINING_TYPE_D, /* 0769; NOON WITH SMALL V; D; NOON */
- JOINING_TYPE_D, /* 076A; LAM WITH BAR; D; LAM */
- JOINING_TYPE_R, /* 076B; REH WITH 2 DOTS VERTICALLY ABOVE; R; REH */
- JOINING_TYPE_R, /* 076C; REH WITH HAMZA ABOVE; R; REH */
- JOINING_TYPE_D, /* 076D; SEEN WITH 2 DOTS VERTICALLY ABOVE; D; SEEN */
- JOINING_TYPE_D, /* 076E; HAH WITH SMALL TAH BELOW; D; HAH */
- JOINING_TYPE_D, /* 076F; HAH WITH SMALL TAH AND 2 DOTS; D; HAH */
- JOINING_TYPE_D, /* 0770; SEEN WITH SMALL TAH AND 2 DOTS; D; SEEN */
- JOINING_TYPE_R, /* 0771; REH WITH SMALL TAH AND 2 DOTS; R; REH */
- JOINING_TYPE_D, /* 0772; HAH WITH SMALL TAH ABOVE; D; HAH */
- JOINING_TYPE_R, /* 0773; ALEF WITH DIGIT TWO ABOVE; R; ALEF */
- JOINING_TYPE_R, /* 0774; ALEF WITH DIGIT THREE ABOVE; R; ALEF */
- JOINING_TYPE_D, /* 0775; FARSI YEH WITH DIGIT TWO ABOVE; D; FARSI YEH */
- JOINING_TYPE_D, /* 0776; FARSI YEH WITH DIGIT THREE ABOVE; D; FARSI YEH */
- JOINING_TYPE_D, /* 0777; YEH WITH DIGIT FOUR BELOW; D; YEH */
- JOINING_TYPE_R, /* 0778; WAW WITH DIGIT TWO ABOVE; R; WAW */
- JOINING_TYPE_R, /* 0779; WAW WITH DIGIT THREE ABOVE; R; WAW */
- JOINING_TYPE_D, /* 077A; YEH BARREE WITH DIGIT TWO ABOVE; D; BURUSHASKI YEH BARREE */
- JOINING_TYPE_D, /* 077B; YEH BARREE WITH DIGIT THREE ABOVE; D; BURUSHASKI YEH BARREE */
- JOINING_TYPE_D, /* 077C; HAH WITH DIGIT FOUR BELOW; D; HAH */
- JOINING_TYPE_D, /* 077D; SEEN WITH DIGIT FOUR ABOVE; D; SEEN */
- JOINING_TYPE_D, /* 077E; SEEN WITH INVERTED V; D; SEEN */
- JOINING_TYPE_D, /* 077F; KAF WITH 2 DOTS ABOVE; D; KAF */
-
- /* N'Ko Characters */
-
- JOINING_TYPE_X, /* 0780 */
- JOINING_TYPE_X, /* 0781 */
- JOINING_TYPE_X, /* 0782 */
- JOINING_TYPE_X, /* 0783 */
- JOINING_TYPE_X, /* 0784 */
- JOINING_TYPE_X, /* 0785 */
- JOINING_TYPE_X, /* 0786 */
- JOINING_TYPE_X, /* 0787 */
- JOINING_TYPE_X, /* 0788 */
- JOINING_TYPE_X, /* 0789 */
- JOINING_TYPE_X, /* 078A */
- JOINING_TYPE_X, /* 078B */
- JOINING_TYPE_X, /* 078C */
- JOINING_TYPE_X, /* 078D */
- JOINING_TYPE_X, /* 078E */
- JOINING_TYPE_X, /* 078F */
- JOINING_TYPE_X, /* 0790 */
- JOINING_TYPE_X, /* 0791 */
- JOINING_TYPE_X, /* 0792 */
- JOINING_TYPE_X, /* 0793 */
- JOINING_TYPE_X, /* 0794 */
- JOINING_TYPE_X, /* 0795 */
- JOINING_TYPE_X, /* 0796 */
- JOINING_TYPE_X, /* 0797 */
- JOINING_TYPE_X, /* 0798 */
- JOINING_TYPE_X, /* 0799 */
- JOINING_TYPE_X, /* 079A */
- JOINING_TYPE_X, /* 079B */
- JOINING_TYPE_X, /* 079C */
- JOINING_TYPE_X, /* 079D */
- JOINING_TYPE_X, /* 079E */
- JOINING_TYPE_X, /* 079F */
- JOINING_TYPE_X, /* 07A0 */
- JOINING_TYPE_X, /* 07A1 */
- JOINING_TYPE_X, /* 07A2 */
- JOINING_TYPE_X, /* 07A3 */
- JOINING_TYPE_X, /* 07A4 */
- JOINING_TYPE_X, /* 07A5 */
- JOINING_TYPE_X, /* 07A6 */
- JOINING_TYPE_X, /* 07A7 */
- JOINING_TYPE_X, /* 07A8 */
- JOINING_TYPE_X, /* 07A9 */
- JOINING_TYPE_X, /* 07AA */
- JOINING_TYPE_X, /* 07AB */
- JOINING_TYPE_X, /* 07AC */
- JOINING_TYPE_X, /* 07AD */
- JOINING_TYPE_X, /* 07AE */
- JOINING_TYPE_X, /* 07AF */
- JOINING_TYPE_X, /* 07B0 */
- JOINING_TYPE_X, /* 07B1 */
- JOINING_TYPE_X, /* 07B2 */
- JOINING_TYPE_X, /* 07B3 */
- JOINING_TYPE_X, /* 07B4 */
- JOINING_TYPE_X, /* 07B5 */
- JOINING_TYPE_X, /* 07B6 */
- JOINING_TYPE_X, /* 07B7 */
- JOINING_TYPE_X, /* 07B8 */
- JOINING_TYPE_X, /* 07B9 */
- JOINING_TYPE_X, /* 07BA */
- JOINING_TYPE_X, /* 07BB */
- JOINING_TYPE_X, /* 07BC */
- JOINING_TYPE_X, /* 07BD */
- JOINING_TYPE_X, /* 07BE */
- JOINING_TYPE_X, /* 07BF */
- JOINING_TYPE_X, /* 07C0 */
- JOINING_TYPE_X, /* 07C1 */
- JOINING_TYPE_X, /* 07C2 */
- JOINING_TYPE_X, /* 07C3 */
- JOINING_TYPE_X, /* 07C4 */
- JOINING_TYPE_X, /* 07C5 */
- JOINING_TYPE_X, /* 07C6 */
- JOINING_TYPE_X, /* 07C7 */
- JOINING_TYPE_X, /* 07C8 */
- JOINING_TYPE_X, /* 07C9 */
- JOINING_TYPE_D, /* 07CA; NKO A; D; No_Joining_Group */
- JOINING_TYPE_D, /* 07CB; NKO EE; D; No_Joining_Group */
- JOINING_TYPE_D, /* 07CC; NKO I; D; No_Joining_Group */
- JOINING_TYPE_D, /* 07CD; NKO E; D; No_Joining_Group */
- JOINING_TYPE_D, /* 07CE; NKO U; D; No_Joining_Group */
- JOINING_TYPE_D, /* 07CF; NKO OO; D; No_Joining_Group */
- JOINING_TYPE_D, /* 07D0; NKO O; D; No_Joining_Group */
- JOINING_TYPE_D, /* 07D1; NKO DAGBASINNA; D; No_Joining_Group */
- JOINING_TYPE_D, /* 07D2; NKO N; D; No_Joining_Group */
- JOINING_TYPE_D, /* 07D3; NKO BA; D; No_Joining_Group */
- JOINING_TYPE_D, /* 07D4; NKO PA; D; No_Joining_Group */
- JOINING_TYPE_D, /* 07D5; NKO TA; D; No_Joining_Group */
- JOINING_TYPE_D, /* 07D6; NKO JA; D; No_Joining_Group */
- JOINING_TYPE_D, /* 07D7; NKO CHA; D; No_Joining_Group */
- JOINING_TYPE_D, /* 07D8; NKO DA; D; No_Joining_Group */
- JOINING_TYPE_D, /* 07D9; NKO RA; D; No_Joining_Group */
- JOINING_TYPE_D, /* 07DA; NKO RRA; D; No_Joining_Group */
- JOINING_TYPE_D, /* 07DB; NKO SA; D; No_Joining_Group */
- JOINING_TYPE_D, /* 07DC; NKO GBA; D; No_Joining_Group */
- JOINING_TYPE_D, /* 07DD; NKO FA; D; No_Joining_Group */
- JOINING_TYPE_D, /* 07DE; NKO KA; D; No_Joining_Group */
- JOINING_TYPE_D, /* 07DF; NKO LA; D; No_Joining_Group */
- JOINING_TYPE_D, /* 07E0; NKO NA WOLOSO; D; No_Joining_Group */
- JOINING_TYPE_D, /* 07E1; NKO MA; D; No_Joining_Group */
- JOINING_TYPE_D, /* 07E2; NKO NYA; D; No_Joining_Group */
- JOINING_TYPE_D, /* 07E3; NKO NA; D; No_Joining_Group */
- JOINING_TYPE_D, /* 07E4; NKO HA; D; No_Joining_Group */
- JOINING_TYPE_D, /* 07E5; NKO WA; D; No_Joining_Group */
- JOINING_TYPE_D, /* 07E6; NKO YA; D; No_Joining_Group */
- JOINING_TYPE_D, /* 07E7; NKO NYA WOLOSO; D; No_Joining_Group */
- JOINING_TYPE_D, /* 07E8; NKO JONA JA; D; No_Joining_Group */
- JOINING_TYPE_D, /* 07E9; NKO JONA CHA; D; No_Joining_Group */
- JOINING_TYPE_D, /* 07EA; NKO JONA RA; D; No_Joining_Group */
- JOINING_TYPE_X, /* 07EB */
- JOINING_TYPE_X, /* 07EC */
- JOINING_TYPE_X, /* 07ED */
- JOINING_TYPE_X, /* 07EE */
- JOINING_TYPE_X, /* 07EF */
- JOINING_TYPE_X, /* 07F0 */
- JOINING_TYPE_X, /* 07F1 */
- JOINING_TYPE_X, /* 07F2 */
- JOINING_TYPE_X, /* 07F3 */
- JOINING_TYPE_X, /* 07F4 */
- JOINING_TYPE_X, /* 07F5 */
- JOINING_TYPE_X, /* 07F6 */
- JOINING_TYPE_X, /* 07F7 */
- JOINING_TYPE_X, /* 07F8 */
- JOINING_TYPE_X, /* 07F9 */
- JOINING_TYPE_C, /* 07FA; NKO LAJANYALAN; C; No_Joining_Group */
-
- /* Mandaic Characters */
-
- JOINING_TYPE_X, /* 07FB */
- JOINING_TYPE_X, /* 07FC */
- JOINING_TYPE_X, /* 07FD */
- JOINING_TYPE_X, /* 07FE */
- JOINING_TYPE_X, /* 07FF */
- JOINING_TYPE_X, /* 0800 */
- JOINING_TYPE_X, /* 0801 */
- JOINING_TYPE_X, /* 0802 */
- JOINING_TYPE_X, /* 0803 */
- JOINING_TYPE_X, /* 0804 */
- JOINING_TYPE_X, /* 0805 */
- JOINING_TYPE_X, /* 0806 */
- JOINING_TYPE_X, /* 0807 */
- JOINING_TYPE_X, /* 0808 */
- JOINING_TYPE_X, /* 0809 */
- JOINING_TYPE_X, /* 080A */
- JOINING_TYPE_X, /* 080B */
- JOINING_TYPE_X, /* 080C */
- JOINING_TYPE_X, /* 080D */
- JOINING_TYPE_X, /* 080E */
- JOINING_TYPE_X, /* 080F */
- JOINING_TYPE_X, /* 0810 */
- JOINING_TYPE_X, /* 0811 */
- JOINING_TYPE_X, /* 0812 */
- JOINING_TYPE_X, /* 0813 */
- JOINING_TYPE_X, /* 0814 */
- JOINING_TYPE_X, /* 0815 */
- JOINING_TYPE_X, /* 0816 */
- JOINING_TYPE_X, /* 0817 */
- JOINING_TYPE_X, /* 0818 */
- JOINING_TYPE_X, /* 0819 */
- JOINING_TYPE_X, /* 081A */
- JOINING_TYPE_X, /* 081B */
- JOINING_TYPE_X, /* 081C */
- JOINING_TYPE_X, /* 081D */
- JOINING_TYPE_X, /* 081E */
- JOINING_TYPE_X, /* 081F */
- JOINING_TYPE_X, /* 0820 */
- JOINING_TYPE_X, /* 0821 */
- JOINING_TYPE_X, /* 0822 */
- JOINING_TYPE_X, /* 0823 */
- JOINING_TYPE_X, /* 0824 */
- JOINING_TYPE_X, /* 0825 */
- JOINING_TYPE_X, /* 0826 */
- JOINING_TYPE_X, /* 0827 */
- JOINING_TYPE_X, /* 0828 */
- JOINING_TYPE_X, /* 0829 */
- JOINING_TYPE_X, /* 082A */
- JOINING_TYPE_X, /* 082B */
- JOINING_TYPE_X, /* 082C */
- JOINING_TYPE_X, /* 082D */
- JOINING_TYPE_X, /* 082E */
- JOINING_TYPE_X, /* 082F */
- JOINING_TYPE_X, /* 0830 */
- JOINING_TYPE_X, /* 0831 */
- JOINING_TYPE_X, /* 0832 */
- JOINING_TYPE_X, /* 0833 */
- JOINING_TYPE_X, /* 0834 */
- JOINING_TYPE_X, /* 0835 */
- JOINING_TYPE_X, /* 0836 */
- JOINING_TYPE_X, /* 0837 */
- JOINING_TYPE_X, /* 0838 */
- JOINING_TYPE_X, /* 0839 */
- JOINING_TYPE_X, /* 083A */
- JOINING_TYPE_X, /* 083B */
- JOINING_TYPE_X, /* 083C */
- JOINING_TYPE_X, /* 083D */
- JOINING_TYPE_X, /* 083E */
- JOINING_TYPE_X, /* 083F */
- JOINING_TYPE_R, /* 0840; MANDAIC HALQA; R; No_Joining_Group */
- JOINING_TYPE_D, /* 0841; MANDAIC AB; D; No_Joining_Group */
- JOINING_TYPE_D, /* 0842; MANDAIC AG; D; No_Joining_Group */
- JOINING_TYPE_D, /* 0843; MANDAIC AD; D; No_Joining_Group */
- JOINING_TYPE_D, /* 0844; MANDAIC AH; D; No_Joining_Group */
- JOINING_TYPE_D, /* 0845; MANDAIC USHENNA; D; No_Joining_Group */
- JOINING_TYPE_R, /* 0846; MANDAIC AZ; R; No_Joining_Group */
- JOINING_TYPE_D, /* 0847; MANDAIC IT; D; No_Joining_Group */
- JOINING_TYPE_D, /* 0848; MANDAIC ATT; D; No_Joining_Group */
- JOINING_TYPE_R, /* 0849; MANDAIC AKSA; R; No_Joining_Group */
- JOINING_TYPE_D, /* 084A; MANDAIC AK; D; No_Joining_Group */
- JOINING_TYPE_D, /* 084B; MANDAIC AL; D; No_Joining_Group */
- JOINING_TYPE_D, /* 084C; MANDAIC AM; D; No_Joining_Group */
- JOINING_TYPE_D, /* 084D; MANDAIC AN; D; No_Joining_Group */
- JOINING_TYPE_D, /* 084E; MANDAIC AS; D; No_Joining_Group */
- JOINING_TYPE_R, /* 084F; MANDAIC IN; R; No_Joining_Group */
- JOINING_TYPE_D, /* 0850; MANDAIC AP; D; No_Joining_Group */
- JOINING_TYPE_D, /* 0851; MANDAIC ASZ; D; No_Joining_Group */
- JOINING_TYPE_D, /* 0852; MANDAIC AQ; D; No_Joining_Group */
- JOINING_TYPE_D, /* 0853; MANDAIC AR; D; No_Joining_Group */
- JOINING_TYPE_R, /* 0854; MANDAIC ASH; R; No_Joining_Group */
- JOINING_TYPE_D, /* 0855; MANDAIC AT; D; No_Joining_Group */
- JOINING_TYPE_U, /* 0856; MANDAIC DUSHENNA; U; No_Joining_Group */
- JOINING_TYPE_U, /* 0857; MANDAIC KAD; U; No_Joining_Group */
- JOINING_TYPE_U, /* 0858; MANDAIC AIN; U; No_Joining_Group */
-
- JOINING_TYPE_X /* dummy */
-};
-
-#define JOINING_TABLE_FIRST 0x0600
-#define JOINING_TABLE_LAST 0x0858
-
-/* == End of generated table == */
-
-HB_END_DECLS
-
-#endif /* HB_OT_SHAPE_COMPLEX_ARABIC_TABLE_H */
diff --git a/src/hb-ot-shape-complex-arabic-table.hh b/src/hb-ot-shape-complex-arabic-table.hh
new file mode 100644
index 0000000..27c6696
--- /dev/null
+++ b/src/hb-ot-shape-complex-arabic-table.hh
@@ -0,0 +1,674 @@
+/*
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * 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.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_OT_SHAPE_COMPLEX_ARABIC_TABLE_HH
+#define HB_OT_SHAPE_COMPLEX_ARABIC_TABLE_HH
+
+#include "hb-private.hh"
+
+HB_BEGIN_DECLS
+
+/* == Start of generated table == */
+/*
+ * The following table is generated by running:
+ *
+ * ./gen-arabic-joining-table.py < ArabicShaping.txt
+ *
+ * on the ArabicShaping.txt file with the header:
+ *
+ * # ArabicShaping-6.1.0.txt
+ * # Date: 2010-11-09, 12:10:00 PST [KW]
+ */
+static const uint8_t joining_table[] =
+{
+
+ /* Arabic characters */
+
+ JOINING_TYPE_U, /* 0600; ARABIC NUMBER SIGN; U; No_Joining_Group */
+ JOINING_TYPE_U, /* 0601; ARABIC SIGN SANAH; U; No_Joining_Group */
+ JOINING_TYPE_U, /* 0602; ARABIC FOOTNOTE MARKER; U; No_Joining_Group */
+ JOINING_TYPE_U, /* 0603; ARABIC SIGN SAFHA; U; No_Joining_Group */
+ JOINING_TYPE_X, /* 0604 */
+ JOINING_TYPE_X, /* 0605 */
+ JOINING_TYPE_X, /* 0606 */
+ JOINING_TYPE_X, /* 0607 */
+ JOINING_TYPE_U, /* 0608; ARABIC RAY; U; No_Joining_Group */
+ JOINING_TYPE_X, /* 0609 */
+ JOINING_TYPE_X, /* 060A */
+ JOINING_TYPE_U, /* 060B; AFGHANI SIGN; U; No_Joining_Group */
+ JOINING_TYPE_X, /* 060C */
+ JOINING_TYPE_X, /* 060D */
+ JOINING_TYPE_X, /* 060E */
+ JOINING_TYPE_X, /* 060F */
+ JOINING_TYPE_X, /* 0610 */
+ JOINING_TYPE_X, /* 0611 */
+ JOINING_TYPE_X, /* 0612 */
+ JOINING_TYPE_X, /* 0613 */
+ JOINING_TYPE_X, /* 0614 */
+ JOINING_TYPE_X, /* 0615 */
+ JOINING_TYPE_X, /* 0616 */
+ JOINING_TYPE_X, /* 0617 */
+ JOINING_TYPE_X, /* 0618 */
+ JOINING_TYPE_X, /* 0619 */
+ JOINING_TYPE_X, /* 061A */
+ JOINING_TYPE_X, /* 061B */
+ JOINING_TYPE_X, /* 061C */
+ JOINING_TYPE_X, /* 061D */
+ JOINING_TYPE_X, /* 061E */
+ JOINING_TYPE_X, /* 061F */
+ JOINING_TYPE_D, /* 0620; YEH WITH RING; D; YEH */
+ JOINING_TYPE_U, /* 0621; HAMZA; U; No_Joining_Group */
+ JOINING_TYPE_R, /* 0622; MADDA ON ALEF; R; ALEF */
+ JOINING_TYPE_R, /* 0623; HAMZA ON ALEF; R; ALEF */
+ JOINING_TYPE_R, /* 0624; HAMZA ON WAW; R; WAW */
+ JOINING_TYPE_R, /* 0625; HAMZA UNDER ALEF; R; ALEF */
+ JOINING_TYPE_D, /* 0626; HAMZA ON YEH; D; YEH */
+ JOINING_TYPE_R, /* 0627; ALEF; R; ALEF */
+ JOINING_TYPE_D, /* 0628; BEH; D; BEH */
+ JOINING_TYPE_R, /* 0629; TEH MARBUTA; R; TEH MARBUTA */
+ JOINING_TYPE_D, /* 062A; TEH; D; BEH */
+ JOINING_TYPE_D, /* 062B; THEH; D; BEH */
+ JOINING_TYPE_D, /* 062C; JEEM; D; HAH */
+ JOINING_TYPE_D, /* 062D; HAH; D; HAH */
+ JOINING_TYPE_D, /* 062E; KHAH; D; HAH */
+ JOINING_TYPE_R, /* 062F; DAL; R; DAL */
+ JOINING_TYPE_R, /* 0630; THAL; R; DAL */
+ JOINING_TYPE_R, /* 0631; REH; R; REH */
+ JOINING_TYPE_R, /* 0632; ZAIN; R; REH */
+ JOINING_TYPE_D, /* 0633; SEEN; D; SEEN */
+ JOINING_TYPE_D, /* 0634; SHEEN; D; SEEN */
+ JOINING_TYPE_D, /* 0635; SAD; D; SAD */
+ JOINING_TYPE_D, /* 0636; DAD; D; SAD */
+ JOINING_TYPE_D, /* 0637; TAH; D; TAH */
+ JOINING_TYPE_D, /* 0638; ZAH; D; TAH */
+ JOINING_TYPE_D, /* 0639; AIN; D; AIN */
+ JOINING_TYPE_D, /* 063A; GHAIN; D; AIN */
+ JOINING_TYPE_D, /* 063B; KEHEH WITH 2 DOTS ABOVE; D; GAF */
+ JOINING_TYPE_D, /* 063C; KEHEH WITH 3 DOTS BELOW; D; GAF */
+ JOINING_TYPE_D, /* 063D; FARSI YEH WITH INVERTED V; D; FARSI YEH */
+ JOINING_TYPE_D, /* 063E; FARSI YEH WITH 2 DOTS ABOVE; D; FARSI YEH */
+ JOINING_TYPE_D, /* 063F; FARSI YEH WITH 3 DOTS ABOVE; D; FARSI YEH */
+ JOINING_TYPE_C, /* 0640; TATWEEL; C; No_Joining_Group */
+ JOINING_TYPE_D, /* 0641; FEH; D; FEH */
+ JOINING_TYPE_D, /* 0642; QAF; D; QAF */
+ JOINING_TYPE_D, /* 0643; KAF; D; KAF */
+ JOINING_TYPE_D, /* 0644; LAM; D; LAM */
+ JOINING_TYPE_D, /* 0645; MEEM; D; MEEM */
+ JOINING_TYPE_D, /* 0646; NOON; D; NOON */
+ JOINING_TYPE_D, /* 0647; HEH; D; HEH */
+ JOINING_TYPE_R, /* 0648; WAW; R; WAW */
+ JOINING_TYPE_D, /* 0649; ALEF MAKSURA; D; YEH */
+ JOINING_TYPE_D, /* 064A; YEH; D; YEH */
+ JOINING_TYPE_X, /* 064B */
+ JOINING_TYPE_X, /* 064C */
+ JOINING_TYPE_X, /* 064D */
+ JOINING_TYPE_X, /* 064E */
+ JOINING_TYPE_X, /* 064F */
+ JOINING_TYPE_X, /* 0650 */
+ JOINING_TYPE_X, /* 0651 */
+ JOINING_TYPE_X, /* 0652 */
+ JOINING_TYPE_X, /* 0653 */
+ JOINING_TYPE_X, /* 0654 */
+ JOINING_TYPE_X, /* 0655 */
+ JOINING_TYPE_X, /* 0656 */
+ JOINING_TYPE_X, /* 0657 */
+ JOINING_TYPE_X, /* 0658 */
+ JOINING_TYPE_X, /* 0659 */
+ JOINING_TYPE_X, /* 065A */
+ JOINING_TYPE_X, /* 065B */
+ JOINING_TYPE_X, /* 065C */
+ JOINING_TYPE_X, /* 065D */
+ JOINING_TYPE_X, /* 065E */
+ JOINING_TYPE_X, /* 065F */
+ JOINING_TYPE_X, /* 0660 */
+ JOINING_TYPE_X, /* 0661 */
+ JOINING_TYPE_X, /* 0662 */
+ JOINING_TYPE_X, /* 0663 */
+ JOINING_TYPE_X, /* 0664 */
+ JOINING_TYPE_X, /* 0665 */
+ JOINING_TYPE_X, /* 0666 */
+ JOINING_TYPE_X, /* 0667 */
+ JOINING_TYPE_X, /* 0668 */
+ JOINING_TYPE_X, /* 0669 */
+ JOINING_TYPE_X, /* 066A */
+ JOINING_TYPE_X, /* 066B */
+ JOINING_TYPE_X, /* 066C */
+ JOINING_TYPE_X, /* 066D */
+ JOINING_TYPE_D, /* 066E; DOTLESS BEH; D; BEH */
+ JOINING_TYPE_D, /* 066F; DOTLESS QAF; D; QAF */
+ JOINING_TYPE_X, /* 0670 */
+ JOINING_TYPE_R, /* 0671; HAMZAT WASL ON ALEF; R; ALEF */
+ JOINING_TYPE_R, /* 0672; WAVY HAMZA ON ALEF; R; ALEF */
+ JOINING_TYPE_R, /* 0673; WAVY HAMZA UNDER ALEF; R; ALEF */
+ JOINING_TYPE_U, /* 0674; HIGH HAMZA; U; No_Joining_Group */
+ JOINING_TYPE_R, /* 0675; HIGH HAMZA ALEF; R; ALEF */
+ JOINING_TYPE_R, /* 0676; HIGH HAMZA WAW; R; WAW */
+ JOINING_TYPE_R, /* 0677; HIGH HAMZA WAW WITH DAMMA; R; WAW */
+ JOINING_TYPE_D, /* 0678; HIGH HAMZA YEH; D; YEH */
+ JOINING_TYPE_D, /* 0679; TEH WITH SMALL TAH; D; BEH */
+ JOINING_TYPE_D, /* 067A; TEH WITH 2 DOTS VERTICAL ABOVE; D; BEH */
+ JOINING_TYPE_D, /* 067B; BEH WITH 2 DOTS VERTICAL BELOW; D; BEH */
+ JOINING_TYPE_D, /* 067C; TEH WITH RING; D; BEH */
+ JOINING_TYPE_D, /* 067D; TEH WITH 3 DOTS ABOVE DOWNWARD; D; BEH */
+ JOINING_TYPE_D, /* 067E; TEH WITH 3 DOTS BELOW; D; BEH */
+ JOINING_TYPE_D, /* 067F; TEH WITH 4 DOTS ABOVE; D; BEH */
+ JOINING_TYPE_D, /* 0680; BEH WITH 4 DOTS BELOW; D; BEH */
+ JOINING_TYPE_D, /* 0681; HAMZA ON HAH; D; HAH */
+ JOINING_TYPE_D, /* 0682; HAH WITH 2 DOTS VERTICAL ABOVE; D; HAH */
+ JOINING_TYPE_D, /* 0683; HAH WITH MIDDLE 2 DOTS; D; HAH */
+ JOINING_TYPE_D, /* 0684; HAH WITH MIDDLE 2 DOTS VERTICAL; D; HAH */
+ JOINING_TYPE_D, /* 0685; HAH WITH 3 DOTS ABOVE; D; HAH */
+ JOINING_TYPE_D, /* 0686; HAH WITH MIDDLE 3 DOTS DOWNWARD; D; HAH */
+ JOINING_TYPE_D, /* 0687; HAH WITH MIDDLE 4 DOTS; D; HAH */
+ JOINING_TYPE_R, /* 0688; DAL WITH SMALL TAH; R; DAL */
+ JOINING_TYPE_R, /* 0689; DAL WITH RING; R; DAL */
+ JOINING_TYPE_R, /* 068A; DAL WITH DOT BELOW; R; DAL */
+ JOINING_TYPE_R, /* 068B; DAL WITH DOT BELOW AND SMALL TAH; R; DAL */
+ JOINING_TYPE_R, /* 068C; DAL WITH 2 DOTS ABOVE; R; DAL */
+ JOINING_TYPE_R, /* 068D; DAL WITH 2 DOTS BELOW; R; DAL */
+ JOINING_TYPE_R, /* 068E; DAL WITH 3 DOTS ABOVE; R; DAL */
+ JOINING_TYPE_R, /* 068F; DAL WITH 3 DOTS ABOVE DOWNWARD; R; DAL */
+ JOINING_TYPE_R, /* 0690; DAL WITH 4 DOTS ABOVE; R; DAL */
+ JOINING_TYPE_R, /* 0691; REH WITH SMALL TAH; R; REH */
+ JOINING_TYPE_R, /* 0692; REH WITH SMALL V; R; REH */
+ JOINING_TYPE_R, /* 0693; REH WITH RING; R; REH */
+ JOINING_TYPE_R, /* 0694; REH WITH DOT BELOW; R; REH */
+ JOINING_TYPE_R, /* 0695; REH WITH SMALL V BELOW; R; REH */
+ JOINING_TYPE_R, /* 0696; REH WITH DOT BELOW AND DOT ABOVE; R; REH */
+ JOINING_TYPE_R, /* 0697; REH WITH 2 DOTS ABOVE; R; REH */
+ JOINING_TYPE_R, /* 0698; REH WITH 3 DOTS ABOVE; R; REH */
+ JOINING_TYPE_R, /* 0699; REH WITH 4 DOTS ABOVE; R; REH */
+ JOINING_TYPE_D, /* 069A; SEEN WITH DOT BELOW AND DOT ABOVE; D; SEEN */
+ JOINING_TYPE_D, /* 069B; SEEN WITH 3 DOTS BELOW; D; SEEN */
+ JOINING_TYPE_D, /* 069C; SEEN WITH 3 DOTS BELOW AND 3 DOTS ABOVE; D; SEEN */
+ JOINING_TYPE_D, /* 069D; SAD WITH 2 DOTS BELOW; D; SAD */
+ JOINING_TYPE_D, /* 069E; SAD WITH 3 DOTS ABOVE; D; SAD */
+ JOINING_TYPE_D, /* 069F; TAH WITH 3 DOTS ABOVE; D; TAH */
+ JOINING_TYPE_D, /* 06A0; AIN WITH 3 DOTS ABOVE; D; AIN */
+ JOINING_TYPE_D, /* 06A1; DOTLESS FEH; D; FEH */
+ JOINING_TYPE_D, /* 06A2; FEH WITH DOT MOVED BELOW; D; FEH */
+ JOINING_TYPE_D, /* 06A3; FEH WITH DOT BELOW; D; FEH */
+ JOINING_TYPE_D, /* 06A4; FEH WITH 3 DOTS ABOVE; D; FEH */
+ JOINING_TYPE_D, /* 06A5; FEH WITH 3 DOTS BELOW; D; FEH */
+ JOINING_TYPE_D, /* 06A6; FEH WITH 4 DOTS ABOVE; D; FEH */
+ JOINING_TYPE_D, /* 06A7; QAF WITH DOT ABOVE; D; QAF */
+ JOINING_TYPE_D, /* 06A8; QAF WITH 3 DOTS ABOVE; D; QAF */
+ JOINING_TYPE_D, /* 06A9; KEHEH; D; GAF */
+ JOINING_TYPE_D, /* 06AA; SWASH KAF; D; SWASH KAF */
+ JOINING_TYPE_D, /* 06AB; KAF WITH RING; D; GAF */
+ JOINING_TYPE_D, /* 06AC; KAF WITH DOT ABOVE; D; KAF */
+ JOINING_TYPE_D, /* 06AD; KAF WITH 3 DOTS ABOVE; D; KAF */
+ JOINING_TYPE_D, /* 06AE; KAF WITH 3 DOTS BELOW; D; KAF */
+ JOINING_TYPE_D, /* 06AF; GAF; D; GAF */
+ JOINING_TYPE_D, /* 06B0; GAF WITH RING; D; GAF */
+ JOINING_TYPE_D, /* 06B1; GAF WITH 2 DOTS ABOVE; D; GAF */
+ JOINING_TYPE_D, /* 06B2; GAF WITH 2 DOTS BELOW; D; GAF */
+ JOINING_TYPE_D, /* 06B3; GAF WITH 2 DOTS VERTICAL BELOW; D; GAF */
+ JOINING_TYPE_D, /* 06B4; GAF WITH 3 DOTS ABOVE; D; GAF */
+ JOINING_TYPE_D, /* 06B5; LAM WITH SMALL V; D; LAM */
+ JOINING_TYPE_D, /* 06B6; LAM WITH DOT ABOVE; D; LAM */
+ JOINING_TYPE_D, /* 06B7; LAM WITH 3 DOTS ABOVE; D; LAM */
+ JOINING_TYPE_D, /* 06B8; LAM WITH 3 DOTS BELOW; D; LAM */
+ JOINING_TYPE_D, /* 06B9; NOON WITH DOT BELOW; D; NOON */
+ JOINING_TYPE_D, /* 06BA; DOTLESS NOON; D; NOON */
+ JOINING_TYPE_D, /* 06BB; DOTLESS NOON WITH SMALL TAH; D; NOON */
+ JOINING_TYPE_D, /* 06BC; NOON WITH RING; D; NOON */
+ JOINING_TYPE_D, /* 06BD; NYA; D; NYA */
+ JOINING_TYPE_D, /* 06BE; KNOTTED HEH; D; KNOTTED HEH */
+ JOINING_TYPE_D, /* 06BF; HAH WITH MIDDLE 3 DOTS DOWNWARD AND DOT ABOVE; D; HAH */
+ JOINING_TYPE_R, /* 06C0; HAMZA ON HEH; R; TEH MARBUTA */
+ JOINING_TYPE_D, /* 06C1; HEH GOAL; D; HEH GOAL */
+ JOINING_TYPE_D, /* 06C2; HAMZA ON HEH GOAL; D; HEH GOAL */
+ JOINING_TYPE_R, /* 06C3; TEH MARBUTA GOAL; R; TEH MARBUTA GOAL */
+ JOINING_TYPE_R, /* 06C4; WAW WITH RING; R; WAW */
+ JOINING_TYPE_R, /* 06C5; WAW WITH BAR; R; WAW */
+ JOINING_TYPE_R, /* 06C6; WAW WITH SMALL V; R; WAW */
+ JOINING_TYPE_R, /* 06C7; WAW WITH DAMMA; R; WAW */
+ JOINING_TYPE_R, /* 06C8; WAW WITH ALEF ABOVE; R; WAW */
+ JOINING_TYPE_R, /* 06C9; WAW WITH INVERTED SMALL V; R; WAW */
+ JOINING_TYPE_R, /* 06CA; WAW WITH 2 DOTS ABOVE; R; WAW */
+ JOINING_TYPE_R, /* 06CB; WAW WITH 3 DOTS ABOVE; R; WAW */
+ JOINING_TYPE_D, /* 06CC; FARSI YEH; D; FARSI YEH */
+ JOINING_TYPE_R, /* 06CD; YEH WITH TAIL; R; YEH WITH TAIL */
+ JOINING_TYPE_D, /* 06CE; FARSI YEH WITH SMALL V; D; FARSI YEH */
+ JOINING_TYPE_R, /* 06CF; WAW WITH DOT ABOVE; R; WAW */
+ JOINING_TYPE_D, /* 06D0; YEH WITH 2 DOTS VERTICAL BELOW; D; YEH */
+ JOINING_TYPE_D, /* 06D1; YEH WITH 3 DOTS BELOW; D; YEH */
+ JOINING_TYPE_R, /* 06D2; YEH BARREE; R; YEH BARREE */
+ JOINING_TYPE_R, /* 06D3; HAMZA ON YEH BARREE; R; YEH BARREE */
+ JOINING_TYPE_X, /* 06D4 */
+ JOINING_TYPE_R, /* 06D5; AE; R; TEH MARBUTA */
+ JOINING_TYPE_X, /* 06D6 */
+ JOINING_TYPE_X, /* 06D7 */
+ JOINING_TYPE_X, /* 06D8 */
+ JOINING_TYPE_X, /* 06D9 */
+ JOINING_TYPE_X, /* 06DA */
+ JOINING_TYPE_X, /* 06DB */
+ JOINING_TYPE_X, /* 06DC */
+ JOINING_TYPE_U, /* 06DD; ARABIC END OF AYAH; U; No_Joining_Group */
+ JOINING_TYPE_X, /* 06DE */
+ JOINING_TYPE_X, /* 06DF */
+ JOINING_TYPE_X, /* 06E0 */
+ JOINING_TYPE_X, /* 06E1 */
+ JOINING_TYPE_X, /* 06E2 */
+ JOINING_TYPE_X, /* 06E3 */
+ JOINING_TYPE_X, /* 06E4 */
+ JOINING_TYPE_X, /* 06E5 */
+ JOINING_TYPE_X, /* 06E6 */
+ JOINING_TYPE_X, /* 06E7 */
+ JOINING_TYPE_X, /* 06E8 */
+ JOINING_TYPE_X, /* 06E9 */
+ JOINING_TYPE_X, /* 06EA */
+ JOINING_TYPE_X, /* 06EB */
+ JOINING_TYPE_X, /* 06EC */
+ JOINING_TYPE_X, /* 06ED */
+ JOINING_TYPE_R, /* 06EE; DAL WITH INVERTED V; R; DAL */
+ JOINING_TYPE_R, /* 06EF; REH WITH INVERTED V; R; REH */
+ JOINING_TYPE_X, /* 06F0 */
+ JOINING_TYPE_X, /* 06F1 */
+ JOINING_TYPE_X, /* 06F2 */
+ JOINING_TYPE_X, /* 06F3 */
+ JOINING_TYPE_X, /* 06F4 */
+ JOINING_TYPE_X, /* 06F5 */
+ JOINING_TYPE_X, /* 06F6 */
+ JOINING_TYPE_X, /* 06F7 */
+ JOINING_TYPE_X, /* 06F8 */
+ JOINING_TYPE_X, /* 06F9 */
+ JOINING_TYPE_D, /* 06FA; SEEN WITH DOT BELOW AND 3 DOTS ABOVE; D; SEEN */
+ JOINING_TYPE_D, /* 06FB; DAD WITH DOT BELOW; D; SAD */
+ JOINING_TYPE_D, /* 06FC; GHAIN WITH DOT BELOW; D; AIN */
+ JOINING_TYPE_X, /* 06FD */
+ JOINING_TYPE_X, /* 06FE */
+ JOINING_TYPE_D, /* 06FF; HEH WITH INVERTED V; D; KNOTTED HEH */
+
+ /* Syriac characters */
+
+ JOINING_TYPE_X, /* 0700 */
+ JOINING_TYPE_X, /* 0701 */
+ JOINING_TYPE_X, /* 0702 */
+ JOINING_TYPE_X, /* 0703 */
+ JOINING_TYPE_X, /* 0704 */
+ JOINING_TYPE_X, /* 0705 */
+ JOINING_TYPE_X, /* 0706 */
+ JOINING_TYPE_X, /* 0707 */
+ JOINING_TYPE_X, /* 0708 */
+ JOINING_TYPE_X, /* 0709 */
+ JOINING_TYPE_X, /* 070A */
+ JOINING_TYPE_X, /* 070B */
+ JOINING_TYPE_X, /* 070C */
+ JOINING_TYPE_X, /* 070D */
+ JOINING_TYPE_X, /* 070E */
+ JOINING_TYPE_X, /* 070F */
+ JOINING_GROUP_ALAPH, /* 0710; ALAPH; R; ALAPH */
+ JOINING_TYPE_X, /* 0711 */
+ JOINING_TYPE_D, /* 0712; BETH; D; BETH */
+ JOINING_TYPE_D, /* 0713; GAMAL; D; GAMAL */
+ JOINING_TYPE_D, /* 0714; GAMAL GARSHUNI; D; GAMAL */
+ JOINING_GROUP_DALATH_RISH, /* 0715; DALATH; R; DALATH RISH */
+ JOINING_GROUP_DALATH_RISH, /* 0716; DOTLESS DALATH RISH; R; DALATH RISH */
+ JOINING_TYPE_R, /* 0717; HE; R; HE */
+ JOINING_TYPE_R, /* 0718; WAW; R; SYRIAC WAW */
+ JOINING_TYPE_R, /* 0719; ZAIN; R; ZAIN */
+ JOINING_TYPE_D, /* 071A; HETH; D; HETH */
+ JOINING_TYPE_D, /* 071B; TETH; D; TETH */
+ JOINING_TYPE_D, /* 071C; TETH GARSHUNI; D; TETH */
+ JOINING_TYPE_D, /* 071D; YUDH; D; YUDH */
+ JOINING_TYPE_R, /* 071E; YUDH HE; R; YUDH HE */
+ JOINING_TYPE_D, /* 071F; KAPH; D; KAPH */
+ JOINING_TYPE_D, /* 0720; LAMADH; D; LAMADH */
+ JOINING_TYPE_D, /* 0721; MIM; D; MIM */
+ JOINING_TYPE_D, /* 0722; NUN; D; NUN */
+ JOINING_TYPE_D, /* 0723; SEMKATH; D; SEMKATH */
+ JOINING_TYPE_D, /* 0724; FINAL SEMKATH; D; FINAL SEMKATH */
+ JOINING_TYPE_D, /* 0725; E; D; E */
+ JOINING_TYPE_D, /* 0726; PE; D; PE */
+ JOINING_TYPE_D, /* 0727; REVERSED PE; D; REVERSED PE */
+ JOINING_TYPE_R, /* 0728; SADHE; R; SADHE */
+ JOINING_TYPE_D, /* 0729; QAPH; D; QAPH */
+ JOINING_GROUP_DALATH_RISH, /* 072A; RISH; R; DALATH RISH */
+ JOINING_TYPE_D, /* 072B; SHIN; D; SHIN */
+ JOINING_TYPE_R, /* 072C; TAW; R; TAW */
+ JOINING_TYPE_D, /* 072D; PERSIAN BHETH; D; BETH */
+ JOINING_TYPE_D, /* 072E; PERSIAN GHAMAL; D; GAMAL */
+ JOINING_GROUP_DALATH_RISH, /* 072F; PERSIAN DHALATH; R; DALATH RISH */
+ JOINING_TYPE_X, /* 0730 */
+ JOINING_TYPE_X, /* 0731 */
+ JOINING_TYPE_X, /* 0732 */
+ JOINING_TYPE_X, /* 0733 */
+ JOINING_TYPE_X, /* 0734 */
+ JOINING_TYPE_X, /* 0735 */
+ JOINING_TYPE_X, /* 0736 */
+ JOINING_TYPE_X, /* 0737 */
+ JOINING_TYPE_X, /* 0738 */
+ JOINING_TYPE_X, /* 0739 */
+ JOINING_TYPE_X, /* 073A */
+ JOINING_TYPE_X, /* 073B */
+ JOINING_TYPE_X, /* 073C */
+ JOINING_TYPE_X, /* 073D */
+ JOINING_TYPE_X, /* 073E */
+ JOINING_TYPE_X, /* 073F */
+ JOINING_TYPE_X, /* 0740 */
+ JOINING_TYPE_X, /* 0741 */
+ JOINING_TYPE_X, /* 0742 */
+ JOINING_TYPE_X, /* 0743 */
+ JOINING_TYPE_X, /* 0744 */
+ JOINING_TYPE_X, /* 0745 */
+ JOINING_TYPE_X, /* 0746 */
+ JOINING_TYPE_X, /* 0747 */
+ JOINING_TYPE_X, /* 0748 */
+ JOINING_TYPE_X, /* 0749 */
+ JOINING_TYPE_X, /* 074A */
+ JOINING_TYPE_X, /* 074B */
+ JOINING_TYPE_X, /* 074C */
+ JOINING_TYPE_R, /* 074D; SOGDIAN ZHAIN; R; ZHAIN */
+ JOINING_TYPE_D, /* 074E; SOGDIAN KHAPH; D; KHAPH */
+ JOINING_TYPE_D, /* 074F; SOGDIAN FE; D; FE */
+
+ /* Arabic supplement characters */
+
+ JOINING_TYPE_D, /* 0750; BEH WITH 3 DOTS HORIZONTALLY BELOW; D; BEH */
+ JOINING_TYPE_D, /* 0751; BEH WITH DOT BELOW AND 3 DOTS ABOVE; D; BEH */
+ JOINING_TYPE_D, /* 0752; BEH WITH 3 DOTS POINTING UPWARDS BELOW; D; BEH */
+ JOINING_TYPE_D, /* 0753; BEH WITH 3 DOTS POINTING UPWARDS BELOW AND 2 DOTS ABOVE; D; BEH */
+ JOINING_TYPE_D, /* 0754; BEH WITH 2 DOTS BELOW AND DOT ABOVE; D; BEH */
+ JOINING_TYPE_D, /* 0755; BEH WITH INVERTED SMALL V BELOW; D; BEH */
+ JOINING_TYPE_D, /* 0756; BEH WITH SMALL V; D; BEH */
+ JOINING_TYPE_D, /* 0757; HAH WITH 2 DOTS ABOVE; D; HAH */
+ JOINING_TYPE_D, /* 0758; HAH WITH 3 DOTS POINTING UPWARDS BELOW; D; HAH */
+ JOINING_TYPE_R, /* 0759; DAL WITH 2 DOTS VERTICALLY BELOW AND SMALL TAH; R; DAL */
+ JOINING_TYPE_R, /* 075A; DAL WITH INVERTED SMALL V BELOW; R; DAL */
+ JOINING_TYPE_R, /* 075B; REH WITH STROKE; R; REH */
+ JOINING_TYPE_D, /* 075C; SEEN WITH 4 DOTS ABOVE; D; SEEN */
+ JOINING_TYPE_D, /* 075D; AIN WITH 2 DOTS ABOVE; D; AIN */
+ JOINING_TYPE_D, /* 075E; AIN WITH 3 DOTS POINTING DOWNWARDS ABOVE; D; AIN */
+ JOINING_TYPE_D, /* 075F; AIN WITH 2 DOTS VERTICALLY ABOVE; D; AIN */
+ JOINING_TYPE_D, /* 0760; FEH WITH 2 DOTS BELOW; D; FEH */
+ JOINING_TYPE_D, /* 0761; FEH WITH 3 DOTS POINTING UPWARDS BELOW; D; FEH */
+ JOINING_TYPE_D, /* 0762; KEHEH WITH DOT ABOVE; D; GAF */
+ JOINING_TYPE_D, /* 0763; KEHEH WITH 3 DOTS ABOVE; D; GAF */
+ JOINING_TYPE_D, /* 0764; KEHEH WITH 3 DOTS POINTING UPWARDS BELOW; D; GAF */
+ JOINING_TYPE_D, /* 0765; MEEM WITH DOT ABOVE; D; MEEM */
+ JOINING_TYPE_D, /* 0766; MEEM WITH DOT BELOW; D; MEEM */
+ JOINING_TYPE_D, /* 0767; NOON WITH 2 DOTS BELOW; D; NOON */
+ JOINING_TYPE_D, /* 0768; NOON WITH SMALL TAH; D; NOON */
+ JOINING_TYPE_D, /* 0769; NOON WITH SMALL V; D; NOON */
+ JOINING_TYPE_D, /* 076A; LAM WITH BAR; D; LAM */
+ JOINING_TYPE_R, /* 076B; REH WITH 2 DOTS VERTICALLY ABOVE; R; REH */
+ JOINING_TYPE_R, /* 076C; REH WITH HAMZA ABOVE; R; REH */
+ JOINING_TYPE_D, /* 076D; SEEN WITH 2 DOTS VERTICALLY ABOVE; D; SEEN */
+ JOINING_TYPE_D, /* 076E; HAH WITH SMALL TAH BELOW; D; HAH */
+ JOINING_TYPE_D, /* 076F; HAH WITH SMALL TAH AND 2 DOTS; D; HAH */
+ JOINING_TYPE_D, /* 0770; SEEN WITH SMALL TAH AND 2 DOTS; D; SEEN */
+ JOINING_TYPE_R, /* 0771; REH WITH SMALL TAH AND 2 DOTS; R; REH */
+ JOINING_TYPE_D, /* 0772; HAH WITH SMALL TAH ABOVE; D; HAH */
+ JOINING_TYPE_R, /* 0773; ALEF WITH DIGIT TWO ABOVE; R; ALEF */
+ JOINING_TYPE_R, /* 0774; ALEF WITH DIGIT THREE ABOVE; R; ALEF */
+ JOINING_TYPE_D, /* 0775; FARSI YEH WITH DIGIT TWO ABOVE; D; FARSI YEH */
+ JOINING_TYPE_D, /* 0776; FARSI YEH WITH DIGIT THREE ABOVE; D; FARSI YEH */
+ JOINING_TYPE_D, /* 0777; YEH WITH DIGIT FOUR BELOW; D; YEH */
+ JOINING_TYPE_R, /* 0778; WAW WITH DIGIT TWO ABOVE; R; WAW */
+ JOINING_TYPE_R, /* 0779; WAW WITH DIGIT THREE ABOVE; R; WAW */
+ JOINING_TYPE_D, /* 077A; YEH BARREE WITH DIGIT TWO ABOVE; D; BURUSHASKI YEH BARREE */
+ JOINING_TYPE_D, /* 077B; YEH BARREE WITH DIGIT THREE ABOVE; D; BURUSHASKI YEH BARREE */
+ JOINING_TYPE_D, /* 077C; HAH WITH DIGIT FOUR BELOW; D; HAH */
+ JOINING_TYPE_D, /* 077D; SEEN WITH DIGIT FOUR ABOVE; D; SEEN */
+ JOINING_TYPE_D, /* 077E; SEEN WITH INVERTED V; D; SEEN */
+ JOINING_TYPE_D, /* 077F; KAF WITH 2 DOTS ABOVE; D; KAF */
+
+ /* N'Ko Characters */
+
+ JOINING_TYPE_X, /* 0780 */
+ JOINING_TYPE_X, /* 0781 */
+ JOINING_TYPE_X, /* 0782 */
+ JOINING_TYPE_X, /* 0783 */
+ JOINING_TYPE_X, /* 0784 */
+ JOINING_TYPE_X, /* 0785 */
+ JOINING_TYPE_X, /* 0786 */
+ JOINING_TYPE_X, /* 0787 */
+ JOINING_TYPE_X, /* 0788 */
+ JOINING_TYPE_X, /* 0789 */
+ JOINING_TYPE_X, /* 078A */
+ JOINING_TYPE_X, /* 078B */
+ JOINING_TYPE_X, /* 078C */
+ JOINING_TYPE_X, /* 078D */
+ JOINING_TYPE_X, /* 078E */
+ JOINING_TYPE_X, /* 078F */
+ JOINING_TYPE_X, /* 0790 */
+ JOINING_TYPE_X, /* 0791 */
+ JOINING_TYPE_X, /* 0792 */
+ JOINING_TYPE_X, /* 0793 */
+ JOINING_TYPE_X, /* 0794 */
+ JOINING_TYPE_X, /* 0795 */
+ JOINING_TYPE_X, /* 0796 */
+ JOINING_TYPE_X, /* 0797 */
+ JOINING_TYPE_X, /* 0798 */
+ JOINING_TYPE_X, /* 0799 */
+ JOINING_TYPE_X, /* 079A */
+ JOINING_TYPE_X, /* 079B */
+ JOINING_TYPE_X, /* 079C */
+ JOINING_TYPE_X, /* 079D */
+ JOINING_TYPE_X, /* 079E */
+ JOINING_TYPE_X, /* 079F */
+ JOINING_TYPE_X, /* 07A0 */
+ JOINING_TYPE_X, /* 07A1 */
+ JOINING_TYPE_X, /* 07A2 */
+ JOINING_TYPE_X, /* 07A3 */
+ JOINING_TYPE_X, /* 07A4 */
+ JOINING_TYPE_X, /* 07A5 */
+ JOINING_TYPE_X, /* 07A6 */
+ JOINING_TYPE_X, /* 07A7 */
+ JOINING_TYPE_X, /* 07A8 */
+ JOINING_TYPE_X, /* 07A9 */
+ JOINING_TYPE_X, /* 07AA */
+ JOINING_TYPE_X, /* 07AB */
+ JOINING_TYPE_X, /* 07AC */
+ JOINING_TYPE_X, /* 07AD */
+ JOINING_TYPE_X, /* 07AE */
+ JOINING_TYPE_X, /* 07AF */
+ JOINING_TYPE_X, /* 07B0 */
+ JOINING_TYPE_X, /* 07B1 */
+ JOINING_TYPE_X, /* 07B2 */
+ JOINING_TYPE_X, /* 07B3 */
+ JOINING_TYPE_X, /* 07B4 */
+ JOINING_TYPE_X, /* 07B5 */
+ JOINING_TYPE_X, /* 07B6 */
+ JOINING_TYPE_X, /* 07B7 */
+ JOINING_TYPE_X, /* 07B8 */
+ JOINING_TYPE_X, /* 07B9 */
+ JOINING_TYPE_X, /* 07BA */
+ JOINING_TYPE_X, /* 07BB */
+ JOINING_TYPE_X, /* 07BC */
+ JOINING_TYPE_X, /* 07BD */
+ JOINING_TYPE_X, /* 07BE */
+ JOINING_TYPE_X, /* 07BF */
+ JOINING_TYPE_X, /* 07C0 */
+ JOINING_TYPE_X, /* 07C1 */
+ JOINING_TYPE_X, /* 07C2 */
+ JOINING_TYPE_X, /* 07C3 */
+ JOINING_TYPE_X, /* 07C4 */
+ JOINING_TYPE_X, /* 07C5 */
+ JOINING_TYPE_X, /* 07C6 */
+ JOINING_TYPE_X, /* 07C7 */
+ JOINING_TYPE_X, /* 07C8 */
+ JOINING_TYPE_X, /* 07C9 */
+ JOINING_TYPE_D, /* 07CA; NKO A; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07CB; NKO EE; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07CC; NKO I; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07CD; NKO E; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07CE; NKO U; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07CF; NKO OO; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07D0; NKO O; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07D1; NKO DAGBASINNA; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07D2; NKO N; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07D3; NKO BA; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07D4; NKO PA; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07D5; NKO TA; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07D6; NKO JA; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07D7; NKO CHA; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07D8; NKO DA; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07D9; NKO RA; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07DA; NKO RRA; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07DB; NKO SA; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07DC; NKO GBA; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07DD; NKO FA; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07DE; NKO KA; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07DF; NKO LA; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07E0; NKO NA WOLOSO; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07E1; NKO MA; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07E2; NKO NYA; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07E3; NKO NA; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07E4; NKO HA; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07E5; NKO WA; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07E6; NKO YA; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07E7; NKO NYA WOLOSO; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07E8; NKO JONA JA; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07E9; NKO JONA CHA; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 07EA; NKO JONA RA; D; No_Joining_Group */
+ JOINING_TYPE_X, /* 07EB */
+ JOINING_TYPE_X, /* 07EC */
+ JOINING_TYPE_X, /* 07ED */
+ JOINING_TYPE_X, /* 07EE */
+ JOINING_TYPE_X, /* 07EF */
+ JOINING_TYPE_X, /* 07F0 */
+ JOINING_TYPE_X, /* 07F1 */
+ JOINING_TYPE_X, /* 07F2 */
+ JOINING_TYPE_X, /* 07F3 */
+ JOINING_TYPE_X, /* 07F4 */
+ JOINING_TYPE_X, /* 07F5 */
+ JOINING_TYPE_X, /* 07F6 */
+ JOINING_TYPE_X, /* 07F7 */
+ JOINING_TYPE_X, /* 07F8 */
+ JOINING_TYPE_X, /* 07F9 */
+ JOINING_TYPE_C, /* 07FA; NKO LAJANYALAN; C; No_Joining_Group */
+
+ /* Mandaic Characters */
+
+ JOINING_TYPE_X, /* 07FB */
+ JOINING_TYPE_X, /* 07FC */
+ JOINING_TYPE_X, /* 07FD */
+ JOINING_TYPE_X, /* 07FE */
+ JOINING_TYPE_X, /* 07FF */
+ JOINING_TYPE_X, /* 0800 */
+ JOINING_TYPE_X, /* 0801 */
+ JOINING_TYPE_X, /* 0802 */
+ JOINING_TYPE_X, /* 0803 */
+ JOINING_TYPE_X, /* 0804 */
+ JOINING_TYPE_X, /* 0805 */
+ JOINING_TYPE_X, /* 0806 */
+ JOINING_TYPE_X, /* 0807 */
+ JOINING_TYPE_X, /* 0808 */
+ JOINING_TYPE_X, /* 0809 */
+ JOINING_TYPE_X, /* 080A */
+ JOINING_TYPE_X, /* 080B */
+ JOINING_TYPE_X, /* 080C */
+ JOINING_TYPE_X, /* 080D */
+ JOINING_TYPE_X, /* 080E */
+ JOINING_TYPE_X, /* 080F */
+ JOINING_TYPE_X, /* 0810 */
+ JOINING_TYPE_X, /* 0811 */
+ JOINING_TYPE_X, /* 0812 */
+ JOINING_TYPE_X, /* 0813 */
+ JOINING_TYPE_X, /* 0814 */
+ JOINING_TYPE_X, /* 0815 */
+ JOINING_TYPE_X, /* 0816 */
+ JOINING_TYPE_X, /* 0817 */
+ JOINING_TYPE_X, /* 0818 */
+ JOINING_TYPE_X, /* 0819 */
+ JOINING_TYPE_X, /* 081A */
+ JOINING_TYPE_X, /* 081B */
+ JOINING_TYPE_X, /* 081C */
+ JOINING_TYPE_X, /* 081D */
+ JOINING_TYPE_X, /* 081E */
+ JOINING_TYPE_X, /* 081F */
+ JOINING_TYPE_X, /* 0820 */
+ JOINING_TYPE_X, /* 0821 */
+ JOINING_TYPE_X, /* 0822 */
+ JOINING_TYPE_X, /* 0823 */
+ JOINING_TYPE_X, /* 0824 */
+ JOINING_TYPE_X, /* 0825 */
+ JOINING_TYPE_X, /* 0826 */
+ JOINING_TYPE_X, /* 0827 */
+ JOINING_TYPE_X, /* 0828 */
+ JOINING_TYPE_X, /* 0829 */
+ JOINING_TYPE_X, /* 082A */
+ JOINING_TYPE_X, /* 082B */
+ JOINING_TYPE_X, /* 082C */
+ JOINING_TYPE_X, /* 082D */
+ JOINING_TYPE_X, /* 082E */
+ JOINING_TYPE_X, /* 082F */
+ JOINING_TYPE_X, /* 0830 */
+ JOINING_TYPE_X, /* 0831 */
+ JOINING_TYPE_X, /* 0832 */
+ JOINING_TYPE_X, /* 0833 */
+ JOINING_TYPE_X, /* 0834 */
+ JOINING_TYPE_X, /* 0835 */
+ JOINING_TYPE_X, /* 0836 */
+ JOINING_TYPE_X, /* 0837 */
+ JOINING_TYPE_X, /* 0838 */
+ JOINING_TYPE_X, /* 0839 */
+ JOINING_TYPE_X, /* 083A */
+ JOINING_TYPE_X, /* 083B */
+ JOINING_TYPE_X, /* 083C */
+ JOINING_TYPE_X, /* 083D */
+ JOINING_TYPE_X, /* 083E */
+ JOINING_TYPE_X, /* 083F */
+ JOINING_TYPE_R, /* 0840; MANDAIC HALQA; R; No_Joining_Group */
+ JOINING_TYPE_D, /* 0841; MANDAIC AB; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 0842; MANDAIC AG; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 0843; MANDAIC AD; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 0844; MANDAIC AH; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 0845; MANDAIC USHENNA; D; No_Joining_Group */
+ JOINING_TYPE_R, /* 0846; MANDAIC AZ; R; No_Joining_Group */
+ JOINING_TYPE_D, /* 0847; MANDAIC IT; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 0848; MANDAIC ATT; D; No_Joining_Group */
+ JOINING_TYPE_R, /* 0849; MANDAIC AKSA; R; No_Joining_Group */
+ JOINING_TYPE_D, /* 084A; MANDAIC AK; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 084B; MANDAIC AL; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 084C; MANDAIC AM; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 084D; MANDAIC AN; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 084E; MANDAIC AS; D; No_Joining_Group */
+ JOINING_TYPE_R, /* 084F; MANDAIC IN; R; No_Joining_Group */
+ JOINING_TYPE_D, /* 0850; MANDAIC AP; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 0851; MANDAIC ASZ; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 0852; MANDAIC AQ; D; No_Joining_Group */
+ JOINING_TYPE_D, /* 0853; MANDAIC AR; D; No_Joining_Group */
+ JOINING_TYPE_R, /* 0854; MANDAIC ASH; R; No_Joining_Group */
+ JOINING_TYPE_D, /* 0855; MANDAIC AT; D; No_Joining_Group */
+ JOINING_TYPE_U, /* 0856; MANDAIC DUSHENNA; U; No_Joining_Group */
+ JOINING_TYPE_U, /* 0857; MANDAIC KAD; U; No_Joining_Group */
+ JOINING_TYPE_U, /* 0858; MANDAIC AIN; U; No_Joining_Group */
+
+ JOINING_TYPE_X /* dummy */
+};
+
+#define JOINING_TABLE_FIRST 0x0600
+#define JOINING_TABLE_LAST 0x0858
+
+/* == End of generated table == */
+
+HB_END_DECLS
+
+#endif /* HB_OT_SHAPE_COMPLEX_ARABIC_TABLE_HH */
diff --git a/src/hb-ot-shape-complex-arabic.cc b/src/hb-ot-shape-complex-arabic.cc
index cc08fbb..3e26568 100644
--- a/src/hb-ot-shape-complex-arabic.cc
+++ b/src/hb-ot-shape-complex-arabic.cc
@@ -55,7 +55,7 @@ enum {
* Joining types:
*/
-#include "hb-ot-shape-complex-arabic-table.h"
+#include "hb-ot-shape-complex-arabic-table.hh"
static unsigned int get_joining_type (hb_codepoint_t u, hb_unicode_general_category_t gen_cat)
{
diff --git a/src/hb-ot-shape-complex-private.hh b/src/hb-ot-shape-complex-private.hh
index 8147945..8225b46 100644
--- a/src/hb-ot-shape-complex-private.hh
+++ b/src/hb-ot-shape-complex-private.hh
@@ -27,7 +27,7 @@
#ifndef HB_OT_SHAPE_COMPLEX_PRIVATE_HH
#define HB_OT_SHAPE_COMPLEX_PRIVATE_HH
-#include "hb-private.h"
+#include "hb-private.hh"
#include "hb-ot-shape-private.hh"
diff --git a/src/hb-ot-shape-private.hh b/src/hb-ot-shape-private.hh
index 1a5c670..f334cda 100644
--- a/src/hb-ot-shape-private.hh
+++ b/src/hb-ot-shape-private.hh
@@ -27,7 +27,7 @@
#ifndef HB_OT_SHAPE_PRIVATE_HH
#define HB_OT_SHAPE_PRIVATE_HH
-#include "hb-private.h"
+#include "hb-private.hh"
#include "hb-ot-shape.h"
diff --git a/src/hb-ot-tag.c b/src/hb-ot-tag.c
deleted file mode 100644
index f7e8c95..0000000
--- a/src/hb-ot-tag.c
+++ /dev/null
@@ -1,677 +0,0 @@
-/*
- * Copyright (C) 2009 Red Hat, Inc.
- *
- * 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.
- *
- * Red Hat Author(s): Behdad Esfahbod
- */
-
-#include "hb-private.h"
-#include "hb-ot.h"
-
-#include <string.h>
-
-HB_BEGIN_DECLS
-
-
-/* hb_script_t */
-
-static hb_tag_t
-hb_ot_old_tag_from_script (hb_script_t script)
-{
- switch ((hb_tag_t) script) {
- case HB_SCRIPT_COPTIC: return HB_TAG('c','o','p','t');
- case HB_SCRIPT_HIRAGANA: return HB_TAG('k','a','n','a');
- case HB_SCRIPT_LAO: return HB_TAG('l','a','o',' ');
- case HB_SCRIPT_YI: return HB_TAG('y','i',' ',' ');
- /* Unicode-5.0 additions */
- case HB_SCRIPT_NKO: return HB_TAG('n','k','o',' ');
- /* Unicode-5.1 additions */
- case HB_SCRIPT_VAI: return HB_TAG('v','a','i',' ');
- /* Unicode-5.2 additions */
- case HB_SCRIPT_MEETEI_MAYEK: return HB_TAG('m','y','e','i');
- /* Unicode-6.0 additions */
- }
-
- /* Else, just change first char to lowercase and return */
- return ((hb_tag_t) script) | 0x20000000;
-}
-
-static hb_script_t
-hb_ot_old_tag_to_script (hb_tag_t tag)
-{
- switch (tag) {
- case HB_TAG('c','o','p','t'): return HB_SCRIPT_COPTIC;
- case HB_TAG('k','a','n','a'): return HB_SCRIPT_HIRAGANA;
- case HB_TAG('l','a','o',' '): return HB_SCRIPT_LAO;
- case HB_TAG('y','i',' ',' '): return HB_SCRIPT_YI;
- /* Unicode-5.0 additions */
- case HB_TAG('n','k','o',' '): return HB_SCRIPT_NKO;
- /* Unicode-5.1 additions */
- case HB_TAG('v','a','i',' '): return HB_SCRIPT_VAI;
- /* Unicode-5.2 additions */
- case HB_TAG('m','y','e','i'): return HB_SCRIPT_MEETEI_MAYEK;
- /* Unicode-6.0 additions */
- }
-
- /* Else, just change first char to uppercase and return */
- return (hb_script_t) (tag & ~0x20000000);
-}
-
-static hb_tag_t
-hb_ot_new_tag_from_script (hb_script_t script)
-{
- switch ((hb_tag_t) script) {
- case HB_SCRIPT_BENGALI: return HB_TAG('b','n','g','2');
- case HB_SCRIPT_DEVANAGARI: return HB_TAG('d','e','v','2');
- case HB_SCRIPT_GUJARATI: return HB_TAG('g','j','r','2');
- case HB_SCRIPT_GURMUKHI: return HB_TAG('g','u','r','2');
- case HB_SCRIPT_KANNADA: return HB_TAG('k','n','d','2');
- case HB_SCRIPT_MALAYALAM: return HB_TAG('m','l','m','2');
- case HB_SCRIPT_ORIYA: return HB_TAG('o','r','y','2');
- case HB_SCRIPT_TAMIL: return HB_TAG('t','m','l','2');
- case HB_SCRIPT_TELUGU: return HB_TAG('t','e','l','2');
- }
-
- return HB_TAG_NONE;
-}
-
-static hb_script_t
-hb_ot_new_tag_to_script (hb_tag_t tag)
-{
- switch (tag) {
- case HB_TAG('b','n','g','2'): return HB_SCRIPT_BENGALI;
- case HB_TAG('d','e','v','2'): return HB_SCRIPT_DEVANAGARI;
- case HB_TAG('g','j','r','2'): return HB_SCRIPT_GUJARATI;
- case HB_TAG('g','u','r','2'): return HB_SCRIPT_GURMUKHI;
- case HB_TAG('k','n','d','2'): return HB_SCRIPT_KANNADA;
- case HB_TAG('m','l','m','2'): return HB_SCRIPT_MALAYALAM;
- case HB_TAG('o','r','y','2'): return HB_SCRIPT_ORIYA;
- case HB_TAG('t','m','l','2'): return HB_SCRIPT_TAMIL;
- case HB_TAG('t','e','l','2'): return HB_SCRIPT_TELUGU;
- }
-
- return HB_SCRIPT_UNKNOWN;
-}
-
-/*
- * Complete list at:
- * http://www.microsoft.com/typography/otspec/scripttags.htm
- *
- * Most of the script tags are the same as the ISO 15924 tag but lowercased.
- * So we just do that, and handle the exceptional cases in a switch.
- */
-
-void
-hb_ot_tags_from_script (hb_script_t script,
- hb_tag_t *script_tag_1,
- hb_tag_t *script_tag_2)
-{
- hb_tag_t new_tag;
-
- *script_tag_2 = HB_TAG_NONE;
- *script_tag_1 = hb_ot_old_tag_from_script (script);
-
- new_tag = hb_ot_new_tag_from_script (script);
- if (unlikely (new_tag != HB_TAG_NONE)) {
- *script_tag_2 = *script_tag_1;
- *script_tag_1 = new_tag;
- }
-}
-
-hb_script_t
-hb_ot_tag_to_script (hb_tag_t tag)
-{
- if (unlikely ((tag & 0x000000FF) == '2'))
- return hb_ot_new_tag_to_script (tag);
-
- return hb_ot_old_tag_to_script (tag);
-}
-
-
-/* hb_language_t */
-
-typedef struct {
- char language[6];
- hb_tag_t tag;
-} LangTag;
-
-/*
- * Complete list at:
- * http://www.microsoft.com/typography/otspec/languagetags.htm
- *
- * Generated by intersecting the OpenType language tag list from
- * Draft OpenType 1.5 spec, with with the ISO 639-3 codes from
- * 2008/08/04, matching on name, and finally adjusted manually.
- *
- * Many items still missing. Those are commented out at the end.
- * Keep sorted for bsearch.
- */
-static const LangTag ot_languages[] = {
- {"aa", HB_TAG('A','F','R',' ')}, /* Afar */
- {"ab", HB_TAG('A','B','K',' ')}, /* Abkhazian */
- {"abq", HB_TAG('A','B','A',' ')}, /* Abaza */
- {"ady", HB_TAG('A','D','Y',' ')}, /* Adyghe */
- {"af", HB_TAG('A','F','K',' ')}, /* Afrikaans */
- {"aiw", HB_TAG('A','R','I',' ')}, /* Aari */
- {"am", HB_TAG('A','M','H',' ')}, /* Amharic */
- {"ar", HB_TAG('A','R','A',' ')}, /* Arabic */
- {"arn", HB_TAG('M','A','P',' ')}, /* Mapudungun */
- {"as", HB_TAG('A','S','M',' ')}, /* Assamese */
- {"av", HB_TAG('A','V','R',' ')}, /* Avaric */
- {"awa", HB_TAG('A','W','A',' ')}, /* Awadhi */
- {"ay", HB_TAG('A','Y','M',' ')}, /* Aymara */
- {"az", HB_TAG('A','Z','E',' ')}, /* Azerbaijani */
- {"ba", HB_TAG('B','S','H',' ')}, /* Bashkir */
- {"bal", HB_TAG('B','L','I',' ')}, /* Baluchi */
- {"bcq", HB_TAG('B','C','H',' ')}, /* Bench */
- {"bem", HB_TAG('B','E','M',' ')}, /* Bemba (Zambia) */
- {"bfq", HB_TAG('B','A','D',' ')}, /* Badaga */
- {"bft", HB_TAG('B','L','T',' ')}, /* Balti */
- {"bg", HB_TAG('B','G','R',' ')}, /* Bulgarian */
- {"bhb", HB_TAG('B','H','I',' ')}, /* Bhili */
- {"bho", HB_TAG('B','H','O',' ')}, /* Bhojpuri */
- {"bik", HB_TAG('B','I','K',' ')}, /* Bikol */
- {"bin", HB_TAG('E','D','O',' ')}, /* Bini */
- {"bm", HB_TAG('B','M','B',' ')}, /* Bambara */
- {"bn", HB_TAG('B','E','N',' ')}, /* Bengali */
- {"bo", HB_TAG('T','I','B',' ')}, /* Tibetan */
- {"br", HB_TAG('B','R','E',' ')}, /* Breton */
- {"brh", HB_TAG('B','R','H',' ')}, /* Brahui */
- {"bs", HB_TAG('B','O','S',' ')}, /* Bosnian */
- {"btb", HB_TAG('B','T','I',' ')}, /* Beti (Cameroon) */
- {"ca", HB_TAG('C','A','T',' ')}, /* Catalan */
- {"ce", HB_TAG('C','H','E',' ')}, /* Chechen */
- {"ceb", HB_TAG('C','E','B',' ')}, /* Cebuano */
- {"chp", HB_TAG('C','H','P',' ')}, /* Chipewyan */
- {"chr", HB_TAG('C','H','R',' ')}, /* Cherokee */
- {"cop", HB_TAG('C','O','P',' ')}, /* Coptic */
- {"cr", HB_TAG('C','R','E',' ')}, /* Cree */
- {"crh", HB_TAG('C','R','T',' ')}, /* Crimean Tatar */
- {"crm", HB_TAG('M','C','R',' ')}, /* Moose Cree */
- {"crx", HB_TAG('C','R','R',' ')}, /* Carrier */
- {"cs", HB_TAG('C','S','Y',' ')}, /* Czech */
- {"cu", HB_TAG('C','S','L',' ')}, /* Church Slavic */
- {"cv", HB_TAG('C','H','U',' ')}, /* Chuvash */
- {"cwd", HB_TAG('D','C','R',' ')}, /* Woods Cree */
- {"cy", HB_TAG('W','E','L',' ')}, /* Welsh */
- {"da", HB_TAG('D','A','N',' ')}, /* Danish */
- {"dap", HB_TAG('N','I','S',' ')}, /* Nisi (India) */
- {"dar", HB_TAG('D','A','R',' ')}, /* Dargwa */
- {"de", HB_TAG('D','E','U',' ')}, /* German */
- {"din", HB_TAG('D','N','K',' ')}, /* Dinka */
- {"dng", HB_TAG('D','U','N',' ')}, /* Dungan */
- {"doi", HB_TAG('D','G','R',' ')}, /* Dogri */
- {"dsb", HB_TAG('L','S','B',' ')}, /* Lower Sorbian */
- {"dv", HB_TAG('D','I','V',' ')}, /* Dhivehi */
- {"dz", HB_TAG('D','Z','N',' ')}, /* Dzongkha */
- {"ee", HB_TAG('E','W','E',' ')}, /* Ewe */
- {"efi", HB_TAG('E','F','I',' ')}, /* Efik */
- {"el", HB_TAG('E','L','L',' ')}, /* Modern Greek (1453-) */
- {"en", HB_TAG('E','N','G',' ')}, /* English */
- {"eo", HB_TAG('N','T','O',' ')}, /* Esperanto */
- {"eot", HB_TAG('B','T','I',' ')}, /* Beti (Côte d'Ivoire) */
- {"es", HB_TAG('E','S','P',' ')}, /* Spanish */
- {"et", HB_TAG('E','T','I',' ')}, /* Estonian */
- {"eu", HB_TAG('E','U','Q',' ')}, /* Basque */
- {"eve", HB_TAG('E','V','N',' ')}, /* Even */
- {"evn", HB_TAG('E','V','K',' ')}, /* Evenki */
- {"fa", HB_TAG('F','A','R',' ')}, /* Persian */
- {"ff", HB_TAG('F','U','L',' ')}, /* Fulah */
- {"fi", HB_TAG('F','I','N',' ')}, /* Finnish */
- {"fil", HB_TAG('P','I','L',' ')}, /* Filipino */
- {"fj", HB_TAG('F','J','I',' ')}, /* Fijian */
- {"fo", HB_TAG('F','O','S',' ')}, /* Faroese */
- {"fon", HB_TAG('F','O','N',' ')}, /* Fon */
- {"fr", HB_TAG('F','R','A',' ')}, /* French */
- {"fur", HB_TAG('F','R','L',' ')}, /* Friulian */
- {"fy", HB_TAG('F','R','I',' ')}, /* Western Frisian */
- {"ga", HB_TAG('I','R','I',' ')}, /* Irish */
- {"gaa", HB_TAG('G','A','D',' ')}, /* Ga */
- {"gag", HB_TAG('G','A','G',' ')}, /* Gagauz */
- {"gbm", HB_TAG('G','A','W',' ')}, /* Garhwali */
- {"gd", HB_TAG('G','A','E',' ')}, /* Scottish Gaelic */
- {"gl", HB_TAG('G','A','L',' ')}, /* Galician */
- {"gld", HB_TAG('N','A','N',' ')}, /* Nanai */
- {"gn", HB_TAG('G','U','A',' ')}, /* Guarani */
- {"gon", HB_TAG('G','O','N',' ')}, /* Gondi */
- {"grt", HB_TAG('G','R','O',' ')}, /* Garo */
- {"gu", HB_TAG('G','U','J',' ')}, /* Gujarati */
- {"guk", HB_TAG('G','M','Z',' ')}, /* Gumuz */
- {"gv", HB_TAG('M','N','X',' ')}, /* Manx Gaelic */
- {"ha", HB_TAG('H','A','U',' ')}, /* Hausa */
- {"har", HB_TAG('H','R','I',' ')}, /* Harari */
- {"he", HB_TAG('I','W','R',' ')}, /* Hebrew */
- {"hi", HB_TAG('H','I','N',' ')}, /* Hindi */
- {"hil", HB_TAG('H','I','L',' ')}, /* Hiligaynon */
- {"hoc", HB_TAG('H','O',' ',' ')}, /* Ho */
- {"hr", HB_TAG('H','R','V',' ')}, /* Croatian */
- {"hsb", HB_TAG('U','S','B',' ')}, /* Upper Sorbian */
- {"ht", HB_TAG('H','A','I',' ')}, /* Haitian */
- {"hu", HB_TAG('H','U','N',' ')}, /* Hungarian */
- {"hy", HB_TAG('H','Y','E',' ')}, /* Armenian */
- {"id", HB_TAG('I','N','D',' ')}, /* Indonesian */
- {"ig", HB_TAG('I','B','O',' ')}, /* Igbo */
- {"igb", HB_TAG('E','B','I',' ')}, /* Ebira */
- {"inh", HB_TAG('I','N','G',' ')}, /* Ingush */
- {"is", HB_TAG('I','S','L',' ')}, /* Icelandic */
- {"it", HB_TAG('I','T','A',' ')}, /* Italian */
- {"iu", HB_TAG('I','N','U',' ')}, /* Inuktitut */
- {"ja", HB_TAG('J','A','N',' ')}, /* Japanese */
- {"jv", HB_TAG('J','A','V',' ')}, /* Javanese */
- {"ka", HB_TAG('K','A','T',' ')}, /* Georgian */
- {"kam", HB_TAG('K','M','B',' ')}, /* Kamba (Kenya) */
- {"kbd", HB_TAG('K','A','B',' ')}, /* Kabardian */
- {"kdr", HB_TAG('K','R','M',' ')}, /* Karaim */
- {"kdt", HB_TAG('K','U','Y',' ')}, /* Kuy */
- {"kfr", HB_TAG('K','A','C',' ')}, /* Kachchi */
- {"kfy", HB_TAG('K','M','N',' ')}, /* Kumaoni */
- {"kha", HB_TAG('K','S','I',' ')}, /* Khasi */
- {"khw", HB_TAG('K','H','W',' ')}, /* Khowar */
- {"ki", HB_TAG('K','I','K',' ')}, /* Kikuyu */
- {"kk", HB_TAG('K','A','Z',' ')}, /* Kazakh */
- {"kl", HB_TAG('G','R','N',' ')}, /* Kalaallisut */
- {"kln", HB_TAG('K','A','L',' ')}, /* Kalenjin */
- {"km", HB_TAG('K','H','M',' ')}, /* Central Khmer */
- {"kmw", HB_TAG('K','M','O',' ')}, /* Komo (Democratic Republic of Congo) */
- {"kn", HB_TAG('K','A','N',' ')}, /* Kannada */
- {"ko", HB_TAG('K','O','R',' ')}, /* Korean */
- {"koi", HB_TAG('K','O','P',' ')}, /* Komi-Permyak */
- {"kok", HB_TAG('K','O','K',' ')}, /* Konkani */
- {"kpe", HB_TAG('K','P','L',' ')}, /* Kpelle */
- {"kpv", HB_TAG('K','O','Z',' ')}, /* Komi-Zyrian */
- {"kpy", HB_TAG('K','Y','K',' ')}, /* Koryak */
- {"kqy", HB_TAG('K','R','T',' ')}, /* Koorete */
- {"kr", HB_TAG('K','N','R',' ')}, /* Kanuri */
- {"kri", HB_TAG('K','R','I',' ')}, /* Krio */
- {"krl", HB_TAG('K','R','L',' ')}, /* Karelian */
- {"kru", HB_TAG('K','U','U',' ')}, /* Kurukh */
- {"ks", HB_TAG('K','S','H',' ')}, /* Kashmiri */
- {"ku", HB_TAG('K','U','R',' ')}, /* Kurdish */
- {"kum", HB_TAG('K','U','M',' ')}, /* Kumyk */
- {"kvd", HB_TAG('K','U','I',' ')}, /* Kui (Indonesia) */
- {"kxu", HB_TAG('K','U','I',' ')}, /* Kui (India) */
- {"ky", HB_TAG('K','I','R',' ')}, /* Kirghiz */
- {"la", HB_TAG('L','A','T',' ')}, /* Latin */
- {"lad", HB_TAG('J','U','D',' ')}, /* Ladino */
- {"lb", HB_TAG('L','T','Z',' ')}, /* Luxembourgish */
- {"lbe", HB_TAG('L','A','K',' ')}, /* Lak */
- {"lbj", HB_TAG('L','D','K',' ')}, /* Ladakhi */
- {"lif", HB_TAG('L','M','B',' ')}, /* Limbu */
- {"lld", HB_TAG('L','A','D',' ')}, /* Ladin */
- {"ln", HB_TAG('L','I','N',' ')}, /* Lingala */
- {"lo", HB_TAG('L','A','O',' ')}, /* Lao */
- {"lt", HB_TAG('L','T','H',' ')}, /* Lithuanian */
- {"luo", HB_TAG('L','U','O',' ')}, /* Luo (Kenya and Tanzania) */
- {"luw", HB_TAG('L','U','O',' ')}, /* Luo (Cameroon) */
- {"lv", HB_TAG('L','V','I',' ')}, /* Latvian */
- {"lzz", HB_TAG('L','A','Z',' ')}, /* Laz */
- {"mai", HB_TAG('M','T','H',' ')}, /* Maithili */
- {"mdc", HB_TAG('M','L','E',' ')}, /* Male (Papua New Guinea) */
- {"mdf", HB_TAG('M','O','K',' ')}, /* Moksha */
- {"mdy", HB_TAG('M','L','E',' ')}, /* Male (Ethiopia) */
- {"men", HB_TAG('M','D','E',' ')}, /* Mende (Sierra Leone) */
- {"mg", HB_TAG('M','L','G',' ')}, /* Malagasy */
- {"mi", HB_TAG('M','R','I',' ')}, /* Maori */
- {"mk", HB_TAG('M','K','D',' ')}, /* Macedonian */
- {"ml", HB_TAG('M','L','R',' ')}, /* Malayalam */
- {"mn", HB_TAG('M','N','G',' ')}, /* Mongolian */
- {"mnc", HB_TAG('M','C','H',' ')}, /* Manchu */
- {"mni", HB_TAG('M','N','I',' ')}, /* Manipuri */
- {"mnk", HB_TAG('M','N','D',' ')}, /* Mandinka */
- {"mns", HB_TAG('M','A','N',' ')}, /* Mansi */
- {"mnw", HB_TAG('M','O','N',' ')}, /* Mon */
- {"mo", HB_TAG('M','O','L',' ')}, /* Moldavian */
- {"moh", HB_TAG('M','O','H',' ')}, /* Mohawk */
- {"mpe", HB_TAG('M','A','J',' ')}, /* Majang */
- {"mr", HB_TAG('M','A','R',' ')}, /* Marathi */
- {"ms", HB_TAG('M','L','Y',' ')}, /* Malay */
- {"mt", HB_TAG('M','T','S',' ')}, /* Maltese */
- {"mwr", HB_TAG('M','A','W',' ')}, /* Marwari */
- {"my", HB_TAG('B','R','M',' ')}, /* Burmese */
- {"mym", HB_TAG('M','E','N',' ')}, /* Me'en */
- {"myv", HB_TAG('E','R','Z',' ')}, /* Erzya */
- {"nb", HB_TAG('N','O','R',' ')}, /* Norwegian Bokmål */
- {"nco", HB_TAG('S','I','B',' ')}, /* Sibe */
- {"ne", HB_TAG('N','E','P',' ')}, /* Nepali */
- {"new", HB_TAG('N','E','W',' ')}, /* Newari */
- {"ng", HB_TAG('N','D','G',' ')}, /* Ndonga */
- {"ngl", HB_TAG('L','M','W',' ')}, /* Lomwe */
- {"niu", HB_TAG('N','I','U',' ')}, /* Niuean */
- {"niv", HB_TAG('G','I','L',' ')}, /* Gilyak */
- {"nl", HB_TAG('N','L','D',' ')}, /* Dutch */
- {"nn", HB_TAG('N','Y','N',' ')}, /* Norwegian Nynorsk */
- {"no", HB_TAG('N','O','R',' ')}, /* Norwegian (deprecated) */
- {"nog", HB_TAG('N','O','G',' ')}, /* Nogai */
- {"nqo", HB_TAG('N','K','O',' ')}, /* N'Ko */
- {"nsk", HB_TAG('N','A','S',' ')}, /* Naskapi */
- {"ny", HB_TAG('C','H','I',' ')}, /* Nyanja */
- {"oc", HB_TAG('O','C','I',' ')}, /* Occitan (post 1500) */
- {"oj", HB_TAG('O','J','B',' ')}, /* Ojibwa */
- {"om", HB_TAG('O','R','O',' ')}, /* Oromo */
- {"or", HB_TAG('O','R','I',' ')}, /* Oriya */
- {"os", HB_TAG('O','S','S',' ')}, /* Ossetian */
- {"pa", HB_TAG('P','A','N',' ')}, /* Panjabi */
- {"pi", HB_TAG('P','A','L',' ')}, /* Pali */
- {"pl", HB_TAG('P','L','K',' ')}, /* Polish */
- {"plp", HB_TAG('P','A','P',' ')}, /* Palpa */
- {"prs", HB_TAG('D','R','I',' ')}, /* Dari */
- {"ps", HB_TAG('P','A','S',' ')}, /* Pushto */
- {"pt", HB_TAG('P','T','G',' ')}, /* Portuguese */
- {"raj", HB_TAG('R','A','J',' ')}, /* Rajasthani */
- {"ria", HB_TAG('R','I','A',' ')}, /* Riang (India) */
- {"ril", HB_TAG('R','I','A',' ')}, /* Riang (Myanmar) */
- {"ro", HB_TAG('R','O','M',' ')}, /* Romanian */
- {"rom", HB_TAG('R','O','Y',' ')}, /* Romany */
- {"ru", HB_TAG('R','U','S',' ')}, /* Russian */
- {"rue", HB_TAG('R','S','Y',' ')}, /* Rusyn */
- {"sa", HB_TAG('S','A','N',' ')}, /* Sanskrit */
- {"sah", HB_TAG('Y','A','K',' ')}, /* Yakut */
- {"sat", HB_TAG('S','A','T',' ')}, /* Santali */
- {"sck", HB_TAG('S','A','D',' ')}, /* Sadri */
- {"sd", HB_TAG('S','N','D',' ')}, /* Sindhi */
- {"se", HB_TAG('N','S','M',' ')}, /* Northern Sami */
- {"seh", HB_TAG('S','N','A',' ')}, /* Sena */
- {"sel", HB_TAG('S','E','L',' ')}, /* Selkup */
- {"sg", HB_TAG('S','G','O',' ')}, /* Sango */
- {"shn", HB_TAG('S','H','N',' ')}, /* Shan */
- {"si", HB_TAG('S','N','H',' ')}, /* Sinhala */
- {"sid", HB_TAG('S','I','D',' ')}, /* Sidamo */
- {"sjd", HB_TAG('K','S','M',' ')}, /* Kildin Sami */
- {"sk", HB_TAG('S','K','Y',' ')}, /* Slovak */
- {"skr", HB_TAG('S','R','K',' ')}, /* Seraiki */
- {"sl", HB_TAG('S','L','V',' ')}, /* Slovenian */
- {"sm", HB_TAG('S','M','O',' ')}, /* Samoan */
- {"sma", HB_TAG('S','S','M',' ')}, /* Southern Sami */
- {"smj", HB_TAG('L','S','M',' ')}, /* Lule Sami */
- {"smn", HB_TAG('I','S','M',' ')}, /* Inari Sami */
- {"sms", HB_TAG('S','K','S',' ')}, /* Skolt Sami */
- {"snk", HB_TAG('S','N','K',' ')}, /* Soninke */
- {"so", HB_TAG('S','M','L',' ')}, /* Somali */
- {"sq", HB_TAG('S','Q','I',' ')}, /* Albanian */
- {"sr", HB_TAG('S','R','B',' ')}, /* Serbian */
- {"srr", HB_TAG('S','R','R',' ')}, /* Serer */
- {"suq", HB_TAG('S','U','R',' ')}, /* Suri */
- {"sv", HB_TAG('S','V','E',' ')}, /* Swedish */
- {"sva", HB_TAG('S','V','A',' ')}, /* Svan */
- {"sw", HB_TAG('S','W','K',' ')}, /* Swahili */
- {"swb", HB_TAG('C','M','R',' ')}, /* Comorian */
- {"syr", HB_TAG('S','Y','R',' ')}, /* Syriac */
- {"ta", HB_TAG('T','A','M',' ')}, /* Tamil */
- {"tcy", HB_TAG('T','U','L',' ')}, /* Tulu */
- {"te", HB_TAG('T','E','L',' ')}, /* Telugu */
- {"tg", HB_TAG('T','A','J',' ')}, /* Tajik */
- {"th", HB_TAG('T','H','A',' ')}, /* Thai */
- {"ti", HB_TAG('T','G','Y',' ')}, /* Tigrinya */
- {"tig", HB_TAG('T','G','R',' ')}, /* Tigre */
- {"tk", HB_TAG('T','K','M',' ')}, /* Turkmen */
- {"tn", HB_TAG('T','N','A',' ')}, /* Tswana */
- {"tnz", HB_TAG('T','N','G',' ')}, /* Tonga (Thailand) */
- {"to", HB_TAG('T','N','G',' ')}, /* Tonga (Tonga Islands) */
- {"tog", HB_TAG('T','N','G',' ')}, /* Tonga (Nyasa) */
- {"toi", HB_TAG('T','N','G',' ')}, /* Tonga (Zambia) */
- {"tr", HB_TAG('T','R','K',' ')}, /* Turkish */
- {"ts", HB_TAG('T','S','G',' ')}, /* Tsonga */
- {"tt", HB_TAG('T','A','T',' ')}, /* Tatar */
- {"tw", HB_TAG('T','W','I',' ')}, /* Twi */
- {"ty", HB_TAG('T','H','T',' ')}, /* Tahitian */
- {"udm", HB_TAG('U','D','M',' ')}, /* Udmurt */
- {"ug", HB_TAG('U','Y','G',' ')}, /* Uighur */
- {"uk", HB_TAG('U','K','R',' ')}, /* Ukrainian */
- {"unr", HB_TAG('M','U','N',' ')}, /* Mundari */
- {"ur", HB_TAG('U','R','D',' ')}, /* Urdu */
- {"uz", HB_TAG('U','Z','B',' ')}, /* Uzbek */
- {"ve", HB_TAG('V','E','N',' ')}, /* Venda */
- {"vi", HB_TAG('V','I','T',' ')}, /* Vietnamese */
- {"wbm", HB_TAG('W','A',' ',' ')}, /* Wa */
- {"wbr", HB_TAG('W','A','G',' ')}, /* Wagdi */
- {"wo", HB_TAG('W','L','F',' ')}, /* Wolof */
- {"xal", HB_TAG('K','L','M',' ')}, /* Kalmyk */
- {"xh", HB_TAG('X','H','S',' ')}, /* Xhosa */
- {"xom", HB_TAG('K','M','O',' ')}, /* Komo (Sudan) */
- {"xsl", HB_TAG('S','S','L',' ')}, /* South Slavey */
- {"yi", HB_TAG('J','I','I',' ')}, /* Yiddish */
- {"yo", HB_TAG('Y','B','A',' ')}, /* Yoruba */
- {"yso", HB_TAG('N','I','S',' ')}, /* Nisi (China) */
- {"zh-cn", HB_TAG('Z','H','S',' ')}, /* Chinese (China) */
- {"zh-hk", HB_TAG('Z','H','H',' ')}, /* Chinese (Hong Kong) */
- {"zh-mo", HB_TAG('Z','H','T',' ')}, /* Chinese (Macao) */
- {"zh-sg", HB_TAG('Z','H','S',' ')}, /* Chinese (Singapore) */
- {"zh-tw", HB_TAG('Z','H','T',' ')}, /* Chinese (Taiwan) */
- {"zne", HB_TAG('Z','N','D',' ')}, /* Zande */
- {"zu", HB_TAG('Z','U','L',' ')} /* Zulu */
-
- /* I couldn't find the language id for these */
-
-/*{"??", HB_TAG('A','G','W',' ')},*/ /* Agaw */
-/*{"??", HB_TAG('A','L','S',' ')},*/ /* Alsatian */
-/*{"??", HB_TAG('A','L','T',' ')},*/ /* Altai */
-/*{"??", HB_TAG('A','R','K',' ')},*/ /* Arakanese */
-/*{"??", HB_TAG('A','T','H',' ')},*/ /* Athapaskan */
-/*{"??", HB_TAG('B','A','G',' ')},*/ /* Baghelkhandi */
-/*{"??", HB_TAG('B','A','L',' ')},*/ /* Balkar */
-/*{"??", HB_TAG('B','A','U',' ')},*/ /* Baule */
-/*{"??", HB_TAG('B','B','R',' ')},*/ /* Berber */
-/*{"??", HB_TAG('B','C','R',' ')},*/ /* Bible Cree */
-/*{"??", HB_TAG('B','E','L',' ')},*/ /* Belarussian */
-/*{"??", HB_TAG('B','I','L',' ')},*/ /* Bilen */
-/*{"??", HB_TAG('B','K','F',' ')},*/ /* Blackfoot */
-/*{"??", HB_TAG('B','L','N',' ')},*/ /* Balante */
-/*{"??", HB_TAG('B','M','L',' ')},*/ /* Bamileke */
-/*{"??", HB_TAG('B','R','I',' ')},*/ /* Braj Bhasha */
-/*{"??", HB_TAG('C','H','G',' ')},*/ /* Chaha Gurage */
-/*{"??", HB_TAG('C','H','H',' ')},*/ /* Chattisgarhi */
-/*{"??", HB_TAG('C','H','K',' ')},*/ /* Chukchi */
-/*{"??", HB_TAG('D','J','R',' ')},*/ /* Djerma */
-/*{"??", HB_TAG('D','N','G',' ')},*/ /* Dangme */
-/*{"??", HB_TAG('E','C','R',' ')},*/ /* Eastern Cree */
-/*{"??", HB_TAG('F','A','N',' ')},*/ /* French Antillean */
-/*{"??", HB_TAG('F','L','E',' ')},*/ /* Flemish */
-/*{"??", HB_TAG('F','N','E',' ')},*/ /* Forest Nenets */
-/*{"??", HB_TAG('F','T','A',' ')},*/ /* Futa */
-/*{"??", HB_TAG('G','A','R',' ')},*/ /* Garshuni */
-/*{"??", HB_TAG('G','E','Z',' ')},*/ /* Ge'ez */
-/*{"??", HB_TAG('H','A','L',' ')},*/ /* Halam */
-/*{"??", HB_TAG('H','A','R',' ')},*/ /* Harauti */
-/*{"??", HB_TAG('H','A','W',' ')},*/ /* Hawaiin */
-/*{"??", HB_TAG('H','B','N',' ')},*/ /* Hammer-Banna */
-/*{"??", HB_TAG('H','M','A',' ')},*/ /* High Mari */
-/*{"??", HB_TAG('H','N','D',' ')},*/ /* Hindko */
-/*{"??", HB_TAG('I','J','O',' ')},*/ /* Ijo */
-/*{"??", HB_TAG('I','L','O',' ')},*/ /* Ilokano */
-/*{"??", HB_TAG('I','R','T',' ')},*/ /* Irish Traditional */
-/*{"??", HB_TAG('J','U','L',' ')},*/ /* Jula */
-/*{"??", HB_TAG('K','A','R',' ')},*/ /* Karachay */
-/*{"??", HB_TAG('K','E','B',' ')},*/ /* Kebena */
-/*{"??", HB_TAG('K','G','E',' ')},*/ /* Khutsuri Georgian */
-/*{"??", HB_TAG('K','H','A',' ')},*/ /* Khakass */
-/*{"??", HB_TAG('K','H','K',' ')},*/ /* Khanty-Kazim */
-/*{"??", HB_TAG('K','H','S',' ')},*/ /* Khanty-Shurishkar */
-/*{"??", HB_TAG('K','H','V',' ')},*/ /* Khanty-Vakhi */
-/*{"??", HB_TAG('K','I','S',' ')},*/ /* Kisii */
-/*{"??", HB_TAG('K','K','N',' ')},*/ /* Kokni */
-/*{"??", HB_TAG('K','M','S',' ')},*/ /* Komso */
-/*{"??", HB_TAG('K','O','D',' ')},*/ /* Kodagu */
-/*{"??", HB_TAG('K','O','H',' ')},*/ /* Korean Old Hangul */
-/*{"??", HB_TAG('K','O','N',' ')},*/ /* Kikongo */
-/*{"??", HB_TAG('K','R','K',' ')},*/ /* Karakalpak */
-/*{"??", HB_TAG('K','R','N',' ')},*/ /* Karen */
-/*{"??", HB_TAG('K','U','L',' ')},*/ /* Kulvi */
-/*{"??", HB_TAG('L','A','H',' ')},*/ /* Lahuli */
-/*{"??", HB_TAG('L','A','M',' ')},*/ /* Lambani */
-/*{"??", HB_TAG('L','C','R',' ')},*/ /* L-Cree */
-/*{"??", HB_TAG('L','E','Z',' ')},*/ /* Lezgi */
-/*{"??", HB_TAG('L','M','A',' ')},*/ /* Low Mari */
-/*{"??", HB_TAG('L','U','B',' ')},*/ /* Luba */
-/*{"??", HB_TAG('L','U','G',' ')},*/ /* Luganda */
-/*{"??", HB_TAG('L','U','H',' ')},*/ /* Luhya */
-/*{"??", HB_TAG('M','A','K',' ')},*/ /* Makua */
-/*{"??", HB_TAG('M','A','L',' ')},*/ /* Malayalam Traditional */
-/*{"??", HB_TAG('M','B','N',' ')},*/ /* Mbundu */
-/*{"??", HB_TAG('M','I','Z',' ')},*/ /* Mizo */
-/*{"??", HB_TAG('M','L','N',' ')},*/ /* Malinke */
-/*{"??", HB_TAG('M','N','K',' ')},*/ /* Maninka */
-/*{"??", HB_TAG('M','O','R',' ')},*/ /* Moroccan */
-/*{"??", HB_TAG('N','A','G',' ')},*/ /* Naga-Assamese */
-/*{"??", HB_TAG('N','C','R',' ')},*/ /* N-Cree */
-/*{"??", HB_TAG('N','D','B',' ')},*/ /* Ndebele */
-/*{"??", HB_TAG('N','G','R',' ')},*/ /* Nagari */
-/*{"??", HB_TAG('N','H','C',' ')},*/ /* Norway House Cree */
-/*{"??", HB_TAG('N','K','L',' ')},*/ /* Nkole */
-/*{"??", HB_TAG('N','T','A',' ')},*/ /* Northern Tai */
-/*{"??", HB_TAG('O','C','R',' ')},*/ /* Oji-Cree */
-/*{"??", HB_TAG('P','A','A',' ')},*/ /* Palestinian Aramaic */
-/*{"??", HB_TAG('P','G','R',' ')},*/ /* Polytonic Greek */
-/*{"??", HB_TAG('P','L','G',' ')},*/ /* Palaung */
-/*{"??", HB_TAG('Q','I','N',' ')},*/ /* Chin */
-/*{"??", HB_TAG('R','B','U',' ')},*/ /* Russian Buriat */
-/*{"??", HB_TAG('R','C','R',' ')},*/ /* R-Cree */
-/*{"??", HB_TAG('R','M','S',' ')},*/ /* Rhaeto-Romanic */
-/*{"??", HB_TAG('R','U','A',' ')},*/ /* Ruanda */
-/*{"??", HB_TAG('S','A','Y',' ')},*/ /* Sayisi */
-/*{"??", HB_TAG('S','E','K',' ')},*/ /* Sekota */
-/*{"??", HB_TAG('S','I','G',' ')},*/ /* Silte Gurage */
-/*{"??", HB_TAG('S','L','A',' ')},*/ /* Slavey */
-/*{"??", HB_TAG('S','O','G',' ')},*/ /* Sodo Gurage */
-/*{"??", HB_TAG('S','O','T',' ')},*/ /* Sotho */
-/*{"??", HB_TAG('S','W','A',' ')},*/ /* Swadaya Aramaic */
-/*{"??", HB_TAG('S','W','Z',' ')},*/ /* Swazi */
-/*{"??", HB_TAG('S','X','T',' ')},*/ /* Sutu */
-/*{"??", HB_TAG('T','A','B',' ')},*/ /* Tabasaran */
-/*{"??", HB_TAG('T','C','R',' ')},*/ /* TH-Cree */
-/*{"??", HB_TAG('T','G','N',' ')},*/ /* Tongan */
-/*{"??", HB_TAG('T','M','N',' ')},*/ /* Temne */
-/*{"??", HB_TAG('T','N','E',' ')},*/ /* Tundra Nenets */
-/*{"??", HB_TAG('T','O','D',' ')},*/ /* Todo */
-/*{"??", HB_TAG('T','U','A',' ')},*/ /* Turoyo Aramaic */
-/*{"??", HB_TAG('T','U','V',' ')},*/ /* Tuvin */
-/*{"??", HB_TAG('W','C','R',' ')},*/ /* West-Cree */
-/*{"??", HB_TAG('X','B','D',' ')},*/ /* Tai Lue */
-/*{"??", HB_TAG('Y','C','R',' ')},*/ /* Y-Cree */
-/*{"??", HB_TAG('Y','I','C',' ')},*/ /* Yi Classic */
-/*{"??", HB_TAG('Y','I','M',' ')},*/ /* Yi Modern */
-/*{"??", HB_TAG('Z','H','P',' ')},*/ /* Chinese Phonetic */
-};
-
-static int
-lang_compare_first_component (const char *a,
- const char *b)
-{
- unsigned int da, db;
- const char *p;
-
- p = strstr (a, "-");
- da = p ? (unsigned int) (p - a) : strlen (a);
-
- p = strstr (b, "-");
- db = p ? (unsigned int) (p - b) : strlen (b);
-
- return strncmp (a, b, MAX (da, db));
-}
-
-static hb_bool_t
-lang_matches (const char *lang_str, const char *spec)
-{
- unsigned int len = strlen (spec);
-
- return lang_str && strncmp (lang_str, spec, len) == 0 &&
- (lang_str[len] == '\0' || lang_str[len] == '-');
-}
-
-hb_tag_t
-hb_ot_tag_from_language (hb_language_t language)
-{
- const char *lang_str;
- LangTag *lang_tag;
-
- if (language == NULL)
- return HB_OT_TAG_DEFAULT_LANGUAGE;
-
- lang_str = hb_language_to_string (language);
-
- if (0 == strncmp (lang_str, "x-hbot", 6)) {
- char tag[4];
- int i;
- lang_str += 6;
- for (i = 0; i < 4 && ISALPHA (lang_str[i]); i++)
- tag[i] = TOUPPER (lang_str[i]);
- for (; i < 4; i++)
- tag[i] = ' ';
- return HB_TAG_CHAR4 (tag);
- }
-
- /* find a language matching in the first component */
- lang_tag = bsearch (lang_str, ot_languages,
- ARRAY_LENGTH (ot_languages), sizeof (LangTag),
- (hb_compare_func_t) lang_compare_first_component);
-
- /* we now need to find the best language matching */
- if (lang_tag)
- {
- hb_bool_t found = FALSE;
-
- /* go to the final one matching in the first component */
- while (lang_tag + 1 < ot_languages + ARRAY_LENGTH (ot_languages) &&
- lang_compare_first_component (lang_str, (lang_tag + 1)->language) == 0)
- lang_tag++;
-
- /* go back, find which one matches completely */
- while (lang_tag >= ot_languages &&
- lang_compare_first_component (lang_str, lang_tag->language) == 0)
- {
- if (lang_matches (lang_str, lang_tag->language)) {
- found = TRUE;
- break;
- }
-
- lang_tag--;
- }
-
- if (!found)
- lang_tag = NULL;
- }
-
- if (lang_tag)
- return lang_tag->tag;
-
- return HB_OT_TAG_DEFAULT_LANGUAGE;
-}
-
-hb_language_t
-hb_ot_tag_to_language (hb_tag_t tag)
-{
- unsigned int i;
- unsigned char buf[11] = "x-hbot";
-
- for (i = 0; i < ARRAY_LENGTH (ot_languages); i++)
- if (ot_languages[i].tag == tag)
- return hb_language_from_string (ot_languages[i].language);
-
- buf[6] = tag >> 24;
- buf[7] = (tag >> 16) & 0xFF;
- buf[8] = (tag >> 8) & 0xFF;
- buf[9] = tag & 0xFF;
- buf[10] = '\0';
- return hb_language_from_string ((char *) buf);
-}
-
-
-HB_END_DECLS
diff --git a/src/hb-ot-tag.cc b/src/hb-ot-tag.cc
new file mode 100644
index 0000000..7db1885
--- /dev/null
+++ b/src/hb-ot-tag.cc
@@ -0,0 +1,677 @@
+/*
+ * Copyright (C) 2009 Red Hat, Inc.
+ *
+ * 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.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ */
+
+#include "hb-private.hh"
+#include "hb-ot.h"
+
+#include <string.h>
+
+HB_BEGIN_DECLS
+
+
+/* hb_script_t */
+
+static hb_tag_t
+hb_ot_old_tag_from_script (hb_script_t script)
+{
+ switch ((hb_tag_t) script) {
+ case HB_SCRIPT_COPTIC: return HB_TAG('c','o','p','t');
+ case HB_SCRIPT_HIRAGANA: return HB_TAG('k','a','n','a');
+ case HB_SCRIPT_LAO: return HB_TAG('l','a','o',' ');
+ case HB_SCRIPT_YI: return HB_TAG('y','i',' ',' ');
+ /* Unicode-5.0 additions */
+ case HB_SCRIPT_NKO: return HB_TAG('n','k','o',' ');
+ /* Unicode-5.1 additions */
+ case HB_SCRIPT_VAI: return HB_TAG('v','a','i',' ');
+ /* Unicode-5.2 additions */
+ case HB_SCRIPT_MEETEI_MAYEK: return HB_TAG('m','y','e','i');
+ /* Unicode-6.0 additions */
+ }
+
+ /* Else, just change first char to lowercase and return */
+ return ((hb_tag_t) script) | 0x20000000;
+}
+
+static hb_script_t
+hb_ot_old_tag_to_script (hb_tag_t tag)
+{
+ switch (tag) {
+ case HB_TAG('c','o','p','t'): return HB_SCRIPT_COPTIC;
+ case HB_TAG('k','a','n','a'): return HB_SCRIPT_HIRAGANA;
+ case HB_TAG('l','a','o',' '): return HB_SCRIPT_LAO;
+ case HB_TAG('y','i',' ',' '): return HB_SCRIPT_YI;
+ /* Unicode-5.0 additions */
+ case HB_TAG('n','k','o',' '): return HB_SCRIPT_NKO;
+ /* Unicode-5.1 additions */
+ case HB_TAG('v','a','i',' '): return HB_SCRIPT_VAI;
+ /* Unicode-5.2 additions */
+ case HB_TAG('m','y','e','i'): return HB_SCRIPT_MEETEI_MAYEK;
+ /* Unicode-6.0 additions */
+ }
+
+ /* Else, just change first char to uppercase and return */
+ return (hb_script_t) (tag & ~0x20000000);
+}
+
+static hb_tag_t
+hb_ot_new_tag_from_script (hb_script_t script)
+{
+ switch ((hb_tag_t) script) {
+ case HB_SCRIPT_BENGALI: return HB_TAG('b','n','g','2');
+ case HB_SCRIPT_DEVANAGARI: return HB_TAG('d','e','v','2');
+ case HB_SCRIPT_GUJARATI: return HB_TAG('g','j','r','2');
+ case HB_SCRIPT_GURMUKHI: return HB_TAG('g','u','r','2');
+ case HB_SCRIPT_KANNADA: return HB_TAG('k','n','d','2');
+ case HB_SCRIPT_MALAYALAM: return HB_TAG('m','l','m','2');
+ case HB_SCRIPT_ORIYA: return HB_TAG('o','r','y','2');
+ case HB_SCRIPT_TAMIL: return HB_TAG('t','m','l','2');
+ case HB_SCRIPT_TELUGU: return HB_TAG('t','e','l','2');
+ }
+
+ return HB_TAG_NONE;
+}
+
+static hb_script_t
+hb_ot_new_tag_to_script (hb_tag_t tag)
+{
+ switch (tag) {
+ case HB_TAG('b','n','g','2'): return HB_SCRIPT_BENGALI;
+ case HB_TAG('d','e','v','2'): return HB_SCRIPT_DEVANAGARI;
+ case HB_TAG('g','j','r','2'): return HB_SCRIPT_GUJARATI;
+ case HB_TAG('g','u','r','2'): return HB_SCRIPT_GURMUKHI;
+ case HB_TAG('k','n','d','2'): return HB_SCRIPT_KANNADA;
+ case HB_TAG('m','l','m','2'): return HB_SCRIPT_MALAYALAM;
+ case HB_TAG('o','r','y','2'): return HB_SCRIPT_ORIYA;
+ case HB_TAG('t','m','l','2'): return HB_SCRIPT_TAMIL;
+ case HB_TAG('t','e','l','2'): return HB_SCRIPT_TELUGU;
+ }
+
+ return HB_SCRIPT_UNKNOWN;
+}
+
+/*
+ * Complete list at:
+ * http://www.microsoft.com/typography/otspec/scripttags.htm
+ *
+ * Most of the script tags are the same as the ISO 15924 tag but lowercased.
+ * So we just do that, and handle the exceptional cases in a switch.
+ */
+
+void
+hb_ot_tags_from_script (hb_script_t script,
+ hb_tag_t *script_tag_1,
+ hb_tag_t *script_tag_2)
+{
+ hb_tag_t new_tag;
+
+ *script_tag_2 = HB_TAG_NONE;
+ *script_tag_1 = hb_ot_old_tag_from_script (script);
+
+ new_tag = hb_ot_new_tag_from_script (script);
+ if (unlikely (new_tag != HB_TAG_NONE)) {
+ *script_tag_2 = *script_tag_1;
+ *script_tag_1 = new_tag;
+ }
+}
+
+hb_script_t
+hb_ot_tag_to_script (hb_tag_t tag)
+{
+ if (unlikely ((tag & 0x000000FF) == '2'))
+ return hb_ot_new_tag_to_script (tag);
+
+ return hb_ot_old_tag_to_script (tag);
+}
+
+
+/* hb_language_t */
+
+typedef struct {
+ char language[6];
+ hb_tag_t tag;
+} LangTag;
+
+/*
+ * Complete list at:
+ * http://www.microsoft.com/typography/otspec/languagetags.htm
+ *
+ * Generated by intersecting the OpenType language tag list from
+ * Draft OpenType 1.5 spec, with with the ISO 639-3 codes from
+ * 2008/08/04, matching on name, and finally adjusted manually.
+ *
+ * Many items still missing. Those are commented out at the end.
+ * Keep sorted for bsearch.
+ */
+static const LangTag ot_languages[] = {
+ {"aa", HB_TAG('A','F','R',' ')}, /* Afar */
+ {"ab", HB_TAG('A','B','K',' ')}, /* Abkhazian */
+ {"abq", HB_TAG('A','B','A',' ')}, /* Abaza */
+ {"ady", HB_TAG('A','D','Y',' ')}, /* Adyghe */
+ {"af", HB_TAG('A','F','K',' ')}, /* Afrikaans */
+ {"aiw", HB_TAG('A','R','I',' ')}, /* Aari */
+ {"am", HB_TAG('A','M','H',' ')}, /* Amharic */
+ {"ar", HB_TAG('A','R','A',' ')}, /* Arabic */
+ {"arn", HB_TAG('M','A','P',' ')}, /* Mapudungun */
+ {"as", HB_TAG('A','S','M',' ')}, /* Assamese */
+ {"av", HB_TAG('A','V','R',' ')}, /* Avaric */
+ {"awa", HB_TAG('A','W','A',' ')}, /* Awadhi */
+ {"ay", HB_TAG('A','Y','M',' ')}, /* Aymara */
+ {"az", HB_TAG('A','Z','E',' ')}, /* Azerbaijani */
+ {"ba", HB_TAG('B','S','H',' ')}, /* Bashkir */
+ {"bal", HB_TAG('B','L','I',' ')}, /* Baluchi */
+ {"bcq", HB_TAG('B','C','H',' ')}, /* Bench */
+ {"bem", HB_TAG('B','E','M',' ')}, /* Bemba (Zambia) */
+ {"bfq", HB_TAG('B','A','D',' ')}, /* Badaga */
+ {"bft", HB_TAG('B','L','T',' ')}, /* Balti */
+ {"bg", HB_TAG('B','G','R',' ')}, /* Bulgarian */
+ {"bhb", HB_TAG('B','H','I',' ')}, /* Bhili */
+ {"bho", HB_TAG('B','H','O',' ')}, /* Bhojpuri */
+ {"bik", HB_TAG('B','I','K',' ')}, /* Bikol */
+ {"bin", HB_TAG('E','D','O',' ')}, /* Bini */
+ {"bm", HB_TAG('B','M','B',' ')}, /* Bambara */
+ {"bn", HB_TAG('B','E','N',' ')}, /* Bengali */
+ {"bo", HB_TAG('T','I','B',' ')}, /* Tibetan */
+ {"br", HB_TAG('B','R','E',' ')}, /* Breton */
+ {"brh", HB_TAG('B','R','H',' ')}, /* Brahui */
+ {"bs", HB_TAG('B','O','S',' ')}, /* Bosnian */
+ {"btb", HB_TAG('B','T','I',' ')}, /* Beti (Cameroon) */
+ {"ca", HB_TAG('C','A','T',' ')}, /* Catalan */
+ {"ce", HB_TAG('C','H','E',' ')}, /* Chechen */
+ {"ceb", HB_TAG('C','E','B',' ')}, /* Cebuano */
+ {"chp", HB_TAG('C','H','P',' ')}, /* Chipewyan */
+ {"chr", HB_TAG('C','H','R',' ')}, /* Cherokee */
+ {"cop", HB_TAG('C','O','P',' ')}, /* Coptic */
+ {"cr", HB_TAG('C','R','E',' ')}, /* Cree */
+ {"crh", HB_TAG('C','R','T',' ')}, /* Crimean Tatar */
+ {"crm", HB_TAG('M','C','R',' ')}, /* Moose Cree */
+ {"crx", HB_TAG('C','R','R',' ')}, /* Carrier */
+ {"cs", HB_TAG('C','S','Y',' ')}, /* Czech */
+ {"cu", HB_TAG('C','S','L',' ')}, /* Church Slavic */
+ {"cv", HB_TAG('C','H','U',' ')}, /* Chuvash */
+ {"cwd", HB_TAG('D','C','R',' ')}, /* Woods Cree */
+ {"cy", HB_TAG('W','E','L',' ')}, /* Welsh */
+ {"da", HB_TAG('D','A','N',' ')}, /* Danish */
+ {"dap", HB_TAG('N','I','S',' ')}, /* Nisi (India) */
+ {"dar", HB_TAG('D','A','R',' ')}, /* Dargwa */
+ {"de", HB_TAG('D','E','U',' ')}, /* German */
+ {"din", HB_TAG('D','N','K',' ')}, /* Dinka */
+ {"dng", HB_TAG('D','U','N',' ')}, /* Dungan */
+ {"doi", HB_TAG('D','G','R',' ')}, /* Dogri */
+ {"dsb", HB_TAG('L','S','B',' ')}, /* Lower Sorbian */
+ {"dv", HB_TAG('D','I','V',' ')}, /* Dhivehi */
+ {"dz", HB_TAG('D','Z','N',' ')}, /* Dzongkha */
+ {"ee", HB_TAG('E','W','E',' ')}, /* Ewe */
+ {"efi", HB_TAG('E','F','I',' ')}, /* Efik */
+ {"el", HB_TAG('E','L','L',' ')}, /* Modern Greek (1453-) */
+ {"en", HB_TAG('E','N','G',' ')}, /* English */
+ {"eo", HB_TAG('N','T','O',' ')}, /* Esperanto */
+ {"eot", HB_TAG('B','T','I',' ')}, /* Beti (Côte d'Ivoire) */
+ {"es", HB_TAG('E','S','P',' ')}, /* Spanish */
+ {"et", HB_TAG('E','T','I',' ')}, /* Estonian */
+ {"eu", HB_TAG('E','U','Q',' ')}, /* Basque */
+ {"eve", HB_TAG('E','V','N',' ')}, /* Even */
+ {"evn", HB_TAG('E','V','K',' ')}, /* Evenki */
+ {"fa", HB_TAG('F','A','R',' ')}, /* Persian */
+ {"ff", HB_TAG('F','U','L',' ')}, /* Fulah */
+ {"fi", HB_TAG('F','I','N',' ')}, /* Finnish */
+ {"fil", HB_TAG('P','I','L',' ')}, /* Filipino */
+ {"fj", HB_TAG('F','J','I',' ')}, /* Fijian */
+ {"fo", HB_TAG('F','O','S',' ')}, /* Faroese */
+ {"fon", HB_TAG('F','O','N',' ')}, /* Fon */
+ {"fr", HB_TAG('F','R','A',' ')}, /* French */
+ {"fur", HB_TAG('F','R','L',' ')}, /* Friulian */
+ {"fy", HB_TAG('F','R','I',' ')}, /* Western Frisian */
+ {"ga", HB_TAG('I','R','I',' ')}, /* Irish */
+ {"gaa", HB_TAG('G','A','D',' ')}, /* Ga */
+ {"gag", HB_TAG('G','A','G',' ')}, /* Gagauz */
+ {"gbm", HB_TAG('G','A','W',' ')}, /* Garhwali */
+ {"gd", HB_TAG('G','A','E',' ')}, /* Scottish Gaelic */
+ {"gl", HB_TAG('G','A','L',' ')}, /* Galician */
+ {"gld", HB_TAG('N','A','N',' ')}, /* Nanai */
+ {"gn", HB_TAG('G','U','A',' ')}, /* Guarani */
+ {"gon", HB_TAG('G','O','N',' ')}, /* Gondi */
+ {"grt", HB_TAG('G','R','O',' ')}, /* Garo */
+ {"gu", HB_TAG('G','U','J',' ')}, /* Gujarati */
+ {"guk", HB_TAG('G','M','Z',' ')}, /* Gumuz */
+ {"gv", HB_TAG('M','N','X',' ')}, /* Manx Gaelic */
+ {"ha", HB_TAG('H','A','U',' ')}, /* Hausa */
+ {"har", HB_TAG('H','R','I',' ')}, /* Harari */
+ {"he", HB_TAG('I','W','R',' ')}, /* Hebrew */
+ {"hi", HB_TAG('H','I','N',' ')}, /* Hindi */
+ {"hil", HB_TAG('H','I','L',' ')}, /* Hiligaynon */
+ {"hoc", HB_TAG('H','O',' ',' ')}, /* Ho */
+ {"hr", HB_TAG('H','R','V',' ')}, /* Croatian */
+ {"hsb", HB_TAG('U','S','B',' ')}, /* Upper Sorbian */
+ {"ht", HB_TAG('H','A','I',' ')}, /* Haitian */
+ {"hu", HB_TAG('H','U','N',' ')}, /* Hungarian */
+ {"hy", HB_TAG('H','Y','E',' ')}, /* Armenian */
+ {"id", HB_TAG('I','N','D',' ')}, /* Indonesian */
+ {"ig", HB_TAG('I','B','O',' ')}, /* Igbo */
+ {"igb", HB_TAG('E','B','I',' ')}, /* Ebira */
+ {"inh", HB_TAG('I','N','G',' ')}, /* Ingush */
+ {"is", HB_TAG('I','S','L',' ')}, /* Icelandic */
+ {"it", HB_TAG('I','T','A',' ')}, /* Italian */
+ {"iu", HB_TAG('I','N','U',' ')}, /* Inuktitut */
+ {"ja", HB_TAG('J','A','N',' ')}, /* Japanese */
+ {"jv", HB_TAG('J','A','V',' ')}, /* Javanese */
+ {"ka", HB_TAG('K','A','T',' ')}, /* Georgian */
+ {"kam", HB_TAG('K','M','B',' ')}, /* Kamba (Kenya) */
+ {"kbd", HB_TAG('K','A','B',' ')}, /* Kabardian */
+ {"kdr", HB_TAG('K','R','M',' ')}, /* Karaim */
+ {"kdt", HB_TAG('K','U','Y',' ')}, /* Kuy */
+ {"kfr", HB_TAG('K','A','C',' ')}, /* Kachchi */
+ {"kfy", HB_TAG('K','M','N',' ')}, /* Kumaoni */
+ {"kha", HB_TAG('K','S','I',' ')}, /* Khasi */
+ {"khw", HB_TAG('K','H','W',' ')}, /* Khowar */
+ {"ki", HB_TAG('K','I','K',' ')}, /* Kikuyu */
+ {"kk", HB_TAG('K','A','Z',' ')}, /* Kazakh */
+ {"kl", HB_TAG('G','R','N',' ')}, /* Kalaallisut */
+ {"kln", HB_TAG('K','A','L',' ')}, /* Kalenjin */
+ {"km", HB_TAG('K','H','M',' ')}, /* Central Khmer */
+ {"kmw", HB_TAG('K','M','O',' ')}, /* Komo (Democratic Republic of Congo) */
+ {"kn", HB_TAG('K','A','N',' ')}, /* Kannada */
+ {"ko", HB_TAG('K','O','R',' ')}, /* Korean */
+ {"koi", HB_TAG('K','O','P',' ')}, /* Komi-Permyak */
+ {"kok", HB_TAG('K','O','K',' ')}, /* Konkani */
+ {"kpe", HB_TAG('K','P','L',' ')}, /* Kpelle */
+ {"kpv", HB_TAG('K','O','Z',' ')}, /* Komi-Zyrian */
+ {"kpy", HB_TAG('K','Y','K',' ')}, /* Koryak */
+ {"kqy", HB_TAG('K','R','T',' ')}, /* Koorete */
+ {"kr", HB_TAG('K','N','R',' ')}, /* Kanuri */
+ {"kri", HB_TAG('K','R','I',' ')}, /* Krio */
+ {"krl", HB_TAG('K','R','L',' ')}, /* Karelian */
+ {"kru", HB_TAG('K','U','U',' ')}, /* Kurukh */
+ {"ks", HB_TAG('K','S','H',' ')}, /* Kashmiri */
+ {"ku", HB_TAG('K','U','R',' ')}, /* Kurdish */
+ {"kum", HB_TAG('K','U','M',' ')}, /* Kumyk */
+ {"kvd", HB_TAG('K','U','I',' ')}, /* Kui (Indonesia) */
+ {"kxu", HB_TAG('K','U','I',' ')}, /* Kui (India) */
+ {"ky", HB_TAG('K','I','R',' ')}, /* Kirghiz */
+ {"la", HB_TAG('L','A','T',' ')}, /* Latin */
+ {"lad", HB_TAG('J','U','D',' ')}, /* Ladino */
+ {"lb", HB_TAG('L','T','Z',' ')}, /* Luxembourgish */
+ {"lbe", HB_TAG('L','A','K',' ')}, /* Lak */
+ {"lbj", HB_TAG('L','D','K',' ')}, /* Ladakhi */
+ {"lif", HB_TAG('L','M','B',' ')}, /* Limbu */
+ {"lld", HB_TAG('L','A','D',' ')}, /* Ladin */
+ {"ln", HB_TAG('L','I','N',' ')}, /* Lingala */
+ {"lo", HB_TAG('L','A','O',' ')}, /* Lao */
+ {"lt", HB_TAG('L','T','H',' ')}, /* Lithuanian */
+ {"luo", HB_TAG('L','U','O',' ')}, /* Luo (Kenya and Tanzania) */
+ {"luw", HB_TAG('L','U','O',' ')}, /* Luo (Cameroon) */
+ {"lv", HB_TAG('L','V','I',' ')}, /* Latvian */
+ {"lzz", HB_TAG('L','A','Z',' ')}, /* Laz */
+ {"mai", HB_TAG('M','T','H',' ')}, /* Maithili */
+ {"mdc", HB_TAG('M','L','E',' ')}, /* Male (Papua New Guinea) */
+ {"mdf", HB_TAG('M','O','K',' ')}, /* Moksha */
+ {"mdy", HB_TAG('M','L','E',' ')}, /* Male (Ethiopia) */
+ {"men", HB_TAG('M','D','E',' ')}, /* Mende (Sierra Leone) */
+ {"mg", HB_TAG('M','L','G',' ')}, /* Malagasy */
+ {"mi", HB_TAG('M','R','I',' ')}, /* Maori */
+ {"mk", HB_TAG('M','K','D',' ')}, /* Macedonian */
+ {"ml", HB_TAG('M','L','R',' ')}, /* Malayalam */
+ {"mn", HB_TAG('M','N','G',' ')}, /* Mongolian */
+ {"mnc", HB_TAG('M','C','H',' ')}, /* Manchu */
+ {"mni", HB_TAG('M','N','I',' ')}, /* Manipuri */
+ {"mnk", HB_TAG('M','N','D',' ')}, /* Mandinka */
+ {"mns", HB_TAG('M','A','N',' ')}, /* Mansi */
+ {"mnw", HB_TAG('M','O','N',' ')}, /* Mon */
+ {"mo", HB_TAG('M','O','L',' ')}, /* Moldavian */
+ {"moh", HB_TAG('M','O','H',' ')}, /* Mohawk */
+ {"mpe", HB_TAG('M','A','J',' ')}, /* Majang */
+ {"mr", HB_TAG('M','A','R',' ')}, /* Marathi */
+ {"ms", HB_TAG('M','L','Y',' ')}, /* Malay */
+ {"mt", HB_TAG('M','T','S',' ')}, /* Maltese */
+ {"mwr", HB_TAG('M','A','W',' ')}, /* Marwari */
+ {"my", HB_TAG('B','R','M',' ')}, /* Burmese */
+ {"mym", HB_TAG('M','E','N',' ')}, /* Me'en */
+ {"myv", HB_TAG('E','R','Z',' ')}, /* Erzya */
+ {"nb", HB_TAG('N','O','R',' ')}, /* Norwegian Bokmål */
+ {"nco", HB_TAG('S','I','B',' ')}, /* Sibe */
+ {"ne", HB_TAG('N','E','P',' ')}, /* Nepali */
+ {"new", HB_TAG('N','E','W',' ')}, /* Newari */
+ {"ng", HB_TAG('N','D','G',' ')}, /* Ndonga */
+ {"ngl", HB_TAG('L','M','W',' ')}, /* Lomwe */
+ {"niu", HB_TAG('N','I','U',' ')}, /* Niuean */
+ {"niv", HB_TAG('G','I','L',' ')}, /* Gilyak */
+ {"nl", HB_TAG('N','L','D',' ')}, /* Dutch */
+ {"nn", HB_TAG('N','Y','N',' ')}, /* Norwegian Nynorsk */
+ {"no", HB_TAG('N','O','R',' ')}, /* Norwegian (deprecated) */
+ {"nog", HB_TAG('N','O','G',' ')}, /* Nogai */
+ {"nqo", HB_TAG('N','K','O',' ')}, /* N'Ko */
+ {"nsk", HB_TAG('N','A','S',' ')}, /* Naskapi */
+ {"ny", HB_TAG('C','H','I',' ')}, /* Nyanja */
+ {"oc", HB_TAG('O','C','I',' ')}, /* Occitan (post 1500) */
+ {"oj", HB_TAG('O','J','B',' ')}, /* Ojibwa */
+ {"om", HB_TAG('O','R','O',' ')}, /* Oromo */
+ {"or", HB_TAG('O','R','I',' ')}, /* Oriya */
+ {"os", HB_TAG('O','S','S',' ')}, /* Ossetian */
+ {"pa", HB_TAG('P','A','N',' ')}, /* Panjabi */
+ {"pi", HB_TAG('P','A','L',' ')}, /* Pali */
+ {"pl", HB_TAG('P','L','K',' ')}, /* Polish */
+ {"plp", HB_TAG('P','A','P',' ')}, /* Palpa */
+ {"prs", HB_TAG('D','R','I',' ')}, /* Dari */
+ {"ps", HB_TAG('P','A','S',' ')}, /* Pushto */
+ {"pt", HB_TAG('P','T','G',' ')}, /* Portuguese */
+ {"raj", HB_TAG('R','A','J',' ')}, /* Rajasthani */
+ {"ria", HB_TAG('R','I','A',' ')}, /* Riang (India) */
+ {"ril", HB_TAG('R','I','A',' ')}, /* Riang (Myanmar) */
+ {"ro", HB_TAG('R','O','M',' ')}, /* Romanian */
+ {"rom", HB_TAG('R','O','Y',' ')}, /* Romany */
+ {"ru", HB_TAG('R','U','S',' ')}, /* Russian */
+ {"rue", HB_TAG('R','S','Y',' ')}, /* Rusyn */
+ {"sa", HB_TAG('S','A','N',' ')}, /* Sanskrit */
+ {"sah", HB_TAG('Y','A','K',' ')}, /* Yakut */
+ {"sat", HB_TAG('S','A','T',' ')}, /* Santali */
+ {"sck", HB_TAG('S','A','D',' ')}, /* Sadri */
+ {"sd", HB_TAG('S','N','D',' ')}, /* Sindhi */
+ {"se", HB_TAG('N','S','M',' ')}, /* Northern Sami */
+ {"seh", HB_TAG('S','N','A',' ')}, /* Sena */
+ {"sel", HB_TAG('S','E','L',' ')}, /* Selkup */
+ {"sg", HB_TAG('S','G','O',' ')}, /* Sango */
+ {"shn", HB_TAG('S','H','N',' ')}, /* Shan */
+ {"si", HB_TAG('S','N','H',' ')}, /* Sinhala */
+ {"sid", HB_TAG('S','I','D',' ')}, /* Sidamo */
+ {"sjd", HB_TAG('K','S','M',' ')}, /* Kildin Sami */
+ {"sk", HB_TAG('S','K','Y',' ')}, /* Slovak */
+ {"skr", HB_TAG('S','R','K',' ')}, /* Seraiki */
+ {"sl", HB_TAG('S','L','V',' ')}, /* Slovenian */
+ {"sm", HB_TAG('S','M','O',' ')}, /* Samoan */
+ {"sma", HB_TAG('S','S','M',' ')}, /* Southern Sami */
+ {"smj", HB_TAG('L','S','M',' ')}, /* Lule Sami */
+ {"smn", HB_TAG('I','S','M',' ')}, /* Inari Sami */
+ {"sms", HB_TAG('S','K','S',' ')}, /* Skolt Sami */
+ {"snk", HB_TAG('S','N','K',' ')}, /* Soninke */
+ {"so", HB_TAG('S','M','L',' ')}, /* Somali */
+ {"sq", HB_TAG('S','Q','I',' ')}, /* Albanian */
+ {"sr", HB_TAG('S','R','B',' ')}, /* Serbian */
+ {"srr", HB_TAG('S','R','R',' ')}, /* Serer */
+ {"suq", HB_TAG('S','U','R',' ')}, /* Suri */
+ {"sv", HB_TAG('S','V','E',' ')}, /* Swedish */
+ {"sva", HB_TAG('S','V','A',' ')}, /* Svan */
+ {"sw", HB_TAG('S','W','K',' ')}, /* Swahili */
+ {"swb", HB_TAG('C','M','R',' ')}, /* Comorian */
+ {"syr", HB_TAG('S','Y','R',' ')}, /* Syriac */
+ {"ta", HB_TAG('T','A','M',' ')}, /* Tamil */
+ {"tcy", HB_TAG('T','U','L',' ')}, /* Tulu */
+ {"te", HB_TAG('T','E','L',' ')}, /* Telugu */
+ {"tg", HB_TAG('T','A','J',' ')}, /* Tajik */
+ {"th", HB_TAG('T','H','A',' ')}, /* Thai */
+ {"ti", HB_TAG('T','G','Y',' ')}, /* Tigrinya */
+ {"tig", HB_TAG('T','G','R',' ')}, /* Tigre */
+ {"tk", HB_TAG('T','K','M',' ')}, /* Turkmen */
+ {"tn", HB_TAG('T','N','A',' ')}, /* Tswana */
+ {"tnz", HB_TAG('T','N','G',' ')}, /* Tonga (Thailand) */
+ {"to", HB_TAG('T','N','G',' ')}, /* Tonga (Tonga Islands) */
+ {"tog", HB_TAG('T','N','G',' ')}, /* Tonga (Nyasa) */
+ {"toi", HB_TAG('T','N','G',' ')}, /* Tonga (Zambia) */
+ {"tr", HB_TAG('T','R','K',' ')}, /* Turkish */
+ {"ts", HB_TAG('T','S','G',' ')}, /* Tsonga */
+ {"tt", HB_TAG('T','A','T',' ')}, /* Tatar */
+ {"tw", HB_TAG('T','W','I',' ')}, /* Twi */
+ {"ty", HB_TAG('T','H','T',' ')}, /* Tahitian */
+ {"udm", HB_TAG('U','D','M',' ')}, /* Udmurt */
+ {"ug", HB_TAG('U','Y','G',' ')}, /* Uighur */
+ {"uk", HB_TAG('U','K','R',' ')}, /* Ukrainian */
+ {"unr", HB_TAG('M','U','N',' ')}, /* Mundari */
+ {"ur", HB_TAG('U','R','D',' ')}, /* Urdu */
+ {"uz", HB_TAG('U','Z','B',' ')}, /* Uzbek */
+ {"ve", HB_TAG('V','E','N',' ')}, /* Venda */
+ {"vi", HB_TAG('V','I','T',' ')}, /* Vietnamese */
+ {"wbm", HB_TAG('W','A',' ',' ')}, /* Wa */
+ {"wbr", HB_TAG('W','A','G',' ')}, /* Wagdi */
+ {"wo", HB_TAG('W','L','F',' ')}, /* Wolof */
+ {"xal", HB_TAG('K','L','M',' ')}, /* Kalmyk */
+ {"xh", HB_TAG('X','H','S',' ')}, /* Xhosa */
+ {"xom", HB_TAG('K','M','O',' ')}, /* Komo (Sudan) */
+ {"xsl", HB_TAG('S','S','L',' ')}, /* South Slavey */
+ {"yi", HB_TAG('J','I','I',' ')}, /* Yiddish */
+ {"yo", HB_TAG('Y','B','A',' ')}, /* Yoruba */
+ {"yso", HB_TAG('N','I','S',' ')}, /* Nisi (China) */
+ {"zh-cn", HB_TAG('Z','H','S',' ')}, /* Chinese (China) */
+ {"zh-hk", HB_TAG('Z','H','H',' ')}, /* Chinese (Hong Kong) */
+ {"zh-mo", HB_TAG('Z','H','T',' ')}, /* Chinese (Macao) */
+ {"zh-sg", HB_TAG('Z','H','S',' ')}, /* Chinese (Singapore) */
+ {"zh-tw", HB_TAG('Z','H','T',' ')}, /* Chinese (Taiwan) */
+ {"zne", HB_TAG('Z','N','D',' ')}, /* Zande */
+ {"zu", HB_TAG('Z','U','L',' ')} /* Zulu */
+
+ /* I couldn't find the language id for these */
+
+/*{"??", HB_TAG('A','G','W',' ')},*/ /* Agaw */
+/*{"??", HB_TAG('A','L','S',' ')},*/ /* Alsatian */
+/*{"??", HB_TAG('A','L','T',' ')},*/ /* Altai */
+/*{"??", HB_TAG('A','R','K',' ')},*/ /* Arakanese */
+/*{"??", HB_TAG('A','T','H',' ')},*/ /* Athapaskan */
+/*{"??", HB_TAG('B','A','G',' ')},*/ /* Baghelkhandi */
+/*{"??", HB_TAG('B','A','L',' ')},*/ /* Balkar */
+/*{"??", HB_TAG('B','A','U',' ')},*/ /* Baule */
+/*{"??", HB_TAG('B','B','R',' ')},*/ /* Berber */
+/*{"??", HB_TAG('B','C','R',' ')},*/ /* Bible Cree */
+/*{"??", HB_TAG('B','E','L',' ')},*/ /* Belarussian */
+/*{"??", HB_TAG('B','I','L',' ')},*/ /* Bilen */
+/*{"??", HB_TAG('B','K','F',' ')},*/ /* Blackfoot */
+/*{"??", HB_TAG('B','L','N',' ')},*/ /* Balante */
+/*{"??", HB_TAG('B','M','L',' ')},*/ /* Bamileke */
+/*{"??", HB_TAG('B','R','I',' ')},*/ /* Braj Bhasha */
+/*{"??", HB_TAG('C','H','G',' ')},*/ /* Chaha Gurage */
+/*{"??", HB_TAG('C','H','H',' ')},*/ /* Chattisgarhi */
+/*{"??", HB_TAG('C','H','K',' ')},*/ /* Chukchi */
+/*{"??", HB_TAG('D','J','R',' ')},*/ /* Djerma */
+/*{"??", HB_TAG('D','N','G',' ')},*/ /* Dangme */
+/*{"??", HB_TAG('E','C','R',' ')},*/ /* Eastern Cree */
+/*{"??", HB_TAG('F','A','N',' ')},*/ /* French Antillean */
+/*{"??", HB_TAG('F','L','E',' ')},*/ /* Flemish */
+/*{"??", HB_TAG('F','N','E',' ')},*/ /* Forest Nenets */
+/*{"??", HB_TAG('F','T','A',' ')},*/ /* Futa */
+/*{"??", HB_TAG('G','A','R',' ')},*/ /* Garshuni */
+/*{"??", HB_TAG('G','E','Z',' ')},*/ /* Ge'ez */
+/*{"??", HB_TAG('H','A','L',' ')},*/ /* Halam */
+/*{"??", HB_TAG('H','A','R',' ')},*/ /* Harauti */
+/*{"??", HB_TAG('H','A','W',' ')},*/ /* Hawaiin */
+/*{"??", HB_TAG('H','B','N',' ')},*/ /* Hammer-Banna */
+/*{"??", HB_TAG('H','M','A',' ')},*/ /* High Mari */
+/*{"??", HB_TAG('H','N','D',' ')},*/ /* Hindko */
+/*{"??", HB_TAG('I','J','O',' ')},*/ /* Ijo */
+/*{"??", HB_TAG('I','L','O',' ')},*/ /* Ilokano */
+/*{"??", HB_TAG('I','R','T',' ')},*/ /* Irish Traditional */
+/*{"??", HB_TAG('J','U','L',' ')},*/ /* Jula */
+/*{"??", HB_TAG('K','A','R',' ')},*/ /* Karachay */
+/*{"??", HB_TAG('K','E','B',' ')},*/ /* Kebena */
+/*{"??", HB_TAG('K','G','E',' ')},*/ /* Khutsuri Georgian */
+/*{"??", HB_TAG('K','H','A',' ')},*/ /* Khakass */
+/*{"??", HB_TAG('K','H','K',' ')},*/ /* Khanty-Kazim */
+/*{"??", HB_TAG('K','H','S',' ')},*/ /* Khanty-Shurishkar */
+/*{"??", HB_TAG('K','H','V',' ')},*/ /* Khanty-Vakhi */
+/*{"??", HB_TAG('K','I','S',' ')},*/ /* Kisii */
+/*{"??", HB_TAG('K','K','N',' ')},*/ /* Kokni */
+/*{"??", HB_TAG('K','M','S',' ')},*/ /* Komso */
+/*{"??", HB_TAG('K','O','D',' ')},*/ /* Kodagu */
+/*{"??", HB_TAG('K','O','H',' ')},*/ /* Korean Old Hangul */
+/*{"??", HB_TAG('K','O','N',' ')},*/ /* Kikongo */
+/*{"??", HB_TAG('K','R','K',' ')},*/ /* Karakalpak */
+/*{"??", HB_TAG('K','R','N',' ')},*/ /* Karen */
+/*{"??", HB_TAG('K','U','L',' ')},*/ /* Kulvi */
+/*{"??", HB_TAG('L','A','H',' ')},*/ /* Lahuli */
+/*{"??", HB_TAG('L','A','M',' ')},*/ /* Lambani */
+/*{"??", HB_TAG('L','C','R',' ')},*/ /* L-Cree */
+/*{"??", HB_TAG('L','E','Z',' ')},*/ /* Lezgi */
+/*{"??", HB_TAG('L','M','A',' ')},*/ /* Low Mari */
+/*{"??", HB_TAG('L','U','B',' ')},*/ /* Luba */
+/*{"??", HB_TAG('L','U','G',' ')},*/ /* Luganda */
+/*{"??", HB_TAG('L','U','H',' ')},*/ /* Luhya */
+/*{"??", HB_TAG('M','A','K',' ')},*/ /* Makua */
+/*{"??", HB_TAG('M','A','L',' ')},*/ /* Malayalam Traditional */
+/*{"??", HB_TAG('M','B','N',' ')},*/ /* Mbundu */
+/*{"??", HB_TAG('M','I','Z',' ')},*/ /* Mizo */
+/*{"??", HB_TAG('M','L','N',' ')},*/ /* Malinke */
+/*{"??", HB_TAG('M','N','K',' ')},*/ /* Maninka */
+/*{"??", HB_TAG('M','O','R',' ')},*/ /* Moroccan */
+/*{"??", HB_TAG('N','A','G',' ')},*/ /* Naga-Assamese */
+/*{"??", HB_TAG('N','C','R',' ')},*/ /* N-Cree */
+/*{"??", HB_TAG('N','D','B',' ')},*/ /* Ndebele */
+/*{"??", HB_TAG('N','G','R',' ')},*/ /* Nagari */
+/*{"??", HB_TAG('N','H','C',' ')},*/ /* Norway House Cree */
+/*{"??", HB_TAG('N','K','L',' ')},*/ /* Nkole */
+/*{"??", HB_TAG('N','T','A',' ')},*/ /* Northern Tai */
+/*{"??", HB_TAG('O','C','R',' ')},*/ /* Oji-Cree */
+/*{"??", HB_TAG('P','A','A',' ')},*/ /* Palestinian Aramaic */
+/*{"??", HB_TAG('P','G','R',' ')},*/ /* Polytonic Greek */
+/*{"??", HB_TAG('P','L','G',' ')},*/ /* Palaung */
+/*{"??", HB_TAG('Q','I','N',' ')},*/ /* Chin */
+/*{"??", HB_TAG('R','B','U',' ')},*/ /* Russian Buriat */
+/*{"??", HB_TAG('R','C','R',' ')},*/ /* R-Cree */
+/*{"??", HB_TAG('R','M','S',' ')},*/ /* Rhaeto-Romanic */
+/*{"??", HB_TAG('R','U','A',' ')},*/ /* Ruanda */
+/*{"??", HB_TAG('S','A','Y',' ')},*/ /* Sayisi */
+/*{"??", HB_TAG('S','E','K',' ')},*/ /* Sekota */
+/*{"??", HB_TAG('S','I','G',' ')},*/ /* Silte Gurage */
+/*{"??", HB_TAG('S','L','A',' ')},*/ /* Slavey */
+/*{"??", HB_TAG('S','O','G',' ')},*/ /* Sodo Gurage */
+/*{"??", HB_TAG('S','O','T',' ')},*/ /* Sotho */
+/*{"??", HB_TAG('S','W','A',' ')},*/ /* Swadaya Aramaic */
+/*{"??", HB_TAG('S','W','Z',' ')},*/ /* Swazi */
+/*{"??", HB_TAG('S','X','T',' ')},*/ /* Sutu */
+/*{"??", HB_TAG('T','A','B',' ')},*/ /* Tabasaran */
+/*{"??", HB_TAG('T','C','R',' ')},*/ /* TH-Cree */
+/*{"??", HB_TAG('T','G','N',' ')},*/ /* Tongan */
+/*{"??", HB_TAG('T','M','N',' ')},*/ /* Temne */
+/*{"??", HB_TAG('T','N','E',' ')},*/ /* Tundra Nenets */
+/*{"??", HB_TAG('T','O','D',' ')},*/ /* Todo */
+/*{"??", HB_TAG('T','U','A',' ')},*/ /* Turoyo Aramaic */
+/*{"??", HB_TAG('T','U','V',' ')},*/ /* Tuvin */
+/*{"??", HB_TAG('W','C','R',' ')},*/ /* West-Cree */
+/*{"??", HB_TAG('X','B','D',' ')},*/ /* Tai Lue */
+/*{"??", HB_TAG('Y','C','R',' ')},*/ /* Y-Cree */
+/*{"??", HB_TAG('Y','I','C',' ')},*/ /* Yi Classic */
+/*{"??", HB_TAG('Y','I','M',' ')},*/ /* Yi Modern */
+/*{"??", HB_TAG('Z','H','P',' ')},*/ /* Chinese Phonetic */
+};
+
+static int
+lang_compare_first_component (const char *a,
+ const char *b)
+{
+ unsigned int da, db;
+ const char *p;
+
+ p = strstr (a, "-");
+ da = p ? (unsigned int) (p - a) : strlen (a);
+
+ p = strstr (b, "-");
+ db = p ? (unsigned int) (p - b) : strlen (b);
+
+ return strncmp (a, b, MAX (da, db));
+}
+
+static hb_bool_t
+lang_matches (const char *lang_str, const char *spec)
+{
+ unsigned int len = strlen (spec);
+
+ return lang_str && strncmp (lang_str, spec, len) == 0 &&
+ (lang_str[len] == '\0' || lang_str[len] == '-');
+}
+
+hb_tag_t
+hb_ot_tag_from_language (hb_language_t language)
+{
+ const char *lang_str;
+ LangTag *lang_tag;
+
+ if (language == NULL)
+ return HB_OT_TAG_DEFAULT_LANGUAGE;
+
+ lang_str = hb_language_to_string (language);
+
+ if (0 == strncmp (lang_str, "x-hbot", 6)) {
+ char tag[4];
+ int i;
+ lang_str += 6;
+ for (i = 0; i < 4 && ISALPHA (lang_str[i]); i++)
+ tag[i] = TOUPPER (lang_str[i]);
+ for (; i < 4; i++)
+ tag[i] = ' ';
+ return HB_TAG_CHAR4 (tag);
+ }
+
+ /* find a language matching in the first component */
+ lang_tag = (LangTag *) bsearch (lang_str, ot_languages,
+ ARRAY_LENGTH (ot_languages), sizeof (LangTag),
+ (hb_compare_func_t) lang_compare_first_component);
+
+ /* we now need to find the best language matching */
+ if (lang_tag)
+ {
+ hb_bool_t found = FALSE;
+
+ /* go to the final one matching in the first component */
+ while (lang_tag + 1 < ot_languages + ARRAY_LENGTH (ot_languages) &&
+ lang_compare_first_component (lang_str, (lang_tag + 1)->language) == 0)
+ lang_tag++;
+
+ /* go back, find which one matches completely */
+ while (lang_tag >= ot_languages &&
+ lang_compare_first_component (lang_str, lang_tag->language) == 0)
+ {
+ if (lang_matches (lang_str, lang_tag->language)) {
+ found = TRUE;
+ break;
+ }
+
+ lang_tag--;
+ }
+
+ if (!found)
+ lang_tag = NULL;
+ }
+
+ if (lang_tag)
+ return lang_tag->tag;
+
+ return HB_OT_TAG_DEFAULT_LANGUAGE;
+}
+
+hb_language_t
+hb_ot_tag_to_language (hb_tag_t tag)
+{
+ unsigned int i;
+ unsigned char buf[11] = "x-hbot";
+
+ for (i = 0; i < ARRAY_LENGTH (ot_languages); i++)
+ if (ot_languages[i].tag == tag)
+ return hb_language_from_string (ot_languages[i].language);
+
+ buf[6] = tag >> 24;
+ buf[7] = (tag >> 16) & 0xFF;
+ buf[8] = (tag >> 8) & 0xFF;
+ buf[9] = tag & 0xFF;
+ buf[10] = '\0';
+ return hb_language_from_string ((char *) buf);
+}
+
+
+HB_END_DECLS
diff --git a/src/hb-private.h b/src/hb-private.h
deleted file mode 100644
index ae10b5d..0000000
--- a/src/hb-private.h
+++ /dev/null
@@ -1,301 +0,0 @@
-/*
- * Copyright (C) 2007,2008,2009 Red Hat, Inc.
- *
- * 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.
- *
- * Red Hat Author(s): Behdad Esfahbod
- */
-
-#ifndef HB_PRIVATE_H
-#define HB_PRIVATE_H
-
-#if HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "hb-common.h"
-
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-
-/* We only use these two for debug output. However, the debug code is
- * always seen by the compiler (and optimized out in non-debug builds.
- * If including these becomes a problem, we can start thinking about
- * someway around that. */
-#include <stdio.h>
-#include <errno.h>
-
-HB_BEGIN_DECLS
-
-
-/* Essentials */
-
-#ifndef NULL
-# define NULL ((void *) 0)
-#endif
-
-#undef FALSE
-#define FALSE 0
-
-#undef TRUE
-#define TRUE 1
-
-
-/* Basics */
-
-#undef MIN
-#define MIN(a,b) ((a) < (b) ? (a) : (b))
-
-#undef MAX
-#define MAX(a,b) ((a) > (b) ? (a) : (b))
-
-#undef ARRAY_LENGTH
-#define ARRAY_LENGTH(__array) ((signed int) (sizeof (__array) / sizeof (__array[0])))
-
-#define HB_STMT_START do
-#define HB_STMT_END while (0)
-
-#define _ASSERT_STATIC1(_line, _cond) typedef int _static_assert_on_line_##_line##_failed[(_cond)?1:-1]
-#define _ASSERT_STATIC0(_line, _cond) _ASSERT_STATIC1 (_line, (_cond))
-#define ASSERT_STATIC(_cond) _ASSERT_STATIC0 (__LINE__, (_cond))
-
-
-/* Lets assert int types. Saves trouble down the road. */
-
-ASSERT_STATIC (sizeof (int8_t) == 1);
-ASSERT_STATIC (sizeof (uint8_t) == 1);
-ASSERT_STATIC (sizeof (int16_t) == 2);
-ASSERT_STATIC (sizeof (uint16_t) == 2);
-ASSERT_STATIC (sizeof (int32_t) == 4);
-ASSERT_STATIC (sizeof (uint32_t) == 4);
-ASSERT_STATIC (sizeof (int64_t) == 8);
-ASSERT_STATIC (sizeof (uint64_t) == 8);
-
-ASSERT_STATIC (sizeof (hb_codepoint_t) == 4);
-ASSERT_STATIC (sizeof (hb_position_t) == 4);
-ASSERT_STATIC (sizeof (hb_mask_t) == 4);
-ASSERT_STATIC (sizeof (hb_var_int_t) == 4);
-
-/* Misc */
-
-
-#if defined(__GNUC__) && (__GNUC__ > 2) && defined(__OPTIMIZE__)
-#define _HB_BOOLEAN_EXPR(expr) ((expr) ? 1 : 0)
-#define likely(expr) (__builtin_expect (_HB_BOOLEAN_EXPR(expr), 1))
-#define unlikely(expr) (__builtin_expect (_HB_BOOLEAN_EXPR(expr), 0))
-#else
-#define likely(expr) (expr)
-#define unlikely(expr) (expr)
-#endif
-
-#ifndef __GNUC__
-#undef __attribute__
-#define __attribute__(x)
-#endif
-
-#if __GNUC__ >= 3
-#define HB_PURE_FUNC __attribute__((pure))
-#define HB_CONST_FUNC __attribute__((const))
-#else
-#define HB_PURE_FUNC
-#define HB_CONST_FUNC
-#endif
-#if __GNUC__ >= 4
-#define HB_UNUSED __attribute__((unused))
-#else
-#define HB_UNUSED
-#endif
-
-#ifndef HB_INTERNAL
-# define HB_INTERNAL __attribute__((__visibility__("hidden")))
-#endif
-
-
-#if (defined(__WIN32__) && !defined(__WINE__)) || defined(_MSC_VER)
-#define snprintf _snprintf
-#endif
-
-#ifdef _MSC_VER
-#undef inline
-#define inline __inline
-#endif
-
-#ifdef __STRICT_ANSI__
-#undef inline
-#define inline __inline__
-#endif
-
-
-#if __GNUC__ >= 3
-#define HB_FUNC __PRETTY_FUNCTION__
-#elif defined(_MSC_VER)
-#define HB_FUNC __FUNCSIG__
-#else
-#define HB_FUNC __func__
-#endif
-
-
-/* Return the number of 1 bits in mask. */
-static inline HB_CONST_FUNC unsigned int
-_hb_popcount32 (uint32_t mask)
-{
-#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
- return __builtin_popcount (mask);
-#else
- /* "HACKMEM 169" */
- register uint32_t y;
- y = (mask >> 1) &033333333333;
- y = mask - y - ((y >>1) & 033333333333);
- return (((y + (y >> 3)) & 030707070707) % 077);
-#endif
-}
-
-/* Returns the number of bits needed to store number */
-static inline HB_CONST_FUNC unsigned int
-_hb_bit_storage (unsigned int number)
-{
-#if defined(__GNUC__) && (__GNUC__ >= 4) && defined(__OPTIMIZE__)
- return likely (number) ? (sizeof (unsigned int) * 8 - __builtin_clz (number)) : 0;
-#else
- register unsigned int n_bits = 0;
- while (number) {
- n_bits++;
- number >>= 1;
- }
- return n_bits;
-#endif
-}
-
-/* Returns the number of zero bits in the least significant side of number */
-static inline HB_CONST_FUNC unsigned int
-_hb_ctz (unsigned int number)
-{
-#if defined(__GNUC__) && (__GNUC__ >= 4) && defined(__OPTIMIZE__)
- return likely (number) ? __builtin_ctz (number) : 0;
-#else
- register unsigned int n_bits = 0;
- if (unlikely (!number)) return 0;
- while (!(number & 1)) {
- n_bits++;
- number >>= 1;
- }
- return n_bits;
-#endif
-}
-
-/* Type of bsearch() / qsort() compare function */
-typedef int (*hb_compare_func_t) (const void *, const void *);
-
-
-/* We need external help for these */
-
-#ifdef HAVE_GLIB
-
-#include <glib.h>
-
-typedef int hb_atomic_int_t;
-#define hb_atomic_int_fetch_and_add(AI, V) g_atomic_int_exchange_and_add (&(AI), V)
-#define hb_atomic_int_get(AI) g_atomic_int_get (&(AI))
-#define hb_atomic_int_set(AI, V) g_atomic_int_set (&(AI), V)
-
-typedef GStaticMutex hb_mutex_t;
-#define HB_MUTEX_INIT G_STATIC_MUTEX_INIT
-#define hb_mutex_init(M) g_static_mutex_init (&M)
-#define hb_mutex_lock(M) g_static_mutex_lock (&M)
-#define hb_mutex_trylock(M) g_static_mutex_trylock (&M)
-#define hb_mutex_unlock(M) g_static_mutex_unlock (&M)
-
-#else
-
-#ifdef _MSC_VER
-#define _HB__STR2__(x) #x
-#define _HB__STR1__(x) _HB__STR2__(x)
-#define _HB__LOC__ __FILE__ "("_HB__STR1__(__LINE__)") : Warning Msg: "
-#pragma message(_HB__LOC__"Could not find any system to define platform macros, library will NOT be thread-safe")
-#else
-#warning "Could not find any system to define platform macros, library will NOT be thread-safe"
-#endif
-
-typedef int hb_atomic_int_t;
-#define hb_atomic_int_fetch_and_add(AI, V) ((AI) += (V), (AI) - (V))
-#define hb_atomic_int_get(AI) (AI)
-#define hb_atomic_int_set(AI, V) HB_STMT_START { (AI) = (V); } HB_STMT_END
-
-typedef int hb_mutex_t;
-#define HB_MUTEX_INIT 0
-#define hb_mutex_init(M) HB_STMT_START { (M) = 0; } HB_STMT_END
-#define hb_mutex_lock(M) HB_STMT_START { (M) = 1; } HB_STMT_END
-#define hb_mutex_trylock(M) ((M) = 1, 1)
-#define hb_mutex_unlock(M) HB_STMT_START { (M) = 0; } HB_STMT_END
-
-#endif
-
-
-/* Big-endian handling */
-
-#define hb_be_uint16(v) ((uint16_t) ((((const uint8_t *)&(v))[0] << 8) + (((const uint8_t *)&(v))[1])))
-
-#define hb_be_uint16_put(v,V) HB_STMT_START { v[0] = (V>>8); v[1] = (V); } HB_STMT_END
-#define hb_be_uint16_get(v) (uint16_t) ((v[0] << 8) + v[1])
-#define hb_be_uint16_cmp(a,b) (a[0] == b[0] && a[1] == b[1])
-
-#define hb_be_uint32_put(v,V) HB_STMT_START { v[0] = (V>>24); v[1] = (V>>16); v[2] = (V>>8); v[3] = (V); } HB_STMT_END
-#define hb_be_uint32_get(v) (uint32_t) ((v[0] << 24) + (v[1] << 16) + (v[2] << 8) + v[3])
-#define hb_be_uint32_cmp(a,b) (a[0] == b[0] && a[1] == b[1] && a[2] == b[2] && a[3] == b[3])
-
-
-/* ASCII tag/character handling */
-
-#define ISALPHA(c) (((c) >= 'a' && (c) <= 'z') || ((c) >= 'A' && (c) <= 'Z'))
-#define TOUPPER(c) (((c) >= 'a' && (c) <= 'z') ? (c) - 'a' + 'A' : (c))
-#define TOLOWER(c) (((c) >= 'A' && (c) <= 'Z') ? (c) - 'A' + 'a' : (c))
-
-#define HB_TAG_CHAR4(s) (HB_TAG(((const char *) s)[0], \
- ((const char *) s)[1], \
- ((const char *) s)[2], \
- ((const char *) s)[3]))
-
-
-/* Debug */
-
-#ifndef HB_DEBUG
-#define HB_DEBUG 0
-#endif
-
-static inline hb_bool_t /* always returns TRUE */
-_hb_trace (const char *what,
- const char *function,
- const void *obj,
- unsigned int depth,
- unsigned int max_depth)
-{
- (void) ((depth < max_depth) && fprintf (stderr, "%s(%p) %-*d-> %s\n", what, obj, depth, depth, function));
- return TRUE;
-}
-
-
-#include "hb-object-private.h"
-
-
-HB_END_DECLS
-
-#endif /* HB_PRIVATE_H */
diff --git a/src/hb-private.hh b/src/hb-private.hh
new file mode 100644
index 0000000..d08a4d0
--- /dev/null
+++ b/src/hb-private.hh
@@ -0,0 +1,301 @@
+/*
+ * Copyright (C) 2007,2008,2009 Red Hat, Inc.
+ *
+ * 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.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_PRIVATE_HH
+#define HB_PRIVATE_HH
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "hb-common.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+/* We only use these two for debug output. However, the debug code is
+ * always seen by the compiler (and optimized out in non-debug builds.
+ * If including these becomes a problem, we can start thinking about
+ * someway around that. */
+#include <stdio.h>
+#include <errno.h>
+
+HB_BEGIN_DECLS
+
+
+/* Essentials */
+
+#ifndef NULL
+# define NULL ((void *) 0)
+#endif
+
+#undef FALSE
+#define FALSE 0
+
+#undef TRUE
+#define TRUE 1
+
+
+/* Basics */
+
+#undef MIN
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+
+#undef MAX
+#define MAX(a,b) ((a) > (b) ? (a) : (b))
+
+#undef ARRAY_LENGTH
+#define ARRAY_LENGTH(__array) ((signed int) (sizeof (__array) / sizeof (__array[0])))
+
+#define HB_STMT_START do
+#define HB_STMT_END while (0)
+
+#define _ASSERT_STATIC1(_line, _cond) typedef int _static_assert_on_line_##_line##_failed[(_cond)?1:-1]
+#define _ASSERT_STATIC0(_line, _cond) _ASSERT_STATIC1 (_line, (_cond))
+#define ASSERT_STATIC(_cond) _ASSERT_STATIC0 (__LINE__, (_cond))
+
+
+/* Lets assert int types. Saves trouble down the road. */
+
+ASSERT_STATIC (sizeof (int8_t) == 1);
+ASSERT_STATIC (sizeof (uint8_t) == 1);
+ASSERT_STATIC (sizeof (int16_t) == 2);
+ASSERT_STATIC (sizeof (uint16_t) == 2);
+ASSERT_STATIC (sizeof (int32_t) == 4);
+ASSERT_STATIC (sizeof (uint32_t) == 4);
+ASSERT_STATIC (sizeof (int64_t) == 8);
+ASSERT_STATIC (sizeof (uint64_t) == 8);
+
+ASSERT_STATIC (sizeof (hb_codepoint_t) == 4);
+ASSERT_STATIC (sizeof (hb_position_t) == 4);
+ASSERT_STATIC (sizeof (hb_mask_t) == 4);
+ASSERT_STATIC (sizeof (hb_var_int_t) == 4);
+
+/* Misc */
+
+
+#if defined(__GNUC__) && (__GNUC__ > 2) && defined(__OPTIMIZE__)
+#define _HB_BOOLEAN_EXPR(expr) ((expr) ? 1 : 0)
+#define likely(expr) (__builtin_expect (_HB_BOOLEAN_EXPR(expr), 1))
+#define unlikely(expr) (__builtin_expect (_HB_BOOLEAN_EXPR(expr), 0))
+#else
+#define likely(expr) (expr)
+#define unlikely(expr) (expr)
+#endif
+
+#ifndef __GNUC__
+#undef __attribute__
+#define __attribute__(x)
+#endif
+
+#if __GNUC__ >= 3
+#define HB_PURE_FUNC __attribute__((pure))
+#define HB_CONST_FUNC __attribute__((const))
+#else
+#define HB_PURE_FUNC
+#define HB_CONST_FUNC
+#endif
+#if __GNUC__ >= 4
+#define HB_UNUSED __attribute__((unused))
+#else
+#define HB_UNUSED
+#endif
+
+#ifndef HB_INTERNAL
+# define HB_INTERNAL __attribute__((__visibility__("hidden")))
+#endif
+
+
+#if (defined(__WIN32__) && !defined(__WINE__)) || defined(_MSC_VER)
+#define snprintf _snprintf
+#endif
+
+#ifdef _MSC_VER
+#undef inline
+#define inline __inline
+#endif
+
+#ifdef __STRICT_ANSI__
+#undef inline
+#define inline __inline__
+#endif
+
+
+#if __GNUC__ >= 3
+#define HB_FUNC __PRETTY_FUNCTION__
+#elif defined(_MSC_VER)
+#define HB_FUNC __FUNCSIG__
+#else
+#define HB_FUNC __func__
+#endif
+
+
+/* Return the number of 1 bits in mask. */
+static inline HB_CONST_FUNC unsigned int
+_hb_popcount32 (uint32_t mask)
+{
+#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
+ return __builtin_popcount (mask);
+#else
+ /* "HACKMEM 169" */
+ register uint32_t y;
+ y = (mask >> 1) &033333333333;
+ y = mask - y - ((y >>1) & 033333333333);
+ return (((y + (y >> 3)) & 030707070707) % 077);
+#endif
+}
+
+/* Returns the number of bits needed to store number */
+static inline HB_CONST_FUNC unsigned int
+_hb_bit_storage (unsigned int number)
+{
+#if defined(__GNUC__) && (__GNUC__ >= 4) && defined(__OPTIMIZE__)
+ return likely (number) ? (sizeof (unsigned int) * 8 - __builtin_clz (number)) : 0;
+#else
+ register unsigned int n_bits = 0;
+ while (number) {
+ n_bits++;
+ number >>= 1;
+ }
+ return n_bits;
+#endif
+}
+
+/* Returns the number of zero bits in the least significant side of number */
+static inline HB_CONST_FUNC unsigned int
+_hb_ctz (unsigned int number)
+{
+#if defined(__GNUC__) && (__GNUC__ >= 4) && defined(__OPTIMIZE__)
+ return likely (number) ? __builtin_ctz (number) : 0;
+#else
+ register unsigned int n_bits = 0;
+ if (unlikely (!number)) return 0;
+ while (!(number & 1)) {
+ n_bits++;
+ number >>= 1;
+ }
+ return n_bits;
+#endif
+}
+
+/* Type of bsearch() / qsort() compare function */
+typedef int (*hb_compare_func_t) (const void *, const void *);
+
+
+/* We need external help for these */
+
+#ifdef HAVE_GLIB
+
+#include <glib.h>
+
+typedef int hb_atomic_int_t;
+#define hb_atomic_int_fetch_and_add(AI, V) g_atomic_int_exchange_and_add (&(AI), V)
+#define hb_atomic_int_get(AI) g_atomic_int_get (&(AI))
+#define hb_atomic_int_set(AI, V) g_atomic_int_set (&(AI), V)
+
+typedef GStaticMutex hb_mutex_t;
+#define HB_MUTEX_INIT G_STATIC_MUTEX_INIT
+#define hb_mutex_init(M) g_static_mutex_init (&M)
+#define hb_mutex_lock(M) g_static_mutex_lock (&M)
+#define hb_mutex_trylock(M) g_static_mutex_trylock (&M)
+#define hb_mutex_unlock(M) g_static_mutex_unlock (&M)
+
+#else
+
+#ifdef _MSC_VER
+#define _HB__STR2__(x) #x
+#define _HB__STR1__(x) _HB__STR2__(x)
+#define _HB__LOC__ __FILE__ "("_HB__STR1__(__LINE__)") : Warning Msg: "
+#pragma message(_HB__LOC__"Could not find any system to define platform macros, library will NOT be thread-safe")
+#else
+#warning "Could not find any system to define platform macros, library will NOT be thread-safe"
+#endif
+
+typedef int hb_atomic_int_t;
+#define hb_atomic_int_fetch_and_add(AI, V) ((AI) += (V), (AI) - (V))
+#define hb_atomic_int_get(AI) (AI)
+#define hb_atomic_int_set(AI, V) HB_STMT_START { (AI) = (V); } HB_STMT_END
+
+typedef int hb_mutex_t;
+#define HB_MUTEX_INIT 0
+#define hb_mutex_init(M) HB_STMT_START { (M) = 0; } HB_STMT_END
+#define hb_mutex_lock(M) HB_STMT_START { (M) = 1; } HB_STMT_END
+#define hb_mutex_trylock(M) ((M) = 1, 1)
+#define hb_mutex_unlock(M) HB_STMT_START { (M) = 0; } HB_STMT_END
+
+#endif
+
+
+/* Big-endian handling */
+
+#define hb_be_uint16(v) ((uint16_t) ((((const uint8_t *)&(v))[0] << 8) + (((const uint8_t *)&(v))[1])))
+
+#define hb_be_uint16_put(v,V) HB_STMT_START { v[0] = (V>>8); v[1] = (V); } HB_STMT_END
+#define hb_be_uint16_get(v) (uint16_t) ((v[0] << 8) + v[1])
+#define hb_be_uint16_cmp(a,b) (a[0] == b[0] && a[1] == b[1])
+
+#define hb_be_uint32_put(v,V) HB_STMT_START { v[0] = (V>>24); v[1] = (V>>16); v[2] = (V>>8); v[3] = (V); } HB_STMT_END
+#define hb_be_uint32_get(v) (uint32_t) ((v[0] << 24) + (v[1] << 16) + (v[2] << 8) + v[3])
+#define hb_be_uint32_cmp(a,b) (a[0] == b[0] && a[1] == b[1] && a[2] == b[2] && a[3] == b[3])
+
+
+/* ASCII tag/character handling */
+
+#define ISALPHA(c) (((c) >= 'a' && (c) <= 'z') || ((c) >= 'A' && (c) <= 'Z'))
+#define TOUPPER(c) (((c) >= 'a' && (c) <= 'z') ? (c) - 'a' + 'A' : (c))
+#define TOLOWER(c) (((c) >= 'A' && (c) <= 'Z') ? (c) - 'A' + 'a' : (c))
+
+#define HB_TAG_CHAR4(s) (HB_TAG(((const char *) s)[0], \
+ ((const char *) s)[1], \
+ ((const char *) s)[2], \
+ ((const char *) s)[3]))
+
+
+/* Debug */
+
+#ifndef HB_DEBUG
+#define HB_DEBUG 0
+#endif
+
+static inline hb_bool_t /* always returns TRUE */
+_hb_trace (const char *what,
+ const char *function,
+ const void *obj,
+ unsigned int depth,
+ unsigned int max_depth)
+{
+ (void) ((depth < max_depth) && fprintf (stderr, "%s(%p) %-*d-> %s\n", what, obj, depth, depth, function));
+ return TRUE;
+}
+
+
+#include "hb-object-private.hh"
+
+
+HB_END_DECLS
+
+#endif /* HB_PRIVATE_HH */
diff --git a/src/hb-shape.cc b/src/hb-shape.cc
index 9d5d418..66d951b 100644
--- a/src/hb-shape.cc
+++ b/src/hb-shape.cc
@@ -24,7 +24,7 @@
* Red Hat Author(s): Behdad Esfahbod
*/
-#include "hb-private.h"
+#include "hb-private.hh"
#include "hb-shape.h"
diff --git a/src/hb-unicode-private.hh b/src/hb-unicode-private.hh
index 67a60f5..af15c04 100644
--- a/src/hb-unicode-private.hh
+++ b/src/hb-unicode-private.hh
@@ -31,7 +31,7 @@
#ifndef HB_UNICODE_PRIVATE_HH
#define HB_UNICODE_PRIVATE_HH
-#include "hb-private.h"
+#include "hb-private.hh"
#include "hb-unicode.h"
diff --git a/src/hb-unicode.cc b/src/hb-unicode.cc
index 9295be7..282a9b6 100644
--- a/src/hb-unicode.cc
+++ b/src/hb-unicode.cc
@@ -28,7 +28,7 @@
* Google Author(s): Behdad Esfahbod
*/
-#include "hb-private.h"
+#include "hb-private.hh"
#include "hb-unicode-private.hh"
diff --git a/src/hb-view.c b/src/hb-view.c
index 60097b9..ac55908 100644
--- a/src/hb-view.c
+++ b/src/hb-view.c
@@ -42,6 +42,9 @@
#include <cairo-ft.h>
#include <hb-ft.h>
+HB_BEGIN_DECLS
+
+
/* Controlled by cmd-line options */
static int margin_t = 10;
static int margin_b = 10;
@@ -533,3 +536,6 @@ main (int argc, char **argv)
return 0;
}
+
+
+HB_END_DECLS
commit f19f4f9b0965ad7473a0f3a1ffcdbf16930e35d4
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Wed Apr 20 18:25:56 2011 -0400
Rename hb-blob.c to hb-blob.cc in preparation of more changes
diff --git a/src/Makefile.am b/src/Makefile.am
index 70c51d1..845c24a 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -11,7 +11,7 @@ lib_LTLIBRARIES = libharfbuzz.la
HBCFLAGS =
HBLIBS =
HBSOURCES = \
- hb-blob.c \
+ hb-blob.cc \
hb-blob-private.h \
hb-buffer.cc \
hb-buffer-private.hh \
diff --git a/src/hb-blob.c b/src/hb-blob.c
deleted file mode 100644
index 5419078..0000000
--- a/src/hb-blob.c
+++ /dev/null
@@ -1,356 +0,0 @@
-/*
- * Copyright (C) 2009 Red Hat, Inc.
- *
- * 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.
- *
- * Red Hat Author(s): Behdad Esfahbod
- */
-
-#include "hb-private.h"
-
-#include "hb-blob-private.h"
-
-#ifdef HAVE_SYS_MMAN_H
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif /* HAVE_UNISTD_H */
-#include <sys/mman.h>
-#endif /* HAVE_SYS_MMAN_H */
-
-#include <stdio.h>
-#include <errno.h>
-
-HB_BEGIN_DECLS
-
-
-#ifndef HB_DEBUG_BLOB
-#define HB_DEBUG_BLOB (HB_DEBUG+0)
-#endif
-
-hb_blob_t _hb_blob_nil = {
- HB_REFERENCE_COUNT_INVALID, /* ref_count */
-
- 0, /* length */
-
- HB_MUTEX_INIT, /* lock */
-
- 0, /* lock_count */
- HB_MEMORY_MODE_READONLY, /* mode */
-
- NULL, /* data */
-
- NULL, /* user_data */
- NULL /* destroy */
-};
-
-static void
-_hb_blob_destroy_user_data (hb_blob_t *blob)
-{
- if (blob->destroy) {
- blob->destroy (blob->user_data);
- blob->user_data = NULL;
- blob->destroy = NULL;
- }
-}
-
-static void
-_hb_blob_unlock_and_destroy (hb_blob_t *blob)
-{
- hb_blob_unlock (blob);
- hb_blob_destroy (blob);
-}
-
-hb_blob_t *
-hb_blob_create (const char *data,
- unsigned int length,
- hb_memory_mode_t mode,
- void *user_data,
- hb_destroy_func_t destroy)
-{
- hb_blob_t *blob;
-
- if (!length || !HB_OBJECT_DO_CREATE (hb_blob_t, blob)) {
- if (destroy)
- destroy (user_data);
- return &_hb_blob_nil;
- }
-
- hb_mutex_init (blob->lock);
- blob->lock_count = 0;
-
- blob->data = data;
- blob->length = length;
- blob->mode = mode;
-
- blob->user_data = user_data;
- blob->destroy = destroy;
-
- if (blob->mode == HB_MEMORY_MODE_DUPLICATE) {
- blob->mode = HB_MEMORY_MODE_READONLY;
- if (!hb_blob_try_writable (blob)) {
- hb_blob_destroy (blob);
- return &_hb_blob_nil;
- }
- }
-
- return blob;
-}
-
-hb_blob_t *
-hb_blob_create_sub_blob (hb_blob_t *parent,
- unsigned int offset,
- unsigned int length)
-{
- hb_blob_t *blob;
- const char *pdata;
-
- if (!length || offset >= parent->length || !HB_OBJECT_DO_CREATE (hb_blob_t, blob))
- return &_hb_blob_nil;
-
- pdata = hb_blob_lock (parent);
-
- blob->data = pdata + offset;
- blob->length = MIN (length, parent->length - offset);
-
- hb_mutex_lock (parent->lock);
- blob->mode = parent->mode;
- hb_mutex_unlock (parent->lock);
-
- blob->user_data = hb_blob_reference (parent);
- blob->destroy = (hb_destroy_func_t) _hb_blob_unlock_and_destroy;
-
- return blob;
-}
-
-hb_blob_t *
-hb_blob_create_empty (void)
-{
- return &_hb_blob_nil;
-}
-
-hb_blob_t *
-hb_blob_reference (hb_blob_t *blob)
-{
- HB_OBJECT_DO_REFERENCE (blob);
-}
-
-void
-hb_blob_destroy (hb_blob_t *blob)
-{
- HB_OBJECT_DO_DESTROY (blob);
-
- _hb_blob_destroy_user_data (blob);
-
- free (blob);
-}
-
-unsigned int
-hb_blob_get_length (hb_blob_t *blob)
-{
- return blob->length;
-}
-
-const char *
-hb_blob_lock (hb_blob_t *blob)
-{
- if (HB_OBJECT_IS_INERT (blob))
- return NULL;
-
- hb_mutex_lock (blob->lock);
-
- (void) (HB_DEBUG_BLOB &&
- fprintf (stderr, "%p %s (%d) -> %p\n", blob, __FUNCTION__,
- blob->lock_count, blob->data));
-
- blob->lock_count++;
-
- hb_mutex_unlock (blob->lock);
-
- return blob->data;
-}
-
-void
-hb_blob_unlock (hb_blob_t *blob)
-{
- if (HB_OBJECT_IS_INERT (blob))
- return;
-
- hb_mutex_lock (blob->lock);
-
- (void) (HB_DEBUG_BLOB &&
- fprintf (stderr, "%p %s (%d) -> %p\n", blob, __FUNCTION__,
- blob->lock_count, blob->data));
-
- assert (blob->lock_count > 0);
- blob->lock_count--;
-
- hb_mutex_unlock (blob->lock);
-}
-
-hb_bool_t
-hb_blob_is_writable (hb_blob_t *blob)
-{
- hb_memory_mode_t mode;
-
- if (HB_OBJECT_IS_INERT (blob))
- return FALSE;
-
- hb_mutex_lock (blob->lock);
-
- mode = blob->mode;
-
- hb_mutex_unlock (blob->lock);
-
- return mode == HB_MEMORY_MODE_WRITABLE;
-}
-
-
-static hb_bool_t
-_try_make_writable_inplace_unix_locked (hb_blob_t *blob)
-{
-#if defined(HAVE_SYS_MMAN_H) && defined(HAVE_MPROTECT)
- uintptr_t pagesize = -1, mask, length;
- const char *addr;
-
-#if defined(HAVE_SYSCONF) && defined(_SC_PAGE_SIZE)
- pagesize = (uintptr_t) sysconf (_SC_PAGE_SIZE);
-#elif defined(HAVE_SYSCONF) && defined(_SC_PAGESIZE)
- pagesize = (uintptr_t) sysconf (_SC_PAGESIZE);
-#elif defined(HAVE_GETPAGESIZE)
- pagesize = (uintptr_t) getpagesize ();
-#endif
-
- if ((uintptr_t) -1L == pagesize) {
- (void) (HB_DEBUG_BLOB &&
- fprintf (stderr, "%p %s: failed to get pagesize: %s\n", blob, __FUNCTION__, strerror (errno)));
- return FALSE;
- }
- (void) (HB_DEBUG_BLOB &&
- fprintf (stderr, "%p %s: pagesize is %lu\n", blob, __FUNCTION__, (unsigned long) pagesize));
-
- mask = ~(pagesize-1);
- addr = (const char *) (((uintptr_t) blob->data) & mask);
- length = (const char *) (((uintptr_t) blob->data + blob->length + pagesize-1) & mask) - addr;
- (void) (HB_DEBUG_BLOB &&
- fprintf (stderr, "%p %s: calling mprotect on [%p..%p] (%lu bytes)\n",
- blob, __FUNCTION__,
- addr, addr+length, (unsigned long) length));
- if (-1 == mprotect ((void *) addr, length, PROT_READ | PROT_WRITE)) {
- (void) (HB_DEBUG_BLOB &&
- fprintf (stderr, "%p %s: %s\n", blob, __FUNCTION__, strerror (errno)));
- return FALSE;
- }
-
- (void) (HB_DEBUG_BLOB &&
- fprintf (stderr, "%p %s: successfully made [%p..%p] (%lu bytes) writable\n",
- blob, __FUNCTION__,
- addr, addr+length, (unsigned long) length));
- return TRUE;
-#else
- return FALSE;
-#endif
-}
-
-static void
-try_writable_inplace_locked (hb_blob_t *blob)
-{
- (void) (HB_DEBUG_BLOB &&
- fprintf (stderr, "%p %s: making writable\n", blob, __FUNCTION__));
-
- if (_try_make_writable_inplace_unix_locked (blob)) {
- (void) (HB_DEBUG_BLOB &&
- fprintf (stderr, "%p %s: making writable -> succeeded\n", blob, __FUNCTION__));
- blob->mode = HB_MEMORY_MODE_WRITABLE;
- } else {
- (void) (HB_DEBUG_BLOB &&
- fprintf (stderr, "%p %s: making writable -> FAILED\n", blob, __FUNCTION__));
- /* Failed to make writable inplace, mark that */
- blob->mode = HB_MEMORY_MODE_READONLY;
- }
-}
-
-hb_bool_t
-hb_blob_try_writable_inplace (hb_blob_t *blob)
-{
- hb_memory_mode_t mode;
-
- if (HB_OBJECT_IS_INERT (blob))
- return FALSE;
-
- hb_mutex_lock (blob->lock);
-
- if (blob->mode == HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE)
- try_writable_inplace_locked (blob);
-
- mode = blob->mode;
-
- hb_mutex_unlock (blob->lock);
-
- return mode == HB_MEMORY_MODE_WRITABLE;
-}
-
-hb_bool_t
-hb_blob_try_writable (hb_blob_t *blob)
-{
- hb_memory_mode_t mode;
-
- if (HB_OBJECT_IS_INERT (blob))
- return FALSE;
-
- hb_mutex_lock (blob->lock);
-
- if (blob->mode == HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE)
- try_writable_inplace_locked (blob);
-
- if (blob->mode == HB_MEMORY_MODE_READONLY)
- {
- char *new_data;
-
- (void) (HB_DEBUG_BLOB &&
- fprintf (stderr, "%p %s (%d) -> %p\n", blob, __FUNCTION__,
- blob->lock_count, blob->data));
-
- if (blob->lock_count)
- goto done;
-
- new_data = malloc (blob->length);
- if (new_data) {
- (void) (HB_DEBUG_BLOB &&
- fprintf (stderr, "%p %s: dupped successfully -> %p\n", blob, __FUNCTION__, blob->data));
- memcpy (new_data, blob->data, blob->length);
- _hb_blob_destroy_user_data (blob);
- blob->mode = HB_MEMORY_MODE_WRITABLE;
- blob->data = new_data;
- blob->user_data = new_data;
- blob->destroy = free;
- }
- }
-
-done:
- mode = blob->mode;
-
- hb_mutex_unlock (blob->lock);
-
- return mode == HB_MEMORY_MODE_WRITABLE;
-}
-
-
-HB_END_DECLS
diff --git a/src/hb-blob.cc b/src/hb-blob.cc
new file mode 100644
index 0000000..511455b
--- /dev/null
+++ b/src/hb-blob.cc
@@ -0,0 +1,356 @@
+/*
+ * Copyright (C) 2009 Red Hat, Inc.
+ *
+ * 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.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ */
+
+#include "hb-private.h"
+
+#include "hb-blob-private.h"
+
+#ifdef HAVE_SYS_MMAN_H
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#include <sys/mman.h>
+#endif /* HAVE_SYS_MMAN_H */
+
+#include <stdio.h>
+#include <errno.h>
+
+HB_BEGIN_DECLS
+
+
+#ifndef HB_DEBUG_BLOB
+#define HB_DEBUG_BLOB (HB_DEBUG+0)
+#endif
+
+hb_blob_t _hb_blob_nil = {
+ HB_REFERENCE_COUNT_INVALID, /* ref_count */
+
+ 0, /* length */
+
+ HB_MUTEX_INIT, /* lock */
+
+ 0, /* lock_count */
+ HB_MEMORY_MODE_READONLY, /* mode */
+
+ NULL, /* data */
+
+ NULL, /* user_data */
+ NULL /* destroy */
+};
+
+static void
+_hb_blob_destroy_user_data (hb_blob_t *blob)
+{
+ if (blob->destroy) {
+ blob->destroy (blob->user_data);
+ blob->user_data = NULL;
+ blob->destroy = NULL;
+ }
+}
+
+static void
+_hb_blob_unlock_and_destroy (hb_blob_t *blob)
+{
+ hb_blob_unlock (blob);
+ hb_blob_destroy (blob);
+}
+
+hb_blob_t *
+hb_blob_create (const char *data,
+ unsigned int length,
+ hb_memory_mode_t mode,
+ void *user_data,
+ hb_destroy_func_t destroy)
+{
+ hb_blob_t *blob;
+
+ if (!length || !HB_OBJECT_DO_CREATE (hb_blob_t, blob)) {
+ if (destroy)
+ destroy (user_data);
+ return &_hb_blob_nil;
+ }
+
+ hb_mutex_init (blob->lock);
+ blob->lock_count = 0;
+
+ blob->data = data;
+ blob->length = length;
+ blob->mode = mode;
+
+ blob->user_data = user_data;
+ blob->destroy = destroy;
+
+ if (blob->mode == HB_MEMORY_MODE_DUPLICATE) {
+ blob->mode = HB_MEMORY_MODE_READONLY;
+ if (!hb_blob_try_writable (blob)) {
+ hb_blob_destroy (blob);
+ return &_hb_blob_nil;
+ }
+ }
+
+ return blob;
+}
+
+hb_blob_t *
+hb_blob_create_sub_blob (hb_blob_t *parent,
+ unsigned int offset,
+ unsigned int length)
+{
+ hb_blob_t *blob;
+ const char *pdata;
+
+ if (!length || offset >= parent->length || !HB_OBJECT_DO_CREATE (hb_blob_t, blob))
+ return &_hb_blob_nil;
+
+ pdata = hb_blob_lock (parent);
+
+ blob->data = pdata + offset;
+ blob->length = MIN (length, parent->length - offset);
+
+ hb_mutex_lock (parent->lock);
+ blob->mode = parent->mode;
+ hb_mutex_unlock (parent->lock);
+
+ blob->user_data = hb_blob_reference (parent);
+ blob->destroy = (hb_destroy_func_t) _hb_blob_unlock_and_destroy;
+
+ return blob;
+}
+
+hb_blob_t *
+hb_blob_create_empty (void)
+{
+ return &_hb_blob_nil;
+}
+
+hb_blob_t *
+hb_blob_reference (hb_blob_t *blob)
+{
+ HB_OBJECT_DO_REFERENCE (blob);
+}
+
+void
+hb_blob_destroy (hb_blob_t *blob)
+{
+ HB_OBJECT_DO_DESTROY (blob);
+
+ _hb_blob_destroy_user_data (blob);
+
+ free (blob);
+}
+
+unsigned int
+hb_blob_get_length (hb_blob_t *blob)
+{
+ return blob->length;
+}
+
+const char *
+hb_blob_lock (hb_blob_t *blob)
+{
+ if (HB_OBJECT_IS_INERT (blob))
+ return NULL;
+
+ hb_mutex_lock (blob->lock);
+
+ (void) (HB_DEBUG_BLOB &&
+ fprintf (stderr, "%p %s (%d) -> %p\n", blob, __FUNCTION__,
+ blob->lock_count, blob->data));
+
+ blob->lock_count++;
+
+ hb_mutex_unlock (blob->lock);
+
+ return blob->data;
+}
+
+void
+hb_blob_unlock (hb_blob_t *blob)
+{
+ if (HB_OBJECT_IS_INERT (blob))
+ return;
+
+ hb_mutex_lock (blob->lock);
+
+ (void) (HB_DEBUG_BLOB &&
+ fprintf (stderr, "%p %s (%d) -> %p\n", blob, __FUNCTION__,
+ blob->lock_count, blob->data));
+
+ assert (blob->lock_count > 0);
+ blob->lock_count--;
+
+ hb_mutex_unlock (blob->lock);
+}
+
+hb_bool_t
+hb_blob_is_writable (hb_blob_t *blob)
+{
+ hb_memory_mode_t mode;
+
+ if (HB_OBJECT_IS_INERT (blob))
+ return FALSE;
+
+ hb_mutex_lock (blob->lock);
+
+ mode = blob->mode;
+
+ hb_mutex_unlock (blob->lock);
+
+ return mode == HB_MEMORY_MODE_WRITABLE;
+}
+
+
+static hb_bool_t
+_try_make_writable_inplace_unix_locked (hb_blob_t *blob)
+{
+#if defined(HAVE_SYS_MMAN_H) && defined(HAVE_MPROTECT)
+ uintptr_t pagesize = -1, mask, length;
+ const char *addr;
+
+#if defined(HAVE_SYSCONF) && defined(_SC_PAGE_SIZE)
+ pagesize = (uintptr_t) sysconf (_SC_PAGE_SIZE);
+#elif defined(HAVE_SYSCONF) && defined(_SC_PAGESIZE)
+ pagesize = (uintptr_t) sysconf (_SC_PAGESIZE);
+#elif defined(HAVE_GETPAGESIZE)
+ pagesize = (uintptr_t) getpagesize ();
+#endif
+
+ if ((uintptr_t) -1L == pagesize) {
+ (void) (HB_DEBUG_BLOB &&
+ fprintf (stderr, "%p %s: failed to get pagesize: %s\n", blob, __FUNCTION__, strerror (errno)));
+ return FALSE;
+ }
+ (void) (HB_DEBUG_BLOB &&
+ fprintf (stderr, "%p %s: pagesize is %lu\n", blob, __FUNCTION__, (unsigned long) pagesize));
+
+ mask = ~(pagesize-1);
+ addr = (const char *) (((uintptr_t) blob->data) & mask);
+ length = (const char *) (((uintptr_t) blob->data + blob->length + pagesize-1) & mask) - addr;
+ (void) (HB_DEBUG_BLOB &&
+ fprintf (stderr, "%p %s: calling mprotect on [%p..%p] (%lu bytes)\n",
+ blob, __FUNCTION__,
+ addr, addr+length, (unsigned long) length));
+ if (-1 == mprotect ((void *) addr, length, PROT_READ | PROT_WRITE)) {
+ (void) (HB_DEBUG_BLOB &&
+ fprintf (stderr, "%p %s: %s\n", blob, __FUNCTION__, strerror (errno)));
+ return FALSE;
+ }
+
+ (void) (HB_DEBUG_BLOB &&
+ fprintf (stderr, "%p %s: successfully made [%p..%p] (%lu bytes) writable\n",
+ blob, __FUNCTION__,
+ addr, addr+length, (unsigned long) length));
+ return TRUE;
+#else
+ return FALSE;
+#endif
+}
+
+static void
+try_writable_inplace_locked (hb_blob_t *blob)
+{
+ (void) (HB_DEBUG_BLOB &&
+ fprintf (stderr, "%p %s: making writable\n", blob, __FUNCTION__));
+
+ if (_try_make_writable_inplace_unix_locked (blob)) {
+ (void) (HB_DEBUG_BLOB &&
+ fprintf (stderr, "%p %s: making writable -> succeeded\n", blob, __FUNCTION__));
+ blob->mode = HB_MEMORY_MODE_WRITABLE;
+ } else {
+ (void) (HB_DEBUG_BLOB &&
+ fprintf (stderr, "%p %s: making writable -> FAILED\n", blob, __FUNCTION__));
+ /* Failed to make writable inplace, mark that */
+ blob->mode = HB_MEMORY_MODE_READONLY;
+ }
+}
+
+hb_bool_t
+hb_blob_try_writable_inplace (hb_blob_t *blob)
+{
+ hb_memory_mode_t mode;
+
+ if (HB_OBJECT_IS_INERT (blob))
+ return FALSE;
+
+ hb_mutex_lock (blob->lock);
+
+ if (blob->mode == HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE)
+ try_writable_inplace_locked (blob);
+
+ mode = blob->mode;
+
+ hb_mutex_unlock (blob->lock);
+
+ return mode == HB_MEMORY_MODE_WRITABLE;
+}
+
+hb_bool_t
+hb_blob_try_writable (hb_blob_t *blob)
+{
+ hb_memory_mode_t mode;
+
+ if (HB_OBJECT_IS_INERT (blob))
+ return FALSE;
+
+ hb_mutex_lock (blob->lock);
+
+ if (blob->mode == HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE)
+ try_writable_inplace_locked (blob);
+
+ if (blob->mode == HB_MEMORY_MODE_READONLY)
+ {
+ char *new_data;
+
+ (void) (HB_DEBUG_BLOB &&
+ fprintf (stderr, "%p %s (%d) -> %p\n", blob, __FUNCTION__,
+ blob->lock_count, blob->data));
+
+ if (blob->lock_count)
+ goto done;
+
+ new_data = (char *) malloc (blob->length);
+ if (new_data) {
+ (void) (HB_DEBUG_BLOB &&
+ fprintf (stderr, "%p %s: dupped successfully -> %p\n", blob, __FUNCTION__, blob->data));
+ memcpy (new_data, blob->data, blob->length);
+ _hb_blob_destroy_user_data (blob);
+ blob->mode = HB_MEMORY_MODE_WRITABLE;
+ blob->data = new_data;
+ blob->user_data = new_data;
+ blob->destroy = free;
+ }
+ }
+
+done:
+ mode = blob->mode;
+
+ hb_mutex_unlock (blob->lock);
+
+ return mode == HB_MEMORY_MODE_WRITABLE;
+}
+
+
+HB_END_DECLS
commit 04744e73bad22d679986173b5f0d84dbbf49dd57
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Wed Apr 20 17:24:03 2011 -0400
[TODO] Remove done items
diff --git a/TODO b/TODO
index dbcb809..b5eb3be 100644
--- a/TODO
+++ b/TODO
@@ -16,10 +16,6 @@ General fixes:
API issues to fix before 1.0:
============================
-- Rename get_table to reference_table
-
-- get_table shouldn't return NULL
-
- Figure out how many .so objects, how to link, etc
- Shall y axis progress downward instead of upward?
@@ -28,8 +24,6 @@ API issues to fix before 1.0:
- Real subclassing support for vfunc vectors
-- Investigate Mozilla's user-data issue, make sure it's addressed
-
- Add hb-cairo glue
- Fix blob, remove mutex, etc.
commit 9417c1c0d2b005eadf0c087ca695121a6200d0f7
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Wed Apr 20 17:21:23 2011 -0400
[API] Make hb_face_reference_table() return empty blob instead of NULL
The idea here is that:
- Like pretty much all other API in harfbuzz, user does not have to
check for NULL.
- In any caller code, the case of missing table should be handled
exactly the same way that a too-short table is handled. Turning
a non-existent talbe into a table of size 0 makes the user code
safer.
diff --git a/src/hb-font.cc b/src/hb-font.cc
index 2475089..96ff4f5 100644
--- a/src/hb-font.cc
+++ b/src/hb-font.cc
@@ -417,6 +417,8 @@ hb_face_reference_table (hb_face_t *face,
return &_hb_blob_nil;
blob = face->get_table (tag, face->user_data);
+ if (unlikely (!blob))
+ blob = hb_blob_create_empty();
return blob;
}
diff --git a/src/hb-open-type-private.hh b/src/hb-open-type-private.hh
index 8f3001b..241c5a0 100644
--- a/src/hb-open-type-private.hh
+++ b/src/hb-open-type-private.hh
@@ -286,9 +286,6 @@ struct Sanitizer
/* TODO is_sane() stuff */
- if (!blob)
- return hb_blob_create_empty ();
-
retry:
(void) (HB_DEBUG_SANITIZE &&
fprintf (stderr, "Sanitizer %p start %s\n", blob, HB_FUNC));
commit c035812feb0d385a9e8c334631738e4915912c71
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Wed Apr 20 17:03:00 2011 -0400
[API] Rename hb_face_get_table() to hb_face_reference_table()
That correctly reflects the reference ownership transfer happening.
diff --git a/src/hb-font.cc b/src/hb-font.cc
index 521120a..2475089 100644
--- a/src/hb-font.cc
+++ b/src/hb-font.cc
@@ -319,7 +319,7 @@ hb_face_create_for_tables (hb_get_table_func_t get_table,
face->ot_layout = _hb_ot_layout_new (face);
- face->head_blob = Sanitizer<head>::sanitize (hb_face_get_table (face, HB_OT_TAG_head));
+ face->head_blob = Sanitizer<head>::sanitize (hb_face_reference_table (face, HB_OT_TAG_head));
face->head_table = Sanitizer<head>::lock_instance (face->head_blob);
return face;
@@ -408,7 +408,7 @@ hb_face_destroy (hb_face_t *face)
}
hb_blob_t *
-hb_face_get_table (hb_face_t *face,
+hb_face_reference_table (hb_face_t *face,
hb_tag_t tag)
{
hb_blob_t *blob;
diff --git a/src/hb-font.h b/src/hb-font.h
index 29cd5cb..397b586 100644
--- a/src/hb-font.h
+++ b/src/hb-font.h
@@ -67,13 +67,10 @@ hb_face_destroy (hb_face_t *face);
* table vs a zero-length table vs a very short table. It only leads to implementations
* that check for non-NULL and assume that they've got a usable table going on... This
* actually happened with Firefox.
- *
- * - It has to be renamed to reference_table() since unlike any other _get_ API, a reference
- * ownership transfer happens and the user is responsible to destroy the result.
*/
hb_blob_t *
-hb_face_get_table (hb_face_t *face,
- hb_tag_t tag);
+hb_face_reference_table (hb_face_t *face,
+ hb_tag_t tag);
unsigned int
hb_face_get_upem (hb_face_t *face);
diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc
index f1287c5..7990fe9 100644
--- a/src/hb-ot-layout.cc
+++ b/src/hb-ot-layout.cc
@@ -47,13 +47,13 @@ _hb_ot_layout_new (hb_face_t *face)
/* Remove this object altogether */
hb_ot_layout_t *layout = (hb_ot_layout_t *) calloc (1, sizeof (hb_ot_layout_t));
- layout->gdef_blob = Sanitizer<GDEF>::sanitize (hb_face_get_table (face, HB_OT_TAG_GDEF));
+ layout->gdef_blob = Sanitizer<GDEF>::sanitize (hb_face_reference_table (face, HB_OT_TAG_GDEF));
layout->gdef = Sanitizer<GDEF>::lock_instance (layout->gdef_blob);
- layout->gsub_blob = Sanitizer<GSUB>::sanitize (hb_face_get_table (face, HB_OT_TAG_GSUB));
+ layout->gsub_blob = Sanitizer<GSUB>::sanitize (hb_face_reference_table (face, HB_OT_TAG_GSUB));
layout->gsub = Sanitizer<GSUB>::lock_instance (layout->gsub_blob);
- layout->gpos_blob = Sanitizer<GPOS>::sanitize (hb_face_get_table (face, HB_OT_TAG_GPOS));
+ layout->gpos_blob = Sanitizer<GPOS>::sanitize (hb_face_reference_table (face, HB_OT_TAG_GPOS));
layout->gpos = Sanitizer<GPOS>::lock_instance (layout->gpos_blob);
return layout;
diff --git a/src/hb-shape.cc b/src/hb-shape.cc
index 2b536fa..9d5d418 100644
--- a/src/hb-shape.cc
+++ b/src/hb-shape.cc
@@ -48,7 +48,7 @@ hb_shape_internal (hb_font_t *font,
{
#if 0 && defined(HAVE_GRAPHITE)
hb_blob_t *silf_blob;
- silf_blob = hb_face_get_table (face, HB_GRAPHITE_TAG_Silf);
+ silf_blob = hb_face_reference_table (face, HB_GRAPHITE_TAG_Silf);
if (hb_blob_get_length(silf_blob))
{
hb_graphite_shape(font, face, buffer, features, num_features);
commit 2d7b61a4b0ed212ca414b3281c2eae3e3db19c13
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Wed Apr 20 16:40:56 2011 -0400
[TODO] Remove done items
diff --git a/TODO b/TODO
index a9ef442..dbcb809 100644
--- a/TODO
+++ b/TODO
@@ -16,16 +16,10 @@ General fixes:
API issues to fix before 1.0:
============================
-- Rename / remove hb_buffer_add_glyph()?
-
-- Sprinkle const all over public and private API
-
- Rename get_table to reference_table
- get_table shouldn't return NULL
-- Use tags for hb_script_t
-
- Figure out how many .so objects, how to link, etc
- Shall y axis progress downward instead of upward?
@@ -36,14 +30,14 @@ API issues to fix before 1.0:
- Investigate Mozilla's user-data issue, make sure it's addressed
-- Add hb-glib / hb-icu two-way script conversion API
-
- Add hb-cairo glue
- Fix blob, remove mutex, etc.
- Add sanitize API (since may affect blob API)
+- Add glib GBoxedType stuff
+
API to add (maybe after 1.0):
============================
diff --git a/src/hb-ft.h b/src/hb-ft.h
index be5c854..5671a00 100644
--- a/src/hb-ft.h
+++ b/src/hb-ft.h
@@ -36,6 +36,7 @@
HB_BEGIN_DECLS
+/* Note: FreeType is not thread-safe. Hence, these functions are not either. */
hb_font_funcs_t *
hb_ft_get_font_funcs (void);
@@ -44,7 +45,6 @@ hb_face_t *
hb_ft_face_create (FT_Face ft_face,
hb_destroy_func_t destroy);
-/* Note: This function is not thread-safe */
hb_face_t *
hb_ft_face_create_cached (FT_Face ft_face);
commit af02933739e03a156b9f7761fd7a63e2a02d0df1
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Wed Apr 20 15:49:31 2011 -0400
[API] Remove hb_*_get_reference_count()
This was a bizzare piece of API that I inherited from cairo. It has
been wrong adding them to cairo in the first place. Remove them before
someone uses them!
diff --git a/src/hb-blob.c b/src/hb-blob.c
index 97ffd99..5419078 100644
--- a/src/hb-blob.c
+++ b/src/hb-blob.c
@@ -152,12 +152,6 @@ hb_blob_reference (hb_blob_t *blob)
HB_OBJECT_DO_REFERENCE (blob);
}
-unsigned int
-hb_blob_get_reference_count (hb_blob_t *blob)
-{
- HB_OBJECT_DO_GET_REFERENCE_COUNT (blob);
-}
-
void
hb_blob_destroy (hb_blob_t *blob)
{
diff --git a/src/hb-blob.h b/src/hb-blob.h
index b6080f1..4097ccc 100644
--- a/src/hb-blob.h
+++ b/src/hb-blob.h
@@ -59,9 +59,6 @@ hb_blob_create_empty (void);
hb_blob_t *
hb_blob_reference (hb_blob_t *blob);
-unsigned int
-hb_blob_get_reference_count (hb_blob_t *blob);
-
void
hb_blob_destroy (hb_blob_t *blob);
diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc
index 2f7a173..5d3b532 100644
--- a/src/hb-buffer.cc
+++ b/src/hb-buffer.cc
@@ -154,12 +154,6 @@ hb_buffer_reference (hb_buffer_t *buffer)
HB_OBJECT_DO_REFERENCE (buffer);
}
-unsigned int
-hb_buffer_get_reference_count (hb_buffer_t *buffer)
-{
- HB_OBJECT_DO_GET_REFERENCE_COUNT (buffer);
-}
-
void
hb_buffer_destroy (hb_buffer_t *buffer)
{
diff --git a/src/hb-buffer.h b/src/hb-buffer.h
index d12faf8..b80ce9f 100644
--- a/src/hb-buffer.h
+++ b/src/hb-buffer.h
@@ -65,9 +65,6 @@ hb_buffer_create (unsigned int pre_alloc_size);
hb_buffer_t *
hb_buffer_reference (hb_buffer_t *buffer);
-unsigned int
-hb_buffer_get_reference_count (hb_buffer_t *buffer);
-
void
hb_buffer_destroy (hb_buffer_t *buffer);
diff --git a/src/hb-font.cc b/src/hb-font.cc
index 43112c1..521120a 100644
--- a/src/hb-font.cc
+++ b/src/hb-font.cc
@@ -115,12 +115,6 @@ hb_font_funcs_reference (hb_font_funcs_t *ffuncs)
HB_OBJECT_DO_REFERENCE (ffuncs);
}
-unsigned int
-hb_font_funcs_get_reference_count (hb_font_funcs_t *ffuncs)
-{
- HB_OBJECT_DO_GET_REFERENCE_COUNT (ffuncs);
-}
-
void
hb_font_funcs_destroy (hb_font_funcs_t *ffuncs)
{
@@ -397,12 +391,6 @@ hb_face_reference (hb_face_t *face)
HB_OBJECT_DO_REFERENCE (face);
}
-unsigned int
-hb_face_get_reference_count (hb_face_t *face)
-{
- HB_OBJECT_DO_GET_REFERENCE_COUNT (face);
-}
-
void
hb_face_destroy (hb_face_t *face)
{
@@ -477,12 +465,6 @@ hb_font_reference (hb_font_t *font)
HB_OBJECT_DO_REFERENCE (font);
}
-unsigned int
-hb_font_get_reference_count (hb_font_t *font)
-{
- HB_OBJECT_DO_GET_REFERENCE_COUNT (font);
-}
-
void
hb_font_destroy (hb_font_t *font)
{
diff --git a/src/hb-font.h b/src/hb-font.h
index 4b9540b..29cd5cb 100644
--- a/src/hb-font.h
+++ b/src/hb-font.h
@@ -55,9 +55,6 @@ hb_face_create_for_tables (hb_get_table_func_t get_table,
hb_face_t *
hb_face_reference (hb_face_t *face);
-unsigned int
-hb_face_get_reference_count (hb_face_t *face);
-
void
hb_face_destroy (hb_face_t *face);
@@ -94,9 +91,6 @@ hb_font_funcs_create (void);
hb_font_funcs_t *
hb_font_funcs_reference (hb_font_funcs_t *ffuncs);
-unsigned int
-hb_font_funcs_get_reference_count (hb_font_funcs_t *ffuncs);
-
void
hb_font_funcs_destroy (hb_font_funcs_t *ffuncs);
@@ -209,9 +203,6 @@ hb_font_create (void);
hb_font_t *
hb_font_reference (hb_font_t *font);
-unsigned int
-hb_font_get_reference_count (hb_font_t *font);
-
void
hb_font_destroy (hb_font_t *font);
diff --git a/src/hb-object-private.h b/src/hb-object-private.h
index a5b5355..c1787c5 100644
--- a/src/hb-object-private.h
+++ b/src/hb-object-private.h
@@ -116,13 +116,6 @@ _hb_trace_object (const void *obj,
return obj; \
} HB_STMT_END
-#define HB_OBJECT_DO_GET_REFERENCE_COUNT(obj) \
- HB_STMT_START { \
- if (unlikely (!(obj) || HB_OBJECT_IS_INERT (obj))) \
- return 0; \
- return HB_REFERENCE_COUNT_GET_VALUE (obj->ref_count); \
- } HB_STMT_END
-
#define HB_OBJECT_DO_DESTROY(obj) \
HB_STMT_START { \
int old_count; \
diff --git a/src/hb-unicode.cc b/src/hb-unicode.cc
index ddad884..9295be7 100644
--- a/src/hb-unicode.cc
+++ b/src/hb-unicode.cc
@@ -128,12 +128,6 @@ hb_unicode_funcs_reference (hb_unicode_funcs_t *ufuncs)
HB_OBJECT_DO_REFERENCE (ufuncs);
}
-unsigned int
-hb_unicode_funcs_get_reference_count (hb_unicode_funcs_t *ufuncs)
-{
- HB_OBJECT_DO_GET_REFERENCE_COUNT (ufuncs);
-}
-
void
hb_unicode_funcs_destroy (hb_unicode_funcs_t *ufuncs)
{
diff --git a/src/hb-unicode.h b/src/hb-unicode.h
index 0b94aa3..0fcef06 100644
--- a/src/hb-unicode.h
+++ b/src/hb-unicode.h
@@ -46,9 +46,6 @@ hb_unicode_funcs_create (hb_unicode_funcs_t *parent_funcs);
hb_unicode_funcs_t *
hb_unicode_funcs_reference (hb_unicode_funcs_t *ufuncs);
-unsigned int
-hb_unicode_funcs_get_reference_count (hb_unicode_funcs_t *ufuncs);
-
void
hb_unicode_funcs_destroy (hb_unicode_funcs_t *ufuncs);
diff --git a/test/test-unicode.c b/test/test-unicode.c
index 923c250..b7a5702 100644
--- a/test/test-unicode.c
+++ b/test/test-unicode.c
@@ -35,7 +35,6 @@ test_nil (void)
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);
}
@@ -45,10 +44,6 @@ 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;
@@ -92,7 +87,6 @@ test_custom (void)
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);
@@ -123,13 +117,10 @@ test_subclassing_nil (void)
hb_unicode_funcs_t *uf, *aa;
uf = hb_unicode_funcs_create (NULL);
- g_assert_cmpint (hb_unicode_funcs_get_reference_count (uf), ==, 1);
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);
@@ -137,8 +128,6 @@ test_subclassing_nil (void)
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);
@@ -151,13 +140,7 @@ test_subclassing_glib (void)
hb_unicode_funcs_t *uf, *aa;
uf = hb_glib_get_unicode_funcs ();
- g_assert_cmpint (hb_unicode_funcs_get_reference_count (uf), ==, 0);
-
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);
@@ -165,7 +148,6 @@ test_subclassing_glib (void)
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);
@@ -178,17 +160,13 @@ test_subclassing_deep (void)
hb_unicode_funcs_t *uf, *aa;
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);
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);
@@ -200,8 +178,6 @@ test_subclassing_deep (void)
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);
More information about the HarfBuzz
mailing list