[HarfBuzz] harfbuzz-ng: Branch 'master' - 12 commits

Behdad Esfahbod behdad at kemper.freedesktop.org
Mon Apr 18 20:42:33 PDT 2011


 TODO                               |    9 
 src/hb-buffer-private.hh           |   15 -
 src/hb-buffer.cc                   |   50 ++--
 src/hb-buffer.h                    |   13 -
 src/hb-common.c                    |   93 +++++++-
 src/hb-common.h                    |  173 +++++++++++++++-
 src/hb-ot-layout.cc                |    6 
 src/hb-ot-layout.h                 |    4 
 src/hb-ot-map.cc                   |    4 
 src/hb-ot-shape-complex-private.hh |    3 
 src/hb-ot-shape.cc                 |   16 -
 src/hb-ot-shape.h                  |    4 
 src/hb-ot-tag.c                    |  228 +++++++++------------
 src/hb-ot-tag.h                    |    6 
 src/hb-shape.cc                    |   24 +-
 src/hb-shape.h                     |   10 
 src/hb-unicode.c                   |  400 -------------------------------------
 src/hb-unicode.h                   |  162 --------------
 src/hb-view.c                      |    8 
 test/test-buffer.c                 |    8 
 test/test-types.c                  |    2 
 21 files changed, 450 insertions(+), 788 deletions(-)

New commits:
commit 62879eebd9965179af8602ba29ac0a64a739b757
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Mon Apr 18 23:40:21 2011 -0400

    [API] Use ISO 15924 tags for hb_script_t
    
    This simplifies the code, reduces static data, and makes the design
    more extensible to future additions of new scripts.

diff --git a/src/hb-common.c b/src/hb-common.c
index a913415..56537e4 100644
--- a/src/hb-common.c
+++ b/src/hb-common.c
@@ -143,253 +143,22 @@ hb_language_to_string (hb_language_t language)
 
 /* hb_script_t */
 
-static const hb_tag_t script_to_iso15924_tag[] =
-{
-  HB_TAG('Z','y','y','y'),	/* HB_SCRIPT_COMMON */
-  HB_TAG('Q','a','a','i'),	/* HB_SCRIPT_INHERITED */
-  HB_TAG('A','r','a','b'),	/* HB_SCRIPT_ARABIC */
-  HB_TAG('A','r','m','n'),	/* HB_SCRIPT_ARMENIAN */
-  HB_TAG('B','e','n','g'),	/* HB_SCRIPT_BENGALI */
-  HB_TAG('B','o','p','o'),	/* HB_SCRIPT_BOPOMOFO */
-  HB_TAG('C','h','e','r'),	/* HB_SCRIPT_CHEROKEE */
-  HB_TAG('Q','a','a','c'),	/* HB_SCRIPT_COPTIC */
-  HB_TAG('C','y','r','l'),	/* HB_SCRIPT_CYRILLIC */
-  HB_TAG('D','s','r','t'),	/* HB_SCRIPT_DESERET */
-  HB_TAG('D','e','v','a'),	/* HB_SCRIPT_DEVANAGARI */
-  HB_TAG('E','t','h','i'),	/* HB_SCRIPT_ETHIOPIC */
-  HB_TAG('G','e','o','r'),	/* HB_SCRIPT_GEORGIAN */
-  HB_TAG('G','o','t','h'),	/* HB_SCRIPT_GOTHIC */
-  HB_TAG('G','r','e','k'),	/* HB_SCRIPT_GREEK */
-  HB_TAG('G','u','j','r'),	/* HB_SCRIPT_GUJARATI */
-  HB_TAG('G','u','r','u'),	/* HB_SCRIPT_GURMUKHI */
-  HB_TAG('H','a','n','i'),	/* HB_SCRIPT_HAN */
-  HB_TAG('H','a','n','g'),	/* HB_SCRIPT_HANGUL */
-  HB_TAG('H','e','b','r'),	/* HB_SCRIPT_HEBREW */
-  HB_TAG('H','i','r','a'),	/* HB_SCRIPT_HIRAGANA */
-  HB_TAG('K','n','d','a'),	/* HB_SCRIPT_KANNADA */
-  HB_TAG('K','a','n','a'),	/* HB_SCRIPT_KATAKANA */
-  HB_TAG('K','h','m','r'),	/* HB_SCRIPT_KHMER */
-  HB_TAG('L','a','o','o'),	/* HB_SCRIPT_LAO */
-  HB_TAG('L','a','t','n'),	/* HB_SCRIPT_LATIN */
-  HB_TAG('M','l','y','m'),	/* HB_SCRIPT_MALAYALAM */
-  HB_TAG('M','o','n','g'),	/* HB_SCRIPT_MONGOLIAN */
-  HB_TAG('M','y','m','r'),	/* HB_SCRIPT_MYANMAR */
-  HB_TAG('O','g','a','m'),	/* HB_SCRIPT_OGHAM */
-  HB_TAG('I','t','a','l'),	/* HB_SCRIPT_OLD_ITALIC */
-  HB_TAG('O','r','y','a'),	/* HB_SCRIPT_ORIYA */
-  HB_TAG('R','u','n','r'),	/* HB_SCRIPT_RUNIC */
-  HB_TAG('S','i','n','h'),	/* HB_SCRIPT_SINHALA */
-  HB_TAG('S','y','r','c'),	/* HB_SCRIPT_SYRIAC */
-  HB_TAG('T','a','m','l'),	/* HB_SCRIPT_TAMIL */
-  HB_TAG('T','e','l','u'),	/* HB_SCRIPT_TELUGU */
-  HB_TAG('T','h','a','a'),	/* HB_SCRIPT_THAANA */
-  HB_TAG('T','h','a','i'),	/* HB_SCRIPT_THAI */
-  HB_TAG('T','i','b','t'),	/* HB_SCRIPT_TIBETAN */
-  HB_TAG('C','a','n','s'),	/* HB_SCRIPT_CANADIAN_ABORIGINAL */
-  HB_TAG('Y','i','i','i'),	/* HB_SCRIPT_YI */
-  HB_TAG('T','g','l','g'),	/* HB_SCRIPT_TAGALOG */
-  HB_TAG('H','a','n','o'),	/* HB_SCRIPT_HANUNOO */
-  HB_TAG('B','u','h','d'),	/* HB_SCRIPT_BUHID */
-  HB_TAG('T','a','g','b'),	/* HB_SCRIPT_TAGBANWA */
-
-  /* Unicode-4.0 additions */
-  HB_TAG('B','r','a','i'),	/* HB_SCRIPT_BRAILLE */
-  HB_TAG('C','p','r','t'),	/* HB_SCRIPT_CYPRIOT */
-  HB_TAG('L','i','m','b'),	/* HB_SCRIPT_LIMBU */
-  HB_TAG('O','s','m','a'),	/* HB_SCRIPT_OSMANYA */
-  HB_TAG('S','h','a','w'),	/* HB_SCRIPT_SHAVIAN */
-  HB_TAG('L','i','n','b'),	/* HB_SCRIPT_LINEAR_B */
-  HB_TAG('T','a','l','e'),	/* HB_SCRIPT_TAI_LE */
-  HB_TAG('U','g','a','r'),	/* HB_SCRIPT_UGARITIC */
-
-  /* Unicode-4.1 additions */
-  HB_TAG('T','a','l','u'),	/* HB_SCRIPT_NEW_TAI_LUE */
-  HB_TAG('B','u','g','i'),	/* HB_SCRIPT_BUGINESE */
-  HB_TAG('G','l','a','g'),	/* HB_SCRIPT_GLAGOLITIC */
-  HB_TAG('T','f','n','g'),	/* HB_SCRIPT_TIFINAGH */
-  HB_TAG('S','y','l','o'),	/* HB_SCRIPT_SYLOTI_NAGRI */
-  HB_TAG('X','p','e','o'),	/* HB_SCRIPT_OLD_PERSIAN */
-  HB_TAG('K','h','a','r'),	/* HB_SCRIPT_KHAROSHTHI */
-
-  /* Unicode-5.0 additions */
-  HB_TAG('Z','z','z','z'),	/* HB_SCRIPT_UNKNOWN */
-  HB_TAG('B','a','l','i'),	/* HB_SCRIPT_BALINESE */
-  HB_TAG('X','s','u','x'),	/* HB_SCRIPT_CUNEIFORM */
-  HB_TAG('P','h','n','x'),	/* HB_SCRIPT_PHOENICIAN */
-  HB_TAG('P','h','a','g'),	/* HB_SCRIPT_PHAGS_PA */
-  HB_TAG('N','k','o','o'),	/* HB_SCRIPT_NKO */
-
-  /* Unicode-5.1 additions */
-  HB_TAG('K','a','l','i'),	/* HB_SCRIPT_KAYAH_LI */
-  HB_TAG('L','e','p','c'),	/* HB_SCRIPT_LEPCHA */
-  HB_TAG('R','j','n','g'),	/* HB_SCRIPT_REJANG */
-  HB_TAG('S','u','n','d'),	/* HB_SCRIPT_SUNDANESE */
-  HB_TAG('S','a','u','r'),	/* HB_SCRIPT_SAURASHTRA */
-  HB_TAG('C','h','a','m'),	/* HB_SCRIPT_CHAM */
-  HB_TAG('O','l','c','k'),	/* HB_SCRIPT_OL_CHIKI */
-  HB_TAG('V','a','i','i'),	/* HB_SCRIPT_VAI */
-  HB_TAG('C','a','r','i'),	/* HB_SCRIPT_CARIAN */
-  HB_TAG('L','y','c','i'),	/* HB_SCRIPT_LYCIAN */
-  HB_TAG('L','y','d','i'),	/* HB_SCRIPT_LYDIAN */
-
-  /* Unicode-5.2 additions */
-  HB_TAG('A','v','s','t'),	/* HB_SCRIPT_AVESTAN */
-  HB_TAG('B','a','m','u'),	/* HB_SCRIPT_BAMUM */
-  HB_TAG('E','g','y','p'),	/* HB_SCRIPT_EGYPTIAN_HIEROGLYPHS */
-  HB_TAG('A','r','m','i'),	/* HB_SCRIPT_IMPERIAL_ARAMAIC */
-  HB_TAG('P','h','l','i'),	/* HB_SCRIPT_INSCRIPTIONAL_PAHLAVI */
-  HB_TAG('P','r','t','i'),	/* HB_SCRIPT_INSCRIPTIONAL_PARTHIAN */
-  HB_TAG('J','a','v','a'),	/* HB_SCRIPT_JAVANESE */
-  HB_TAG('K','t','h','i'),	/* HB_SCRIPT_KAITHI */
-  HB_TAG('L','i','s','u'),	/* HB_SCRIPT_LISU */
-  HB_TAG('M','t','e','i'),	/* HB_SCRIPT_MEETEI_MAYEK */
-  HB_TAG('S','a','r','b'),	/* HB_SCRIPT_OLD_SOUTH_ARABIAN */
-  HB_TAG('O','r','k','h'),	/* HB_SCRIPT_OLD_TURKIC */
-  HB_TAG('S','a','m','r'),	/* HB_SCRIPT_SAMARITAN */
-  HB_TAG('L','a','n','a'),	/* HB_SCRIPT_TAI_THAM */
-  HB_TAG('T','a','v','t'),	/* HB_SCRIPT_TAI_VIET */
-
-  /* Unicode-6.0 additions */
-  HB_TAG('B','a','t','k'),	/* HB_SCRIPT_BATAK */
-  HB_TAG('B','r','a','h'),	/* HB_SCRIPT_BRAHMI */
-  HB_TAG('M','a','n','d') 	/* HB_SCRIPT_MANDAIC */
-};
-
-struct tag_script_pair {
-  hb_tag_t tag;
-  hb_script_t script;
-};
-static const struct tag_script_pair script_from_iso15924_tag[] =
-{
-  {HB_TAG('A','r','a','b'), HB_SCRIPT_ARABIC},
-  {HB_TAG('A','r','m','i'), HB_SCRIPT_IMPERIAL_ARAMAIC},
-  {HB_TAG('A','r','m','n'), HB_SCRIPT_ARMENIAN},
-  {HB_TAG('A','v','s','t'), HB_SCRIPT_AVESTAN},
-  {HB_TAG('B','a','l','i'), HB_SCRIPT_BALINESE},
-  {HB_TAG('B','a','m','u'), HB_SCRIPT_BAMUM},
-  {HB_TAG('B','a','t','k'), HB_SCRIPT_BATAK},
-  {HB_TAG('B','e','n','g'), HB_SCRIPT_BENGALI},
-  {HB_TAG('B','o','p','o'), HB_SCRIPT_BOPOMOFO},
-  {HB_TAG('B','r','a','h'), HB_SCRIPT_BRAHMI},
-  {HB_TAG('B','r','a','i'), HB_SCRIPT_BRAILLE},
-  {HB_TAG('B','u','g','i'), HB_SCRIPT_BUGINESE},
-  {HB_TAG('B','u','h','d'), HB_SCRIPT_BUHID},
-  {HB_TAG('C','a','n','s'), HB_SCRIPT_CANADIAN_ABORIGINAL},
-  {HB_TAG('C','a','r','i'), HB_SCRIPT_CARIAN},
-  {HB_TAG('C','h','a','m'), HB_SCRIPT_CHAM},
-  {HB_TAG('C','h','e','r'), HB_SCRIPT_CHEROKEE},
-  {HB_TAG('C','p','r','t'), HB_SCRIPT_CYPRIOT},
-  {HB_TAG('C','y','r','l'), HB_SCRIPT_CYRILLIC},
-  {HB_TAG('C','y','r','s'), HB_SCRIPT_CYRILLIC},
-  {HB_TAG('D','e','v','a'), HB_SCRIPT_DEVANAGARI},
-  {HB_TAG('D','s','r','t'), HB_SCRIPT_DESERET},
-  {HB_TAG('E','g','y','p'), HB_SCRIPT_EGYPTIAN_HIEROGLYPHS},
-  {HB_TAG('E','t','h','i'), HB_SCRIPT_ETHIOPIC},
-  {HB_TAG('G','e','o','a'), HB_SCRIPT_GEORGIAN},
-  {HB_TAG('G','e','o','n'), HB_SCRIPT_GEORGIAN},
-  {HB_TAG('G','e','o','r'), HB_SCRIPT_GEORGIAN},
-  {HB_TAG('G','l','a','g'), HB_SCRIPT_GLAGOLITIC},
-  {HB_TAG('G','o','t','h'), HB_SCRIPT_GOTHIC},
-  {HB_TAG('G','r','e','k'), HB_SCRIPT_GREEK},
-  {HB_TAG('G','u','j','r'), HB_SCRIPT_GUJARATI},
-  {HB_TAG('G','u','r','u'), HB_SCRIPT_GURMUKHI},
-  {HB_TAG('H','a','n','g'), HB_SCRIPT_HANGUL},
-  {HB_TAG('H','a','n','i'), HB_SCRIPT_HAN},
-  {HB_TAG('H','a','n','o'), HB_SCRIPT_HANUNOO},
-  {HB_TAG('H','e','b','r'), HB_SCRIPT_HEBREW},
-  {HB_TAG('H','i','r','a'), HB_SCRIPT_HIRAGANA},
-  {HB_TAG('I','t','a','l'), HB_SCRIPT_OLD_ITALIC},
-  {HB_TAG('J','a','v','a'), HB_SCRIPT_JAVANESE},
-  {HB_TAG('K','a','l','i'), HB_SCRIPT_KAYAH_LI},
-  {HB_TAG('K','a','n','a'), HB_SCRIPT_KATAKANA},
-  {HB_TAG('K','h','a','r'), HB_SCRIPT_KHAROSHTHI},
-  {HB_TAG('K','h','m','r'), HB_SCRIPT_KHMER},
-  {HB_TAG('K','n','d','a'), HB_SCRIPT_KANNADA},
-  {HB_TAG('K','t','h','i'), HB_SCRIPT_KAITHI},
-  {HB_TAG('L','a','n','a'), HB_SCRIPT_TAI_THAM},
-  {HB_TAG('L','a','o','o'), HB_SCRIPT_LAO},
-  {HB_TAG('L','a','t','f'), HB_SCRIPT_LATIN},
-  {HB_TAG('L','a','t','g'), HB_SCRIPT_LATIN},
-  {HB_TAG('L','a','t','n'), HB_SCRIPT_LATIN},
-  {HB_TAG('L','e','p','c'), HB_SCRIPT_LEPCHA},
-  {HB_TAG('L','i','m','b'), HB_SCRIPT_LIMBU},
-  {HB_TAG('L','i','n','b'), HB_SCRIPT_LINEAR_B},
-  {HB_TAG('L','i','s','u'), HB_SCRIPT_LISU},
-  {HB_TAG('L','y','c','i'), HB_SCRIPT_LYCIAN},
-  {HB_TAG('L','y','d','i'), HB_SCRIPT_LYDIAN},
-  {HB_TAG('M','a','n','d'), HB_SCRIPT_MANDAIC},
-  {HB_TAG('M','l','y','m'), HB_SCRIPT_MALAYALAM},
-  {HB_TAG('M','o','n','g'), HB_SCRIPT_MONGOLIAN},
-  {HB_TAG('M','t','e','i'), HB_SCRIPT_MEETEI_MAYEK},
-  {HB_TAG('M','y','m','r'), HB_SCRIPT_MYANMAR},
-  {HB_TAG('N','k','o','o'), HB_SCRIPT_NKO},
-  {HB_TAG('O','g','a','m'), HB_SCRIPT_OGHAM},
-  {HB_TAG('O','l','c','k'), HB_SCRIPT_OL_CHIKI},
-  {HB_TAG('O','r','k','h'), HB_SCRIPT_OLD_TURKIC},
-  {HB_TAG('O','r','y','a'), HB_SCRIPT_ORIYA},
-  {HB_TAG('O','s','m','a'), HB_SCRIPT_OSMANYA},
-  {HB_TAG('P','h','a','g'), HB_SCRIPT_PHAGS_PA},
-  {HB_TAG('P','h','l','i'), HB_SCRIPT_INSCRIPTIONAL_PAHLAVI},
-  {HB_TAG('P','h','n','x'), HB_SCRIPT_PHOENICIAN},
-  {HB_TAG('P','r','t','i'), HB_SCRIPT_INSCRIPTIONAL_PARTHIAN},
-  {HB_TAG('Q','a','a','c'), HB_SCRIPT_COPTIC},
-  {HB_TAG('Q','a','a','i'), HB_SCRIPT_INHERITED},
-  {HB_TAG('R','j','n','g'), HB_SCRIPT_REJANG},
-  {HB_TAG('R','u','n','r'), HB_SCRIPT_RUNIC},
-  {HB_TAG('S','a','m','r'), HB_SCRIPT_SAMARITAN},
-  {HB_TAG('S','a','r','b'), HB_SCRIPT_OLD_SOUTH_ARABIAN},
-  {HB_TAG('S','a','u','r'), HB_SCRIPT_SAURASHTRA},
-  {HB_TAG('S','h','a','w'), HB_SCRIPT_SHAVIAN},
-  {HB_TAG('S','i','n','h'), HB_SCRIPT_SINHALA},
-  {HB_TAG('S','u','n','d'), HB_SCRIPT_SUNDANESE},
-  {HB_TAG('S','y','l','o'), HB_SCRIPT_SYLOTI_NAGRI},
-  {HB_TAG('S','y','r','c'), HB_SCRIPT_SYRIAC},
-  {HB_TAG('S','y','r','e'), HB_SCRIPT_SYRIAC},
-  {HB_TAG('S','y','r','n'), HB_SCRIPT_SYRIAC},
-  {HB_TAG('T','a','g','b'), HB_SCRIPT_TAGBANWA},
-  {HB_TAG('T','a','l','e'), HB_SCRIPT_TAI_LE},
-  {HB_TAG('T','a','l','u'), HB_SCRIPT_NEW_TAI_LUE},
-  {HB_TAG('T','a','m','l'), HB_SCRIPT_TAMIL},
-  {HB_TAG('T','a','v','t'), HB_SCRIPT_TAI_VIET},
-  {HB_TAG('T','e','l','u'), HB_SCRIPT_TELUGU},
-  {HB_TAG('T','f','n','g'), HB_SCRIPT_TIFINAGH},
-  {HB_TAG('T','g','l','g'), HB_SCRIPT_TAGALOG},
-  {HB_TAG('T','h','a','a'), HB_SCRIPT_THAANA},
-  {HB_TAG('T','h','a','i'), HB_SCRIPT_THAI},
-  {HB_TAG('T','i','b','t'), HB_SCRIPT_TIBETAN},
-  {HB_TAG('U','g','a','r'), HB_SCRIPT_UGARITIC},
-  {HB_TAG('V','a','i','i'), HB_SCRIPT_VAI},
-  {HB_TAG('X','p','e','o'), HB_SCRIPT_OLD_PERSIAN},
-  {HB_TAG('X','s','u','x'), HB_SCRIPT_CUNEIFORM},
-  {HB_TAG('Y','i','i','i'), HB_SCRIPT_YI},
-  {HB_TAG('Z','y','y','y'), HB_SCRIPT_COMMON},
-  {HB_TAG('Z','z','z','z'), HB_SCRIPT_UNKNOWN}
-};
-
-static int
-_tag_cmp (hb_tag_t *pa, hb_tag_t *pb)
-{
-  hb_tag_t a = *pa, b = *pb;
-  return a < b ? -1 : a == b ? 0 : +1;
-}
-
-
 hb_script_t
 hb_script_from_iso15924_tag (hb_tag_t tag)
 {
-  const struct tag_script_pair *pair;
-
   /* Be lenient, adjust case (one capital letter followed by three small letters) */
   tag = (tag & 0xDFDFDFDF) | 0x00202020;
 
-  pair = (const struct tag_script_pair *) bsearch (&tag,
-						   script_from_iso15924_tag,
-						   ARRAY_LENGTH (script_from_iso15924_tag),
-						   sizeof (script_from_iso15924_tag[0]),
-						   (hb_compare_func_t) _tag_cmp);
-
-  if (pair)
-    return pair->script;
+  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)
@@ -408,142 +177,42 @@ hb_script_from_string (const char *s)
 hb_tag_t
 hb_script_to_iso15924_tag (hb_script_t script)
 {
-  if (likely ((unsigned int) script < ARRAY_LENGTH (script_to_iso15924_tag)))
-    return script_to_iso15924_tag[script];
-
-  /* if script is of the right shape (one capital letter followed by three small letters),
-   * return as is. */
-  if (((uint32_t) script & 0xE0E0E0E0) == 0x40606060)
-    return (hb_tag_t) script;
-
-  /* Otherwise, we don't know what that is */
-  return script_to_iso15924_tag[HB_SCRIPT_UNKNOWN];
+  return (hb_tag_t) script;
 }
 
-
-#define LTR HB_DIRECTION_LTR
-#define RTL HB_DIRECTION_RTL
-const hb_direction_t horiz_dir[] =
-{
-  LTR,	/* Zyyy */
-  LTR,	/* Qaai */
-  RTL,	/* Arab */
-  LTR,	/* Armn */
-  LTR,	/* Beng */
-  LTR,	/* Bopo */
-  LTR,	/* Cher */
-  LTR,	/* Qaac */
-  LTR,	/* Cyrl (Cyrs) */
-  LTR,	/* Dsrt */
-  LTR,	/* Deva */
-  LTR,	/* Ethi */
-  LTR,	/* Geor (Geon, Geoa) */
-  LTR,	/* Goth */
-  LTR,	/* Grek */
-  LTR,	/* Gujr */
-  LTR,	/* Guru */
-  LTR,	/* Hani */
-  LTR,	/* Hang */
-  RTL,	/* Hebr */
-  LTR,	/* Hira */
-  LTR,	/* Knda */
-  LTR,	/* Kana */
-  LTR,	/* Khmr */
-  LTR,	/* Laoo */
-  LTR,	/* Latn (Latf, Latg) */
-  LTR,	/* Mlym */
-  LTR,	/* Mong */
-  LTR,	/* Mymr */
-  LTR,	/* Ogam */
-  LTR,	/* Ital */
-  LTR,	/* Orya */
-  LTR,	/* Runr */
-  LTR,	/* Sinh */
-  RTL,	/* Syrc (Syrj, Syrn, Syre) */
-  LTR,	/* Taml */
-  LTR,	/* Telu */
-  RTL,	/* Thaa */
-  LTR,	/* Thai */
-  LTR,	/* Tibt */
-  LTR,	/* Cans */
-  LTR,	/* Yiii */
-  LTR,	/* Tglg */
-  LTR,	/* Hano */
-  LTR,	/* Buhd */
-  LTR,	/* Tagb */
-
-  /* Unicode-4.0 additions */
-  LTR,	/* Brai */
-  RTL,	/* Cprt */
-  LTR,	/* Limb */
-  LTR,	/* Osma */
-  LTR,	/* Shaw */
-  LTR,	/* Linb */
-  LTR,	/* Tale */
-  LTR,	/* Ugar */
-
-  /* Unicode-4.1 additions */
-  LTR,	/* Talu */
-  LTR,	/* Bugi */
-  LTR,	/* Glag */
-  LTR,	/* Tfng */
-  LTR,	/* Sylo */
-  LTR,	/* Xpeo */
-  LTR,	/* Khar */
-
-  /* Unicode-5.0 additions */
-  LTR,	/* Zzzz */
-  LTR,	/* Bali */
-  LTR,	/* Xsux */
-  RTL,	/* Phnx */
-  LTR,	/* Phag */
-  RTL,	/* Nkoo */
-
-  /* Unicode-5.1 additions */
-  LTR,	/* Kali */
-  LTR,	/* Lepc */
-  LTR,	/* Rjng */
-  LTR,	/* Sund */
-  LTR,	/* Saur */
-  LTR,	/* Cham */
-  LTR,	/* Olck */
-  LTR,	/* Vaii */
-  LTR,	/* Cari */
-  LTR,	/* Lyci */
-  LTR,	/* Lydi */
-
-  /* Unicode-5.2 additions */
-  RTL,	/* Avst */
-  LTR,	/* Bamu */
-  LTR,	/* Egyp */
-  RTL,	/* Armi */
-  RTL,	/* Phli */
-  RTL,	/* Prti */
-  LTR,	/* Java */
-  LTR,	/* Kthi */
-  LTR,	/* Lisu */
-  LTR,	/* Mtei */
-  RTL,	/* Sarb */
-  RTL,	/* Orkh */
-  RTL,	/* Samr */
-  LTR,	/* Lana */
-  LTR,	/* Tavt */
-
-  /* Unicode-6.0 additions */
-  LTR,	/* Batk */
-  LTR,	/* Brah */
-  RTL 	/* Mand */
-};
-#undef LTR
-#undef RTL
-
 hb_direction_t
 hb_script_get_horizontal_direction (hb_script_t script)
 {
-  if (unlikely ((unsigned int) script >= ARRAY_LENGTH (horiz_dir)))
-    return HB_DIRECTION_LTR;
+  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 horiz_dir[script];
+  return HB_DIRECTION_LTR;
 }
 
 
diff --git a/src/hb-common.h b/src/hb-common.h
index 21caa71..c6481bb 100644
--- a/src/hb-common.h
+++ b/src/hb-common.h
@@ -148,117 +148,118 @@ typedef enum
 /* hb_script_t */
 
 typedef enum
-{                               /* ISO 15924 code */
-  HB_SCRIPT_INVALID = -1,
-
-  HB_SCRIPT_COMMON       = 0,   /* Zyyy */
-  HB_SCRIPT_INHERITED,          /* Qaai */
-  HB_SCRIPT_ARABIC,             /* Arab */
-  HB_SCRIPT_ARMENIAN,           /* Armn */
-  HB_SCRIPT_BENGALI,            /* Beng */
-  HB_SCRIPT_BOPOMOFO,           /* Bopo */
-  HB_SCRIPT_CHEROKEE,           /* Cher */
-  HB_SCRIPT_COPTIC,             /* Qaac */
-  HB_SCRIPT_CYRILLIC,           /* Cyrl (Cyrs) */
-  HB_SCRIPT_DESERET,            /* Dsrt */
-  HB_SCRIPT_DEVANAGARI,         /* Deva */
-  HB_SCRIPT_ETHIOPIC,           /* Ethi */
-  HB_SCRIPT_GEORGIAN,           /* Geor (Geon, Geoa) */
-  HB_SCRIPT_GOTHIC,             /* Goth */
-  HB_SCRIPT_GREEK,              /* Grek */
-  HB_SCRIPT_GUJARATI,           /* Gujr */
-  HB_SCRIPT_GURMUKHI,           /* Guru */
-  HB_SCRIPT_HAN,                /* Hani */
-  HB_SCRIPT_HANGUL,             /* Hang */
-  HB_SCRIPT_HEBREW,             /* Hebr */
-  HB_SCRIPT_HIRAGANA,           /* Hira */
-  HB_SCRIPT_KANNADA,            /* Knda */
-  HB_SCRIPT_KATAKANA,           /* Kana */
-  HB_SCRIPT_KHMER,              /* Khmr */
-  HB_SCRIPT_LAO,                /* Laoo */
-  HB_SCRIPT_LATIN,              /* Latn (Latf, Latg) */
-  HB_SCRIPT_MALAYALAM,          /* Mlym */
-  HB_SCRIPT_MONGOLIAN,          /* Mong */
-  HB_SCRIPT_MYANMAR,            /* Mymr */
-  HB_SCRIPT_OGHAM,              /* Ogam */
-  HB_SCRIPT_OLD_ITALIC,         /* Ital */
-  HB_SCRIPT_ORIYA,              /* Orya */
-  HB_SCRIPT_RUNIC,              /* Runr */
-  HB_SCRIPT_SINHALA,            /* Sinh */
-  HB_SCRIPT_SYRIAC,             /* Syrc (Syrj, Syrn, Syre) */
-  HB_SCRIPT_TAMIL,              /* Taml */
-  HB_SCRIPT_TELUGU,             /* Telu */
-  HB_SCRIPT_THAANA,             /* Thaa */
-  HB_SCRIPT_THAI,               /* Thai */
-  HB_SCRIPT_TIBETAN,            /* Tibt */
-  HB_SCRIPT_CANADIAN_ABORIGINAL, /* Cans */
-  HB_SCRIPT_YI,                 /* Yiii */
-  HB_SCRIPT_TAGALOG,            /* Tglg */
-  HB_SCRIPT_HANUNOO,            /* Hano */
-  HB_SCRIPT_BUHID,              /* Buhd */
-  HB_SCRIPT_TAGBANWA,           /* Tagb */
+{
+  HB_SCRIPT_COMMON                  = HB_TAG ('Z','y','y','y'),
+  HB_SCRIPT_INHERITED               = HB_TAG ('Q','a','a','i'),
+  HB_SCRIPT_ARABIC                  = HB_TAG ('A','r','a','b'),
+  HB_SCRIPT_ARMENIAN                = HB_TAG ('A','r','m','n'),
+  HB_SCRIPT_BENGALI                 = HB_TAG ('B','e','n','g'),
+  HB_SCRIPT_BOPOMOFO                = HB_TAG ('B','o','p','o'),
+  HB_SCRIPT_CHEROKEE                = HB_TAG ('C','h','e','r'),
+  HB_SCRIPT_COPTIC                  = HB_TAG ('Q','a','a','c'),
+  HB_SCRIPT_CYRILLIC                = HB_TAG ('C','y','r','l'),
+  HB_SCRIPT_DESERET                 = HB_TAG ('D','s','r','t'),
+  HB_SCRIPT_DEVANAGARI              = HB_TAG ('D','e','v','a'),
+  HB_SCRIPT_ETHIOPIC                = HB_TAG ('E','t','h','i'),
+  HB_SCRIPT_GEORGIAN                = HB_TAG ('G','e','o','r'),
+  HB_SCRIPT_GOTHIC                  = HB_TAG ('G','o','t','h'),
+  HB_SCRIPT_GREEK                   = HB_TAG ('G','r','e','k'),
+  HB_SCRIPT_GUJARATI                = HB_TAG ('G','u','j','r'),
+  HB_SCRIPT_GURMUKHI                = HB_TAG ('G','u','r','u'),
+  HB_SCRIPT_HAN                     = HB_TAG ('H','a','n','i'),
+  HB_SCRIPT_HANGUL                  = HB_TAG ('H','a','n','g'),
+  HB_SCRIPT_HEBREW                  = HB_TAG ('H','e','b','r'),
+  HB_SCRIPT_HIRAGANA                = HB_TAG ('H','i','r','a'),
+  HB_SCRIPT_KANNADA                 = HB_TAG ('K','n','d','a'),
+  HB_SCRIPT_KATAKANA                = HB_TAG ('K','a','n','a'),
+  HB_SCRIPT_KHMER                   = HB_TAG ('K','h','m','r'),
+  HB_SCRIPT_LAO                     = HB_TAG ('L','a','o','o'),
+  HB_SCRIPT_LATIN                   = HB_TAG ('L','a','t','n'),
+  HB_SCRIPT_MALAYALAM               = HB_TAG ('M','l','y','m'),
+  HB_SCRIPT_MONGOLIAN               = HB_TAG ('M','o','n','g'),
+  HB_SCRIPT_MYANMAR                 = HB_TAG ('M','y','m','r'),
+  HB_SCRIPT_OGHAM                   = HB_TAG ('O','g','a','m'),
+  HB_SCRIPT_OLD_ITALIC              = HB_TAG ('I','t','a','l'),
+  HB_SCRIPT_ORIYA                   = HB_TAG ('O','r','y','a'),
+  HB_SCRIPT_RUNIC                   = HB_TAG ('R','u','n','r'),
+  HB_SCRIPT_SINHALA                 = HB_TAG ('S','i','n','h'),
+  HB_SCRIPT_SYRIAC                  = HB_TAG ('S','y','r','c'),
+  HB_SCRIPT_TAMIL                   = HB_TAG ('T','a','m','l'),
+  HB_SCRIPT_TELUGU                  = HB_TAG ('T','e','l','u'),
+  HB_SCRIPT_THAANA                  = HB_TAG ('T','h','a','a'),
+  HB_SCRIPT_THAI                    = HB_TAG ('T','h','a','i'),
+  HB_SCRIPT_TIBETAN                 = HB_TAG ('T','i','b','t'),
+  HB_SCRIPT_CANADIAN_ABORIGINAL     = HB_TAG ('C','a','n','s'),
+  HB_SCRIPT_YI                      = HB_TAG ('Y','i','i','i'),
+  HB_SCRIPT_TAGALOG                 = HB_TAG ('T','g','l','g'),
+  HB_SCRIPT_HANUNOO                 = HB_TAG ('H','a','n','o'),
+  HB_SCRIPT_BUHID                   = HB_TAG ('B','u','h','d'),
+  HB_SCRIPT_TAGBANWA                = HB_TAG ('T','a','g','b'),
 
   /* Unicode-4.0 additions */
-  HB_SCRIPT_BRAILLE,            /* Brai */
-  HB_SCRIPT_CYPRIOT,            /* Cprt */
-  HB_SCRIPT_LIMBU,              /* Limb */
-  HB_SCRIPT_OSMANYA,            /* Osma */
-  HB_SCRIPT_SHAVIAN,            /* Shaw */
-  HB_SCRIPT_LINEAR_B,           /* Linb */
-  HB_SCRIPT_TAI_LE,             /* Tale */
-  HB_SCRIPT_UGARITIC,           /* Ugar */
+  HB_SCRIPT_BRAILLE                 = HB_TAG ('B','r','a','i'),
+  HB_SCRIPT_CYPRIOT                 = HB_TAG ('C','p','r','t'),
+  HB_SCRIPT_LIMBU                   = HB_TAG ('L','i','m','b'),
+  HB_SCRIPT_OSMANYA                 = HB_TAG ('O','s','m','a'),
+  HB_SCRIPT_SHAVIAN                 = HB_TAG ('S','h','a','w'),
+  HB_SCRIPT_LINEAR_B                = HB_TAG ('L','i','n','b'),
+  HB_SCRIPT_TAI_LE                  = HB_TAG ('T','a','l','e'),
+  HB_SCRIPT_UGARITIC                = HB_TAG ('U','g','a','r'),
 
   /* Unicode-4.1 additions */
-  HB_SCRIPT_NEW_TAI_LUE,        /* Talu */
-  HB_SCRIPT_BUGINESE,           /* Bugi */
-  HB_SCRIPT_GLAGOLITIC,         /* Glag */
-  HB_SCRIPT_TIFINAGH,           /* Tfng */
-  HB_SCRIPT_SYLOTI_NAGRI,       /* Sylo */
-  HB_SCRIPT_OLD_PERSIAN,        /* Xpeo */
-  HB_SCRIPT_KHAROSHTHI,         /* Khar */
+  HB_SCRIPT_NEW_TAI_LUE             = HB_TAG ('T','a','l','u'),
+  HB_SCRIPT_BUGINESE                = HB_TAG ('B','u','g','i'),
+  HB_SCRIPT_GLAGOLITIC              = HB_TAG ('G','l','a','g'),
+  HB_SCRIPT_TIFINAGH                = HB_TAG ('T','f','n','g'),
+  HB_SCRIPT_SYLOTI_NAGRI            = HB_TAG ('S','y','l','o'),
+  HB_SCRIPT_OLD_PERSIAN             = HB_TAG ('X','p','e','o'),
+  HB_SCRIPT_KHAROSHTHI              = HB_TAG ('K','h','a','r'),
 
   /* Unicode-5.0 additions */
-  HB_SCRIPT_UNKNOWN,            /* Zzzz */
-  HB_SCRIPT_BALINESE,           /* Bali */
-  HB_SCRIPT_CUNEIFORM,          /* Xsux */
-  HB_SCRIPT_PHOENICIAN,         /* Phnx */
-  HB_SCRIPT_PHAGS_PA,           /* Phag */
-  HB_SCRIPT_NKO,                /* Nkoo */
+  HB_SCRIPT_UNKNOWN                 = HB_TAG ('Z','z','z','z'),
+  HB_SCRIPT_BALINESE                = HB_TAG ('B','a','l','i'),
+  HB_SCRIPT_CUNEIFORM               = HB_TAG ('X','s','u','x'),
+  HB_SCRIPT_PHOENICIAN              = HB_TAG ('P','h','n','x'),
+  HB_SCRIPT_PHAGS_PA                = HB_TAG ('P','h','a','g'),
+  HB_SCRIPT_NKO                     = HB_TAG ('N','k','o','o'),
 
   /* Unicode-5.1 additions */
-  HB_SCRIPT_KAYAH_LI,           /* Kali */
-  HB_SCRIPT_LEPCHA,             /* Lepc */
-  HB_SCRIPT_REJANG,             /* Rjng */
-  HB_SCRIPT_SUNDANESE,          /* Sund */
-  HB_SCRIPT_SAURASHTRA,         /* Saur */
-  HB_SCRIPT_CHAM,               /* Cham */
-  HB_SCRIPT_OL_CHIKI,           /* Olck */
-  HB_SCRIPT_VAI,                /* Vaii */
-  HB_SCRIPT_CARIAN,             /* Cari */
-  HB_SCRIPT_LYCIAN,             /* Lyci */
-  HB_SCRIPT_LYDIAN,             /* Lydi */
+  HB_SCRIPT_KAYAH_LI                = HB_TAG ('K','a','l','i'),
+  HB_SCRIPT_LEPCHA                  = HB_TAG ('L','e','p','c'),
+  HB_SCRIPT_REJANG                  = HB_TAG ('R','j','n','g'),
+  HB_SCRIPT_SUNDANESE               = HB_TAG ('S','u','n','d'),
+  HB_SCRIPT_SAURASHTRA              = HB_TAG ('S','a','u','r'),
+  HB_SCRIPT_CHAM                    = HB_TAG ('C','h','a','m'),
+  HB_SCRIPT_OL_CHIKI                = HB_TAG ('O','l','c','k'),
+  HB_SCRIPT_VAI                     = HB_TAG ('V','a','i','i'),
+  HB_SCRIPT_CARIAN                  = HB_TAG ('C','a','r','i'),
+  HB_SCRIPT_LYCIAN                  = HB_TAG ('L','y','c','i'),
+  HB_SCRIPT_LYDIAN                  = HB_TAG ('L','y','d','i'),
 
   /* Unicode-5.2 additions */
-  HB_SCRIPT_AVESTAN,                /* Avst */
-  HB_SCRIPT_BAMUM,                  /* Bamu */
-  HB_SCRIPT_EGYPTIAN_HIEROGLYPHS,   /* Egyp */
-  HB_SCRIPT_IMPERIAL_ARAMAIC,       /* Armi */
-  HB_SCRIPT_INSCRIPTIONAL_PAHLAVI,  /* Phli */
-  HB_SCRIPT_INSCRIPTIONAL_PARTHIAN, /* Prti */
-  HB_SCRIPT_JAVANESE,               /* Java */
-  HB_SCRIPT_KAITHI,                 /* Kthi */
-  HB_SCRIPT_LISU,                   /* Lisu */
-  HB_SCRIPT_MEETEI_MAYEK,           /* Mtei */
-  HB_SCRIPT_OLD_SOUTH_ARABIAN,      /* Sarb */
-  HB_SCRIPT_OLD_TURKIC,             /* Orkh */
-  HB_SCRIPT_SAMARITAN,              /* Samr */
-  HB_SCRIPT_TAI_THAM,               /* Lana */
-  HB_SCRIPT_TAI_VIET,               /* Tavt */
+  HB_SCRIPT_AVESTAN                 = HB_TAG ('A','v','s','t'),
+  HB_SCRIPT_BAMUM                   = HB_TAG ('B','a','m','u'),
+  HB_SCRIPT_EGYPTIAN_HIEROGLYPHS    = HB_TAG ('E','g','y','p'),
+  HB_SCRIPT_IMPERIAL_ARAMAIC        = HB_TAG ('A','r','m','i'),
+  HB_SCRIPT_INSCRIPTIONAL_PAHLAVI   = HB_TAG ('P','h','l','i'),
+  HB_SCRIPT_INSCRIPTIONAL_PARTHIAN  = HB_TAG ('P','r','t','i'),
+  HB_SCRIPT_JAVANESE                = HB_TAG ('J','a','v','a'),
+  HB_SCRIPT_KAITHI                  = HB_TAG ('K','t','h','i'),
+  HB_SCRIPT_LISU                    = HB_TAG ('L','i','s','u'),
+  HB_SCRIPT_MEETEI_MAYEK            = HB_TAG ('M','t','e','i'),
+  HB_SCRIPT_OLD_SOUTH_ARABIAN       = HB_TAG ('S','a','r','b'),
+  HB_SCRIPT_OLD_TURKIC              = HB_TAG ('O','r','k','h'),
+  HB_SCRIPT_SAMARITAN               = HB_TAG ('S','a','m','r'),
+  HB_SCRIPT_TAI_THAM                = HB_TAG ('L','a','n','a'),
+  HB_SCRIPT_TAI_VIET                = HB_TAG ('T','a','v','t'),
 
   /* Unicode-6.0 additions */
-  HB_SCRIPT_BATAK,                  /* Batk */
-  HB_SCRIPT_BRAHMI,                 /* Brah */
-  HB_SCRIPT_MANDAIC                 /* Mand */
+  HB_SCRIPT_BATAK                   = HB_TAG ('B','a','t','k'),
+  HB_SCRIPT_BRAHMI                  = HB_TAG ('B','r','a','h'),
+  HB_SCRIPT_MANDAIC                 = HB_TAG ('M','a','n','d'),
+
+  /* No script set */
+  HB_SCRIPT_INVALID                 = HB_TAG_NONE
 } hb_script_t;
 
 
diff --git a/src/hb-ot-map.cc b/src/hb-ot-map.cc
index ca96ba9..7793600 100644
--- a/src/hb-ot-map.cc
+++ b/src/hb-ot-map.cc
@@ -73,10 +73,10 @@ hb_ot_map_t::compile (hb_face_t *face,
   /* Fetch script/language indices for GSUB/GPOS.  We need these later to skip
    * features not available in either table and not waste precious bits for them. */
 
-  const hb_tag_t *script_tags;
+  hb_tag_t script_tags[3] = {HB_TAG_NONE};
   hb_tag_t language_tag;
 
-  script_tags = hb_ot_tags_from_script (props->script);
+  hb_ot_tags_from_script (props->script, &script_tags[0], &script_tags[1]);
   language_tag = hb_ot_tag_from_language (props->language);
 
   unsigned int script_index[2], language_index[2];
diff --git a/src/hb-ot-shape-complex-private.hh b/src/hb-ot-shape-complex-private.hh
index fed167d..8147945 100644
--- a/src/hb-ot-shape-complex-private.hh
+++ b/src/hb-ot-shape-complex-private.hh
@@ -37,7 +37,8 @@ HB_BEGIN_DECLS
 static inline hb_ot_complex_shaper_t
 hb_ot_shape_complex_categorize (const hb_segment_properties_t *props)
 {
-  switch ((int) props->script) {
+  switch ((int) props->script)
+  {
     case HB_SCRIPT_ARABIC:
     case HB_SCRIPT_NKO:
     case HB_SCRIPT_SYRIAC:
diff --git a/src/hb-ot-tag.c b/src/hb-ot-tag.c
index 8f62f84..ecc1882 100644
--- a/src/hb-ot-tag.c
+++ b/src/hb-ot-tag.c
@@ -32,150 +32,122 @@
 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) | 0x02000000;
+}
+
+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 & ~0x02000000);
+}
+
+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.
  */
-static const hb_tag_t ot_scripts[][3] = {
-  {HB_TAG('D','F','L','T')},	/* HB_SCRIPT_COMMON */
-  {HB_TAG('D','F','L','T')},	/* HB_SCRIPT_INHERITED */
-  {HB_TAG('a','r','a','b')},	/* HB_SCRIPT_ARABIC */
-  {HB_TAG('a','r','m','n')},	/* HB_SCRIPT_ARMENIAN */
-  {HB_TAG('b','n','g','2'), HB_TAG('b','e','n','g')},	/* HB_SCRIPT_BENGALI */
-  {HB_TAG('b','o','p','o')},	/* HB_SCRIPT_BOPOMOFO */
-  {HB_TAG('c','h','e','r')},	/* HB_SCRIPT_CHEROKEE */
-  {HB_TAG('c','o','p','t')},	/* HB_SCRIPT_COPTIC */
-  {HB_TAG('c','y','r','l')},	/* HB_SCRIPT_CYRILLIC */
-  {HB_TAG('d','s','r','t')},	/* HB_SCRIPT_DESERET */
-  {HB_TAG('d','e','v','2'), HB_TAG('d','e','v','a')},	/* HB_SCRIPT_DEVANAGARI */
-  {HB_TAG('e','t','h','i')},	/* HB_SCRIPT_ETHIOPIC */
-  {HB_TAG('g','e','o','r')},	/* HB_SCRIPT_GEORGIAN */
-  {HB_TAG('g','o','t','h')},	/* HB_SCRIPT_GOTHIC */
-  {HB_TAG('g','r','e','k')},	/* HB_SCRIPT_GREEK */
-  {HB_TAG('g','j','r','2'), HB_TAG('g','u','j','r')},	/* HB_SCRIPT_GUJARATI */
-  {HB_TAG('g','u','r','2'), HB_TAG('g','u','r','u')},	/* HB_SCRIPT_GURMUKHI */
-  {HB_TAG('h','a','n','i')},	/* HB_SCRIPT_HAN */
-  {HB_TAG('h','a','n','g')},	/* HB_SCRIPT_HANGUL */
-  {HB_TAG('h','e','b','r')},	/* HB_SCRIPT_HEBREW */
-  {HB_TAG('k','a','n','a')},	/* HB_SCRIPT_HIRAGANA */
-  {HB_TAG('k','n','d','2'), HB_TAG('k','n','d','a')},	/* HB_SCRIPT_KANNADA */
-  {HB_TAG('k','a','n','a')},	/* HB_SCRIPT_KATAKANA */
-  {HB_TAG('k','h','m','r')},	/* HB_SCRIPT_KHMER */
-  {HB_TAG('l','a','o',' ')},	/* HB_SCRIPT_LAO */
-  {HB_TAG('l','a','t','n')},	/* HB_SCRIPT_LATIN */
-  {HB_TAG('m','l','m','2'), HB_TAG('m','l','y','m')},	/* HB_SCRIPT_MALAYALAM */
-  {HB_TAG('m','o','n','g')},	/* HB_SCRIPT_MONGOLIAN */
-  {HB_TAG('m','y','m','r')},	/* HB_SCRIPT_MYANMAR */
-  {HB_TAG('o','g','a','m')},	/* HB_SCRIPT_OGHAM */
-  {HB_TAG('i','t','a','l')},	/* HB_SCRIPT_OLD_ITALIC */
-  {HB_TAG('o','r','y','2'), HB_TAG('o','r','y','a')},	/* HB_SCRIPT_ORIYA */
-  {HB_TAG('r','u','n','r')},	/* HB_SCRIPT_RUNIC */
-  {HB_TAG('s','i','n','h')},	/* HB_SCRIPT_SINHALA */
-  {HB_TAG('s','y','r','c')},	/* HB_SCRIPT_SYRIAC */
-  {HB_TAG('t','m','l','2'), HB_TAG('t','a','m','l')},	/* HB_SCRIPT_TAMIL */
-  {HB_TAG('t','e','l','2'), HB_TAG('t','e','l','u')},	/* HB_SCRIPT_TELUGU */
-  {HB_TAG('t','h','a','a')},	/* HB_SCRIPT_THAANA */
-  {HB_TAG('t','h','a','i')},	/* HB_SCRIPT_THAI */
-  {HB_TAG('t','i','b','t')},	/* HB_SCRIPT_TIBETAN */
-  {HB_TAG('c','a','n','s')},	/* HB_SCRIPT_CANADIAN_ABORIGINAL */
-  {HB_TAG('y','i',' ',' ')},	/* HB_SCRIPT_YI */
-  {HB_TAG('t','g','l','g')},	/* HB_SCRIPT_TAGALOG */
-  {HB_TAG('h','a','n','o')},	/* HB_SCRIPT_HANUNOO */
-  {HB_TAG('b','u','h','d')},	/* HB_SCRIPT_BUHID */
-  {HB_TAG('t','a','g','b')},	/* HB_SCRIPT_TAGBANWA */
-
-  /* Unicode-4.0 additions */
-  {HB_TAG('b','r','a','i')},	/* HB_SCRIPT_BRAILLE */
-  {HB_TAG('c','p','r','t')},	/* HB_SCRIPT_CYPRIOT */
-  {HB_TAG('l','i','m','b')},	/* HB_SCRIPT_LIMBU */
-  {HB_TAG('o','s','m','a')},	/* HB_SCRIPT_OSMANYA */
-  {HB_TAG('s','h','a','w')},	/* HB_SCRIPT_SHAVIAN */
-  {HB_TAG('l','i','n','b')},	/* HB_SCRIPT_LINEAR_B */
-  {HB_TAG('t','a','l','e')},	/* HB_SCRIPT_TAI_LE */
-  {HB_TAG('u','g','a','r')},	/* HB_SCRIPT_UGARITIC */
-
-  /* Unicode-4.1 additions */
-  {HB_TAG('t','a','l','u')},	/* HB_SCRIPT_NEW_TAI_LUE */
-  {HB_TAG('b','u','g','i')},	/* HB_SCRIPT_BUGINESE */
-  {HB_TAG('g','l','a','g')},	/* HB_SCRIPT_GLAGOLITIC */
-  {HB_TAG('t','f','n','g')},	/* HB_SCRIPT_TIFINAGH */
-  {HB_TAG('s','y','l','o')},	/* HB_SCRIPT_SYLOTI_NAGRI */
-  {HB_TAG('x','p','e','o')},	/* HB_SCRIPT_OLD_PERSIAN */
-  {HB_TAG('k','h','a','r')},	/* HB_SCRIPT_KHAROSHTHI */
-
-  /* Unicode-5.0 additions */
-  {HB_TAG('D','F','L','T')},	/* HB_SCRIPT_UNKNOWN */
-  {HB_TAG('b','a','l','i')},	/* HB_SCRIPT_BALINESE */
-  {HB_TAG('x','s','u','x')},	/* HB_SCRIPT_CUNEIFORM */
-  {HB_TAG('p','h','n','x')},	/* HB_SCRIPT_PHOENICIAN */
-  {HB_TAG('p','h','a','g')},	/* HB_SCRIPT_PHAGS_PA */
-  {HB_TAG('n','k','o',' ')},	/* HB_SCRIPT_NKO */
-
-  /* Unicode-5.1 additions */
-  {HB_TAG('k','a','l','i')},	/* HB_SCRIPT_KAYAH_LI */
-  {HB_TAG('l','e','p','c')},	/* HB_SCRIPT_LEPCHA */
-  {HB_TAG('r','j','n','g')},	/* HB_SCRIPT_REJANG */
-  {HB_TAG('s','u','n','d')},	/* HB_SCRIPT_SUNDANESE */
-  {HB_TAG('s','a','u','r')},	/* HB_SCRIPT_SAURASHTRA */
-  {HB_TAG('c','h','a','m')},	/* HB_SCRIPT_CHAM */
-  {HB_TAG('o','l','c','k')},	/* HB_SCRIPT_OL_CHIKI */
-  {HB_TAG('v','a','i',' ')},	/* HB_SCRIPT_VAI */
-  {HB_TAG('c','a','r','i')},	/* HB_SCRIPT_CARIAN */
-  {HB_TAG('l','y','c','i')},	/* HB_SCRIPT_LYCIAN */
-  {HB_TAG('l','y','d','i')},	/* HB_SCRIPT_LYDIAN */
-
-  /* Unicode-5.2 additions */
-  {HB_TAG('a','v','s','t')},	/* HB_SCRIPT_AVESTAN */
-  {HB_TAG('b','a','m','u')},	/* HB_SCRIPT_BAMUM */
-  {HB_TAG('e','g','y','p')},	/* HB_SCRIPT_EGYPTIAN_HIEROGLYPHS */
-  {HB_TAG('a','r','m','i')},	/* HB_SCRIPT_IMPERIAL_ARAMAIC */
-  {HB_TAG('p','h','l','i')},	/* HB_SCRIPT_INSCRIPTIONAL_PAHLAVI */
-  {HB_TAG('p','r','t','i')},	/* HB_SCRIPT_INSCRIPTIONAL_PARTHIAN */
-  {HB_TAG('j','a','v','a')},	/* HB_SCRIPT_JAVANESE */
-  {HB_TAG('k','t','h','i')},	/* HB_SCRIPT_KAITHI */
-  {HB_TAG('l','i','s','u')},	/* HB_SCRIPT_LISU */
-  {HB_TAG('m','y','e','i')},	/* HB_SCRIPT_MEETEI_MAYEK */
-  {HB_TAG('s','a','r','b')},	/* HB_SCRIPT_OLD_SOUTH_ARABIAN */
-  {HB_TAG('o','r','k','h')},	/* HB_SCRIPT_OLD_TURKIC */
-  {HB_TAG('s','a','m','r')},	/* HB_SCRIPT_SAMARITAN */
-  {HB_TAG('l','a','n','a')},	/* HB_SCRIPT_TAI_THAM */
-  {HB_TAG('t','a','v','t')},	/* HB_SCRIPT_TAI_VIET */
-
-  /* Unicode-6.0 additions */
-  {HB_TAG('b','a','t','k')},	/* HB_SCRIPT_BATAK */
-  {HB_TAG('b','r','a','h')},	/* HB_SCRIPT_BRAHMI */
-  {HB_TAG('m','a','n','d')} 	/* HB_SCRIPT_MANDAIC */
-};
 
-const hb_tag_t *
-hb_ot_tags_from_script (hb_script_t script)
+void
+hb_ot_tags_from_script (hb_script_t  script,
+			hb_tag_t    *script_tag_1,
+			hb_tag_t    *script_tag_2)
 {
-  static const hb_tag_t def_tag[] = {HB_OT_TAG_DEFAULT_SCRIPT, HB_TAG_NONE};
-
-  /* XXX Handle non-enum scripts */
+  hb_tag_t new_tag;
 
-  if (unlikely ((unsigned int) script >= ARRAY_LENGTH (ot_scripts)))
-    return def_tag;
+  *script_tag_2 = HB_TAG_NONE;
+  *script_tag_1 = hb_ot_old_tag_from_script (script);
 
-  return ot_scripts[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)
 {
-  int i;
+  if (unlikely ((tag & 0x000000FF) == '2'))
+    return hb_ot_new_tag_to_script (tag);
 
-  for (i = 0; i < ARRAY_LENGTH (ot_scripts); i++) {
-    const hb_tag_t *p;
-    for (p = ot_scripts[i]; *p; p++)
-      if (tag == *p)
-        return i;
-  }
+  return hb_ot_old_tag_to_script (tag);
+}
 
-  /* XXX Convert to non-enum scripts */
 
-  return HB_SCRIPT_UNKNOWN;
-}
+/* hb_language_t */
 
 typedef struct {
   char language[6];
diff --git a/src/hb-ot-tag.h b/src/hb-ot-tag.h
index 4a5e26d..345c80e 100644
--- a/src/hb-ot-tag.h
+++ b/src/hb-ot-tag.h
@@ -35,8 +35,10 @@ HB_BEGIN_DECLS
 #define HB_OT_TAG_DEFAULT_SCRIPT	HB_TAG ('D', 'F', 'L', 'T')
 #define HB_OT_TAG_DEFAULT_LANGUAGE	HB_TAG ('d', 'f', 'l', 't')
 
-const hb_tag_t *
-hb_ot_tags_from_script (hb_script_t script);
+void
+hb_ot_tags_from_script (hb_script_t  script,
+			hb_tag_t    *script_tag_1,
+			hb_tag_t    *script_tag_2);
 
 hb_script_t
 hb_ot_tag_to_script (hb_tag_t tag);
diff --git a/src/hb-shape.cc b/src/hb-shape.cc
index 9e2ea4e..368abfc 100644
--- a/src/hb-shape.cc
+++ b/src/hb-shape.cc
@@ -78,7 +78,9 @@ hb_shape (hb_font_t          *font,
     unsigned int count = buffer->len;
     for (unsigned int i = 0; i < count; i++) {
       hb_script_t script = get_script (buffer->info[i].codepoint);
-      if (likely (script > HB_SCRIPT_INHERITED)) {
+      if (likely (script != HB_SCRIPT_COMMON &&
+		  script != HB_SCRIPT_INHERITED &&
+		  script != HB_SCRIPT_UNKNOWN)) {
         buffer->props.script = script;
         break;
       }
diff --git a/test/test-types.c b/test/test-types.c
index 48aa087..5d7043e 100644
--- a/test/test-types.c
+++ b/test/test-types.c
@@ -108,7 +108,7 @@ test_types_script (void)
 
   hb_tag_t x123 = HB_TAG_CHAR4 ("x123");
 
-  g_assert_cmpint ((signed) HB_SCRIPT_INVALID, ==, -1);
+  g_assert_cmpint ((hb_tag_t) HB_SCRIPT_INVALID, ==, HB_TAG_NONE);
   g_assert_cmphex (HB_SCRIPT_ARABIC, !=, HB_SCRIPT_LATIN);
 
   g_assert_cmphex (HB_SCRIPT_ARABIC, ==, hb_script_from_iso15924_tag (arab));
commit c0af193c8e25c4f11d23b8893e9ce1c2d2615bb2
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Apr 15 19:26:24 2011 -0400

    Change buffer default properties to invalid
    
    This includes HB_DIRECTION_INVALID and HB_SCRIPT_INVALID.
    
    The INVALID will cause a "guess whatever from the text" in hb_shape().
    While it's not ideal, it works better than the previous defaults at
    least (HB_DIRECTION_LTR and HB_SCRIPT_COMMON).

diff --git a/src/hb-buffer-private.hh b/src/hb-buffer-private.hh
index 4b1ff12..2b063b7 100644
--- a/src/hb-buffer-private.hh
+++ b/src/hb-buffer-private.hh
@@ -94,8 +94,6 @@ struct _hb_buffer_t {
 
   /* Buffer contents */
 
-  unsigned int allocated; /* Length of allocated arrays */
-
   hb_bool_t have_output; /* Whether we have an output buffer going on */
   hb_bool_t have_positions; /* Whether we have positions */
   hb_bool_t in_error; /* Allocation failed */
@@ -104,14 +102,13 @@ struct _hb_buffer_t {
   unsigned int len; /* Length of ->info and ->pos arrays */
   unsigned int out_len; /* Length of ->out array if have_output */
 
+  unsigned int serial;
+
+  unsigned int allocated; /* Length of allocated arrays */
   hb_glyph_info_t     *info;
   hb_glyph_info_t     *out_info;
   hb_glyph_position_t *pos;
 
-  /* Other stuff */
-
-  unsigned int serial;
-
 
   /* Methods */
   inline unsigned int backtrack_len (void) const
diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc
index 4020d2c..b71aa57 100644
--- a/src/hb-buffer.cc
+++ b/src/hb-buffer.cc
@@ -37,7 +37,12 @@ HB_BEGIN_DECLS
 static hb_buffer_t _hb_buffer_nil = {
   HB_REFERENCE_COUNT_INVALID, /* ref_count */
 
-  &_hb_unicode_funcs_nil  /* unicode */
+  &_hb_unicode_funcs_nil,  /* unicode */
+  {
+    HB_DIRECTION_INVALID,
+    HB_SCRIPT_INVALID,
+    NULL,
+  },
 };
 
 /* Here is how the buffer works internally:
@@ -138,7 +143,7 @@ hb_buffer_create (unsigned int pre_alloc_size)
   if (pre_alloc_size)
     _hb_buffer_ensure (buffer, pre_alloc_size);
 
-  buffer->unicode = &_hb_unicode_funcs_nil;
+  hb_buffer_reset (buffer);
 
   return buffer;
 }
@@ -231,19 +236,22 @@ hb_buffer_get_language (hb_buffer_t *buffer)
 void
 hb_buffer_reset (hb_buffer_t *buffer)
 {
+  hb_unicode_funcs_destroy (buffer->unicode);
+  buffer->unicode = _hb_buffer_nil.unicode;
+
+  buffer->props = _hb_buffer_nil.props;
+
   buffer->have_output = FALSE;
   buffer->have_positions = FALSE;
   buffer->in_error = FALSE;
+
+  buffer->i = 0;
   buffer->len = 0;
   buffer->out_len = 0;
-  buffer->i = 0;
-  buffer->out_info = buffer->info;
-  buffer->serial = 0;
 
-  buffer->props = _hb_buffer_nil.props;
+  buffer->serial = 0;
 
-  hb_unicode_funcs_destroy (buffer->unicode);
-  buffer->unicode = _hb_buffer_nil.unicode;
+  buffer->out_info = buffer->info;
 }
 
 hb_bool_t
diff --git a/src/hb-view.c b/src/hb-view.c
index 87d9b30..d7e41fd 100644
--- a/src/hb-view.c
+++ b/src/hb-view.c
@@ -355,10 +355,8 @@ _hb_cr_text_glyphs (cairo_t *cr,
   hb_buffer_add_utf8 (hb_buffer, text, len, 0, len);
   if (script)
     hb_buffer_set_script (hb_buffer, hb_script_from_string (script));
-  else
-    hb_buffer_set_script (hb_buffer, HB_SCRIPT_INVALID);
-  hb_buffer_set_direction (hb_buffer, HB_DIRECTION_INVALID);
-  hb_buffer_set_language (hb_buffer, hb_language_from_string (language));
+  if (language)
+    hb_buffer_set_language (hb_buffer, hb_language_from_string (language));
 
   hb_shape (hb_font, hb_face, hb_buffer, features, num_features);
 
diff --git a/test/test-buffer.c b/test/test-buffer.c
index 4316f17..dad2eac 100644
--- a/test/test-buffer.c
+++ b/test/test-buffer.c
@@ -100,8 +100,8 @@ test_buffer_properties (Fixture *fixture, gconstpointer user_data)
 {
   /* TODO check unicode_funcs */
 
-  g_assert (hb_buffer_get_direction (fixture->b) == HB_DIRECTION_LTR);
-  g_assert (hb_buffer_get_script (fixture->b) == HB_SCRIPT_COMMON);
+  g_assert (hb_buffer_get_direction (fixture->b) == HB_DIRECTION_INVALID);
+  g_assert (hb_buffer_get_script (fixture->b) == HB_SCRIPT_INVALID);
   g_assert (hb_buffer_get_language (fixture->b) == NULL);
 
   hb_buffer_set_direction (fixture->b, HB_DIRECTION_RTL);
commit 00bec2c969555e76c3f84650a1d3c45308e585ad
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Apr 15 19:16:54 2011 -0400

    Move enum types to hb-common.h

diff --git a/src/hb-common.c b/src/hb-common.c
index ac62e83..a913415 100644
--- a/src/hb-common.c
+++ b/src/hb-common.c
@@ -141,4 +141,410 @@ hb_language_to_string (hb_language_t language)
 }
 
 
+/* hb_script_t */
+
+static const hb_tag_t script_to_iso15924_tag[] =
+{
+  HB_TAG('Z','y','y','y'),	/* HB_SCRIPT_COMMON */
+  HB_TAG('Q','a','a','i'),	/* HB_SCRIPT_INHERITED */
+  HB_TAG('A','r','a','b'),	/* HB_SCRIPT_ARABIC */
+  HB_TAG('A','r','m','n'),	/* HB_SCRIPT_ARMENIAN */
+  HB_TAG('B','e','n','g'),	/* HB_SCRIPT_BENGALI */
+  HB_TAG('B','o','p','o'),	/* HB_SCRIPT_BOPOMOFO */
+  HB_TAG('C','h','e','r'),	/* HB_SCRIPT_CHEROKEE */
+  HB_TAG('Q','a','a','c'),	/* HB_SCRIPT_COPTIC */
+  HB_TAG('C','y','r','l'),	/* HB_SCRIPT_CYRILLIC */
+  HB_TAG('D','s','r','t'),	/* HB_SCRIPT_DESERET */
+  HB_TAG('D','e','v','a'),	/* HB_SCRIPT_DEVANAGARI */
+  HB_TAG('E','t','h','i'),	/* HB_SCRIPT_ETHIOPIC */
+  HB_TAG('G','e','o','r'),	/* HB_SCRIPT_GEORGIAN */
+  HB_TAG('G','o','t','h'),	/* HB_SCRIPT_GOTHIC */
+  HB_TAG('G','r','e','k'),	/* HB_SCRIPT_GREEK */
+  HB_TAG('G','u','j','r'),	/* HB_SCRIPT_GUJARATI */
+  HB_TAG('G','u','r','u'),	/* HB_SCRIPT_GURMUKHI */
+  HB_TAG('H','a','n','i'),	/* HB_SCRIPT_HAN */
+  HB_TAG('H','a','n','g'),	/* HB_SCRIPT_HANGUL */
+  HB_TAG('H','e','b','r'),	/* HB_SCRIPT_HEBREW */
+  HB_TAG('H','i','r','a'),	/* HB_SCRIPT_HIRAGANA */
+  HB_TAG('K','n','d','a'),	/* HB_SCRIPT_KANNADA */
+  HB_TAG('K','a','n','a'),	/* HB_SCRIPT_KATAKANA */
+  HB_TAG('K','h','m','r'),	/* HB_SCRIPT_KHMER */
+  HB_TAG('L','a','o','o'),	/* HB_SCRIPT_LAO */
+  HB_TAG('L','a','t','n'),	/* HB_SCRIPT_LATIN */
+  HB_TAG('M','l','y','m'),	/* HB_SCRIPT_MALAYALAM */
+  HB_TAG('M','o','n','g'),	/* HB_SCRIPT_MONGOLIAN */
+  HB_TAG('M','y','m','r'),	/* HB_SCRIPT_MYANMAR */
+  HB_TAG('O','g','a','m'),	/* HB_SCRIPT_OGHAM */
+  HB_TAG('I','t','a','l'),	/* HB_SCRIPT_OLD_ITALIC */
+  HB_TAG('O','r','y','a'),	/* HB_SCRIPT_ORIYA */
+  HB_TAG('R','u','n','r'),	/* HB_SCRIPT_RUNIC */
+  HB_TAG('S','i','n','h'),	/* HB_SCRIPT_SINHALA */
+  HB_TAG('S','y','r','c'),	/* HB_SCRIPT_SYRIAC */
+  HB_TAG('T','a','m','l'),	/* HB_SCRIPT_TAMIL */
+  HB_TAG('T','e','l','u'),	/* HB_SCRIPT_TELUGU */
+  HB_TAG('T','h','a','a'),	/* HB_SCRIPT_THAANA */
+  HB_TAG('T','h','a','i'),	/* HB_SCRIPT_THAI */
+  HB_TAG('T','i','b','t'),	/* HB_SCRIPT_TIBETAN */
+  HB_TAG('C','a','n','s'),	/* HB_SCRIPT_CANADIAN_ABORIGINAL */
+  HB_TAG('Y','i','i','i'),	/* HB_SCRIPT_YI */
+  HB_TAG('T','g','l','g'),	/* HB_SCRIPT_TAGALOG */
+  HB_TAG('H','a','n','o'),	/* HB_SCRIPT_HANUNOO */
+  HB_TAG('B','u','h','d'),	/* HB_SCRIPT_BUHID */
+  HB_TAG('T','a','g','b'),	/* HB_SCRIPT_TAGBANWA */
+
+  /* Unicode-4.0 additions */
+  HB_TAG('B','r','a','i'),	/* HB_SCRIPT_BRAILLE */
+  HB_TAG('C','p','r','t'),	/* HB_SCRIPT_CYPRIOT */
+  HB_TAG('L','i','m','b'),	/* HB_SCRIPT_LIMBU */
+  HB_TAG('O','s','m','a'),	/* HB_SCRIPT_OSMANYA */
+  HB_TAG('S','h','a','w'),	/* HB_SCRIPT_SHAVIAN */
+  HB_TAG('L','i','n','b'),	/* HB_SCRIPT_LINEAR_B */
+  HB_TAG('T','a','l','e'),	/* HB_SCRIPT_TAI_LE */
+  HB_TAG('U','g','a','r'),	/* HB_SCRIPT_UGARITIC */
+
+  /* Unicode-4.1 additions */
+  HB_TAG('T','a','l','u'),	/* HB_SCRIPT_NEW_TAI_LUE */
+  HB_TAG('B','u','g','i'),	/* HB_SCRIPT_BUGINESE */
+  HB_TAG('G','l','a','g'),	/* HB_SCRIPT_GLAGOLITIC */
+  HB_TAG('T','f','n','g'),	/* HB_SCRIPT_TIFINAGH */
+  HB_TAG('S','y','l','o'),	/* HB_SCRIPT_SYLOTI_NAGRI */
+  HB_TAG('X','p','e','o'),	/* HB_SCRIPT_OLD_PERSIAN */
+  HB_TAG('K','h','a','r'),	/* HB_SCRIPT_KHAROSHTHI */
+
+  /* Unicode-5.0 additions */
+  HB_TAG('Z','z','z','z'),	/* HB_SCRIPT_UNKNOWN */
+  HB_TAG('B','a','l','i'),	/* HB_SCRIPT_BALINESE */
+  HB_TAG('X','s','u','x'),	/* HB_SCRIPT_CUNEIFORM */
+  HB_TAG('P','h','n','x'),	/* HB_SCRIPT_PHOENICIAN */
+  HB_TAG('P','h','a','g'),	/* HB_SCRIPT_PHAGS_PA */
+  HB_TAG('N','k','o','o'),	/* HB_SCRIPT_NKO */
+
+  /* Unicode-5.1 additions */
+  HB_TAG('K','a','l','i'),	/* HB_SCRIPT_KAYAH_LI */
+  HB_TAG('L','e','p','c'),	/* HB_SCRIPT_LEPCHA */
+  HB_TAG('R','j','n','g'),	/* HB_SCRIPT_REJANG */
+  HB_TAG('S','u','n','d'),	/* HB_SCRIPT_SUNDANESE */
+  HB_TAG('S','a','u','r'),	/* HB_SCRIPT_SAURASHTRA */
+  HB_TAG('C','h','a','m'),	/* HB_SCRIPT_CHAM */
+  HB_TAG('O','l','c','k'),	/* HB_SCRIPT_OL_CHIKI */
+  HB_TAG('V','a','i','i'),	/* HB_SCRIPT_VAI */
+  HB_TAG('C','a','r','i'),	/* HB_SCRIPT_CARIAN */
+  HB_TAG('L','y','c','i'),	/* HB_SCRIPT_LYCIAN */
+  HB_TAG('L','y','d','i'),	/* HB_SCRIPT_LYDIAN */
+
+  /* Unicode-5.2 additions */
+  HB_TAG('A','v','s','t'),	/* HB_SCRIPT_AVESTAN */
+  HB_TAG('B','a','m','u'),	/* HB_SCRIPT_BAMUM */
+  HB_TAG('E','g','y','p'),	/* HB_SCRIPT_EGYPTIAN_HIEROGLYPHS */
+  HB_TAG('A','r','m','i'),	/* HB_SCRIPT_IMPERIAL_ARAMAIC */
+  HB_TAG('P','h','l','i'),	/* HB_SCRIPT_INSCRIPTIONAL_PAHLAVI */
+  HB_TAG('P','r','t','i'),	/* HB_SCRIPT_INSCRIPTIONAL_PARTHIAN */
+  HB_TAG('J','a','v','a'),	/* HB_SCRIPT_JAVANESE */
+  HB_TAG('K','t','h','i'),	/* HB_SCRIPT_KAITHI */
+  HB_TAG('L','i','s','u'),	/* HB_SCRIPT_LISU */
+  HB_TAG('M','t','e','i'),	/* HB_SCRIPT_MEETEI_MAYEK */
+  HB_TAG('S','a','r','b'),	/* HB_SCRIPT_OLD_SOUTH_ARABIAN */
+  HB_TAG('O','r','k','h'),	/* HB_SCRIPT_OLD_TURKIC */
+  HB_TAG('S','a','m','r'),	/* HB_SCRIPT_SAMARITAN */
+  HB_TAG('L','a','n','a'),	/* HB_SCRIPT_TAI_THAM */
+  HB_TAG('T','a','v','t'),	/* HB_SCRIPT_TAI_VIET */
+
+  /* Unicode-6.0 additions */
+  HB_TAG('B','a','t','k'),	/* HB_SCRIPT_BATAK */
+  HB_TAG('B','r','a','h'),	/* HB_SCRIPT_BRAHMI */
+  HB_TAG('M','a','n','d') 	/* HB_SCRIPT_MANDAIC */
+};
+
+struct tag_script_pair {
+  hb_tag_t tag;
+  hb_script_t script;
+};
+static const struct tag_script_pair script_from_iso15924_tag[] =
+{
+  {HB_TAG('A','r','a','b'), HB_SCRIPT_ARABIC},
+  {HB_TAG('A','r','m','i'), HB_SCRIPT_IMPERIAL_ARAMAIC},
+  {HB_TAG('A','r','m','n'), HB_SCRIPT_ARMENIAN},
+  {HB_TAG('A','v','s','t'), HB_SCRIPT_AVESTAN},
+  {HB_TAG('B','a','l','i'), HB_SCRIPT_BALINESE},
+  {HB_TAG('B','a','m','u'), HB_SCRIPT_BAMUM},
+  {HB_TAG('B','a','t','k'), HB_SCRIPT_BATAK},
+  {HB_TAG('B','e','n','g'), HB_SCRIPT_BENGALI},
+  {HB_TAG('B','o','p','o'), HB_SCRIPT_BOPOMOFO},
+  {HB_TAG('B','r','a','h'), HB_SCRIPT_BRAHMI},
+  {HB_TAG('B','r','a','i'), HB_SCRIPT_BRAILLE},
+  {HB_TAG('B','u','g','i'), HB_SCRIPT_BUGINESE},
+  {HB_TAG('B','u','h','d'), HB_SCRIPT_BUHID},
+  {HB_TAG('C','a','n','s'), HB_SCRIPT_CANADIAN_ABORIGINAL},
+  {HB_TAG('C','a','r','i'), HB_SCRIPT_CARIAN},
+  {HB_TAG('C','h','a','m'), HB_SCRIPT_CHAM},
+  {HB_TAG('C','h','e','r'), HB_SCRIPT_CHEROKEE},
+  {HB_TAG('C','p','r','t'), HB_SCRIPT_CYPRIOT},
+  {HB_TAG('C','y','r','l'), HB_SCRIPT_CYRILLIC},
+  {HB_TAG('C','y','r','s'), HB_SCRIPT_CYRILLIC},
+  {HB_TAG('D','e','v','a'), HB_SCRIPT_DEVANAGARI},
+  {HB_TAG('D','s','r','t'), HB_SCRIPT_DESERET},
+  {HB_TAG('E','g','y','p'), HB_SCRIPT_EGYPTIAN_HIEROGLYPHS},
+  {HB_TAG('E','t','h','i'), HB_SCRIPT_ETHIOPIC},
+  {HB_TAG('G','e','o','a'), HB_SCRIPT_GEORGIAN},
+  {HB_TAG('G','e','o','n'), HB_SCRIPT_GEORGIAN},
+  {HB_TAG('G','e','o','r'), HB_SCRIPT_GEORGIAN},
+  {HB_TAG('G','l','a','g'), HB_SCRIPT_GLAGOLITIC},
+  {HB_TAG('G','o','t','h'), HB_SCRIPT_GOTHIC},
+  {HB_TAG('G','r','e','k'), HB_SCRIPT_GREEK},
+  {HB_TAG('G','u','j','r'), HB_SCRIPT_GUJARATI},
+  {HB_TAG('G','u','r','u'), HB_SCRIPT_GURMUKHI},
+  {HB_TAG('H','a','n','g'), HB_SCRIPT_HANGUL},
+  {HB_TAG('H','a','n','i'), HB_SCRIPT_HAN},
+  {HB_TAG('H','a','n','o'), HB_SCRIPT_HANUNOO},
+  {HB_TAG('H','e','b','r'), HB_SCRIPT_HEBREW},
+  {HB_TAG('H','i','r','a'), HB_SCRIPT_HIRAGANA},
+  {HB_TAG('I','t','a','l'), HB_SCRIPT_OLD_ITALIC},
+  {HB_TAG('J','a','v','a'), HB_SCRIPT_JAVANESE},
+  {HB_TAG('K','a','l','i'), HB_SCRIPT_KAYAH_LI},
+  {HB_TAG('K','a','n','a'), HB_SCRIPT_KATAKANA},
+  {HB_TAG('K','h','a','r'), HB_SCRIPT_KHAROSHTHI},
+  {HB_TAG('K','h','m','r'), HB_SCRIPT_KHMER},
+  {HB_TAG('K','n','d','a'), HB_SCRIPT_KANNADA},
+  {HB_TAG('K','t','h','i'), HB_SCRIPT_KAITHI},
+  {HB_TAG('L','a','n','a'), HB_SCRIPT_TAI_THAM},
+  {HB_TAG('L','a','o','o'), HB_SCRIPT_LAO},
+  {HB_TAG('L','a','t','f'), HB_SCRIPT_LATIN},
+  {HB_TAG('L','a','t','g'), HB_SCRIPT_LATIN},
+  {HB_TAG('L','a','t','n'), HB_SCRIPT_LATIN},
+  {HB_TAG('L','e','p','c'), HB_SCRIPT_LEPCHA},
+  {HB_TAG('L','i','m','b'), HB_SCRIPT_LIMBU},
+  {HB_TAG('L','i','n','b'), HB_SCRIPT_LINEAR_B},
+  {HB_TAG('L','i','s','u'), HB_SCRIPT_LISU},
+  {HB_TAG('L','y','c','i'), HB_SCRIPT_LYCIAN},
+  {HB_TAG('L','y','d','i'), HB_SCRIPT_LYDIAN},
+  {HB_TAG('M','a','n','d'), HB_SCRIPT_MANDAIC},
+  {HB_TAG('M','l','y','m'), HB_SCRIPT_MALAYALAM},
+  {HB_TAG('M','o','n','g'), HB_SCRIPT_MONGOLIAN},
+  {HB_TAG('M','t','e','i'), HB_SCRIPT_MEETEI_MAYEK},
+  {HB_TAG('M','y','m','r'), HB_SCRIPT_MYANMAR},
+  {HB_TAG('N','k','o','o'), HB_SCRIPT_NKO},
+  {HB_TAG('O','g','a','m'), HB_SCRIPT_OGHAM},
+  {HB_TAG('O','l','c','k'), HB_SCRIPT_OL_CHIKI},
+  {HB_TAG('O','r','k','h'), HB_SCRIPT_OLD_TURKIC},
+  {HB_TAG('O','r','y','a'), HB_SCRIPT_ORIYA},
+  {HB_TAG('O','s','m','a'), HB_SCRIPT_OSMANYA},
+  {HB_TAG('P','h','a','g'), HB_SCRIPT_PHAGS_PA},
+  {HB_TAG('P','h','l','i'), HB_SCRIPT_INSCRIPTIONAL_PAHLAVI},
+  {HB_TAG('P','h','n','x'), HB_SCRIPT_PHOENICIAN},
+  {HB_TAG('P','r','t','i'), HB_SCRIPT_INSCRIPTIONAL_PARTHIAN},
+  {HB_TAG('Q','a','a','c'), HB_SCRIPT_COPTIC},
+  {HB_TAG('Q','a','a','i'), HB_SCRIPT_INHERITED},
+  {HB_TAG('R','j','n','g'), HB_SCRIPT_REJANG},
+  {HB_TAG('R','u','n','r'), HB_SCRIPT_RUNIC},
+  {HB_TAG('S','a','m','r'), HB_SCRIPT_SAMARITAN},
+  {HB_TAG('S','a','r','b'), HB_SCRIPT_OLD_SOUTH_ARABIAN},
+  {HB_TAG('S','a','u','r'), HB_SCRIPT_SAURASHTRA},
+  {HB_TAG('S','h','a','w'), HB_SCRIPT_SHAVIAN},
+  {HB_TAG('S','i','n','h'), HB_SCRIPT_SINHALA},
+  {HB_TAG('S','u','n','d'), HB_SCRIPT_SUNDANESE},
+  {HB_TAG('S','y','l','o'), HB_SCRIPT_SYLOTI_NAGRI},
+  {HB_TAG('S','y','r','c'), HB_SCRIPT_SYRIAC},
+  {HB_TAG('S','y','r','e'), HB_SCRIPT_SYRIAC},
+  {HB_TAG('S','y','r','n'), HB_SCRIPT_SYRIAC},
+  {HB_TAG('T','a','g','b'), HB_SCRIPT_TAGBANWA},
+  {HB_TAG('T','a','l','e'), HB_SCRIPT_TAI_LE},
+  {HB_TAG('T','a','l','u'), HB_SCRIPT_NEW_TAI_LUE},
+  {HB_TAG('T','a','m','l'), HB_SCRIPT_TAMIL},
+  {HB_TAG('T','a','v','t'), HB_SCRIPT_TAI_VIET},
+  {HB_TAG('T','e','l','u'), HB_SCRIPT_TELUGU},
+  {HB_TAG('T','f','n','g'), HB_SCRIPT_TIFINAGH},
+  {HB_TAG('T','g','l','g'), HB_SCRIPT_TAGALOG},
+  {HB_TAG('T','h','a','a'), HB_SCRIPT_THAANA},
+  {HB_TAG('T','h','a','i'), HB_SCRIPT_THAI},
+  {HB_TAG('T','i','b','t'), HB_SCRIPT_TIBETAN},
+  {HB_TAG('U','g','a','r'), HB_SCRIPT_UGARITIC},
+  {HB_TAG('V','a','i','i'), HB_SCRIPT_VAI},
+  {HB_TAG('X','p','e','o'), HB_SCRIPT_OLD_PERSIAN},
+  {HB_TAG('X','s','u','x'), HB_SCRIPT_CUNEIFORM},
+  {HB_TAG('Y','i','i','i'), HB_SCRIPT_YI},
+  {HB_TAG('Z','y','y','y'), HB_SCRIPT_COMMON},
+  {HB_TAG('Z','z','z','z'), HB_SCRIPT_UNKNOWN}
+};
+
+static int
+_tag_cmp (hb_tag_t *pa, hb_tag_t *pb)
+{
+  hb_tag_t a = *pa, b = *pb;
+  return a < b ? -1 : a == b ? 0 : +1;
+}
+
+
+hb_script_t
+hb_script_from_iso15924_tag (hb_tag_t tag)
+{
+  const struct tag_script_pair *pair;
+
+  /* Be lenient, adjust case (one capital letter followed by three small letters) */
+  tag = (tag & 0xDFDFDFDF) | 0x00202020;
+
+  pair = (const struct tag_script_pair *) bsearch (&tag,
+						   script_from_iso15924_tag,
+						   ARRAY_LENGTH (script_from_iso15924_tag),
+						   sizeof (script_from_iso15924_tag[0]),
+						   (hb_compare_func_t) _tag_cmp);
+
+  if (pair)
+    return pair->script;
+
+  /* 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)
+{
+  if (likely ((unsigned int) script < ARRAY_LENGTH (script_to_iso15924_tag)))
+    return script_to_iso15924_tag[script];
+
+  /* if script is of the right shape (one capital letter followed by three small letters),
+   * return as is. */
+  if (((uint32_t) script & 0xE0E0E0E0) == 0x40606060)
+    return (hb_tag_t) script;
+
+  /* Otherwise, we don't know what that is */
+  return script_to_iso15924_tag[HB_SCRIPT_UNKNOWN];
+}
+
+
+#define LTR HB_DIRECTION_LTR
+#define RTL HB_DIRECTION_RTL
+const hb_direction_t horiz_dir[] =
+{
+  LTR,	/* Zyyy */
+  LTR,	/* Qaai */
+  RTL,	/* Arab */
+  LTR,	/* Armn */
+  LTR,	/* Beng */
+  LTR,	/* Bopo */
+  LTR,	/* Cher */
+  LTR,	/* Qaac */
+  LTR,	/* Cyrl (Cyrs) */
+  LTR,	/* Dsrt */
+  LTR,	/* Deva */
+  LTR,	/* Ethi */
+  LTR,	/* Geor (Geon, Geoa) */
+  LTR,	/* Goth */
+  LTR,	/* Grek */
+  LTR,	/* Gujr */
+  LTR,	/* Guru */
+  LTR,	/* Hani */
+  LTR,	/* Hang */
+  RTL,	/* Hebr */
+  LTR,	/* Hira */
+  LTR,	/* Knda */
+  LTR,	/* Kana */
+  LTR,	/* Khmr */
+  LTR,	/* Laoo */
+  LTR,	/* Latn (Latf, Latg) */
+  LTR,	/* Mlym */
+  LTR,	/* Mong */
+  LTR,	/* Mymr */
+  LTR,	/* Ogam */
+  LTR,	/* Ital */
+  LTR,	/* Orya */
+  LTR,	/* Runr */
+  LTR,	/* Sinh */
+  RTL,	/* Syrc (Syrj, Syrn, Syre) */
+  LTR,	/* Taml */
+  LTR,	/* Telu */
+  RTL,	/* Thaa */
+  LTR,	/* Thai */
+  LTR,	/* Tibt */
+  LTR,	/* Cans */
+  LTR,	/* Yiii */
+  LTR,	/* Tglg */
+  LTR,	/* Hano */
+  LTR,	/* Buhd */
+  LTR,	/* Tagb */
+
+  /* Unicode-4.0 additions */
+  LTR,	/* Brai */
+  RTL,	/* Cprt */
+  LTR,	/* Limb */
+  LTR,	/* Osma */
+  LTR,	/* Shaw */
+  LTR,	/* Linb */
+  LTR,	/* Tale */
+  LTR,	/* Ugar */
+
+  /* Unicode-4.1 additions */
+  LTR,	/* Talu */
+  LTR,	/* Bugi */
+  LTR,	/* Glag */
+  LTR,	/* Tfng */
+  LTR,	/* Sylo */
+  LTR,	/* Xpeo */
+  LTR,	/* Khar */
+
+  /* Unicode-5.0 additions */
+  LTR,	/* Zzzz */
+  LTR,	/* Bali */
+  LTR,	/* Xsux */
+  RTL,	/* Phnx */
+  LTR,	/* Phag */
+  RTL,	/* Nkoo */
+
+  /* Unicode-5.1 additions */
+  LTR,	/* Kali */
+  LTR,	/* Lepc */
+  LTR,	/* Rjng */
+  LTR,	/* Sund */
+  LTR,	/* Saur */
+  LTR,	/* Cham */
+  LTR,	/* Olck */
+  LTR,	/* Vaii */
+  LTR,	/* Cari */
+  LTR,	/* Lyci */
+  LTR,	/* Lydi */
+
+  /* Unicode-5.2 additions */
+  RTL,	/* Avst */
+  LTR,	/* Bamu */
+  LTR,	/* Egyp */
+  RTL,	/* Armi */
+  RTL,	/* Phli */
+  RTL,	/* Prti */
+  LTR,	/* Java */
+  LTR,	/* Kthi */
+  LTR,	/* Lisu */
+  LTR,	/* Mtei */
+  RTL,	/* Sarb */
+  RTL,	/* Orkh */
+  RTL,	/* Samr */
+  LTR,	/* Lana */
+  LTR,	/* Tavt */
+
+  /* Unicode-6.0 additions */
+  LTR,	/* Batk */
+  LTR,	/* Brah */
+  RTL 	/* Mand */
+};
+#undef LTR
+#undef RTL
+
+hb_direction_t
+hb_script_get_horizontal_direction (hb_script_t script)
+{
+  if (unlikely ((unsigned int) script >= ARRAY_LENGTH (horiz_dir)))
+    return HB_DIRECTION_LTR;
+
+  return horiz_dir[script];
+}
+
+
 HB_END_DECLS
diff --git a/src/hb-common.h b/src/hb-common.h
index 4dadc94..21caa71 100644
--- a/src/hb-common.h
+++ b/src/hb-common.h
@@ -108,6 +108,176 @@ const char *
 hb_language_to_string (hb_language_t language);
 
 
+/* hb_unicode_general_category_t */
+
+typedef enum
+{
+  HB_UNICODE_GENERAL_CATEGORY_CONTROL,			/* Cc */
+  HB_UNICODE_GENERAL_CATEGORY_FORMAT,			/* Cf */
+  HB_UNICODE_GENERAL_CATEGORY_UNASSIGNED,		/* Cn */
+  HB_UNICODE_GENERAL_CATEGORY_PRIVATE_USE,		/* Co */
+  HB_UNICODE_GENERAL_CATEGORY_SURROGATE,		/* Cs */
+  HB_UNICODE_GENERAL_CATEGORY_LOWERCASE_LETTER,		/* Ll */
+  HB_UNICODE_GENERAL_CATEGORY_MODIFIER_LETTER,		/* Lm */
+  HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER,		/* Lo */
+  HB_UNICODE_GENERAL_CATEGORY_TITLECASE_LETTER,		/* Lt */
+  HB_UNICODE_GENERAL_CATEGORY_UPPERCASE_LETTER,		/* Lu */
+  HB_UNICODE_GENERAL_CATEGORY_COMBINING_MARK,		/* Mc */
+  HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK,		/* Me */
+  HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK,		/* Mn */
+  HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER,		/* Nd */
+  HB_UNICODE_GENERAL_CATEGORY_LETTER_NUMBER,		/* Nl */
+  HB_UNICODE_GENERAL_CATEGORY_OTHER_NUMBER,		/* No */
+  HB_UNICODE_GENERAL_CATEGORY_CONNECT_PUNCTUATION,	/* Pc */
+  HB_UNICODE_GENERAL_CATEGORY_DASH_PUNCTUATION,		/* Pd */
+  HB_UNICODE_GENERAL_CATEGORY_CLOSE_PUNCTUATION,	/* Pe */
+  HB_UNICODE_GENERAL_CATEGORY_FINAL_PUNCTUATION,	/* Pf */
+  HB_UNICODE_GENERAL_CATEGORY_INITIAL_PUNCTUATION,	/* Pi */
+  HB_UNICODE_GENERAL_CATEGORY_OTHER_PUNCTUATION,	/* Po */
+  HB_UNICODE_GENERAL_CATEGORY_OPEN_PUNCTUATION,		/* Ps */
+  HB_UNICODE_GENERAL_CATEGORY_CURRENCY_SYMBOL,		/* Sc */
+  HB_UNICODE_GENERAL_CATEGORY_MODIFIER_SYMBOL,		/* Sk */
+  HB_UNICODE_GENERAL_CATEGORY_MATH_SYMBOL,		/* Sm */
+  HB_UNICODE_GENERAL_CATEGORY_OTHER_SYMBOL,		/* So */
+  HB_UNICODE_GENERAL_CATEGORY_LINE_SEPARATOR,		/* Zl */
+  HB_UNICODE_GENERAL_CATEGORY_PARAGRAPH_SEPARATOR,	/* Zp */
+  HB_UNICODE_GENERAL_CATEGORY_SPACE_SEPARATOR		/* Zs */
+} hb_unicode_general_category_t;
+
+
+/* hb_script_t */
+
+typedef enum
+{                               /* ISO 15924 code */
+  HB_SCRIPT_INVALID = -1,
+
+  HB_SCRIPT_COMMON       = 0,   /* Zyyy */
+  HB_SCRIPT_INHERITED,          /* Qaai */
+  HB_SCRIPT_ARABIC,             /* Arab */
+  HB_SCRIPT_ARMENIAN,           /* Armn */
+  HB_SCRIPT_BENGALI,            /* Beng */
+  HB_SCRIPT_BOPOMOFO,           /* Bopo */
+  HB_SCRIPT_CHEROKEE,           /* Cher */
+  HB_SCRIPT_COPTIC,             /* Qaac */
+  HB_SCRIPT_CYRILLIC,           /* Cyrl (Cyrs) */
+  HB_SCRIPT_DESERET,            /* Dsrt */
+  HB_SCRIPT_DEVANAGARI,         /* Deva */
+  HB_SCRIPT_ETHIOPIC,           /* Ethi */
+  HB_SCRIPT_GEORGIAN,           /* Geor (Geon, Geoa) */
+  HB_SCRIPT_GOTHIC,             /* Goth */
+  HB_SCRIPT_GREEK,              /* Grek */
+  HB_SCRIPT_GUJARATI,           /* Gujr */
+  HB_SCRIPT_GURMUKHI,           /* Guru */
+  HB_SCRIPT_HAN,                /* Hani */
+  HB_SCRIPT_HANGUL,             /* Hang */
+  HB_SCRIPT_HEBREW,             /* Hebr */
+  HB_SCRIPT_HIRAGANA,           /* Hira */
+  HB_SCRIPT_KANNADA,            /* Knda */
+  HB_SCRIPT_KATAKANA,           /* Kana */
+  HB_SCRIPT_KHMER,              /* Khmr */
+  HB_SCRIPT_LAO,                /* Laoo */
+  HB_SCRIPT_LATIN,              /* Latn (Latf, Latg) */
+  HB_SCRIPT_MALAYALAM,          /* Mlym */
+  HB_SCRIPT_MONGOLIAN,          /* Mong */
+  HB_SCRIPT_MYANMAR,            /* Mymr */
+  HB_SCRIPT_OGHAM,              /* Ogam */
+  HB_SCRIPT_OLD_ITALIC,         /* Ital */
+  HB_SCRIPT_ORIYA,              /* Orya */
+  HB_SCRIPT_RUNIC,              /* Runr */
+  HB_SCRIPT_SINHALA,            /* Sinh */
+  HB_SCRIPT_SYRIAC,             /* Syrc (Syrj, Syrn, Syre) */
+  HB_SCRIPT_TAMIL,              /* Taml */
+  HB_SCRIPT_TELUGU,             /* Telu */
+  HB_SCRIPT_THAANA,             /* Thaa */
+  HB_SCRIPT_THAI,               /* Thai */
+  HB_SCRIPT_TIBETAN,            /* Tibt */
+  HB_SCRIPT_CANADIAN_ABORIGINAL, /* Cans */
+  HB_SCRIPT_YI,                 /* Yiii */
+  HB_SCRIPT_TAGALOG,            /* Tglg */
+  HB_SCRIPT_HANUNOO,            /* Hano */
+  HB_SCRIPT_BUHID,              /* Buhd */
+  HB_SCRIPT_TAGBANWA,           /* Tagb */
+
+  /* Unicode-4.0 additions */
+  HB_SCRIPT_BRAILLE,            /* Brai */
+  HB_SCRIPT_CYPRIOT,            /* Cprt */
+  HB_SCRIPT_LIMBU,              /* Limb */
+  HB_SCRIPT_OSMANYA,            /* Osma */
+  HB_SCRIPT_SHAVIAN,            /* Shaw */
+  HB_SCRIPT_LINEAR_B,           /* Linb */
+  HB_SCRIPT_TAI_LE,             /* Tale */
+  HB_SCRIPT_UGARITIC,           /* Ugar */
+
+  /* Unicode-4.1 additions */
+  HB_SCRIPT_NEW_TAI_LUE,        /* Talu */
+  HB_SCRIPT_BUGINESE,           /* Bugi */
+  HB_SCRIPT_GLAGOLITIC,         /* Glag */
+  HB_SCRIPT_TIFINAGH,           /* Tfng */
+  HB_SCRIPT_SYLOTI_NAGRI,       /* Sylo */
+  HB_SCRIPT_OLD_PERSIAN,        /* Xpeo */
+  HB_SCRIPT_KHAROSHTHI,         /* Khar */
+
+  /* Unicode-5.0 additions */
+  HB_SCRIPT_UNKNOWN,            /* Zzzz */
+  HB_SCRIPT_BALINESE,           /* Bali */
+  HB_SCRIPT_CUNEIFORM,          /* Xsux */
+  HB_SCRIPT_PHOENICIAN,         /* Phnx */
+  HB_SCRIPT_PHAGS_PA,           /* Phag */
+  HB_SCRIPT_NKO,                /* Nkoo */
+
+  /* Unicode-5.1 additions */
+  HB_SCRIPT_KAYAH_LI,           /* Kali */
+  HB_SCRIPT_LEPCHA,             /* Lepc */
+  HB_SCRIPT_REJANG,             /* Rjng */
+  HB_SCRIPT_SUNDANESE,          /* Sund */
+  HB_SCRIPT_SAURASHTRA,         /* Saur */
+  HB_SCRIPT_CHAM,               /* Cham */
+  HB_SCRIPT_OL_CHIKI,           /* Olck */
+  HB_SCRIPT_VAI,                /* Vaii */
+  HB_SCRIPT_CARIAN,             /* Cari */
+  HB_SCRIPT_LYCIAN,             /* Lyci */
+  HB_SCRIPT_LYDIAN,             /* Lydi */
+
+  /* Unicode-5.2 additions */
+  HB_SCRIPT_AVESTAN,                /* Avst */
+  HB_SCRIPT_BAMUM,                  /* Bamu */
+  HB_SCRIPT_EGYPTIAN_HIEROGLYPHS,   /* Egyp */
+  HB_SCRIPT_IMPERIAL_ARAMAIC,       /* Armi */
+  HB_SCRIPT_INSCRIPTIONAL_PAHLAVI,  /* Phli */
+  HB_SCRIPT_INSCRIPTIONAL_PARTHIAN, /* Prti */
+  HB_SCRIPT_JAVANESE,               /* Java */
+  HB_SCRIPT_KAITHI,                 /* Kthi */
+  HB_SCRIPT_LISU,                   /* Lisu */
+  HB_SCRIPT_MEETEI_MAYEK,           /* Mtei */
+  HB_SCRIPT_OLD_SOUTH_ARABIAN,      /* Sarb */
+  HB_SCRIPT_OLD_TURKIC,             /* Orkh */
+  HB_SCRIPT_SAMARITAN,              /* Samr */
+  HB_SCRIPT_TAI_THAM,               /* Lana */
+  HB_SCRIPT_TAI_VIET,               /* Tavt */
+
+  /* Unicode-6.0 additions */
+  HB_SCRIPT_BATAK,                  /* Batk */
+  HB_SCRIPT_BRAHMI,                 /* Brah */
+  HB_SCRIPT_MANDAIC                 /* Mand */
+} hb_script_t;
+
+
+/* Script functions */
+
+hb_script_t
+hb_script_from_iso15924_tag (hb_tag_t tag);
+
+/* suger for tag_from_string() then script_from_iso15924_tag */
+hb_script_t
+hb_script_from_string (const char *s);
+
+hb_tag_t
+hb_script_to_iso15924_tag (hb_script_t script);
+
+hb_direction_t
+hb_script_get_horizontal_direction (hb_script_t script);
+
+
 HB_END_DECLS
 
 #endif /* HB_COMMON_H */
diff --git a/src/hb-unicode.c b/src/hb-unicode.c
index bf18631..9bb3524 100644
--- a/src/hb-unicode.c
+++ b/src/hb-unicode.c
@@ -234,410 +234,4 @@ hb_unicode_get_eastasian_width (hb_unicode_funcs_t *ufuncs,
 }
 
 
-/* hb_script_t */
-
-static const hb_tag_t script_to_iso15924_tag[] =
-{
-  HB_TAG('Z','y','y','y'),	/* HB_SCRIPT_COMMON */
-  HB_TAG('Q','a','a','i'),	/* HB_SCRIPT_INHERITED */
-  HB_TAG('A','r','a','b'),	/* HB_SCRIPT_ARABIC */
-  HB_TAG('A','r','m','n'),	/* HB_SCRIPT_ARMENIAN */
-  HB_TAG('B','e','n','g'),	/* HB_SCRIPT_BENGALI */
-  HB_TAG('B','o','p','o'),	/* HB_SCRIPT_BOPOMOFO */
-  HB_TAG('C','h','e','r'),	/* HB_SCRIPT_CHEROKEE */
-  HB_TAG('Q','a','a','c'),	/* HB_SCRIPT_COPTIC */
-  HB_TAG('C','y','r','l'),	/* HB_SCRIPT_CYRILLIC */
-  HB_TAG('D','s','r','t'),	/* HB_SCRIPT_DESERET */
-  HB_TAG('D','e','v','a'),	/* HB_SCRIPT_DEVANAGARI */
-  HB_TAG('E','t','h','i'),	/* HB_SCRIPT_ETHIOPIC */
-  HB_TAG('G','e','o','r'),	/* HB_SCRIPT_GEORGIAN */
-  HB_TAG('G','o','t','h'),	/* HB_SCRIPT_GOTHIC */
-  HB_TAG('G','r','e','k'),	/* HB_SCRIPT_GREEK */
-  HB_TAG('G','u','j','r'),	/* HB_SCRIPT_GUJARATI */
-  HB_TAG('G','u','r','u'),	/* HB_SCRIPT_GURMUKHI */
-  HB_TAG('H','a','n','i'),	/* HB_SCRIPT_HAN */
-  HB_TAG('H','a','n','g'),	/* HB_SCRIPT_HANGUL */
-  HB_TAG('H','e','b','r'),	/* HB_SCRIPT_HEBREW */
-  HB_TAG('H','i','r','a'),	/* HB_SCRIPT_HIRAGANA */
-  HB_TAG('K','n','d','a'),	/* HB_SCRIPT_KANNADA */
-  HB_TAG('K','a','n','a'),	/* HB_SCRIPT_KATAKANA */
-  HB_TAG('K','h','m','r'),	/* HB_SCRIPT_KHMER */
-  HB_TAG('L','a','o','o'),	/* HB_SCRIPT_LAO */
-  HB_TAG('L','a','t','n'),	/* HB_SCRIPT_LATIN */
-  HB_TAG('M','l','y','m'),	/* HB_SCRIPT_MALAYALAM */
-  HB_TAG('M','o','n','g'),	/* HB_SCRIPT_MONGOLIAN */
-  HB_TAG('M','y','m','r'),	/* HB_SCRIPT_MYANMAR */
-  HB_TAG('O','g','a','m'),	/* HB_SCRIPT_OGHAM */
-  HB_TAG('I','t','a','l'),	/* HB_SCRIPT_OLD_ITALIC */
-  HB_TAG('O','r','y','a'),	/* HB_SCRIPT_ORIYA */
-  HB_TAG('R','u','n','r'),	/* HB_SCRIPT_RUNIC */
-  HB_TAG('S','i','n','h'),	/* HB_SCRIPT_SINHALA */
-  HB_TAG('S','y','r','c'),	/* HB_SCRIPT_SYRIAC */
-  HB_TAG('T','a','m','l'),	/* HB_SCRIPT_TAMIL */
-  HB_TAG('T','e','l','u'),	/* HB_SCRIPT_TELUGU */
-  HB_TAG('T','h','a','a'),	/* HB_SCRIPT_THAANA */
-  HB_TAG('T','h','a','i'),	/* HB_SCRIPT_THAI */
-  HB_TAG('T','i','b','t'),	/* HB_SCRIPT_TIBETAN */
-  HB_TAG('C','a','n','s'),	/* HB_SCRIPT_CANADIAN_ABORIGINAL */
-  HB_TAG('Y','i','i','i'),	/* HB_SCRIPT_YI */
-  HB_TAG('T','g','l','g'),	/* HB_SCRIPT_TAGALOG */
-  HB_TAG('H','a','n','o'),	/* HB_SCRIPT_HANUNOO */
-  HB_TAG('B','u','h','d'),	/* HB_SCRIPT_BUHID */
-  HB_TAG('T','a','g','b'),	/* HB_SCRIPT_TAGBANWA */
-
-  /* Unicode-4.0 additions */
-  HB_TAG('B','r','a','i'),	/* HB_SCRIPT_BRAILLE */
-  HB_TAG('C','p','r','t'),	/* HB_SCRIPT_CYPRIOT */
-  HB_TAG('L','i','m','b'),	/* HB_SCRIPT_LIMBU */
-  HB_TAG('O','s','m','a'),	/* HB_SCRIPT_OSMANYA */
-  HB_TAG('S','h','a','w'),	/* HB_SCRIPT_SHAVIAN */
-  HB_TAG('L','i','n','b'),	/* HB_SCRIPT_LINEAR_B */
-  HB_TAG('T','a','l','e'),	/* HB_SCRIPT_TAI_LE */
-  HB_TAG('U','g','a','r'),	/* HB_SCRIPT_UGARITIC */
-
-  /* Unicode-4.1 additions */
-  HB_TAG('T','a','l','u'),	/* HB_SCRIPT_NEW_TAI_LUE */
-  HB_TAG('B','u','g','i'),	/* HB_SCRIPT_BUGINESE */
-  HB_TAG('G','l','a','g'),	/* HB_SCRIPT_GLAGOLITIC */
-  HB_TAG('T','f','n','g'),	/* HB_SCRIPT_TIFINAGH */
-  HB_TAG('S','y','l','o'),	/* HB_SCRIPT_SYLOTI_NAGRI */
-  HB_TAG('X','p','e','o'),	/* HB_SCRIPT_OLD_PERSIAN */
-  HB_TAG('K','h','a','r'),	/* HB_SCRIPT_KHAROSHTHI */
-
-  /* Unicode-5.0 additions */
-  HB_TAG('Z','z','z','z'),	/* HB_SCRIPT_UNKNOWN */
-  HB_TAG('B','a','l','i'),	/* HB_SCRIPT_BALINESE */
-  HB_TAG('X','s','u','x'),	/* HB_SCRIPT_CUNEIFORM */
-  HB_TAG('P','h','n','x'),	/* HB_SCRIPT_PHOENICIAN */
-  HB_TAG('P','h','a','g'),	/* HB_SCRIPT_PHAGS_PA */
-  HB_TAG('N','k','o','o'),	/* HB_SCRIPT_NKO */
-
-  /* Unicode-5.1 additions */
-  HB_TAG('K','a','l','i'),	/* HB_SCRIPT_KAYAH_LI */
-  HB_TAG('L','e','p','c'),	/* HB_SCRIPT_LEPCHA */
-  HB_TAG('R','j','n','g'),	/* HB_SCRIPT_REJANG */
-  HB_TAG('S','u','n','d'),	/* HB_SCRIPT_SUNDANESE */
-  HB_TAG('S','a','u','r'),	/* HB_SCRIPT_SAURASHTRA */
-  HB_TAG('C','h','a','m'),	/* HB_SCRIPT_CHAM */
-  HB_TAG('O','l','c','k'),	/* HB_SCRIPT_OL_CHIKI */
-  HB_TAG('V','a','i','i'),	/* HB_SCRIPT_VAI */
-  HB_TAG('C','a','r','i'),	/* HB_SCRIPT_CARIAN */
-  HB_TAG('L','y','c','i'),	/* HB_SCRIPT_LYCIAN */
-  HB_TAG('L','y','d','i'),	/* HB_SCRIPT_LYDIAN */
-
-  /* Unicode-5.2 additions */
-  HB_TAG('A','v','s','t'),	/* HB_SCRIPT_AVESTAN */
-  HB_TAG('B','a','m','u'),	/* HB_SCRIPT_BAMUM */
-  HB_TAG('E','g','y','p'),	/* HB_SCRIPT_EGYPTIAN_HIEROGLYPHS */
-  HB_TAG('A','r','m','i'),	/* HB_SCRIPT_IMPERIAL_ARAMAIC */
-  HB_TAG('P','h','l','i'),	/* HB_SCRIPT_INSCRIPTIONAL_PAHLAVI */
-  HB_TAG('P','r','t','i'),	/* HB_SCRIPT_INSCRIPTIONAL_PARTHIAN */
-  HB_TAG('J','a','v','a'),	/* HB_SCRIPT_JAVANESE */
-  HB_TAG('K','t','h','i'),	/* HB_SCRIPT_KAITHI */
-  HB_TAG('L','i','s','u'),	/* HB_SCRIPT_LISU */
-  HB_TAG('M','t','e','i'),	/* HB_SCRIPT_MEETEI_MAYEK */
-  HB_TAG('S','a','r','b'),	/* HB_SCRIPT_OLD_SOUTH_ARABIAN */
-  HB_TAG('O','r','k','h'),	/* HB_SCRIPT_OLD_TURKIC */
-  HB_TAG('S','a','m','r'),	/* HB_SCRIPT_SAMARITAN */
-  HB_TAG('L','a','n','a'),	/* HB_SCRIPT_TAI_THAM */
-  HB_TAG('T','a','v','t'),	/* HB_SCRIPT_TAI_VIET */
-
-  /* Unicode-6.0 additions */
-  HB_TAG('B','a','t','k'),	/* HB_SCRIPT_BATAK */
-  HB_TAG('B','r','a','h'),	/* HB_SCRIPT_BRAHMI */
-  HB_TAG('M','a','n','d') 	/* HB_SCRIPT_MANDAIC */
-};
-
-struct tag_script_pair {
-  hb_tag_t tag;
-  hb_script_t script;
-};
-static const struct tag_script_pair script_from_iso15924_tag[] =
-{
-  {HB_TAG('A','r','a','b'), HB_SCRIPT_ARABIC},
-  {HB_TAG('A','r','m','i'), HB_SCRIPT_IMPERIAL_ARAMAIC},
-  {HB_TAG('A','r','m','n'), HB_SCRIPT_ARMENIAN},
-  {HB_TAG('A','v','s','t'), HB_SCRIPT_AVESTAN},
-  {HB_TAG('B','a','l','i'), HB_SCRIPT_BALINESE},
-  {HB_TAG('B','a','m','u'), HB_SCRIPT_BAMUM},
-  {HB_TAG('B','a','t','k'), HB_SCRIPT_BATAK},
-  {HB_TAG('B','e','n','g'), HB_SCRIPT_BENGALI},
-  {HB_TAG('B','o','p','o'), HB_SCRIPT_BOPOMOFO},
-  {HB_TAG('B','r','a','h'), HB_SCRIPT_BRAHMI},
-  {HB_TAG('B','r','a','i'), HB_SCRIPT_BRAILLE},
-  {HB_TAG('B','u','g','i'), HB_SCRIPT_BUGINESE},
-  {HB_TAG('B','u','h','d'), HB_SCRIPT_BUHID},
-  {HB_TAG('C','a','n','s'), HB_SCRIPT_CANADIAN_ABORIGINAL},
-  {HB_TAG('C','a','r','i'), HB_SCRIPT_CARIAN},
-  {HB_TAG('C','h','a','m'), HB_SCRIPT_CHAM},
-  {HB_TAG('C','h','e','r'), HB_SCRIPT_CHEROKEE},
-  {HB_TAG('C','p','r','t'), HB_SCRIPT_CYPRIOT},
-  {HB_TAG('C','y','r','l'), HB_SCRIPT_CYRILLIC},
-  {HB_TAG('C','y','r','s'), HB_SCRIPT_CYRILLIC},
-  {HB_TAG('D','e','v','a'), HB_SCRIPT_DEVANAGARI},
-  {HB_TAG('D','s','r','t'), HB_SCRIPT_DESERET},
-  {HB_TAG('E','g','y','p'), HB_SCRIPT_EGYPTIAN_HIEROGLYPHS},
-  {HB_TAG('E','t','h','i'), HB_SCRIPT_ETHIOPIC},
-  {HB_TAG('G','e','o','a'), HB_SCRIPT_GEORGIAN},
-  {HB_TAG('G','e','o','n'), HB_SCRIPT_GEORGIAN},
-  {HB_TAG('G','e','o','r'), HB_SCRIPT_GEORGIAN},
-  {HB_TAG('G','l','a','g'), HB_SCRIPT_GLAGOLITIC},
-  {HB_TAG('G','o','t','h'), HB_SCRIPT_GOTHIC},
-  {HB_TAG('G','r','e','k'), HB_SCRIPT_GREEK},
-  {HB_TAG('G','u','j','r'), HB_SCRIPT_GUJARATI},
-  {HB_TAG('G','u','r','u'), HB_SCRIPT_GURMUKHI},
-  {HB_TAG('H','a','n','g'), HB_SCRIPT_HANGUL},
-  {HB_TAG('H','a','n','i'), HB_SCRIPT_HAN},
-  {HB_TAG('H','a','n','o'), HB_SCRIPT_HANUNOO},
-  {HB_TAG('H','e','b','r'), HB_SCRIPT_HEBREW},
-  {HB_TAG('H','i','r','a'), HB_SCRIPT_HIRAGANA},
-  {HB_TAG('I','t','a','l'), HB_SCRIPT_OLD_ITALIC},
-  {HB_TAG('J','a','v','a'), HB_SCRIPT_JAVANESE},
-  {HB_TAG('K','a','l','i'), HB_SCRIPT_KAYAH_LI},
-  {HB_TAG('K','a','n','a'), HB_SCRIPT_KATAKANA},
-  {HB_TAG('K','h','a','r'), HB_SCRIPT_KHAROSHTHI},
-  {HB_TAG('K','h','m','r'), HB_SCRIPT_KHMER},
-  {HB_TAG('K','n','d','a'), HB_SCRIPT_KANNADA},
-  {HB_TAG('K','t','h','i'), HB_SCRIPT_KAITHI},
-  {HB_TAG('L','a','n','a'), HB_SCRIPT_TAI_THAM},
-  {HB_TAG('L','a','o','o'), HB_SCRIPT_LAO},
-  {HB_TAG('L','a','t','f'), HB_SCRIPT_LATIN},
-  {HB_TAG('L','a','t','g'), HB_SCRIPT_LATIN},
-  {HB_TAG('L','a','t','n'), HB_SCRIPT_LATIN},
-  {HB_TAG('L','e','p','c'), HB_SCRIPT_LEPCHA},
-  {HB_TAG('L','i','m','b'), HB_SCRIPT_LIMBU},
-  {HB_TAG('L','i','n','b'), HB_SCRIPT_LINEAR_B},
-  {HB_TAG('L','i','s','u'), HB_SCRIPT_LISU},
-  {HB_TAG('L','y','c','i'), HB_SCRIPT_LYCIAN},
-  {HB_TAG('L','y','d','i'), HB_SCRIPT_LYDIAN},
-  {HB_TAG('M','a','n','d'), HB_SCRIPT_MANDAIC},
-  {HB_TAG('M','l','y','m'), HB_SCRIPT_MALAYALAM},
-  {HB_TAG('M','o','n','g'), HB_SCRIPT_MONGOLIAN},
-  {HB_TAG('M','t','e','i'), HB_SCRIPT_MEETEI_MAYEK},
-  {HB_TAG('M','y','m','r'), HB_SCRIPT_MYANMAR},
-  {HB_TAG('N','k','o','o'), HB_SCRIPT_NKO},
-  {HB_TAG('O','g','a','m'), HB_SCRIPT_OGHAM},
-  {HB_TAG('O','l','c','k'), HB_SCRIPT_OL_CHIKI},
-  {HB_TAG('O','r','k','h'), HB_SCRIPT_OLD_TURKIC},
-  {HB_TAG('O','r','y','a'), HB_SCRIPT_ORIYA},
-  {HB_TAG('O','s','m','a'), HB_SCRIPT_OSMANYA},
-  {HB_TAG('P','h','a','g'), HB_SCRIPT_PHAGS_PA},
-  {HB_TAG('P','h','l','i'), HB_SCRIPT_INSCRIPTIONAL_PAHLAVI},
-  {HB_TAG('P','h','n','x'), HB_SCRIPT_PHOENICIAN},
-  {HB_TAG('P','r','t','i'), HB_SCRIPT_INSCRIPTIONAL_PARTHIAN},
-  {HB_TAG('Q','a','a','c'), HB_SCRIPT_COPTIC},
-  {HB_TAG('Q','a','a','i'), HB_SCRIPT_INHERITED},
-  {HB_TAG('R','j','n','g'), HB_SCRIPT_REJANG},
-  {HB_TAG('R','u','n','r'), HB_SCRIPT_RUNIC},
-  {HB_TAG('S','a','m','r'), HB_SCRIPT_SAMARITAN},
-  {HB_TAG('S','a','r','b'), HB_SCRIPT_OLD_SOUTH_ARABIAN},
-  {HB_TAG('S','a','u','r'), HB_SCRIPT_SAURASHTRA},
-  {HB_TAG('S','h','a','w'), HB_SCRIPT_SHAVIAN},
-  {HB_TAG('S','i','n','h'), HB_SCRIPT_SINHALA},
-  {HB_TAG('S','u','n','d'), HB_SCRIPT_SUNDANESE},
-  {HB_TAG('S','y','l','o'), HB_SCRIPT_SYLOTI_NAGRI},
-  {HB_TAG('S','y','r','c'), HB_SCRIPT_SYRIAC},
-  {HB_TAG('S','y','r','e'), HB_SCRIPT_SYRIAC},
-  {HB_TAG('S','y','r','n'), HB_SCRIPT_SYRIAC},
-  {HB_TAG('T','a','g','b'), HB_SCRIPT_TAGBANWA},
-  {HB_TAG('T','a','l','e'), HB_SCRIPT_TAI_LE},
-  {HB_TAG('T','a','l','u'), HB_SCRIPT_NEW_TAI_LUE},
-  {HB_TAG('T','a','m','l'), HB_SCRIPT_TAMIL},
-  {HB_TAG('T','a','v','t'), HB_SCRIPT_TAI_VIET},
-  {HB_TAG('T','e','l','u'), HB_SCRIPT_TELUGU},
-  {HB_TAG('T','f','n','g'), HB_SCRIPT_TIFINAGH},
-  {HB_TAG('T','g','l','g'), HB_SCRIPT_TAGALOG},
-  {HB_TAG('T','h','a','a'), HB_SCRIPT_THAANA},
-  {HB_TAG('T','h','a','i'), HB_SCRIPT_THAI},
-  {HB_TAG('T','i','b','t'), HB_SCRIPT_TIBETAN},
-  {HB_TAG('U','g','a','r'), HB_SCRIPT_UGARITIC},
-  {HB_TAG('V','a','i','i'), HB_SCRIPT_VAI},
-  {HB_TAG('X','p','e','o'), HB_SCRIPT_OLD_PERSIAN},
-  {HB_TAG('X','s','u','x'), HB_SCRIPT_CUNEIFORM},
-  {HB_TAG('Y','i','i','i'), HB_SCRIPT_YI},
-  {HB_TAG('Z','y','y','y'), HB_SCRIPT_COMMON},
-  {HB_TAG('Z','z','z','z'), HB_SCRIPT_UNKNOWN}
-};
-
-static int
-_tag_cmp (hb_tag_t *pa, hb_tag_t *pb)
-{
-  hb_tag_t a = *pa, b = *pb;
-  return a < b ? -1 : a == b ? 0 : +1;
-}
-
-
-hb_script_t
-hb_script_from_iso15924_tag (hb_tag_t tag)
-{
-  const struct tag_script_pair *pair;
-
-  /* Be lenient, adjust case (one capital letter followed by three small letters) */
-  tag = (tag & 0xDFDFDFDF) | 0x00202020;
-
-  pair = (const struct tag_script_pair *) bsearch (&tag,
-						   script_from_iso15924_tag,
-						   ARRAY_LENGTH (script_from_iso15924_tag),
-						   sizeof (script_from_iso15924_tag[0]),
-						   (hb_compare_func_t) _tag_cmp);
-
-  if (pair)
-    return pair->script;
-
-  /* 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)
-{
-  if (likely ((unsigned int) script < ARRAY_LENGTH (script_to_iso15924_tag)))
-    return script_to_iso15924_tag[script];
-
-  /* if script is of the right shape (one capital letter followed by three small letters),
-   * return as is. */
-  if (((uint32_t) script & 0xE0E0E0E0) == 0x40606060)
-    return (hb_tag_t) script;
-
-  /* Otherwise, we don't know what that is */
-  return script_to_iso15924_tag[HB_SCRIPT_UNKNOWN];
-}
-
-
-#define LTR HB_DIRECTION_LTR
-#define RTL HB_DIRECTION_RTL
-const hb_direction_t horiz_dir[] =
-{
-  LTR,	/* Zyyy */
-  LTR,	/* Qaai */
-  RTL,	/* Arab */
-  LTR,	/* Armn */
-  LTR,	/* Beng */
-  LTR,	/* Bopo */
-  LTR,	/* Cher */
-  LTR,	/* Qaac */
-  LTR,	/* Cyrl (Cyrs) */
-  LTR,	/* Dsrt */
-  LTR,	/* Deva */
-  LTR,	/* Ethi */
-  LTR,	/* Geor (Geon, Geoa) */
-  LTR,	/* Goth */
-  LTR,	/* Grek */
-  LTR,	/* Gujr */
-  LTR,	/* Guru */
-  LTR,	/* Hani */
-  LTR,	/* Hang */
-  RTL,	/* Hebr */
-  LTR,	/* Hira */
-  LTR,	/* Knda */
-  LTR,	/* Kana */
-  LTR,	/* Khmr */
-  LTR,	/* Laoo */
-  LTR,	/* Latn (Latf, Latg) */
-  LTR,	/* Mlym */
-  LTR,	/* Mong */
-  LTR,	/* Mymr */
-  LTR,	/* Ogam */
-  LTR,	/* Ital */
-  LTR,	/* Orya */
-  LTR,	/* Runr */
-  LTR,	/* Sinh */
-  RTL,	/* Syrc (Syrj, Syrn, Syre) */
-  LTR,	/* Taml */
-  LTR,	/* Telu */
-  RTL,	/* Thaa */
-  LTR,	/* Thai */
-  LTR,	/* Tibt */
-  LTR,	/* Cans */
-  LTR,	/* Yiii */
-  LTR,	/* Tglg */
-  LTR,	/* Hano */
-  LTR,	/* Buhd */
-  LTR,	/* Tagb */
-
-  /* Unicode-4.0 additions */
-  LTR,	/* Brai */
-  RTL,	/* Cprt */
-  LTR,	/* Limb */
-  LTR,	/* Osma */
-  LTR,	/* Shaw */
-  LTR,	/* Linb */
-  LTR,	/* Tale */
-  LTR,	/* Ugar */
-
-  /* Unicode-4.1 additions */
-  LTR,	/* Talu */
-  LTR,	/* Bugi */
-  LTR,	/* Glag */
-  LTR,	/* Tfng */
-  LTR,	/* Sylo */
-  LTR,	/* Xpeo */
-  LTR,	/* Khar */
-
-  /* Unicode-5.0 additions */
-  LTR,	/* Zzzz */
-  LTR,	/* Bali */
-  LTR,	/* Xsux */
-  RTL,	/* Phnx */
-  LTR,	/* Phag */
-  RTL,	/* Nkoo */
-
-  /* Unicode-5.1 additions */
-  LTR,	/* Kali */
-  LTR,	/* Lepc */
-  LTR,	/* Rjng */
-  LTR,	/* Sund */
-  LTR,	/* Saur */
-  LTR,	/* Cham */
-  LTR,	/* Olck */
-  LTR,	/* Vaii */
-  LTR,	/* Cari */
-  LTR,	/* Lyci */
-  LTR,	/* Lydi */
-
-  /* Unicode-5.2 additions */
-  RTL,	/* Avst */
-  LTR,	/* Bamu */
-  LTR,	/* Egyp */
-  RTL,	/* Armi */
-  RTL,	/* Phli */
-  RTL,	/* Prti */
-  LTR,	/* Java */
-  LTR,	/* Kthi */
-  LTR,	/* Lisu */
-  LTR,	/* Mtei */
-  RTL,	/* Sarb */
-  RTL,	/* Orkh */
-  RTL,	/* Samr */
-  LTR,	/* Lana */
-  LTR,	/* Tavt */
-
-  /* Unicode-6.0 additions */
-  LTR,	/* Batk */
-  LTR,	/* Brah */
-  RTL 	/* Mand */
-};
-#undef LTR
-#undef RTL
-
-hb_direction_t
-hb_script_get_horizontal_direction (hb_script_t script)
-{
-  if (unlikely ((unsigned int) script >= ARRAY_LENGTH (horiz_dir)))
-    return HB_DIRECTION_LTR;
-
-  return horiz_dir[script];
-}
-
-
 HB_END_DECLS
diff --git a/src/hb-unicode.h b/src/hb-unicode.h
index 56e3012..fb8fe97 100644
--- a/src/hb-unicode.h
+++ b/src/hb-unicode.h
@@ -32,157 +32,6 @@
 HB_BEGIN_DECLS
 
 
-/* Unicode General Category property */
-typedef enum
-{
-  HB_UNICODE_GENERAL_CATEGORY_CONTROL,			/* Cc */
-  HB_UNICODE_GENERAL_CATEGORY_FORMAT,			/* Cf */
-  HB_UNICODE_GENERAL_CATEGORY_UNASSIGNED,		/* Cn */
-  HB_UNICODE_GENERAL_CATEGORY_PRIVATE_USE,		/* Co */
-  HB_UNICODE_GENERAL_CATEGORY_SURROGATE,		/* Cs */
-  HB_UNICODE_GENERAL_CATEGORY_LOWERCASE_LETTER,		/* Ll */
-  HB_UNICODE_GENERAL_CATEGORY_MODIFIER_LETTER,		/* Lm */
-  HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER,		/* Lo */
-  HB_UNICODE_GENERAL_CATEGORY_TITLECASE_LETTER,		/* Lt */
-  HB_UNICODE_GENERAL_CATEGORY_UPPERCASE_LETTER,		/* Lu */
-  HB_UNICODE_GENERAL_CATEGORY_COMBINING_MARK,		/* Mc */
-  HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK,		/* Me */
-  HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK,		/* Mn */
-  HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER,		/* Nd */
-  HB_UNICODE_GENERAL_CATEGORY_LETTER_NUMBER,		/* Nl */
-  HB_UNICODE_GENERAL_CATEGORY_OTHER_NUMBER,		/* No */
-  HB_UNICODE_GENERAL_CATEGORY_CONNECT_PUNCTUATION,	/* Pc */
-  HB_UNICODE_GENERAL_CATEGORY_DASH_PUNCTUATION,		/* Pd */
-  HB_UNICODE_GENERAL_CATEGORY_CLOSE_PUNCTUATION,	/* Pe */
-  HB_UNICODE_GENERAL_CATEGORY_FINAL_PUNCTUATION,	/* Pf */
-  HB_UNICODE_GENERAL_CATEGORY_INITIAL_PUNCTUATION,	/* Pi */
-  HB_UNICODE_GENERAL_CATEGORY_OTHER_PUNCTUATION,	/* Po */
-  HB_UNICODE_GENERAL_CATEGORY_OPEN_PUNCTUATION,		/* Ps */
-  HB_UNICODE_GENERAL_CATEGORY_CURRENCY_SYMBOL,		/* Sc */
-  HB_UNICODE_GENERAL_CATEGORY_MODIFIER_SYMBOL,		/* Sk */
-  HB_UNICODE_GENERAL_CATEGORY_MATH_SYMBOL,		/* Sm */
-  HB_UNICODE_GENERAL_CATEGORY_OTHER_SYMBOL,		/* So */
-  HB_UNICODE_GENERAL_CATEGORY_LINE_SEPARATOR,		/* Zl */
-  HB_UNICODE_GENERAL_CATEGORY_PARAGRAPH_SEPARATOR,	/* Zp */
-  HB_UNICODE_GENERAL_CATEGORY_SPACE_SEPARATOR		/* Zs */
-} hb_unicode_general_category_t;
-
-/* Unicode Script property */
-typedef enum
-{                               /* ISO 15924 code */
-  HB_SCRIPT_INVALID = -1,
-
-  HB_SCRIPT_COMMON       = 0,   /* Zyyy */
-  HB_SCRIPT_INHERITED,          /* Qaai */
-  HB_SCRIPT_ARABIC,             /* Arab */
-  HB_SCRIPT_ARMENIAN,           /* Armn */
-  HB_SCRIPT_BENGALI,            /* Beng */
-  HB_SCRIPT_BOPOMOFO,           /* Bopo */
-  HB_SCRIPT_CHEROKEE,           /* Cher */
-  HB_SCRIPT_COPTIC,             /* Qaac */
-  HB_SCRIPT_CYRILLIC,           /* Cyrl (Cyrs) */
-  HB_SCRIPT_DESERET,            /* Dsrt */
-  HB_SCRIPT_DEVANAGARI,         /* Deva */
-  HB_SCRIPT_ETHIOPIC,           /* Ethi */
-  HB_SCRIPT_GEORGIAN,           /* Geor (Geon, Geoa) */
-  HB_SCRIPT_GOTHIC,             /* Goth */
-  HB_SCRIPT_GREEK,              /* Grek */
-  HB_SCRIPT_GUJARATI,           /* Gujr */
-  HB_SCRIPT_GURMUKHI,           /* Guru */
-  HB_SCRIPT_HAN,                /* Hani */
-  HB_SCRIPT_HANGUL,             /* Hang */
-  HB_SCRIPT_HEBREW,             /* Hebr */
-  HB_SCRIPT_HIRAGANA,           /* Hira */
-  HB_SCRIPT_KANNADA,            /* Knda */
-  HB_SCRIPT_KATAKANA,           /* Kana */
-  HB_SCRIPT_KHMER,              /* Khmr */
-  HB_SCRIPT_LAO,                /* Laoo */
-  HB_SCRIPT_LATIN,              /* Latn (Latf, Latg) */
-  HB_SCRIPT_MALAYALAM,          /* Mlym */
-  HB_SCRIPT_MONGOLIAN,          /* Mong */
-  HB_SCRIPT_MYANMAR,            /* Mymr */
-  HB_SCRIPT_OGHAM,              /* Ogam */
-  HB_SCRIPT_OLD_ITALIC,         /* Ital */
-  HB_SCRIPT_ORIYA,              /* Orya */
-  HB_SCRIPT_RUNIC,              /* Runr */
-  HB_SCRIPT_SINHALA,            /* Sinh */
-  HB_SCRIPT_SYRIAC,             /* Syrc (Syrj, Syrn, Syre) */
-  HB_SCRIPT_TAMIL,              /* Taml */
-  HB_SCRIPT_TELUGU,             /* Telu */
-  HB_SCRIPT_THAANA,             /* Thaa */
-  HB_SCRIPT_THAI,               /* Thai */
-  HB_SCRIPT_TIBETAN,            /* Tibt */
-  HB_SCRIPT_CANADIAN_ABORIGINAL, /* Cans */
-  HB_SCRIPT_YI,                 /* Yiii */
-  HB_SCRIPT_TAGALOG,            /* Tglg */
-  HB_SCRIPT_HANUNOO,            /* Hano */
-  HB_SCRIPT_BUHID,              /* Buhd */
-  HB_SCRIPT_TAGBANWA,           /* Tagb */
-
-  /* Unicode-4.0 additions */
-  HB_SCRIPT_BRAILLE,            /* Brai */
-  HB_SCRIPT_CYPRIOT,            /* Cprt */
-  HB_SCRIPT_LIMBU,              /* Limb */
-  HB_SCRIPT_OSMANYA,            /* Osma */
-  HB_SCRIPT_SHAVIAN,            /* Shaw */
-  HB_SCRIPT_LINEAR_B,           /* Linb */
-  HB_SCRIPT_TAI_LE,             /* Tale */
-  HB_SCRIPT_UGARITIC,           /* Ugar */
-
-  /* Unicode-4.1 additions */
-  HB_SCRIPT_NEW_TAI_LUE,        /* Talu */
-  HB_SCRIPT_BUGINESE,           /* Bugi */
-  HB_SCRIPT_GLAGOLITIC,         /* Glag */
-  HB_SCRIPT_TIFINAGH,           /* Tfng */
-  HB_SCRIPT_SYLOTI_NAGRI,       /* Sylo */
-  HB_SCRIPT_OLD_PERSIAN,        /* Xpeo */
-  HB_SCRIPT_KHAROSHTHI,         /* Khar */
-
-  /* Unicode-5.0 additions */
-  HB_SCRIPT_UNKNOWN,            /* Zzzz */
-  HB_SCRIPT_BALINESE,           /* Bali */
-  HB_SCRIPT_CUNEIFORM,          /* Xsux */
-  HB_SCRIPT_PHOENICIAN,         /* Phnx */
-  HB_SCRIPT_PHAGS_PA,           /* Phag */
-  HB_SCRIPT_NKO,                /* Nkoo */
-
-  /* Unicode-5.1 additions */
-  HB_SCRIPT_KAYAH_LI,           /* Kali */
-  HB_SCRIPT_LEPCHA,             /* Lepc */
-  HB_SCRIPT_REJANG,             /* Rjng */
-  HB_SCRIPT_SUNDANESE,          /* Sund */
-  HB_SCRIPT_SAURASHTRA,         /* Saur */
-  HB_SCRIPT_CHAM,               /* Cham */
-  HB_SCRIPT_OL_CHIKI,           /* Olck */
-  HB_SCRIPT_VAI,                /* Vaii */
-  HB_SCRIPT_CARIAN,             /* Cari */
-  HB_SCRIPT_LYCIAN,             /* Lyci */
-  HB_SCRIPT_LYDIAN,             /* Lydi */
-
-  /* Unicode-5.2 additions */
-  HB_SCRIPT_AVESTAN,                /* Avst */
-  HB_SCRIPT_BAMUM,                  /* Bamu */
-  HB_SCRIPT_EGYPTIAN_HIEROGLYPHS,   /* Egyp */
-  HB_SCRIPT_IMPERIAL_ARAMAIC,       /* Armi */
-  HB_SCRIPT_INSCRIPTIONAL_PAHLAVI,  /* Phli */
-  HB_SCRIPT_INSCRIPTIONAL_PARTHIAN, /* Prti */
-  HB_SCRIPT_JAVANESE,               /* Java */
-  HB_SCRIPT_KAITHI,                 /* Kthi */
-  HB_SCRIPT_LISU,                   /* Lisu */
-  HB_SCRIPT_MEETEI_MAYEK,           /* Mtei */
-  HB_SCRIPT_OLD_SOUTH_ARABIAN,      /* Sarb */
-  HB_SCRIPT_OLD_TURKIC,             /* Orkh */
-  HB_SCRIPT_SAMARITAN,              /* Samr */
-  HB_SCRIPT_TAI_THAM,               /* Lana */
-  HB_SCRIPT_TAI_VIET,               /* Tavt */
-
-  /* Unicode-6.0 additions */
-  HB_SCRIPT_BATAK,                  /* Batk */
-  HB_SCRIPT_BRAHMI,                 /* Brah */
-  HB_SCRIPT_MANDAIC                 /* Mand */
-} hb_script_t;
-
-
 /*
  * hb_unicode_funcs_t
  */
@@ -290,21 +139,6 @@ hb_unicode_get_eastasian_width (hb_unicode_funcs_t *ufuncs,
 				hb_codepoint_t unicode);
 
 
-/* Script functions */
-
-hb_script_t
-hb_script_from_iso15924_tag (hb_tag_t tag);
-
-/* suger for tag_from_string() then script_from_iso15924_tag */
-hb_script_t
-hb_script_from_string (const char *s);
-
-hb_tag_t
-hb_script_to_iso15924_tag (hb_script_t script);
-
-hb_direction_t
-hb_script_get_horizontal_direction (hb_script_t script);
-
 HB_END_DECLS
 
 #endif /* HB_UNICODE_H */
commit 5dd4609f4da5674966a0169d9fa533ac5bc9f464
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Apr 15 19:16:34 2011 -0400

    [TODO] Add new item

diff --git a/TODO b/TODO
index 72e9f3e..a9ef442 100644
--- a/TODO
+++ b/TODO
@@ -11,6 +11,7 @@ General fixes:
 
 - Use size_t in sanitize
 
+- Use templates instead of macros for objects?
 
 API issues to fix before 1.0:
 ============================
commit b54cd07b2623b68171e00179a9dc3ecbea7aa6a1
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Apr 15 19:12:01 2011 -0400

    Mark internal buffer variables private

diff --git a/src/hb-buffer.h b/src/hb-buffer.h
index 2151a45..293ec82 100644
--- a/src/hb-buffer.h
+++ b/src/hb-buffer.h
@@ -42,6 +42,8 @@ typedef struct _hb_glyph_info_t {
   hb_codepoint_t codepoint;
   hb_mask_t      mask;
   uint32_t       cluster;
+
+  /*< private >*/
   hb_var_int_t   var1;
   hb_var_int_t   var2;
 } hb_glyph_info_t;
@@ -51,6 +53,8 @@ typedef struct _hb_glyph_position_t {
   hb_position_t  y_advance;
   hb_position_t  x_offset;
   hb_position_t  y_offset;
+
+  /*< private >*/
   hb_var_int_t   var;
 } hb_glyph_position_t;
 
commit 0e8d35c0932ddc20ebf430f2fd82c087da698954
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Apr 15 19:07:10 2011 -0400

    Add hb_script_from_string()

diff --git a/src/hb-unicode.c b/src/hb-unicode.c
index 63c39b1..bf18631 100644
--- a/src/hb-unicode.c
+++ b/src/hb-unicode.c
@@ -492,6 +492,12 @@ hb_script_from_iso15924_tag (hb_tag_t tag)
   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)
 {
diff --git a/src/hb-unicode.h b/src/hb-unicode.h
index 148b5a2..56e3012 100644
--- a/src/hb-unicode.h
+++ b/src/hb-unicode.h
@@ -295,6 +295,10 @@ hb_unicode_get_eastasian_width (hb_unicode_funcs_t *ufuncs,
 hb_script_t
 hb_script_from_iso15924_tag (hb_tag_t tag);
 
+/* suger for tag_from_string() then script_from_iso15924_tag */
+hb_script_t
+hb_script_from_string (const char *s);
+
 hb_tag_t
 hb_script_to_iso15924_tag (hb_script_t script);
 
diff --git a/src/hb-view.c b/src/hb-view.c
index 3a5b9e7..87d9b30 100644
--- a/src/hb-view.c
+++ b/src/hb-view.c
@@ -354,7 +354,7 @@ _hb_cr_text_glyphs (cairo_t *cr,
 
   hb_buffer_add_utf8 (hb_buffer, text, len, 0, len);
   if (script)
-    hb_buffer_set_script (hb_buffer, hb_script_from_iso15924_tag (hb_tag_from_string (script)));
+    hb_buffer_set_script (hb_buffer, hb_script_from_string (script));
   else
     hb_buffer_set_script (hb_buffer, HB_SCRIPT_INVALID);
   hb_buffer_set_direction (hb_buffer, HB_DIRECTION_INVALID);
commit 8f0d7e0c3fd4b05c43ac449be4f374dc2dc56127
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Apr 15 18:59:56 2011 -0400

    Remove hb_buffer_clear_positions(), add hb_ot_layout_position_start()

diff --git a/src/hb-buffer-private.hh b/src/hb-buffer-private.hh
index d8834c5..4b1ff12 100644
--- a/src/hb-buffer-private.hh
+++ b/src/hb-buffer-private.hh
@@ -2,7 +2,7 @@
  * Copyright (C) 1998-2004  David Turner and Werner Lemberg
  * Copyright (C) 2004,2007,2009,2010  Red Hat, Inc.
  *
- * This is part of HarfBuzz, a text shaping library.
+ *  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
@@ -52,6 +52,9 @@ HB_INTERNAL void
 _hb_buffer_clear_output (hb_buffer_t *buffer);
 
 HB_INTERNAL void
+_hb_buffer_clear_positions (hb_buffer_t *buffer);
+
+HB_INTERNAL void
 _hb_buffer_replace_glyphs_be16 (hb_buffer_t *buffer,
 				unsigned int num_in,
 				unsigned int num_out,
@@ -116,6 +119,7 @@ struct _hb_buffer_t {
   inline unsigned int next_serial (void) { return serial++; }
   inline void swap (void) { _hb_buffer_swap (this); }
   inline void clear_output (void) { _hb_buffer_clear_output (this); }
+  inline void clear_positions (void) { _hb_buffer_clear_positions (this); }
   inline void next_glyph (void) { _hb_buffer_next_glyph (this); }
   inline void replace_glyphs_be16 (unsigned int num_in,
 				   unsigned int num_out,
diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc
index f5dc02f..4020d2c 100644
--- a/src/hb-buffer.cc
+++ b/src/hb-buffer.cc
@@ -3,7 +3,7 @@
  * Copyright (C) 2004,2007,2009,2010  Red Hat, Inc.
  * Copyright (C) 2011  Google, Inc.
  *
- * This is part of HarfBuzz, a text shaping library.
+ *  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
@@ -272,16 +272,6 @@ hb_buffer_add_glyph (hb_buffer_t    *buffer,
   buffer->len++;
 }
 
-void
-hb_buffer_clear_positions (hb_buffer_t *buffer)
-{
-  _hb_buffer_clear_output (buffer);
-  buffer->have_output = FALSE;
-  buffer->have_positions = TRUE;
-
-  memset (buffer->pos, 0, sizeof (buffer->pos[0]) * buffer->len);
-}
-
 /* HarfBuzz-Internal API */
 
 void
@@ -289,11 +279,21 @@ _hb_buffer_clear_output (hb_buffer_t *buffer)
 {
   buffer->have_output = TRUE;
   buffer->have_positions = FALSE;
+
   buffer->out_len = 0;
   buffer->out_info = buffer->info;
 }
 
 void
+_hb_buffer_clear_positions (hb_buffer_t *buffer)
+{
+  buffer->have_output = FALSE;
+  buffer->have_positions = TRUE;
+
+  memset (buffer->pos, 0, sizeof (buffer->pos[0]) * buffer->len);
+}
+
+void
 _hb_buffer_swap (hb_buffer_t *buffer)
 {
   unsigned int tmp;
@@ -477,7 +477,7 @@ hb_glyph_position_t *
 hb_buffer_get_glyph_positions (hb_buffer_t *buffer)
 {
   if (!buffer->have_positions)
-    hb_buffer_clear_positions (buffer);
+    _hb_buffer_clear_positions (buffer);
 
   return (hb_glyph_position_t *) buffer->pos;
 }
diff --git a/src/hb-buffer.h b/src/hb-buffer.h
index 49f6a49..2151a45 100644
--- a/src/hb-buffer.h
+++ b/src/hb-buffer.h
@@ -3,7 +3,7 @@
  * Copyright (C) 2004,2007,2009  Red Hat, Inc.
  * Copyright (C) 2011  Google, Inc.
  *
- * This is part of HarfBuzz, a text shaping library.
+ *  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
@@ -102,9 +102,6 @@ hb_buffer_get_language (hb_buffer_t *buffer);
 void
 hb_buffer_reset (hb_buffer_t *buffer);
 
-void
-hb_buffer_clear_positions (hb_buffer_t *buffer);
-
 hb_bool_t
 hb_buffer_ensure (hb_buffer_t  *buffer,
 		  unsigned int  size);
diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc
index fc4b1d3..f1287c5 100644
--- a/src/hb-ot-layout.cc
+++ b/src/hb-ot-layout.cc
@@ -462,6 +462,12 @@ hb_ot_layout_has_positioning (hb_face_t *face)
   return &_get_gpos (face) != &Null(GPOS);
 }
 
+void
+hb_ot_layout_position_start (hb_buffer_t  *buffer)
+{
+  buffer->clear_positions ();
+}
+
 hb_bool_t
 hb_ot_layout_position_lookup   (hb_font_t    *font,
 				hb_face_t    *face,
diff --git a/src/hb-ot-layout.h b/src/hb-ot-layout.h
index 9619eb7..0e0d77f 100644
--- a/src/hb-ot-layout.h
+++ b/src/hb-ot-layout.h
@@ -179,6 +179,10 @@ hb_ot_layout_substitute_lookup (hb_face_t    *face,
 hb_bool_t
 hb_ot_layout_has_positioning (hb_face_t *face);
 
+/* Should be called before all the position_lookup's are done.  Resets positions to zero. */
+void
+hb_ot_layout_position_start (hb_buffer_t  *buffer);
+
 hb_bool_t
 hb_ot_layout_position_lookup (hb_font_t    *font,
 			      hb_face_t    *face,
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index 76d4a56..2364d3c 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -249,7 +249,7 @@ hb_substitute_complex_fallback (hb_ot_shape_context_t *c HB_UNUSED)
 static void
 hb_position_default (hb_ot_shape_context_t *c)
 {
-  hb_buffer_clear_positions (c->buffer);
+  hb_ot_layout_position_start (c->buffer);
 
   unsigned int count = c->buffer->len;
   for (unsigned int i = 0; i < count; i++) {
commit 2fc56edff6d64f190271454ccb1b5fd347d4f172
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Apr 15 18:35:08 2011 -0400

    [API] Remove hb_buffer_clear()
    
    One should use hb_buffer_reset() really.

diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc
index 839a256..f5dc02f 100644
--- a/src/hb-buffer.cc
+++ b/src/hb-buffer.cc
@@ -231,17 +231,6 @@ hb_buffer_get_language (hb_buffer_t *buffer)
 void
 hb_buffer_reset (hb_buffer_t *buffer)
 {
-  hb_buffer_clear (buffer);
-
-  buffer->props = _hb_buffer_nil.props;
-
-  hb_unicode_funcs_destroy (buffer->unicode);
-  buffer->unicode = _hb_buffer_nil.unicode;
-}
-
-void
-hb_buffer_clear (hb_buffer_t *buffer)
-{
   buffer->have_output = FALSE;
   buffer->have_positions = FALSE;
   buffer->in_error = FALSE;
@@ -250,6 +239,11 @@ hb_buffer_clear (hb_buffer_t *buffer)
   buffer->i = 0;
   buffer->out_info = buffer->info;
   buffer->serial = 0;
+
+  buffer->props = _hb_buffer_nil.props;
+
+  hb_unicode_funcs_destroy (buffer->unicode);
+  buffer->unicode = _hb_buffer_nil.unicode;
 }
 
 hb_bool_t
diff --git a/src/hb-buffer.h b/src/hb-buffer.h
index a2785ee..49f6a49 100644
--- a/src/hb-buffer.h
+++ b/src/hb-buffer.h
@@ -102,10 +102,6 @@ hb_buffer_get_language (hb_buffer_t *buffer);
 void
 hb_buffer_reset (hb_buffer_t *buffer);
 
-/* Clears buffer glyphs, but doesn't touch other buffer attributes. */
-void
-hb_buffer_clear (hb_buffer_t *buffer);
-
 void
 hb_buffer_clear_positions (hb_buffer_t *buffer);
 
diff --git a/test/test-buffer.c b/test/test-buffer.c
index d4c9243..4316f17 100644
--- a/test/test-buffer.c
+++ b/test/test-buffer.c
@@ -146,10 +146,6 @@ test_buffer_contents (Fixture *fixture, gconstpointer user_data)
     g_assert_cmphex (glyphs[i].var1.u32,  ==, 0);
     g_assert_cmphex (glyphs[i].var2.u32,  ==, 0);
   }
-
-  hb_buffer_clear (fixture->b);
-  /* XXX Make sure clear() doesn't unset other properties? */
-  g_assert_cmpint (hb_buffer_get_length (fixture->b), ==, 0);
 }
 
 static void
commit 7f5bdc80541cdc90aa1acafba5e9e0bd2df53ff4
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Apr 15 18:34:55 2011 -0400

    [TODO] Remove done items

diff --git a/TODO b/TODO
index 0eccb48..72e9f3e 100644
--- a/TODO
+++ b/TODO
@@ -25,8 +25,6 @@ API issues to fix before 1.0:
 
 - Use tags for hb_script_t
 
-- Better name for iso15924 script functions
-
 - Figure out how many .so objects, how to link, etc
 
 - Shall y axis progress downward instead of upward?
@@ -69,8 +67,6 @@ Build fixes:
 
 - GNOME Bug 612402 - (hb-arm) HarfBuzz compilation fix for arm
 
-- Better define HB_INTERNAL
-
 
 Optimizations:
 =============
commit 5814dfa3f5aa41bc3df06b78980d57d7bea0ba58
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Apr 15 14:41:04 2011 -0400

    Cosmetic

diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index 4950e00..76d4a56 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -366,16 +366,16 @@ hb_ot_shape_execute (hb_ot_shape_plan_t *plan,
 }
 
 void
-hb_ot_shape (hb_font_t    *font,
-	     hb_face_t    *face,
-	     hb_buffer_t  *buffer,
-	     const hb_feature_t *user_features,
-	     unsigned int        num_user_features)
+hb_ot_shape (hb_font_t          *font,
+	     hb_face_t          *face,
+	     hb_buffer_t        *buffer,
+	     const hb_feature_t *features,
+	     unsigned int        num_features)
 {
   hb_ot_shape_plan_t plan;
 
-  hb_ot_shape_plan_internal (&plan, face, &buffer->props, user_features, num_user_features);
-  hb_ot_shape_execute (&plan, font, face, buffer, user_features, num_user_features);
+  hb_ot_shape_plan_internal (&plan, face, &buffer->props, features, num_features);
+  hb_ot_shape_execute (&plan, font, face, buffer, features, num_features);
 }
 
 
diff --git a/src/hb-ot-shape.h b/src/hb-ot-shape.h
index c90e0fe..45d8104 100644
--- a/src/hb-ot-shape.h
+++ b/src/hb-ot-shape.h
@@ -37,8 +37,8 @@ void
 hb_ot_shape (hb_font_t          *font,
 	     hb_face_t          *face,
 	     hb_buffer_t        *buffer,
-	     const hb_feature_t *user_features,
-	     unsigned int        num_user_features);
+	     const hb_feature_t *features,
+	     unsigned int        num_features);
 
 
 HB_END_DECLS
diff --git a/src/hb-shape.cc b/src/hb-shape.cc
index 0a6f1dc..9e2ea4e 100644
--- a/src/hb-shape.cc
+++ b/src/hb-shape.cc
@@ -40,11 +40,11 @@ HB_BEGIN_DECLS
 
 
 static void
-hb_shape_internal (hb_font_t    *font,
-		   hb_face_t    *face,
-		   hb_buffer_t  *buffer,
-		   hb_feature_t *features,
-		   unsigned int  num_features)
+hb_shape_internal (hb_font_t          *font,
+		   hb_face_t          *face,
+		   hb_buffer_t        *buffer,
+		   const hb_feature_t *features,
+		   unsigned int        num_features)
 {
 #if 0 && defined(HAVE_GRAPHITE)
   hb_blob_t *silf_blob;
@@ -62,11 +62,11 @@ hb_shape_internal (hb_font_t    *font,
 }
 
 void
-hb_shape (hb_font_t    *font,
-	  hb_face_t    *face,
-	  hb_buffer_t  *buffer,
-	  hb_feature_t *features,
-	  unsigned int  num_features)
+hb_shape (hb_font_t          *font,
+	  hb_face_t          *face,
+	  hb_buffer_t        *buffer,
+	  const hb_feature_t *features,
+	  unsigned int        num_features)
 {
   hb_segment_properties_t orig_props;
 
diff --git a/src/hb-shape.h b/src/hb-shape.h
index 48f1a55..6bc3257 100644
--- a/src/hb-shape.h
+++ b/src/hb-shape.h
@@ -42,11 +42,11 @@ typedef struct _hb_feature_t {
 } hb_feature_t;
 
 void
-hb_shape (hb_font_t    *font,
-	  hb_face_t    *face,
-	  hb_buffer_t  *buffer,
-	  hb_feature_t *features,
-	  unsigned int  num_features);
+hb_shape (hb_font_t          *font,
+	  hb_face_t          *face,
+	  hb_buffer_t        *buffer,
+	  const hb_feature_t *features,
+	  unsigned int        num_features);
 
 
 HB_END_DECLS
commit cfbfeb88a6ec059ea97a6624e63cfacc642b685a
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Apr 15 12:40:40 2011 -0400

    [TODO] Remove done items

diff --git a/TODO b/TODO
index def1e21..0eccb48 100644
--- a/TODO
+++ b/TODO
@@ -15,10 +15,6 @@ General fixes:
 API issues to fix before 1.0:
 ============================
 
-- Add hb_buffer_resize()?
-
-- Add hb_buffer_reset()?
-
 - Rename / remove hb_buffer_add_glyph()?
 
 - Sprinkle const all over public and private API
commit 3cbdf70e0a92f1c24e16c0d4dcfbec4ac59a77a3
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Apr 15 12:32:06 2011 -0400

    Make hb_language_t typesafe

diff --git a/src/hb-common.c b/src/hb-common.c
index c57ba0b..ac62e83 100644
--- a/src/hb-common.c
+++ b/src/hb-common.c
@@ -51,6 +51,10 @@ hb_tag_from_string (const char *s)
 
 /* 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,
@@ -99,7 +103,7 @@ hb_language_from_string (const char *str)
 {
   static unsigned int num_langs;
   static unsigned int num_alloced;
-  static const char **langs;
+  static hb_language_t *langs;
   unsigned int i;
   unsigned char *p;
 
@@ -109,31 +113,31 @@ hb_language_from_string (const char *str)
     return NULL;
 
   for (i = 0; i < num_langs; i++)
-    if (lang_equal (str, 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);
-    const char **new_langs = realloc (langs, new_alloced * sizeof (langs[0]));
+    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] = strdup (str);
-  for (p = (unsigned char *) langs[i]; *p; p++)
+  langs[i] = (hb_language_t) strdup (str);
+  for (p = (unsigned char *) langs[i]->s; *p; p++)
     *p = canon_map[*p];
 
   num_langs++;
 
-  return (hb_language_t) langs[i];
+  return langs[i];
 }
 
 const char *
 hb_language_to_string (hb_language_t language)
 {
-  return (const char *) language;
+  return language->s;
 }
 
 
diff --git a/src/hb-common.h b/src/hb-common.h
index 606e117..4dadc94 100644
--- a/src/hb-common.h
+++ b/src/hb-common.h
@@ -99,7 +99,7 @@ typedef enum _hb_direction_t {
 
 /* hb_language_t */
 
-typedef const void *hb_language_t;
+typedef struct _hb_language_t *hb_language_t;
 
 hb_language_t
 hb_language_from_string (const char *str);



More information about the HarfBuzz mailing list