Update freetype to e1394d56752cac3bd68ab2358a8e1384ce7b9aaa

Integrated patches from freetype2 git repository, up to hashval
e1394d56752cac3bd68ab2358a8e1384ce7b9aaa, which is post-2.5.3.

Most recent commit message from freetype git:
  Minor documentation improvement.

Noteworthy patches included:
  Fix Savannah bug #41697, part 2.
  Fix Savannah bug #41697, part 1.

Bug: 16575323
Change-Id: I4f8f9375afd2540618b3ebf6152d77b743975dce
diff --git a/include/config/ftconfig.h b/include/config/ftconfig.h
index 0770e78..89a0f8f 100644
--- a/include/config/ftconfig.h
+++ b/include/config/ftconfig.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    ANSI-specific configuration file (specification only).               */
 /*                                                                         */
-/*  Copyright 1996-2004, 2006-2008, 2010-2011, 2013 by                     */
+/*  Copyright 1996-2004, 2006-2008, 2010-2011, 2013, 2014 by               */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -333,219 +333,6 @@
 #define FT_DUMMY_STMNT  FT_BEGIN_STMNT FT_END_STMNT
 
 
-#ifndef  FT_CONFIG_OPTION_NO_ASSEMBLER
-  /* Provide assembler fragments for performance-critical functions. */
-  /* These must be defined `static __inline__' with GCC.             */
-
-#if defined( __CC_ARM ) || defined( __ARMCC__ )  /* RVCT */
-
-#define FT_MULFIX_ASSEMBLER  FT_MulFix_arm
-
-  /* documentation is in freetype.h */
-
-  static __inline FT_Int32
-  FT_MulFix_arm( FT_Int32  a,
-                 FT_Int32  b )
-  {
-    register FT_Int32  t, t2;
-
-
-    __asm
-    {
-      smull t2, t,  b,  a           /* (lo=t2,hi=t) = a*b */
-      mov   a,  t,  asr #31         /* a   = (hi >> 31) */
-      add   a,  a,  #0x8000         /* a  += 0x8000 */
-      adds  t2, t2, a               /* t2 += a */
-      adc   t,  t,  #0              /* t  += carry */
-      mov   a,  t2, lsr #16         /* a   = t2 >> 16 */
-      orr   a,  a,  t,  lsl #16     /* a  |= t << 16 */
-    }
-    return a;
-  }
-
-#endif /* __CC_ARM || __ARMCC__ */
-
-
-#ifdef __GNUC__
-
-#if defined( __arm__ )                                 && \
-    ( !defined( __thumb__ ) || defined( __thumb2__ ) ) && \
-    !( defined( __CC_ARM ) || defined( __ARMCC__ ) )
-
-#define FT_MULFIX_ASSEMBLER  FT_MulFix_arm
-
-  /* documentation is in freetype.h */
-
-  static __inline__ FT_Int32
-  FT_MulFix_arm( FT_Int32  a,
-                 FT_Int32  b )
-  {
-    register FT_Int32  t, t2;
-
-
-    __asm__ __volatile__ (
-      "smull  %1, %2, %4, %3\n\t"       /* (lo=%1,hi=%2) = a*b */
-      "mov    %0, %2, asr #31\n\t"      /* %0  = (hi >> 31) */
-#ifdef __clang__
-      "add.w  %0, %0, #0x8000\n\t"      /* %0 += 0x8000 */
-#else
-      "add    %0, %0, #0x8000\n\t"      /* %0 += 0x8000 */
-#endif
-      "adds   %1, %1, %0\n\t"           /* %1 += %0 */
-      "adc    %2, %2, #0\n\t"           /* %2 += carry */
-      "mov    %0, %1, lsr #16\n\t"      /* %0  = %1 >> 16 */
-      "orr    %0, %0, %2, lsl #16\n\t"  /* %0 |= %2 << 16 */
-      : "=r"(a), "=&r"(t2), "=&r"(t)
-      : "r"(a), "r"(b)
-      : "cc" );
-    return a;
-  }
-
-#endif /* __arm__                      && */
-       /* ( __thumb2__ || !__thumb__ ) && */
-       /* !( __CC_ARM || __ARMCC__ )      */
-
-
-#if defined( __i386__ )
-
-#define FT_MULFIX_ASSEMBLER  FT_MulFix_i386
-
-  /* documentation is in freetype.h */
-
-  static __inline__ FT_Int32
-  FT_MulFix_i386( FT_Int32  a,
-                  FT_Int32  b )
-  {
-    register FT_Int32  result;
-
-
-    __asm__ __volatile__ (
-      "imul  %%edx\n"
-      "movl  %%edx, %%ecx\n"
-      "sarl  $31, %%ecx\n"
-      "addl  $0x8000, %%ecx\n"
-      "addl  %%ecx, %%eax\n"
-      "adcl  $0, %%edx\n"
-      "shrl  $16, %%eax\n"
-      "shll  $16, %%edx\n"
-      "addl  %%edx, %%eax\n"
-      : "=a"(result), "=d"(b)
-      : "a"(a), "d"(b)
-      : "%ecx", "cc" );
-    return result;
-  }
-
-#endif /* i386 */
-
-#endif /* __GNUC__ */
-
-
-#ifdef _MSC_VER /* Visual C++ */
-
-#ifdef _M_IX86
-
-#define FT_MULFIX_ASSEMBLER  FT_MulFix_i386
-
-  /* documentation is in freetype.h */
-
-  static __inline FT_Int32
-  FT_MulFix_i386( FT_Int32  a,
-                  FT_Int32  b )
-  {
-    register FT_Int32  result;
-
-    __asm
-    {
-      mov eax, a
-      mov edx, b
-      imul edx
-      mov ecx, edx
-      sar ecx, 31
-      add ecx, 8000h
-      add eax, ecx
-      adc edx, 0
-      shr eax, 16
-      shl edx, 16
-      add eax, edx
-      mov result, eax
-    }
-    return result;
-  }
-
-#endif /* _M_IX86 */
-
-#endif /* _MSC_VER */
-
-
-#if defined( __GNUC__ ) && defined( __x86_64__ )
-
-#define FT_MULFIX_ASSEMBLER  FT_MulFix_x86_64
-
-  static __inline__ FT_Int32
-  FT_MulFix_x86_64( FT_Int32  a,
-                    FT_Int32  b )
-  {
-    /* Temporarily disable the warning that C90 doesn't support */
-    /* `long long'.                                             */
-#if ( __GNUC__ > 4 ) || ( ( __GNUC__ == 4 ) && ( __GNUC_MINOR__ >= 6 ) )
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wlong-long"
-#endif
-
-#if 1
-    /* Technically not an assembly fragment, but GCC does a really good */
-    /* job at inlining it and generating good machine code for it.      */
-    long long  ret, tmp;
-
-
-    ret  = (long long)a * b;
-    tmp  = ret >> 63;
-    ret += 0x8000 + tmp;
-
-    return (FT_Int32)( ret >> 16 );
-#else
-
-    /* For some reason, GCC 4.6 on Ubuntu 12.04 generates invalid machine  */
-    /* code from the lines below.  The main issue is that `wide_a' is not  */
-    /* properly initialized by sign-extending `a'.  Instead, the generated */
-    /* machine code assumes that the register that contains `a' on input   */
-    /* can be used directly as a 64-bit value, which is wrong most of the  */
-    /* time.                                                               */
-    long long  wide_a = (long long)a;
-    long long  wide_b = (long long)b;
-    long long  result;
-
-
-    __asm__ __volatile__ (
-      "imul %2, %1\n"
-      "mov %1, %0\n"
-      "sar $63, %0\n"
-      "lea 0x8000(%1, %0), %0\n"
-      "sar $16, %0\n"
-      : "=&r"(result), "=&r"(wide_a)
-      : "r"(wide_b)
-      : "cc" );
-
-    return (FT_Int32)result;
-#endif
-
-#if ( __GNUC__ > 4 ) || ( ( __GNUC__ == 4 ) && ( __GNUC_MINOR__ >= 6 ) )
-#pragma GCC diagnostic pop
-#endif
-  }
-
-#endif /* __GNUC__ && __x86_64__ */
-
-#endif /* !FT_CONFIG_OPTION_NO_ASSEMBLER */
-
-
-#ifdef FT_CONFIG_OPTION_INLINE_MULFIX
-#ifdef FT_MULFIX_ASSEMBLER
-#define FT_MULFIX_INLINED  FT_MULFIX_ASSEMBLER
-#endif
-#endif
-
-
 #ifdef FT_MAKE_OPTION_SINGLE_OBJECT
 
 #define FT_LOCAL( x )      static  x
diff --git a/include/config/ftoption.h b/include/config/ftoption.h
index 72cc060..db795d3 100644
--- a/include/config/ftoption.h
+++ b/include/config/ftoption.h
@@ -230,6 +230,19 @@
 
   /*************************************************************************/
   /*                                                                       */
+  /*  HarfBuzz support.                                                    */
+  /*                                                                       */
+  /*   FreeType uses the HarfBuzz library to improve auto-hinting of       */
+  /*   OpenType fonts.  If available, many glyphs not directly addressable */
+  /*   by a font's character map will be hinted also.                      */
+  /*                                                                       */
+  /*   Define this macro if you want to enable this `feature'.             */
+  /*                                                                       */
+/* #define FT_CONFIG_OPTION_USE_HARFBUZZ */
+
+
+  /*************************************************************************/
+  /*                                                                       */
   /* DLL export compilation                                                */
   /*                                                                       */
   /*   When compiling FreeType as a DLL, some systems/compilers need a     */
diff --git a/include/freetype.h b/include/freetype.h
index 372319a..d6217e9 100644
--- a/include/freetype.h
+++ b/include/freetype.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType high-level API and common types (specification only).       */
 /*                                                                         */
-/*  Copyright 1996-2013 by                                                 */
+/*  Copyright 1996-2014 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -1592,7 +1592,6 @@
   /*                         This field is only valid for the composite    */
   /*                         glyph format that should normally only be     */
   /*                         loaded with the @FT_LOAD_NO_RECURSE flag.     */
-  /*                         For now this is internal to FreeType.         */
   /*                                                                       */
   /*    subglyphs         :: An array of subglyph descriptors for          */
   /*                         composite glyphs.  There are `num_subglyphs'  */
@@ -2305,6 +2304,8 @@
   /*    glyph relative to this size.  For more information refer to        */
   /*    `http://www.freetype.org/freetype2/docs/glyphs/glyphs-2.html'      */
   /*                                                                       */
+  /*    Don't use this function if you are using the FreeType cache API.   */
+  /*                                                                       */
   FT_EXPORT( FT_Error )
   FT_Request_Size( FT_Face          face,
                    FT_Size_Request  req );
@@ -2379,6 +2380,8 @@
   /*    constrained, to this pixel size.  Refer to @FT_Request_Size to     */
   /*    understand how requested sizes relate to actual sizes.             */
   /*                                                                       */
+  /*    Don't use this function if you are using the FreeType cache API.   */
+  /*                                                                       */
   FT_EXPORT( FT_Error )
   FT_Set_Pixel_Sizes( FT_Face  face,
                       FT_UInt  pixel_width,
@@ -2556,14 +2559,11 @@
    *     Ignored.  Deprecated.
    *
    *   FT_LOAD_NO_RECURSE ::
-   *     This flag is only used internally.  It merely indicates that the
-   *     font driver should not load composite glyphs recursively.  Instead,
-   *     it should set the `num_subglyph' and `subglyphs' values of the
-   *     glyph slot accordingly, and set `glyph->format' to
-   *     @FT_GLYPH_FORMAT_COMPOSITE.
-   *
-   *     The description of sub-glyphs is not available to client
-   *     applications for now.
+   *     Indicate that the font driver should not load composite glyphs
+   *     recursively.  Instead, it should set the `num_subglyph' and
+   *     `subglyphs' values of the glyph slot accordingly, and set
+   *     `glyph->format' to @FT_GLYPH_FORMAT_COMPOSITE.  The description of
+   *     subglyphs can then be accessed with @FT_Get_SubGlyph_Info.
    *
    *     This flag implies @FT_LOAD_NO_SCALE and @FT_LOAD_IGNORE_TRANSFORM.
    *
@@ -2871,6 +2871,10 @@
   /* <Return>                                                              */
   /*    FreeType error code.  0~means success.                             */
   /*                                                                       */
+  /* <Note>                                                                */
+  /*    To get meaningful results, font scaling values must be set with    */
+  /*    functions like @FT_Set_Char_Size before calling FT_Render_Glyph.   */
+  /*                                                                       */
   FT_EXPORT( FT_Error )
   FT_Render_Glyph( FT_GlyphSlot    slot,
                    FT_Render_Mode  render_mode );
@@ -3057,9 +3061,8 @@
   /*    glyph index~0 always corresponds to the `missing glyph' (called    */
   /*    `.notdef').                                                        */
   /*                                                                       */
-  /*    This function is not compiled within the library if the config     */
-  /*    macro `FT_CONFIG_OPTION_NO_GLYPH_NAMES' is defined in              */
-  /*    `ftoptions.h'.                                                     */
+  /*    This function always returns an error if the config macro          */
+  /*    `FT_CONFIG_OPTION_NO_GLYPH_NAMES' is not defined in `ftoptions.h'. */
   /*                                                                       */
   FT_EXPORT( FT_Error )
   FT_Get_Glyph_Name( FT_Face     face,
@@ -3957,7 +3960,7 @@
    */
 #define FREETYPE_MAJOR  2
 #define FREETYPE_MINOR  5
-#define FREETYPE_PATCH  2
+#define FREETYPE_PATCH  3
 
 
   /*************************************************************************/
diff --git a/include/ftautoh.h b/include/ftautoh.h
index bf97b3f..936791e 100644
--- a/include/ftautoh.h
+++ b/include/ftautoh.h
@@ -287,7 +287,52 @@
    *   face-specific property like @glyph-to-script-map, or by auto-hinting
    *   any glyph from that face.  In particular, if you have already created
    *   an @FT_Face structure but not loaded any glyph (using the
-   *   auto-hinter), a change of the fallback glyph will affect this face.
+   *   auto-hinter), a change of the fallback script will affect this face.
+   *
+   */
+
+
+  /**************************************************************************
+   *
+   * @property:
+   *   default-script
+   *
+   * @description:
+   *   *Experimental* *only*
+   *
+   *   If Freetype gets compiled with FT_CONFIG_OPTION_USE_HARFBUZZ to make
+   *   the HarfBuzz library access OpenType features for getting better
+   *   glyph coverages, this property sets the (auto-fitter) script to be
+   *   used for the default (OpenType) script data of a font's GSUB table.
+   *   Features for the default script are intended for all scripts not
+   *   explicitly handled in GSUB; an example is a `dlig' feature,
+   *   containing the combination of the characters `T', `E', and `L' to
+   *   form a `TEL' ligature.
+   *
+   *   By default, this is @FT_AUTOHINTER_SCRIPT_LATIN.  Using the
+   *   `default-script' property, this default value can be changed.
+   *
+   *   {
+   *     FT_Library  library;
+   *     FT_UInt     default_script = FT_AUTOHINTER_SCRIPT_NONE;
+   *
+   *
+   *     FT_Init_FreeType( &library );
+   *
+   *     FT_Property_Set( library, "autofitter",
+   *                               "default-script", &default_script );
+   *   }
+   *
+   * @note:
+   *   This property can be used with @FT_Property_Get also.
+   *
+   *   It's important to use the right timing for changing this value: The
+   *   creation of the glyph-to-script map that eventually uses the
+   *   default script value gets triggered either by setting or reading a
+   *   face-specific property like @glyph-to-script-map, or by auto-hinting
+   *   any glyph from that face.  In particular, if you have already created
+   *   an @FT_Face structure but not loaded any glyph (using the
+   *   auto-hinter), a change of the default script will affect this face.
    *
    */
 
diff --git a/include/ftbdf.h b/include/ftbdf.h
index 4f8baf8..8b3c411 100644
--- a/include/ftbdf.h
+++ b/include/ftbdf.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType API for accessing BDF-specific strings (specification).     */
 /*                                                                         */
-/*  Copyright 2002, 2003, 2004, 2006, 2009 by                              */
+/*  Copyright 2002-2004, 2006, 2009, 2014 by                               */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -106,7 +106,8 @@
   *      The property type.
   *
   *    u.atom ::
-  *      The atom string, if type is @BDF_PROPERTY_TYPE_ATOM.
+  *      The atom string, if type is @BDF_PROPERTY_TYPE_ATOM.  May be
+  *      NULL, indicating an empty string.
   *
   *    u.integer ::
   *      A signed integer, if type is @BDF_PROPERTY_TYPE_INTEGER.
diff --git a/include/fterrdef.h b/include/fterrdef.h
index 76c7b9e..99b2fad 100644
--- a/include/fterrdef.h
+++ b/include/fterrdef.h
@@ -31,218 +31,218 @@
 
   /* generic errors */
 
-  FT_NOERRORDEF_( Ok,                                        0x00, \
+  FT_NOERRORDEF_( Ok,                                        0x00,
                   "no error" )
 
-  FT_ERRORDEF_( Cannot_Open_Resource,                        0x01, \
+  FT_ERRORDEF_( Cannot_Open_Resource,                        0x01,
                 "cannot open resource" )
-  FT_ERRORDEF_( Unknown_File_Format,                         0x02, \
+  FT_ERRORDEF_( Unknown_File_Format,                         0x02,
                 "unknown file format" )
-  FT_ERRORDEF_( Invalid_File_Format,                         0x03, \
+  FT_ERRORDEF_( Invalid_File_Format,                         0x03,
                 "broken file" )
-  FT_ERRORDEF_( Invalid_Version,                             0x04, \
+  FT_ERRORDEF_( Invalid_Version,                             0x04,
                 "invalid FreeType version" )
-  FT_ERRORDEF_( Lower_Module_Version,                        0x05, \
+  FT_ERRORDEF_( Lower_Module_Version,                        0x05,
                 "module version is too low" )
-  FT_ERRORDEF_( Invalid_Argument,                            0x06, \
+  FT_ERRORDEF_( Invalid_Argument,                            0x06,
                 "invalid argument" )
-  FT_ERRORDEF_( Unimplemented_Feature,                       0x07, \
+  FT_ERRORDEF_( Unimplemented_Feature,                       0x07,
                 "unimplemented feature" )
-  FT_ERRORDEF_( Invalid_Table,                               0x08, \
+  FT_ERRORDEF_( Invalid_Table,                               0x08,
                 "broken table" )
-  FT_ERRORDEF_( Invalid_Offset,                              0x09, \
+  FT_ERRORDEF_( Invalid_Offset,                              0x09,
                 "broken offset within table" )
-  FT_ERRORDEF_( Array_Too_Large,                             0x0A, \
+  FT_ERRORDEF_( Array_Too_Large,                             0x0A,
                 "array allocation size too large" )
-  FT_ERRORDEF_( Missing_Module,                              0x0B, \
+  FT_ERRORDEF_( Missing_Module,                              0x0B,
                 "missing module" )
-  FT_ERRORDEF_( Missing_Property,                            0x0C, \
+  FT_ERRORDEF_( Missing_Property,                            0x0C,
                 "missing property" )
 
   /* glyph/character errors */
 
-  FT_ERRORDEF_( Invalid_Glyph_Index,                         0x10, \
+  FT_ERRORDEF_( Invalid_Glyph_Index,                         0x10,
                 "invalid glyph index" )
-  FT_ERRORDEF_( Invalid_Character_Code,                      0x11, \
+  FT_ERRORDEF_( Invalid_Character_Code,                      0x11,
                 "invalid character code" )
-  FT_ERRORDEF_( Invalid_Glyph_Format,                        0x12, \
+  FT_ERRORDEF_( Invalid_Glyph_Format,                        0x12,
                 "unsupported glyph image format" )
-  FT_ERRORDEF_( Cannot_Render_Glyph,                         0x13, \
+  FT_ERRORDEF_( Cannot_Render_Glyph,                         0x13,
                 "cannot render this glyph format" )
-  FT_ERRORDEF_( Invalid_Outline,                             0x14, \
+  FT_ERRORDEF_( Invalid_Outline,                             0x14,
                 "invalid outline" )
-  FT_ERRORDEF_( Invalid_Composite,                           0x15, \
+  FT_ERRORDEF_( Invalid_Composite,                           0x15,
                 "invalid composite glyph" )
-  FT_ERRORDEF_( Too_Many_Hints,                              0x16, \
+  FT_ERRORDEF_( Too_Many_Hints,                              0x16,
                 "too many hints" )
-  FT_ERRORDEF_( Invalid_Pixel_Size,                          0x17, \
+  FT_ERRORDEF_( Invalid_Pixel_Size,                          0x17,
                 "invalid pixel size" )
 
   /* handle errors */
 
-  FT_ERRORDEF_( Invalid_Handle,                              0x20, \
+  FT_ERRORDEF_( Invalid_Handle,                              0x20,
                 "invalid object handle" )
-  FT_ERRORDEF_( Invalid_Library_Handle,                      0x21, \
+  FT_ERRORDEF_( Invalid_Library_Handle,                      0x21,
                 "invalid library handle" )
-  FT_ERRORDEF_( Invalid_Driver_Handle,                       0x22, \
+  FT_ERRORDEF_( Invalid_Driver_Handle,                       0x22,
                 "invalid module handle" )
-  FT_ERRORDEF_( Invalid_Face_Handle,                         0x23, \
+  FT_ERRORDEF_( Invalid_Face_Handle,                         0x23,
                 "invalid face handle" )
-  FT_ERRORDEF_( Invalid_Size_Handle,                         0x24, \
+  FT_ERRORDEF_( Invalid_Size_Handle,                         0x24,
                 "invalid size handle" )
-  FT_ERRORDEF_( Invalid_Slot_Handle,                         0x25, \
+  FT_ERRORDEF_( Invalid_Slot_Handle,                         0x25,
                 "invalid glyph slot handle" )
-  FT_ERRORDEF_( Invalid_CharMap_Handle,                      0x26, \
+  FT_ERRORDEF_( Invalid_CharMap_Handle,                      0x26,
                 "invalid charmap handle" )
-  FT_ERRORDEF_( Invalid_Cache_Handle,                        0x27, \
+  FT_ERRORDEF_( Invalid_Cache_Handle,                        0x27,
                 "invalid cache manager handle" )
-  FT_ERRORDEF_( Invalid_Stream_Handle,                       0x28, \
+  FT_ERRORDEF_( Invalid_Stream_Handle,                       0x28,
                 "invalid stream handle" )
 
   /* driver errors */
 
-  FT_ERRORDEF_( Too_Many_Drivers,                            0x30, \
+  FT_ERRORDEF_( Too_Many_Drivers,                            0x30,
                 "too many modules" )
-  FT_ERRORDEF_( Too_Many_Extensions,                         0x31, \
+  FT_ERRORDEF_( Too_Many_Extensions,                         0x31,
                 "too many extensions" )
 
   /* memory errors */
 
-  FT_ERRORDEF_( Out_Of_Memory,                               0x40, \
+  FT_ERRORDEF_( Out_Of_Memory,                               0x40,
                 "out of memory" )
-  FT_ERRORDEF_( Unlisted_Object,                             0x41, \
+  FT_ERRORDEF_( Unlisted_Object,                             0x41,
                 "unlisted object" )
 
   /* stream errors */
 
-  FT_ERRORDEF_( Cannot_Open_Stream,                          0x51, \
+  FT_ERRORDEF_( Cannot_Open_Stream,                          0x51,
                 "cannot open stream" )
-  FT_ERRORDEF_( Invalid_Stream_Seek,                         0x52, \
+  FT_ERRORDEF_( Invalid_Stream_Seek,                         0x52,
                 "invalid stream seek" )
-  FT_ERRORDEF_( Invalid_Stream_Skip,                         0x53, \
+  FT_ERRORDEF_( Invalid_Stream_Skip,                         0x53,
                 "invalid stream skip" )
-  FT_ERRORDEF_( Invalid_Stream_Read,                         0x54, \
+  FT_ERRORDEF_( Invalid_Stream_Read,                         0x54,
                 "invalid stream read" )
-  FT_ERRORDEF_( Invalid_Stream_Operation,                    0x55, \
+  FT_ERRORDEF_( Invalid_Stream_Operation,                    0x55,
                 "invalid stream operation" )
-  FT_ERRORDEF_( Invalid_Frame_Operation,                     0x56, \
+  FT_ERRORDEF_( Invalid_Frame_Operation,                     0x56,
                 "invalid frame operation" )
-  FT_ERRORDEF_( Nested_Frame_Access,                         0x57, \
+  FT_ERRORDEF_( Nested_Frame_Access,                         0x57,
                 "nested frame access" )
-  FT_ERRORDEF_( Invalid_Frame_Read,                          0x58, \
+  FT_ERRORDEF_( Invalid_Frame_Read,                          0x58,
                 "invalid frame read" )
 
   /* raster errors */
 
-  FT_ERRORDEF_( Raster_Uninitialized,                        0x60, \
+  FT_ERRORDEF_( Raster_Uninitialized,                        0x60,
                 "raster uninitialized" )
-  FT_ERRORDEF_( Raster_Corrupted,                            0x61, \
+  FT_ERRORDEF_( Raster_Corrupted,                            0x61,
                 "raster corrupted" )
-  FT_ERRORDEF_( Raster_Overflow,                             0x62, \
+  FT_ERRORDEF_( Raster_Overflow,                             0x62,
                 "raster overflow" )
-  FT_ERRORDEF_( Raster_Negative_Height,                      0x63, \
+  FT_ERRORDEF_( Raster_Negative_Height,                      0x63,
                 "negative height while rastering" )
 
   /* cache errors */
 
-  FT_ERRORDEF_( Too_Many_Caches,                             0x70, \
+  FT_ERRORDEF_( Too_Many_Caches,                             0x70,
                 "too many registered caches" )
 
   /* TrueType and SFNT errors */
 
-  FT_ERRORDEF_( Invalid_Opcode,                              0x80, \
+  FT_ERRORDEF_( Invalid_Opcode,                              0x80,
                 "invalid opcode" )
-  FT_ERRORDEF_( Too_Few_Arguments,                           0x81, \
+  FT_ERRORDEF_( Too_Few_Arguments,                           0x81,
                 "too few arguments" )
-  FT_ERRORDEF_( Stack_Overflow,                              0x82, \
+  FT_ERRORDEF_( Stack_Overflow,                              0x82,
                 "stack overflow" )
-  FT_ERRORDEF_( Code_Overflow,                               0x83, \
+  FT_ERRORDEF_( Code_Overflow,                               0x83,
                 "code overflow" )
-  FT_ERRORDEF_( Bad_Argument,                                0x84, \
+  FT_ERRORDEF_( Bad_Argument,                                0x84,
                 "bad argument" )
-  FT_ERRORDEF_( Divide_By_Zero,                              0x85, \
+  FT_ERRORDEF_( Divide_By_Zero,                              0x85,
                 "division by zero" )
-  FT_ERRORDEF_( Invalid_Reference,                           0x86, \
+  FT_ERRORDEF_( Invalid_Reference,                           0x86,
                 "invalid reference" )
-  FT_ERRORDEF_( Debug_OpCode,                                0x87, \
+  FT_ERRORDEF_( Debug_OpCode,                                0x87,
                 "found debug opcode" )
-  FT_ERRORDEF_( ENDF_In_Exec_Stream,                         0x88, \
+  FT_ERRORDEF_( ENDF_In_Exec_Stream,                         0x88,
                 "found ENDF opcode in execution stream" )
-  FT_ERRORDEF_( Nested_DEFS,                                 0x89, \
+  FT_ERRORDEF_( Nested_DEFS,                                 0x89,
                 "nested DEFS" )
-  FT_ERRORDEF_( Invalid_CodeRange,                           0x8A, \
+  FT_ERRORDEF_( Invalid_CodeRange,                           0x8A,
                 "invalid code range" )
-  FT_ERRORDEF_( Execution_Too_Long,                          0x8B, \
+  FT_ERRORDEF_( Execution_Too_Long,                          0x8B,
                 "execution context too long" )
-  FT_ERRORDEF_( Too_Many_Function_Defs,                      0x8C, \
+  FT_ERRORDEF_( Too_Many_Function_Defs,                      0x8C,
                 "too many function definitions" )
-  FT_ERRORDEF_( Too_Many_Instruction_Defs,                   0x8D, \
+  FT_ERRORDEF_( Too_Many_Instruction_Defs,                   0x8D,
                 "too many instruction definitions" )
-  FT_ERRORDEF_( Table_Missing,                               0x8E, \
+  FT_ERRORDEF_( Table_Missing,                               0x8E,
                 "SFNT font table missing" )
-  FT_ERRORDEF_( Horiz_Header_Missing,                        0x8F, \
+  FT_ERRORDEF_( Horiz_Header_Missing,                        0x8F,
                 "horizontal header (hhea) table missing" )
-  FT_ERRORDEF_( Locations_Missing,                           0x90, \
+  FT_ERRORDEF_( Locations_Missing,                           0x90,
                 "locations (loca) table missing" )
-  FT_ERRORDEF_( Name_Table_Missing,                          0x91, \
+  FT_ERRORDEF_( Name_Table_Missing,                          0x91,
                 "name table missing" )
-  FT_ERRORDEF_( CMap_Table_Missing,                          0x92, \
+  FT_ERRORDEF_( CMap_Table_Missing,                          0x92,
                 "character map (cmap) table missing" )
-  FT_ERRORDEF_( Hmtx_Table_Missing,                          0x93, \
+  FT_ERRORDEF_( Hmtx_Table_Missing,                          0x93,
                 "horizontal metrics (hmtx) table missing" )
-  FT_ERRORDEF_( Post_Table_Missing,                          0x94, \
+  FT_ERRORDEF_( Post_Table_Missing,                          0x94,
                 "PostScript (post) table missing" )
-  FT_ERRORDEF_( Invalid_Horiz_Metrics,                       0x95, \
+  FT_ERRORDEF_( Invalid_Horiz_Metrics,                       0x95,
                 "invalid horizontal metrics" )
-  FT_ERRORDEF_( Invalid_CharMap_Format,                      0x96, \
+  FT_ERRORDEF_( Invalid_CharMap_Format,                      0x96,
                 "invalid character map (cmap) format" )
-  FT_ERRORDEF_( Invalid_PPem,                                0x97, \
+  FT_ERRORDEF_( Invalid_PPem,                                0x97,
                 "invalid ppem value" )
-  FT_ERRORDEF_( Invalid_Vert_Metrics,                        0x98, \
+  FT_ERRORDEF_( Invalid_Vert_Metrics,                        0x98,
                 "invalid vertical metrics" )
-  FT_ERRORDEF_( Could_Not_Find_Context,                      0x99, \
+  FT_ERRORDEF_( Could_Not_Find_Context,                      0x99,
                 "could not find context" )
-  FT_ERRORDEF_( Invalid_Post_Table_Format,                   0x9A, \
+  FT_ERRORDEF_( Invalid_Post_Table_Format,                   0x9A,
                 "invalid PostScript (post) table format" )
-  FT_ERRORDEF_( Invalid_Post_Table,                          0x9B, \
+  FT_ERRORDEF_( Invalid_Post_Table,                          0x9B,
                 "invalid PostScript (post) table" )
 
   /* CFF, CID, and Type 1 errors */
 
-  FT_ERRORDEF_( Syntax_Error,                                0xA0, \
+  FT_ERRORDEF_( Syntax_Error,                                0xA0,
                 "opcode syntax error" )
-  FT_ERRORDEF_( Stack_Underflow,                             0xA1, \
+  FT_ERRORDEF_( Stack_Underflow,                             0xA1,
                 "argument stack underflow" )
-  FT_ERRORDEF_( Ignore,                                      0xA2, \
+  FT_ERRORDEF_( Ignore,                                      0xA2,
                 "ignore" )
-  FT_ERRORDEF_( No_Unicode_Glyph_Name,                       0xA3, \
+  FT_ERRORDEF_( No_Unicode_Glyph_Name,                       0xA3,
                 "no Unicode glyph name found" )
-  FT_ERRORDEF_( Glyph_Too_Big,                               0xA4, \
+  FT_ERRORDEF_( Glyph_Too_Big,                               0xA4,
                 "glyph to big for hinting" )
 
   /* BDF errors */
 
-  FT_ERRORDEF_( Missing_Startfont_Field,                     0xB0, \
+  FT_ERRORDEF_( Missing_Startfont_Field,                     0xB0,
                 "`STARTFONT' field missing" )
-  FT_ERRORDEF_( Missing_Font_Field,                          0xB1, \
+  FT_ERRORDEF_( Missing_Font_Field,                          0xB1,
                 "`FONT' field missing" )
-  FT_ERRORDEF_( Missing_Size_Field,                          0xB2, \
+  FT_ERRORDEF_( Missing_Size_Field,                          0xB2,
                 "`SIZE' field missing" )
-  FT_ERRORDEF_( Missing_Fontboundingbox_Field,               0xB3, \
+  FT_ERRORDEF_( Missing_Fontboundingbox_Field,               0xB3,
                 "`FONTBOUNDINGBOX' field missing" )
-  FT_ERRORDEF_( Missing_Chars_Field,                         0xB4, \
+  FT_ERRORDEF_( Missing_Chars_Field,                         0xB4,
                 "`CHARS' field missing" )
-  FT_ERRORDEF_( Missing_Startchar_Field,                     0xB5, \
+  FT_ERRORDEF_( Missing_Startchar_Field,                     0xB5,
                 "`STARTCHAR' field missing" )
-  FT_ERRORDEF_( Missing_Encoding_Field,                      0xB6, \
+  FT_ERRORDEF_( Missing_Encoding_Field,                      0xB6,
                 "`ENCODING' field missing" )
-  FT_ERRORDEF_( Missing_Bbx_Field,                           0xB7, \
+  FT_ERRORDEF_( Missing_Bbx_Field,                           0xB7,
                 "`BBX' field missing" )
-  FT_ERRORDEF_( Bbx_Too_Big,                                 0xB8, \
+  FT_ERRORDEF_( Bbx_Too_Big,                                 0xB8,
                 "`BBX' too big" )
-  FT_ERRORDEF_( Corrupted_Font_Header,                       0xB9, \
+  FT_ERRORDEF_( Corrupted_Font_Header,                       0xB9,
                 "Font header corrupted or missing fields" )
-  FT_ERRORDEF_( Corrupted_Font_Glyphs,                       0xBA, \
+  FT_ERRORDEF_( Corrupted_Font_Glyphs,                       0xBA,
                 "Font glyphs corrupted or missing fields" )
 
 
diff --git a/include/ftoutln.h b/include/ftoutln.h
index 8c7c57d..6c6d3f9 100644
--- a/include/ftoutln.h
+++ b/include/ftoutln.h
@@ -5,7 +5,7 @@
 /*    Support for the FT_Outline type used to store glyph shapes of        */
 /*    most scalable font formats (specification).                          */
 /*                                                                         */
-/*  Copyright 1996-2003, 2005-2013 by                                      */
+/*  Copyright 1996-2003, 2005-2014 by                                      */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -355,6 +355,9 @@
   /*        FT_Outline_Embolden( &face->slot->outline, strength );         */
   /*    }                                                                  */
   /*                                                                       */
+  /*    To get meaningful results, font scaling values must be set with    */
+  /*    functions like @FT_Set_Char_Size before calling FT_Render_Glyph.   */
+  /*                                                                       */
   FT_EXPORT( FT_Error )
   FT_Outline_Embolden( FT_Outline*  outline,
                        FT_Pos       strength );
diff --git a/include/internal/ftobjs.h b/include/internal/ftobjs.h
index 701c850..faa37f8 100644
--- a/include/internal/ftobjs.h
+++ b/include/internal/ftobjs.h
@@ -83,14 +83,6 @@
 
 
   /*
-   *  Return the highest power of 2 that is <= value; this correspond to
-   *  the highest bit in a given 32-bit value.
-   */
-  FT_BASE( FT_UInt32 )
-  ft_highpow2( FT_UInt32  value );
-
-
-  /*
    *  character classification functions -- since these are used to parse
    *  font files, we must not use those in <ctypes.h> which are
    *  locale-dependent
diff --git a/include/internal/ftrfork.h b/include/internal/ftrfork.h
index 6307f2d..d750cbe 100644
--- a/include/internal/ftrfork.h
+++ b/include/internal/ftrfork.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Embedded resource forks accessor (specification).                    */
 /*                                                                         */
-/*  Copyright 2004, 2006, 2007, 2012 by                                    */
+/*  Copyright 2004, 2006, 2007, 2012, 2013 by                              */
 /*  Masatake YAMATO and Redhat K.K.                                        */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -94,7 +94,7 @@
   /* this array is a function in PIC mode, so no ; is needed in END */
 #define CONST_FT_RFORK_RULE_ARRAY_BEGIN( name, type )  \
           void                                         \
-          FT_Init_ ## name( type*  storage )           \
+          FT_Init_Table_ ## name( type*  storage )     \
           {                                            \
             type*  local = storage;                    \
                                                        \
@@ -224,6 +224,13 @@
   /*    tag ::                                                             */
   /*      The resource tag.                                                */
   /*                                                                       */
+  /*    sort_by_res_id ::                                                  */
+  /*      A Boolean to sort the fragmented resource by their ids.          */
+  /*      The fragmented resources for `POST' resource should be sorted    */
+  /*      to restore Type1 font properly.  For `snft' resources, sorting   */
+  /*      may induce a different order of the faces in comparison to that  */
+  /*      by QuickDraw API.                                                */
+  /*                                                                       */
   /* <Output>                                                              */
   /*    offsets ::                                                         */
   /*      The stream offsets for the resource data specified by `tag'.     */
@@ -246,6 +253,7 @@
                               FT_Long     map_offset,
                               FT_Long     rdata_pos,
                               FT_Long     tag,
+                              FT_Bool     sort_by_res_id,
                               FT_Long   **offsets,
                               FT_Long    *count );
 
diff --git a/include/internal/fttrace.h b/include/internal/fttrace.h
index a9d98b6..d5253db 100644
--- a/include/internal/fttrace.h
+++ b/include/internal/fttrace.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Tracing handling (specification only).                               */
 /*                                                                         */
-/*  Copyright 2002, 2004-2007, 2009, 2011-2013 by                          */
+/*  Copyright 2002, 2004-2007, 2009, 2011-2014 by                          */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -148,5 +148,7 @@
 FT_TRACE_DEF( aflatin )
 FT_TRACE_DEF( aflatin2 )
 FT_TRACE_DEF( afwarp )
+FT_TRACE_DEF( afharfbuzz )
+FT_TRACE_DEF( afglobal )
 
 /* END */
diff --git a/src/autofit/afblue.c b/src/autofit/afblue.c
index 22ef6d5..f3526bf 100644
--- a/src/autofit/afblue.c
+++ b/src/autofit/afblue.c
@@ -26,15 +26,21 @@
   af_blue_strings[] =
   {
     /* */
-    'T', 'H', 'E', 'Z', 'O', 'C', 'Q', 'S',  /* THEZOCQS */
+    '\xD0', '\x91', '\xD0', '\x92', '\xD0', '\x95', '\xD0', '\x9F', '\xD0', '\x97', '\xD0', '\x9E', '\xD0', '\xA1', '\xD0', '\xAD',  /* БВЕПЗОСЭ */
     '\0',
-    'H', 'E', 'Z', 'L', 'O', 'C', 'U', 'S',  /* HEZLOCUS */
+    '\xD0', '\x91', '\xD0', '\x92', '\xD0', '\x95', '\xD0', '\xA8', '\xD0', '\x97', '\xD0', '\x9E', '\xD0', '\xA1', '\xD0', '\xAD',  /* БВЕШЗОСЭ */
     '\0',
-    'f', 'i', 'j', 'k', 'd', 'b', 'h',  /* fijkdbh */
+    '\xD1', '\x85', '\xD0', '\xBF', '\xD0', '\xBD', '\xD1', '\x88', '\xD0', '\xB5', '\xD0', '\xB7', '\xD0', '\xBE', '\xD1', '\x81',  /* хпншезос */
     '\0',
-    'x', 'z', 'r', 'o', 'e', 's', 'c',  /* xzroesc */
+    '\xD1', '\x80', '\xD1', '\x83', '\xD1', '\x84',  /* руф */
     '\0',
-    'p', 'q', 'g', 'j', 'y',  /* pqgjy */
+    '\xE0', '\xA4', '\x95', '\xE0', '\xA4', '\xAE', '\xE0', '\xA4', '\x85', '\xE0', '\xA4', '\x86', '\xE0', '\xA4', '\xA5', '\xE0', '\xA4', '\xA7', '\xE0', '\xA4', '\xAD', '\xE0', '\xA4', '\xB6',  /* क म अ आ थ ध भ श */
+    '\0',
+    '\xE0', '\xA4', '\x88', '\xE0', '\xA4', '\x90', '\xE0', '\xA4', '\x93', '\xE0', '\xA4', '\x94', '\xE0', '\xA4', '\xBF', '\xE0', '\xA5', '\x80', '\xE0', '\xA5', '\x8B', '\xE0', '\xA5', '\x8C',  /* ई ऐ ओ औ ि ी ो ौ */
+    '\0',
+    '\xE0', '\xA4', '\x95', '\xE0', '\xA4', '\xAE', '\xE0', '\xA4', '\x85', '\xE0', '\xA4', '\x86', '\xE0', '\xA4', '\xA5', '\xE0', '\xA4', '\xA7', '\xE0', '\xA4', '\xAD', '\xE0', '\xA4', '\xB6',  /* क म अ आ थ ध भ श */
+    '\0',
+    '\xE0', '\xA5', '\x81', '\xE0', '\xA5', '\x83',  /* ु ृ */
     '\0',
     '\xCE', '\x93', '\xCE', '\x92', '\xCE', '\x95', '\xCE', '\x96', '\xCE', '\x98', '\xCE', '\x9F', '\xCE', '\xA9',  /* ΓΒΕΖΘΟΩ */
     '\0',
@@ -46,26 +52,27 @@
     '\0',
     '\xCE', '\xB2', '\xCE', '\xB3', '\xCE', '\xB7', '\xCE', '\xBC', '\xCF', '\x81', '\xCF', '\x86', '\xCF', '\x87', '\xCF', '\x88',  /* βγημρφχψ */
     '\0',
-    '\xD0', '\x91', '\xD0', '\x92', '\xD0', '\x95', '\xD0', '\x9F', '\xD0', '\x97', '\xD0', '\x9E', '\xD0', '\xA1', '\xD0', '\xAD',  /* БВЕПЗОСЭ */
-    '\0',
-    '\xD0', '\x91', '\xD0', '\x92', '\xD0', '\x95', '\xD0', '\xA8', '\xD0', '\x97', '\xD0', '\x9E', '\xD0', '\xA1', '\xD0', '\xAD',  /* БВЕШЗОСЭ */
-    '\0',
-    '\xD1', '\x85', '\xD0', '\xBF', '\xD0', '\xBD', '\xD1', '\x88', '\xD0', '\xB5', '\xD0', '\xB7', '\xD0', '\xBE', '\xD1', '\x81',  /* хпншезос */
-    '\0',
-    '\xD1', '\x80', '\xD1', '\x83', '\xD1', '\x84',  /* руф */
-    '\0',
     '\xD7', '\x91', '\xD7', '\x93', '\xD7', '\x94', '\xD7', '\x97', '\xD7', '\x9A', '\xD7', '\x9B', '\xD7', '\x9D', '\xD7', '\xA1',  /* בדהחךכםס */
     '\0',
     '\xD7', '\x91', '\xD7', '\x98', '\xD7', '\x9B', '\xD7', '\x9D', '\xD7', '\xA1', '\xD7', '\xA6',  /* בטכםסצ */
     '\0',
     '\xD7', '\xA7', '\xD7', '\x9A', '\xD7', '\x9F', '\xD7', '\xA3', '\xD7', '\xA5',  /* קךןףץ */
+    '\0',
+    'T', 'H', 'E', 'Z', 'O', 'C', 'Q', 'S',  /* THEZOCQS */
+    '\0',
+    'H', 'E', 'Z', 'L', 'O', 'C', 'U', 'S',  /* HEZLOCUS */
+    '\0',
+    'f', 'i', 'j', 'k', 'd', 'b', 'h',  /* fijkdbh */
+    '\0',
+    'x', 'z', 'r', 'o', 'e', 's', 'c',  /* xzroesc */
+    '\0',
+    'p', 'q', 'g', 'j', 'y',  /* pqgjy */
 #ifdef AF_CONFIG_OPTION_CJK
     '\0',
     '\xE4', '\xBB', '\x96', '\xE4', '\xBB', '\xAC', '\xE4', '\xBD', '\xA0', '\xE4', '\xBE', '\x86', '\xE5', '\x80', '\x91', '\xE5', '\x88', '\xB0', '\xE5', '\x92', '\x8C', '\xE5', '\x9C', '\xB0',  /* 他们你來們到和地 */
     '\xE5', '\xAF', '\xB9', '\xE5', '\xB0', '\x8D', '\xE5', '\xB0', '\xB1', '\xE5', '\xB8', '\xAD', '\xE6', '\x88', '\x91', '\xE6', '\x97', '\xB6', '\xE6', '\x99', '\x82', '\xE6', '\x9C', '\x83',  /* 对對就席我时時會 */
     '\xE6', '\x9D', '\xA5', '\xE7', '\x82', '\xBA', '\xE8', '\x83', '\xBD', '\xE8', '\x88', '\xB0', '\xE8', '\xAA', '\xAA', '\xE8', '\xAF', '\xB4', '\xE8', '\xBF', '\x99', '\xE9', '\x80', '\x99',  /* 来為能舰說说这這 */
-    '\xE9', '\xBD', '\x8A',  /* 齊 */
-    '\0',
+    '\xE9', '\xBD', '\x8A', '|',  /* 齊 | */
     '\xE5', '\x86', '\x9B', '\xE5', '\x90', '\x8C', '\xE5', '\xB7', '\xB2', '\xE6', '\x84', '\xBF', '\xE6', '\x97', '\xA2', '\xE6', '\x98', '\x9F', '\xE6', '\x98', '\xAF', '\xE6', '\x99', '\xAF',  /* 军同已愿既星是景 */
     '\xE6', '\xB0', '\x91', '\xE7', '\x85', '\xA7', '\xE7', '\x8E', '\xB0', '\xE7', '\x8F', '\xBE', '\xE7', '\x90', '\x86', '\xE7', '\x94', '\xA8', '\xE7', '\xBD', '\xAE', '\xE8', '\xA6', '\x81',  /* 民照现現理用置要 */
     '\xE8', '\xBB', '\x8D', '\xE9', '\x82', '\xA3', '\xE9', '\x85', '\x8D', '\xE9', '\x87', '\x8C', '\xE9', '\x96', '\x8B', '\xE9', '\x9B', '\xB7', '\xE9', '\x9C', '\xB2', '\xE9', '\x9D', '\xA2',  /* 軍那配里開雷露面 */
@@ -74,8 +81,7 @@
     '\xE4', '\xB8', '\xAA', '\xE4', '\xB8', '\xBA', '\xE4', '\xBA', '\xBA', '\xE4', '\xBB', '\x96', '\xE4', '\xBB', '\xA5', '\xE4', '\xBB', '\xAC', '\xE4', '\xBD', '\xA0', '\xE4', '\xBE', '\x86',  /* 个为人他以们你來 */
     '\xE5', '\x80', '\x8B', '\xE5', '\x80', '\x91', '\xE5', '\x88', '\xB0', '\xE5', '\x92', '\x8C', '\xE5', '\xA4', '\xA7', '\xE5', '\xAF', '\xB9', '\xE5', '\xB0', '\x8D', '\xE5', '\xB0', '\xB1',  /* 個們到和大对對就 */
     '\xE6', '\x88', '\x91', '\xE6', '\x97', '\xB6', '\xE6', '\x99', '\x82', '\xE6', '\x9C', '\x89', '\xE6', '\x9D', '\xA5', '\xE7', '\x82', '\xBA', '\xE8', '\xA6', '\x81', '\xE8', '\xAA', '\xAA',  /* 我时時有来為要說 */
-    '\xE8', '\xAF', '\xB4',  /* 说 */
-    '\0',
+    '\xE8', '\xAF', '\xB4', '|',  /* 说 | */
     '\xE4', '\xB8', '\xBB', '\xE4', '\xBA', '\x9B', '\xE5', '\x9B', '\xA0', '\xE5', '\xAE', '\x83', '\xE6', '\x83', '\xB3', '\xE6', '\x84', '\x8F', '\xE7', '\x90', '\x86', '\xE7', '\x94', '\x9F',  /* 主些因它想意理生 */
     '\xE7', '\x95', '\xB6', '\xE7', '\x9C', '\x8B', '\xE7', '\x9D', '\x80', '\xE7', '\xBD', '\xAE', '\xE8', '\x80', '\x85', '\xE8', '\x87', '\xAA', '\xE8', '\x91', '\x97', '\xE8', '\xA3', '\xA1',  /* 當看着置者自著裡 */
     '\xE8', '\xBF', '\x87', '\xE8', '\xBF', '\x98', '\xE8', '\xBF', '\x9B', '\xE9', '\x80', '\xB2', '\xE9', '\x81', '\x8E', '\xE9', '\x81', '\x93', '\xE9', '\x82', '\x84', '\xE9', '\x87', '\x8C',  /* 过还进進過道還里 */
@@ -85,8 +91,7 @@
     '\xE4', '\xBA', '\x9B', '\xE4', '\xBB', '\xAC', '\xE4', '\xBD', '\xA0', '\xE4', '\xBE', '\x86', '\xE5', '\x80', '\x91', '\xE5', '\x88', '\xB0', '\xE5', '\x92', '\x8C', '\xE5', '\x9C', '\xB0',  /* 些们你來們到和地 */
     '\xE5', '\xA5', '\xB9', '\xE5', '\xB0', '\x86', '\xE5', '\xB0', '\x87', '\xE5', '\xB0', '\xB1', '\xE5', '\xB9', '\xB4', '\xE5', '\xBE', '\x97', '\xE6', '\x83', '\x85', '\xE6', '\x9C', '\x80',  /* 她将將就年得情最 */
     '\xE6', '\xA0', '\xB7', '\xE6', '\xA8', '\xA3', '\xE7', '\x90', '\x86', '\xE8', '\x83', '\xBD', '\xE8', '\xAA', '\xAA', '\xE8', '\xAF', '\xB4', '\xE8', '\xBF', '\x99', '\xE9', '\x80', '\x99',  /* 样樣理能說说这這 */
-    '\xE9', '\x80', '\x9A',  /* 通 */
-    '\0',
+    '\xE9', '\x80', '\x9A', '|',  /* 通 | */
     '\xE5', '\x8D', '\xB3', '\xE5', '\x90', '\x97', '\xE5', '\x90', '\xA7', '\xE5', '\x90', '\xAC', '\xE5', '\x91', '\xA2', '\xE5', '\x93', '\x81', '\xE5', '\x93', '\x8D', '\xE5', '\x97', '\x8E',  /* 即吗吧听呢品响嗎 */
     '\xE5', '\xB8', '\x88', '\xE5', '\xB8', '\xAB', '\xE6', '\x94', '\xB6', '\xE6', '\x96', '\xAD', '\xE6', '\x96', '\xB7', '\xE6', '\x98', '\x8E', '\xE7', '\x9C', '\xBC', '\xE9', '\x96', '\x93',  /* 师師收断斷明眼間 */
     '\xE9', '\x97', '\xB4', '\xE9', '\x99', '\x85', '\xE9', '\x99', '\x88', '\xE9', '\x99', '\x90', '\xE9', '\x99', '\xA4', '\xE9', '\x99', '\xB3', '\xE9', '\x9A', '\x8F', '\xE9', '\x9A', '\x9B',  /* 间际陈限除陳随際 */
@@ -95,8 +100,7 @@
     '\xE4', '\xBA', '\x8B', '\xE5', '\x89', '\x8D', '\xE5', '\xAD', '\xB8', '\xE5', '\xB0', '\x86', '\xE5', '\xB0', '\x87', '\xE6', '\x83', '\x85', '\xE6', '\x83', '\xB3', '\xE6', '\x88', '\x96',  /* 事前學将將情想或 */
     '\xE6', '\x94', '\xBF', '\xE6', '\x96', '\xAF', '\xE6', '\x96', '\xB0', '\xE6', '\xA0', '\xB7', '\xE6', '\xA8', '\xA3', '\xE6', '\xB0', '\x91', '\xE6', '\xB2', '\x92', '\xE6', '\xB2', '\xA1',  /* 政斯新样樣民沒没 */
     '\xE7', '\x84', '\xB6', '\xE7', '\x89', '\xB9', '\xE7', '\x8E', '\xB0', '\xE7', '\x8F', '\xBE', '\xE7', '\x90', '\x83', '\xE7', '\xAC', '\xAC', '\xE7', '\xB6', '\x93', '\xE8', '\xB0', '\x81',  /* 然特现現球第經谁 */
-    '\xE8', '\xB5', '\xB7',  /* 起 */
-    '\0',
+    '\xE8', '\xB5', '\xB7', '|',  /* 起 | */
     '\xE4', '\xBE', '\x8B', '\xE5', '\x88', '\xA5', '\xE5', '\x88', '\xAB', '\xE5', '\x88', '\xB6', '\xE5', '\x8A', '\xA8', '\xE5', '\x8B', '\x95', '\xE5', '\x90', '\x97', '\xE5', '\x97', '\x8E',  /* 例別别制动動吗嗎 */
     '\xE5', '\xA2', '\x9E', '\xE6', '\x8C', '\x87', '\xE6', '\x98', '\x8E', '\xE6', '\x9C', '\x9D', '\xE6', '\x9C', '\x9F', '\xE6', '\x9E', '\x84', '\xE7', '\x89', '\xA9', '\xE7', '\xA1', '\xAE',  /* 增指明朝期构物确 */
     '\xE7', '\xA7', '\x8D', '\xE8', '\xAA', '\xBF', '\xE8', '\xB0', '\x83', '\xE8', '\xB2', '\xBB', '\xE8', '\xB4', '\xB9', '\xE9', '\x82', '\xA3', '\xE9', '\x83', '\xBD', '\xE9', '\x96', '\x93',  /* 种調调費费那都間 */
@@ -108,19 +112,26 @@
   };
 
 
-  /* stringsets are specific to scripts */
+  /* stringsets are specific to styles */
   FT_LOCAL_ARRAY_DEF( AF_Blue_StringRec )
   af_blue_stringsets[] =
   {
     /* */
-    { AF_BLUE_STRING_LATIN_CAPITAL_TOP,     AF_BLUE_PROPERTY_LATIN_TOP        },
-    { AF_BLUE_STRING_LATIN_CAPITAL_BOTTOM,  0                                 },
-    { AF_BLUE_STRING_LATIN_SMALL_F_TOP,     AF_BLUE_PROPERTY_LATIN_TOP        },
-    { AF_BLUE_STRING_LATIN_SMALL,           AF_BLUE_PROPERTY_LATIN_TOP      |
-                                            AF_BLUE_PROPERTY_LATIN_X_HEIGHT   },
-    { AF_BLUE_STRING_LATIN_SMALL,           0                                 },
-    { AF_BLUE_STRING_LATIN_SMALL_DESCENDER, 0                                 },
-    { AF_BLUE_STRING_MAX,                   0                                 },
+    { AF_BLUE_STRING_CYRILLIC_CAPITAL_TOP,     AF_BLUE_PROPERTY_LATIN_TOP        },
+    { AF_BLUE_STRING_CYRILLIC_CAPITAL_BOTTOM,  0                                 },
+    { AF_BLUE_STRING_CYRILLIC_SMALL,           AF_BLUE_PROPERTY_LATIN_TOP      |
+                                               AF_BLUE_PROPERTY_LATIN_X_HEIGHT   },
+    { AF_BLUE_STRING_CYRILLIC_SMALL,           0                                 },
+    { AF_BLUE_STRING_CYRILLIC_SMALL_DESCENDER, 0                                 },
+    { AF_BLUE_STRING_MAX,                      0                                 },
+    { AF_BLUE_STRING_DEVANAGARI_TOP,    AF_BLUE_PROPERTY_LATIN_TOP        },
+    { AF_BLUE_STRING_DEVANAGARI_HEAD,   AF_BLUE_PROPERTY_LATIN_TOP        },
+    { AF_BLUE_STRING_DEVANAGARI_BASE,   AF_BLUE_PROPERTY_LATIN_TOP      |
+                                        AF_BLUE_PROPERTY_LATIN_NEUTRAL  |
+                                        AF_BLUE_PROPERTY_LATIN_X_HEIGHT   },
+    { AF_BLUE_STRING_DEVANAGARI_BASE,   0                                 },
+    { AF_BLUE_STRING_DEVANAGARI_BOTTOM, 0                                 },
+    { AF_BLUE_STRING_MAX,               0                                 },
     { AF_BLUE_STRING_GREEK_CAPITAL_TOP,     AF_BLUE_PROPERTY_LATIN_TOP        },
     { AF_BLUE_STRING_GREEK_CAPITAL_BOTTOM,  0                                 },
     { AF_BLUE_STRING_GREEK_SMALL_BETA_TOP,  AF_BLUE_PROPERTY_LATIN_TOP        },
@@ -129,35 +140,28 @@
     { AF_BLUE_STRING_GREEK_SMALL,           0                                 },
     { AF_BLUE_STRING_GREEK_SMALL_DESCENDER, 0                                 },
     { AF_BLUE_STRING_MAX,                   0                                 },
-    { AF_BLUE_STRING_CYRILLIC_CAPITAL_TOP,     AF_BLUE_PROPERTY_LATIN_TOP        },
-    { AF_BLUE_STRING_CYRILLIC_CAPITAL_BOTTOM,  0                                 },
-    { AF_BLUE_STRING_CYRILLIC_SMALL,           AF_BLUE_PROPERTY_LATIN_TOP      |
-                                               AF_BLUE_PROPERTY_LATIN_X_HEIGHT   },
-    { AF_BLUE_STRING_CYRILLIC_SMALL,           0                                 },
-    { AF_BLUE_STRING_CYRILLIC_SMALL_DESCENDER, 0                                 },
-    { AF_BLUE_STRING_MAX,                      0                                 },
     { AF_BLUE_STRING_HEBREW_TOP,       AF_BLUE_PROPERTY_LATIN_TOP  |
                                        AF_BLUE_PROPERTY_LATIN_LONG   },
     { AF_BLUE_STRING_HEBREW_BOTTOM,    0                             },
     { AF_BLUE_STRING_HEBREW_DESCENDER, 0                             },
     { AF_BLUE_STRING_MAX,              0                             },
+    { AF_BLUE_STRING_LATIN_CAPITAL_TOP,     AF_BLUE_PROPERTY_LATIN_TOP        },
+    { AF_BLUE_STRING_LATIN_CAPITAL_BOTTOM,  0                                 },
+    { AF_BLUE_STRING_LATIN_SMALL_F_TOP,     AF_BLUE_PROPERTY_LATIN_TOP        },
+    { AF_BLUE_STRING_LATIN_SMALL,           AF_BLUE_PROPERTY_LATIN_TOP      |
+                                            AF_BLUE_PROPERTY_LATIN_X_HEIGHT   },
+    { AF_BLUE_STRING_LATIN_SMALL,           0                                 },
+    { AF_BLUE_STRING_LATIN_SMALL_DESCENDER, 0                                 },
+    { AF_BLUE_STRING_MAX,                   0                                 },
 #ifdef AF_CONFIG_OPTION_CJK
-    { AF_BLUE_STRING_CJK_TOP_FILL,      AF_BLUE_PROPERTY_CJK_TOP |
-                                        AF_BLUE_PROPERTY_CJK_FILL    },
-    { AF_BLUE_STRING_CJK_TOP_UNFILL,    AF_BLUE_PROPERTY_CJK_TOP     },
-    { AF_BLUE_STRING_CJK_BOTTOM_FILL,   AF_BLUE_PROPERTY_CJK_FILL    },
-    { AF_BLUE_STRING_CJK_BOTTOM_UNFILL, 0                            },
+    { AF_BLUE_STRING_CJK_TOP,    AF_BLUE_PROPERTY_CJK_TOP     },
+    { AF_BLUE_STRING_CJK_BOTTOM, 0                            },
 #ifdef AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT
-    { AF_BLUE_STRING_CJK_LEFT_FILL,     AF_BLUE_PROPERTY_CJK_HORIZ |
-                                        AF_BLUE_PROPERTY_CJK_FILL    },
-    { AF_BLUE_STRING_CJK_LEFT_UNFILL,   AF_BLUE_PROPERTY_CJK_HORIZ   },
-    { AF_BLUE_STRING_CJK_RIGHT_FILL,    AF_BLUE_PROPERTY_CJK_HORIZ |
-                                        AF_BLUE_PROPERTY_CJK_RIGHT |
-                                        AF_BLUE_PROPERTY_CJK_FILL    },
-    { AF_BLUE_STRING_CJK_RIGHT_UNFILL,  AF_BLUE_PROPERTY_CJK_HORIZ |
-                                        AF_BLUE_PROPERTY_CJK_RIGHT   },
+    { AF_BLUE_STRING_CJK_LEFT,   AF_BLUE_PROPERTY_CJK_HORIZ   },
+    { AF_BLUE_STRING_CJK_RIGHT,  AF_BLUE_PROPERTY_CJK_HORIZ |
+                                 AF_BLUE_PROPERTY_CJK_RIGHT   },
 #endif /* AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT */
-    { AF_BLUE_STRING_MAX,               0                            },
+    { AF_BLUE_STRING_MAX,        0                            },
 #endif /* AF_CONFIG_OPTION_CJK                */
 
   };
diff --git a/src/autofit/afblue.cin b/src/autofit/afblue.cin
index c693d89..c6762be 100644
--- a/src/autofit/afblue.cin
+++ b/src/autofit/afblue.cin
@@ -27,7 +27,7 @@
   };
 
 
-  /* stringsets are specific to scripts */
+  /* stringsets are specific to styles */
   FT_LOCAL_ARRAY_DEF( AF_Blue_StringRec )
   af_blue_stringsets[] =
   {
diff --git a/src/autofit/afblue.dat b/src/autofit/afblue.dat
index d488f3f..74a472d 100644
--- a/src/autofit/afblue.dat
+++ b/src/autofit/afblue.dat
@@ -2,7 +2,7 @@
 //
 //    Auto-fitter data for blue strings.
 //
-//  Copyright 2013 by
+//  Copyright 2013, 2014 by
 //  David Turner, Robert Wilhelm, and Werner Lemberg.
 //
 //  This file is part of the FreeType project, and may only be used,
@@ -34,11 +34,11 @@
 //   using C syntax.  There can be only one string per line, thus the
 //   starting and ending double quote must be the first and last character
 //   in the line, respectively, ignoring whitespace before and after the
-//   string.  If there are multiple strings (in multiple lines), they are
-//   concatenated to a single string.  In the output, a string gets
-//   represented as a series of singles bytes, followed by a zero byte.  The
-//   enumeration values simply hold byte offsets to the start of the
-//   corresponding strings.
+//   string.  Space characters within the string are ignored too.  If there
+//   are multiple strings (in multiple lines), they are concatenated to a
+//   single string.  In the output, a string gets represented as a series of
+//   singles bytes, followed by a zero byte.  The enumeration values simply
+//   hold byte offsets to the start of the corresponding strings.
 //
 // - Data blocks enclosed in balanced braces, which get copied verbatim and
 //   which can span multiple lines.  The opening brace of a block must be
@@ -63,18 +63,32 @@
 // characters, not bytes.
 
 
+// The blue zone string data, to be used in the blue stringsets below.
+
 AF_BLUE_STRING_ENUM AF_BLUE_STRINGS_ARRAY AF_BLUE_STRING_MAX_LEN:
 
-  AF_BLUE_STRING_LATIN_CAPITAL_TOP
-    "THEZOCQS"
-  AF_BLUE_STRING_LATIN_CAPITAL_BOTTOM
-    "HEZLOCUS"
-  AF_BLUE_STRING_LATIN_SMALL_F_TOP
-    "fijkdbh"
-  AF_BLUE_STRING_LATIN_SMALL
-    "xzroesc"
-  AF_BLUE_STRING_LATIN_SMALL_DESCENDER
-    "pqgjy"
+  AF_BLUE_STRING_CYRILLIC_CAPITAL_TOP
+    "БВЕПЗОСЭ"
+  AF_BLUE_STRING_CYRILLIC_CAPITAL_BOTTOM
+    "БВЕШЗОСЭ"
+  AF_BLUE_STRING_CYRILLIC_SMALL
+    "хпншезос"
+  AF_BLUE_STRING_CYRILLIC_SMALL_DESCENDER
+    "руф"
+
+  // we separate the letters with spaces to avoid ligatures;
+  // this is just for convenience to simplify reading
+  AF_BLUE_STRING_DEVANAGARI_BASE
+    "क म अ आ थ ध भ श"
+  AF_BLUE_STRING_DEVANAGARI_TOP
+    "ई ऐ ओ औ ि ी ो ौ"
+  // note that some fonts have extreme variation in the height of the
+  // round head elements; for this reason we also define the `base'
+  // blue zone, which must be always present
+  AF_BLUE_STRING_DEVANAGARI_HEAD
+    "क म अ आ थ ध भ श"
+  AF_BLUE_STRING_DEVANAGARI_BOTTOM
+    "ु ृ"
 
   AF_BLUE_STRING_GREEK_CAPITAL_TOP
     "ΓΒΕΖΘΟΩ"
@@ -87,15 +101,6 @@
   AF_BLUE_STRING_GREEK_SMALL_DESCENDER
     "βγημρφχψ"
 
-  AF_BLUE_STRING_CYRILLIC_CAPITAL_TOP
-    "БВЕПЗОСЭ"
-  AF_BLUE_STRING_CYRILLIC_CAPITAL_BOTTOM
-    "БВЕШЗОСЭ"
-  AF_BLUE_STRING_CYRILLIC_SMALL
-    "хпншезос"
-  AF_BLUE_STRING_CYRILLIC_SMALL_DESCENDER
-    "руф"
-
   AF_BLUE_STRING_HEBREW_TOP
     "בדהחךכםס"
   AF_BLUE_STRING_HEBREW_BOTTOM
@@ -103,24 +108,33 @@
   AF_BLUE_STRING_HEBREW_DESCENDER
     "קךןףץ"
 
+  AF_BLUE_STRING_LATIN_CAPITAL_TOP
+    "THEZOCQS"
+  AF_BLUE_STRING_LATIN_CAPITAL_BOTTOM
+    "HEZLOCUS"
+  AF_BLUE_STRING_LATIN_SMALL_F_TOP
+    "fijkdbh"
+  AF_BLUE_STRING_LATIN_SMALL
+    "xzroesc"
+  AF_BLUE_STRING_LATIN_SMALL_DESCENDER
+    "pqgjy"
+
 #ifdef AF_CONFIG_OPTION_CJK
 
-  AF_BLUE_STRING_CJK_TOP_FILL
+  AF_BLUE_STRING_CJK_TOP
     "他们你來們到和地"
     "对對就席我时時會"
     "来為能舰說说这這"
-    "齊"
-  AF_BLUE_STRING_CJK_TOP_UNFILL
+    "齊 |"
     "军同已愿既星是景"
     "民照现現理用置要"
     "軍那配里開雷露面"
     "顾"
-  AF_BLUE_STRING_CJK_BOTTOM_FILL
+  AF_BLUE_STRING_CJK_BOTTOM
     "个为人他以们你來"
     "個們到和大对對就"
     "我时時有来為要說"
-    "说"
-  AF_BLUE_STRING_CJK_BOTTOM_UNFILL
+    "说 |"
     "主些因它想意理生"
     "當看着置者自著裡"
     "过还进進過道還里"
@@ -128,22 +142,20 @@
 
 #ifdef AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT
 
-  AF_BLUE_STRING_CJK_LEFT_FILL
+  AF_BLUE_STRING_CJK_LEFT
     "些们你來們到和地"
     "她将將就年得情最"
     "样樣理能說说这這"
-    "通"
-  AF_BLUE_STRING_CJK_LEFT_UNFILL
+    "通 |"
     "即吗吧听呢品响嗎"
     "师師收断斷明眼間"
     "间际陈限除陳随際"
     "隨"
-  AF_BLUE_STRING_CJK_RIGHT_FILL
+  AF_BLUE_STRING_CJK_RIGHT
     "事前學将將情想或"
     "政斯新样樣民沒没"
     "然特现現球第經谁"
-    "起"
-  AF_BLUE_STRING_CJK_RIGHT_UNFILL
+    "起 |"
     "例別别制动動吗嗎"
     "增指明朝期构物确"
     "种調调費费那都間"
@@ -154,17 +166,118 @@
 #endif /* AF_CONFIG_OPTION_CJK                */
 
 
+// The blue zone stringsets, as used in the script styles, cf. `afstyles.h'.
+//
+// The AF_BLUE_PROPERTY_XXX flags are defined in `afblue.h'; here some
+// explanations.
+//
+// A blue zone in general is defined by a reference and an overshoot line.
+// During the hinting process, all coordinate values between those two lines
+// are set equal to the reference value, provided that the blue zone is not
+// wider than 0.75 pixels (otherwise the blue zone gets ignored).  All
+// entries must have `AF_BLUE_STRING_MAX' as the final line.
+//
+// During the glyph analysis, edges are sorted from bottom to top, and then
+// sequentially checked, edge by edge, against the blue zones in the order
+// given below.
+//
+//
+// latin auto-hinter
+// -----------------
+//
+// Characters in a blue string are automatically classified as having a flat
+// (reference) or a round (overshoot) extremum.  The blue zone is then set
+// up by the mean values of all flat extrema and all round extrema,
+// respectively.  Only horizontal blue zones (i.e., adjusting vertical
+// coordinate values) are supported.
+//
+// For the latin auto-hinter, the overshoot should be larger than the
+// reference for top zones, and vice versa for bottom zones.
+//
+//   LATIN_TOP
+//     Take the maximum flat and round coordinate values of the blue string
+//     characters for computing the blue zone's reference and overshoot
+//     values.
+//
+//     If not set, take the minimum values.
+//
+//   LATIN_NEUTRAL
+//     Ignore round extrema and define the blue zone with flat values only.
+//     Both top and bottom of contours can match.  This is useful for
+//     scripts like Devanagari where vowel signs attach to the base
+//     character and are implemented as components of composite glyphs.
+//
+//     If not set, both round and flat extrema are taken into account.
+//     Additionally, only the top or the bottom of a contour can match,
+//     depending on the LATIN_TOP flag.
+//
+//     Neutral blue zones should always follow non-neutral blue zones.
+//
+//   LATIN_X_HEIGHT
+//     Scale all glyphs vertically from the corresponding script to make the
+//     reference line of this blue zone align on the grid.  The scaling
+//     takes place before all other blue zones get aligned to the grid.
+//     Only one blue character string of a script style can have this flag.
+//
+//   LATIN_LONG
+//     Apply an additional constraint for blue zone values: Don't
+//     necessarily use the extremum as-is but a segment of the topmost (or
+//     bottommost) contour that is longer than a heuristic threshold, and
+//     which is not too far away vertically from the real extremum.  This
+//     ensures that small bumps in the outline are ignored (for example, the
+//     `vertical serifs' found in many Hebrew glyph designs).
+//
+//     The segment must be at least EM/25 font units long, and the distance
+//     to the extremum must be smaller than EM/4.
+//
+//
+// cjk auto-hinter
+// ---------------
+//
+// Characters in a blue string are *not* automatically classified.  Instead,
+// first come the characters used for the overshoot value, then the
+// character `|', then the characters used for the reference value.  The
+// blue zone is then set up by the mean values of all reference values and
+// all overshoot values, respectively.  Both horizontal and vertical blue
+// zones (i.e., adjusting vertical and horizontal coordinate values,
+// respectively) are supported.
+//
+// For the cjk auto-hinter, the overshoot should be smaller than the
+// reference for top zones, and vice versa for bottom zones.
+//
+//   CJK_TOP
+//     Take the maximum flat and round coordinate values of the blue string
+//     characters.  If not set, take the minimum values.
+//
+//   CJK_RIGHT
+//     A synonym for CJK_TOP.  If CJK_HORIZ is set, this flag indicates the
+//     right blue zone, taking horizontal maximum values.
+//
+//   CJK_HORIZ
+//     Define a blue zone for horizontal hinting (i.e., vertical blue
+//     zones).  If not set, this is a blue zone for vertical hinting.
+
+
 AF_BLUE_STRINGSET_ENUM AF_BLUE_STRINGSETS_ARRAY AF_BLUE_STRINGSET_MAX_LEN:
 
-  AF_BLUE_STRINGSET_LATN
-    { AF_BLUE_STRING_LATIN_CAPITAL_TOP,     AF_BLUE_PROPERTY_LATIN_TOP        }
-    { AF_BLUE_STRING_LATIN_CAPITAL_BOTTOM,  0                                 }
-    { AF_BLUE_STRING_LATIN_SMALL_F_TOP,     AF_BLUE_PROPERTY_LATIN_TOP        }
-    { AF_BLUE_STRING_LATIN_SMALL,           AF_BLUE_PROPERTY_LATIN_TOP      |
-                                            AF_BLUE_PROPERTY_LATIN_X_HEIGHT   }
-    { AF_BLUE_STRING_LATIN_SMALL,           0                                 }
-    { AF_BLUE_STRING_LATIN_SMALL_DESCENDER, 0                                 }
-    { AF_BLUE_STRING_MAX,                   0                                 }
+  AF_BLUE_STRINGSET_CYRL
+    { AF_BLUE_STRING_CYRILLIC_CAPITAL_TOP,     AF_BLUE_PROPERTY_LATIN_TOP        }
+    { AF_BLUE_STRING_CYRILLIC_CAPITAL_BOTTOM,  0                                 }
+    { AF_BLUE_STRING_CYRILLIC_SMALL,           AF_BLUE_PROPERTY_LATIN_TOP      |
+                                               AF_BLUE_PROPERTY_LATIN_X_HEIGHT   }
+    { AF_BLUE_STRING_CYRILLIC_SMALL,           0                                 }
+    { AF_BLUE_STRING_CYRILLIC_SMALL_DESCENDER, 0                                 }
+    { AF_BLUE_STRING_MAX,                      0                                 }
+
+  AF_BLUE_STRINGSET_DEVA
+    { AF_BLUE_STRING_DEVANAGARI_TOP,    AF_BLUE_PROPERTY_LATIN_TOP        }
+    { AF_BLUE_STRING_DEVANAGARI_HEAD,   AF_BLUE_PROPERTY_LATIN_TOP        }
+    { AF_BLUE_STRING_DEVANAGARI_BASE,   AF_BLUE_PROPERTY_LATIN_TOP      |
+                                        AF_BLUE_PROPERTY_LATIN_NEUTRAL  |
+                                        AF_BLUE_PROPERTY_LATIN_X_HEIGHT   }
+    { AF_BLUE_STRING_DEVANAGARI_BASE,   0                                 }
+    { AF_BLUE_STRING_DEVANAGARI_BOTTOM, 0                                 }
+    { AF_BLUE_STRING_MAX,               0                                 }
 
   AF_BLUE_STRINGSET_GREK
     { AF_BLUE_STRING_GREEK_CAPITAL_TOP,     AF_BLUE_PROPERTY_LATIN_TOP        }
@@ -176,15 +289,6 @@
     { AF_BLUE_STRING_GREEK_SMALL_DESCENDER, 0                                 }
     { AF_BLUE_STRING_MAX,                   0                                 }
 
-  AF_BLUE_STRINGSET_CYRL
-    { AF_BLUE_STRING_CYRILLIC_CAPITAL_TOP,     AF_BLUE_PROPERTY_LATIN_TOP        }
-    { AF_BLUE_STRING_CYRILLIC_CAPITAL_BOTTOM,  0                                 }
-    { AF_BLUE_STRING_CYRILLIC_SMALL,           AF_BLUE_PROPERTY_LATIN_TOP      |
-                                               AF_BLUE_PROPERTY_LATIN_X_HEIGHT   }
-    { AF_BLUE_STRING_CYRILLIC_SMALL,           0                                 }
-    { AF_BLUE_STRING_CYRILLIC_SMALL_DESCENDER, 0                                 }
-    { AF_BLUE_STRING_MAX,                      0                                 }
-
   AF_BLUE_STRINGSET_HEBR
     { AF_BLUE_STRING_HEBREW_TOP,       AF_BLUE_PROPERTY_LATIN_TOP  |
                                        AF_BLUE_PROPERTY_LATIN_LONG   }
@@ -192,25 +296,27 @@
     { AF_BLUE_STRING_HEBREW_DESCENDER, 0                             }
     { AF_BLUE_STRING_MAX,              0                             }
 
+  AF_BLUE_STRINGSET_LATN
+    { AF_BLUE_STRING_LATIN_CAPITAL_TOP,     AF_BLUE_PROPERTY_LATIN_TOP        }
+    { AF_BLUE_STRING_LATIN_CAPITAL_BOTTOM,  0                                 }
+    { AF_BLUE_STRING_LATIN_SMALL_F_TOP,     AF_BLUE_PROPERTY_LATIN_TOP        }
+    { AF_BLUE_STRING_LATIN_SMALL,           AF_BLUE_PROPERTY_LATIN_TOP      |
+                                            AF_BLUE_PROPERTY_LATIN_X_HEIGHT   }
+    { AF_BLUE_STRING_LATIN_SMALL,           0                                 }
+    { AF_BLUE_STRING_LATIN_SMALL_DESCENDER, 0                                 }
+    { AF_BLUE_STRING_MAX,                   0                                 }
+
 #ifdef AF_CONFIG_OPTION_CJK
 
   AF_BLUE_STRINGSET_HANI
-    { AF_BLUE_STRING_CJK_TOP_FILL,      AF_BLUE_PROPERTY_CJK_TOP |
-                                        AF_BLUE_PROPERTY_CJK_FILL    }
-    { AF_BLUE_STRING_CJK_TOP_UNFILL,    AF_BLUE_PROPERTY_CJK_TOP     }
-    { AF_BLUE_STRING_CJK_BOTTOM_FILL,   AF_BLUE_PROPERTY_CJK_FILL    }
-    { AF_BLUE_STRING_CJK_BOTTOM_UNFILL, 0                            }
+    { AF_BLUE_STRING_CJK_TOP,    AF_BLUE_PROPERTY_CJK_TOP     }
+    { AF_BLUE_STRING_CJK_BOTTOM, 0                            }
 #ifdef AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT
-    { AF_BLUE_STRING_CJK_LEFT_FILL,     AF_BLUE_PROPERTY_CJK_HORIZ |
-                                        AF_BLUE_PROPERTY_CJK_FILL    }
-    { AF_BLUE_STRING_CJK_LEFT_UNFILL,   AF_BLUE_PROPERTY_CJK_HORIZ   }
-    { AF_BLUE_STRING_CJK_RIGHT_FILL,    AF_BLUE_PROPERTY_CJK_HORIZ |
-                                        AF_BLUE_PROPERTY_CJK_RIGHT |
-                                        AF_BLUE_PROPERTY_CJK_FILL    }
-    { AF_BLUE_STRING_CJK_RIGHT_UNFILL,  AF_BLUE_PROPERTY_CJK_HORIZ |
-                                        AF_BLUE_PROPERTY_CJK_RIGHT   }
+    { AF_BLUE_STRING_CJK_LEFT,   AF_BLUE_PROPERTY_CJK_HORIZ   }
+    { AF_BLUE_STRING_CJK_RIGHT,  AF_BLUE_PROPERTY_CJK_HORIZ |
+                                 AF_BLUE_PROPERTY_CJK_RIGHT   }
 #endif /* AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT */
-    { AF_BLUE_STRING_MAX,               0                            }
+    { AF_BLUE_STRING_MAX,        0                            }
 
 #endif /* AF_CONFIG_OPTION_CJK                */
 
diff --git a/src/autofit/afblue.h b/src/autofit/afblue.h
index 86a3649..d239e8e 100644
--- a/src/autofit/afblue.h
+++ b/src/autofit/afblue.h
@@ -7,7 +7,7 @@
 /*                                                                         */
 /*    Auto-fitter data for blue strings (specification).                   */
 /*                                                                         */
-/*  Copyright 2013 by                                                      */
+/*  Copyright 2013, 2014 by                                                */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -67,49 +67,49 @@
   /* At the bottommost level, we define strings for finding blue zones. */
 
 
-#define AF_BLUE_STRING_MAX_LEN  25
+#define AF_BLUE_STRING_MAX_LEN  51
 
   /* The AF_Blue_String enumeration values are offsets into the */
   /* `af_blue_strings' array.                                   */
 
   typedef enum  AF_Blue_String_
   {
-    AF_BLUE_STRING_LATIN_CAPITAL_TOP = 0,
-    AF_BLUE_STRING_LATIN_CAPITAL_BOTTOM = 9,
-    AF_BLUE_STRING_LATIN_SMALL_F_TOP = 18,
-    AF_BLUE_STRING_LATIN_SMALL = 26,
-    AF_BLUE_STRING_LATIN_SMALL_DESCENDER = 34,
-    AF_BLUE_STRING_GREEK_CAPITAL_TOP = 40,
-    AF_BLUE_STRING_GREEK_CAPITAL_BOTTOM = 55,
-    AF_BLUE_STRING_GREEK_SMALL_BETA_TOP = 68,
-    AF_BLUE_STRING_GREEK_SMALL = 81,
-    AF_BLUE_STRING_GREEK_SMALL_DESCENDER = 98,
-    AF_BLUE_STRING_CYRILLIC_CAPITAL_TOP = 115,
-    AF_BLUE_STRING_CYRILLIC_CAPITAL_BOTTOM = 132,
-    AF_BLUE_STRING_CYRILLIC_SMALL = 149,
-    AF_BLUE_STRING_CYRILLIC_SMALL_DESCENDER = 166,
-    AF_BLUE_STRING_HEBREW_TOP = 173,
-    AF_BLUE_STRING_HEBREW_BOTTOM = 190,
-    AF_BLUE_STRING_HEBREW_DESCENDER = 203,
-    af_blue_1_1 = 213,
+    AF_BLUE_STRING_CYRILLIC_CAPITAL_TOP = 0,
+    AF_BLUE_STRING_CYRILLIC_CAPITAL_BOTTOM = 17,
+    AF_BLUE_STRING_CYRILLIC_SMALL = 34,
+    AF_BLUE_STRING_CYRILLIC_SMALL_DESCENDER = 51,
+    AF_BLUE_STRING_DEVANAGARI_BASE = 58,
+    AF_BLUE_STRING_DEVANAGARI_TOP = 83,
+    AF_BLUE_STRING_DEVANAGARI_HEAD = 108,
+    AF_BLUE_STRING_DEVANAGARI_BOTTOM = 133,
+    AF_BLUE_STRING_GREEK_CAPITAL_TOP = 140,
+    AF_BLUE_STRING_GREEK_CAPITAL_BOTTOM = 155,
+    AF_BLUE_STRING_GREEK_SMALL_BETA_TOP = 168,
+    AF_BLUE_STRING_GREEK_SMALL = 181,
+    AF_BLUE_STRING_GREEK_SMALL_DESCENDER = 198,
+    AF_BLUE_STRING_HEBREW_TOP = 215,
+    AF_BLUE_STRING_HEBREW_BOTTOM = 232,
+    AF_BLUE_STRING_HEBREW_DESCENDER = 245,
+    AF_BLUE_STRING_LATIN_CAPITAL_TOP = 256,
+    AF_BLUE_STRING_LATIN_CAPITAL_BOTTOM = 265,
+    AF_BLUE_STRING_LATIN_SMALL_F_TOP = 274,
+    AF_BLUE_STRING_LATIN_SMALL = 282,
+    AF_BLUE_STRING_LATIN_SMALL_DESCENDER = 290,
+    af_blue_1_1 = 295,
 #ifdef AF_CONFIG_OPTION_CJK
-    AF_BLUE_STRING_CJK_TOP_FILL = af_blue_1_1 + 1,
-    AF_BLUE_STRING_CJK_TOP_UNFILL = af_blue_1_1 + 77,
-    AF_BLUE_STRING_CJK_BOTTOM_FILL = af_blue_1_1 + 153,
-    AF_BLUE_STRING_CJK_BOTTOM_UNFILL = af_blue_1_1 + 229,
+    AF_BLUE_STRING_CJK_TOP = af_blue_1_1 + 1,
+    AF_BLUE_STRING_CJK_BOTTOM = af_blue_1_1 + 153,
     af_blue_1_1_1 = af_blue_1_1 + 304,
 #ifdef AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT
-    AF_BLUE_STRING_CJK_LEFT_FILL = af_blue_1_1_1 + 1,
-    AF_BLUE_STRING_CJK_LEFT_UNFILL = af_blue_1_1_1 + 77,
-    AF_BLUE_STRING_CJK_RIGHT_FILL = af_blue_1_1_1 + 153,
-    AF_BLUE_STRING_CJK_RIGHT_UNFILL = af_blue_1_1_1 + 229,
-    af_blue_1_2_1 = af_blue_1_1_1 + 304,
+    AF_BLUE_STRING_CJK_LEFT = af_blue_1_1_1 + 1,
+    AF_BLUE_STRING_CJK_RIGHT = af_blue_1_1_1 + 153,
+    af_blue_1_1_2 = af_blue_1_1_1 + 304,
 #else
-    af_blue_1_2_1 = af_blue_1_1_1 + 0,
+    af_blue_1_1_2 = af_blue_1_1_1 + 0,
 #endif /* AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT */
-    af_blue_1_2 = af_blue_1_2_1 + 0,
+    af_blue_1_2 = af_blue_1_1_2 + 0,
 #else
-    af_blue_1_2 = af_blue_1_2_1 + 0,
+    af_blue_1_2 = af_blue_1_1 + 0,
 #endif /* AF_CONFIG_OPTION_CJK                */
 
 
@@ -130,45 +130,46 @@
   /*************************************************************************/
   /*************************************************************************/
 
-  /* The next level is to group blue strings into script-specific sets. */
+  /* The next level is to group blue strings into style-specific sets. */
 
 
   /* Properties are specific to a writing system.  We assume that a given  */
   /* blue string can't be used in more than a single writing system, which */
   /* is a safe bet.                                                        */
-#define AF_BLUE_PROPERTY_LATIN_TOP       ( 1 << 0 )
-#define AF_BLUE_PROPERTY_LATIN_X_HEIGHT  ( 1 << 1 )
-#define AF_BLUE_PROPERTY_LATIN_LONG      ( 1 << 2 )
+#define AF_BLUE_PROPERTY_LATIN_TOP       ( 1 << 0 )   /* must have value 1 */
+#define AF_BLUE_PROPERTY_LATIN_NEUTRAL   ( 1 << 1 )
+#define AF_BLUE_PROPERTY_LATIN_X_HEIGHT  ( 1 << 2 )
+#define AF_BLUE_PROPERTY_LATIN_LONG      ( 1 << 3 )
 
-#define AF_BLUE_PROPERTY_CJK_HORIZ  ( 1 << 0 )
-#define AF_BLUE_PROPERTY_CJK_TOP    ( 1 << 1 )
-#define AF_BLUE_PROPERTY_CJK_FILL   ( 1 << 2 )
+#define AF_BLUE_PROPERTY_CJK_TOP    ( 1 << 0 )        /* must have value 1 */
+#define AF_BLUE_PROPERTY_CJK_HORIZ  ( 1 << 1 )        /* must have value 2 */
 #define AF_BLUE_PROPERTY_CJK_RIGHT  AF_BLUE_PROPERTY_CJK_TOP
 
 
-#define AF_BLUE_STRINGSET_MAX_LEN  9
+#define AF_BLUE_STRINGSET_MAX_LEN  7
 
   /* The AF_Blue_Stringset enumeration values are offsets into the */
   /* `af_blue_stringsets' array.                                   */
 
   typedef enum  AF_Blue_Stringset_
   {
-    AF_BLUE_STRINGSET_LATN = 0,
-    AF_BLUE_STRINGSET_GREK = 7,
-    AF_BLUE_STRINGSET_CYRL = 14,
-    AF_BLUE_STRINGSET_HEBR = 20,
-    af_blue_2_1 = 24,
+    AF_BLUE_STRINGSET_CYRL = 0,
+    AF_BLUE_STRINGSET_DEVA = 6,
+    AF_BLUE_STRINGSET_GREK = 12,
+    AF_BLUE_STRINGSET_HEBR = 19,
+    AF_BLUE_STRINGSET_LATN = 23,
+    af_blue_2_1 = 30,
 #ifdef AF_CONFIG_OPTION_CJK
     AF_BLUE_STRINGSET_HANI = af_blue_2_1 + 0,
-    af_blue_2_1_1 = af_blue_2_1 + 4,
+    af_blue_2_1_1 = af_blue_2_1 + 2,
 #ifdef AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT
-    af_blue_2_2_1 = af_blue_2_1_1 + 4,
+    af_blue_2_1_2 = af_blue_2_1_1 + 2,
 #else
-    af_blue_2_2_1 = af_blue_2_1_1 + 0,
+    af_blue_2_1_2 = af_blue_2_1_1 + 0,
 #endif /* AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT */
-    af_blue_2_2 = af_blue_2_2_1 + 1,
+    af_blue_2_2 = af_blue_2_1_2 + 1,
 #else
-    af_blue_2_2 = af_blue_2_2_1 + 0,
+    af_blue_2_2 = af_blue_2_1 + 0,
 #endif /* AF_CONFIG_OPTION_CJK                */
 
 
diff --git a/src/autofit/afblue.hin b/src/autofit/afblue.hin
index 00282c3..0b4b48d 100644
--- a/src/autofit/afblue.hin
+++ b/src/autofit/afblue.hin
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auto-fitter data for blue strings (specification).                   */
 /*                                                                         */
-/*  Copyright 2013 by                                                      */
+/*  Copyright 2013, 2014 by                                                */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -90,19 +90,19 @@
   /*************************************************************************/
   /*************************************************************************/
 
-  /* The next level is to group blue strings into script-specific sets. */
+  /* The next level is to group blue strings into style-specific sets. */
 
 
   /* Properties are specific to a writing system.  We assume that a given  */
   /* blue string can't be used in more than a single writing system, which */
   /* is a safe bet.                                                        */
-#define AF_BLUE_PROPERTY_LATIN_TOP       ( 1 << 0 )
-#define AF_BLUE_PROPERTY_LATIN_X_HEIGHT  ( 1 << 1 )
-#define AF_BLUE_PROPERTY_LATIN_LONG      ( 1 << 2 )
+#define AF_BLUE_PROPERTY_LATIN_TOP       ( 1 << 0 )   /* must have value 1 */
+#define AF_BLUE_PROPERTY_LATIN_NEUTRAL   ( 1 << 1 )
+#define AF_BLUE_PROPERTY_LATIN_X_HEIGHT  ( 1 << 2 )
+#define AF_BLUE_PROPERTY_LATIN_LONG      ( 1 << 3 )
 
-#define AF_BLUE_PROPERTY_CJK_HORIZ  ( 1 << 0 )
-#define AF_BLUE_PROPERTY_CJK_TOP    ( 1 << 1 )
-#define AF_BLUE_PROPERTY_CJK_FILL   ( 1 << 2 )
+#define AF_BLUE_PROPERTY_CJK_TOP    ( 1 << 0 )        /* must have value 1 */
+#define AF_BLUE_PROPERTY_CJK_HORIZ  ( 1 << 1 )        /* must have value 2 */
 #define AF_BLUE_PROPERTY_CJK_RIGHT  AF_BLUE_PROPERTY_CJK_TOP
 
 
diff --git a/src/autofit/afcjk.c b/src/autofit/afcjk.c
index 7a6f835..ca7acca 100644
--- a/src/autofit/afcjk.c
+++ b/src/autofit/afcjk.c
@@ -2,9 +2,9 @@
 /*                                                                         */
 /*  afcjk.c                                                                */
 /*                                                                         */
-/*    Auto-fitter hinting routines for CJK script (body).                  */
+/*    Auto-fitter hinting routines for CJK writing system (body).          */
 /*                                                                         */
-/*  Copyright 2006-2013 by                                                 */
+/*  Copyright 2006-2014 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -27,6 +27,7 @@
 #include FT_INTERNAL_DEBUG_H
 
 #include "afglobal.h"
+#include "afpic.h"
 #include "aflatin.h"
 
 
@@ -74,10 +75,10 @@
 
 
     FT_TRACE5(( "\n"
-                "cjk standard widths computation (script `%s')\n"
-                "===============================================\n"
+                "cjk standard widths computation (style `%s')\n"
+                "===================================================\n"
                 "\n",
-                af_script_names[metrics->root.script_class->script] ));
+                af_style_names[metrics->root.style_class->style] ));
 
     af_glyph_hints_init( hints, face->memory );
 
@@ -86,20 +87,59 @@
 
     {
       FT_Error          error;
-      FT_UInt           glyph_index;
+      FT_ULong          glyph_index;
+      FT_Long           y_offset;
       int               dim;
       AF_CJKMetricsRec  dummy[1];
       AF_Scaler         scaler = &dummy->root.scaler;
 
+#ifdef FT_CONFIG_OPTION_PIC
+      AF_FaceGlobals  globals = metrics->root.globals;
+#endif
 
-      glyph_index = FT_Get_Char_Index(
-                      face,
-                      metrics->root.script_class->standard_char );
-      if ( glyph_index == 0 )
-        goto Exit;
+      AF_StyleClass   style_class  = metrics->root.style_class;
+      AF_ScriptClass  script_class = AF_SCRIPT_CLASSES_GET
+                                       [style_class->script];
+
+      FT_UInt32  standard_char;
+
+
+      standard_char = script_class->standard_char1;
+      af_get_char_index( &metrics->root,
+                         standard_char,
+                         &glyph_index,
+                         &y_offset );
+      if ( !glyph_index )
+      {
+        if ( script_class->standard_char2 )
+        {
+          standard_char = script_class->standard_char2;
+          af_get_char_index( &metrics->root,
+                             standard_char,
+                             &glyph_index,
+                             &y_offset );
+          if ( !glyph_index )
+          {
+            if ( script_class->standard_char3 )
+            {
+              standard_char = script_class->standard_char3;
+              af_get_char_index( &metrics->root,
+                                 standard_char,
+                                 &glyph_index,
+                                 &y_offset );
+              if ( !glyph_index )
+                goto Exit;
+            }
+            else
+              goto Exit;
+          }
+        }
+        else
+          goto Exit;
+      }
 
       FT_TRACE5(( "standard character: U+%04lX (glyph index %d)\n",
-                  metrics->root.script_class->standard_char, glyph_index ));
+                  standard_char, glyph_index ));
 
       error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE );
       if ( error || face->glyph->outline.n_points <= 0 )
@@ -118,7 +158,7 @@
       scaler->render_mode = FT_RENDER_MODE_NORMAL;
       scaler->flags       = 0;
 
-      af_glyph_hints_rescale( hints, (AF_ScriptMetrics)dummy );
+      af_glyph_hints_rescale( hints, (AF_StyleMetrics)dummy );
 
       error = af_glyph_hints_reload( hints, &face->glyph->outline );
       if ( error )
@@ -138,6 +178,8 @@
           goto Exit;
 
         af_latin_hints_link_segments( hints,
+                                      0,
+                                      NULL,
                                       (AF_Dimension)dim );
 
         seg   = axhints->segments;
@@ -221,34 +263,22 @@
     FT_Int      num_fills;
     FT_Int      num_flats;
 
+    FT_Bool     fill;
+
     AF_CJKBlue  blue;
     FT_Error    error;
     AF_CJKAxis  axis;
     FT_Outline  outline;
 
-    AF_Blue_Stringset         bss = metrics->root.script_class->blue_stringset;
+    AF_StyleClass  sc = metrics->root.style_class;
+
+    AF_Blue_Stringset         bss = sc->blue_stringset;
     const AF_Blue_StringRec*  bs  = &af_blue_stringsets[bss];
 
-#ifdef FT_DEBUG_LEVEL_TRACE
-    FT_String*  cjk_blue_name[4] =
-    {
-      (FT_String*)"bottom",    /* --   , --  */
-      (FT_String*)"top",       /* --   , TOP */
-      (FT_String*)"left",      /* HORIZ, --  */
-      (FT_String*)"right"      /* HORIZ, TOP */
-    };
 
-    FT_String*  cjk_blue_type_name[2] =
-    {
-      (FT_String*)"unfilled",  /* --   */
-      (FT_String*)"filled"     /* FILL */
-    };
-#endif
-
-
-    /* we walk over the blue character strings as specified in the    */
-    /* script's entry in the `af_blue_stringset' array, computing its */
-    /* extremum points (depending on the string properties)           */
+    /* we walk over the blue character strings as specified in the   */
+    /* style's entry in the `af_blue_stringset' array, computing its */
+    /* extremum points (depending on the string properties)          */
 
     FT_TRACE5(( "cjk blue zones computation\n"
                 "==========================\n"
@@ -266,20 +296,35 @@
       else
         axis = &metrics->axis[AF_DIMENSION_VERT];
 
-      FT_TRACE5(( "blue zone %d:\n", axis->blue_count ));
+#ifdef FT_DEBUG_LEVEL_TRACE
+      {
+        FT_String*  cjk_blue_name[4] =
+        {
+          (FT_String*)"bottom",    /* --   , --  */
+          (FT_String*)"top",       /* --   , TOP */
+          (FT_String*)"left",      /* HORIZ, --  */
+          (FT_String*)"right"      /* HORIZ, TOP */
+        };
+
+
+        FT_TRACE5(( "blue zone %d (%s):\n",
+                    axis->blue_count,
+                    cjk_blue_name[AF_CJK_IS_HORIZ_BLUE( bs ) |
+                                  AF_CJK_IS_TOP_BLUE( bs )   ] ));
+      }
+#endif /* FT_DEBUG_LEVEL_TRACE */
 
       num_fills = 0;
       num_flats = 0;
 
-      FT_TRACE5(( "  cjk blue %s/%s\n",
-                  cjk_blue_name[AF_CJK_IS_HORIZ_BLUE( bs ) |
-                                AF_CJK_IS_TOP_BLUE( bs )   ],
-                  cjk_blue_type_name[!!AF_CJK_IS_FILLED_BLUE( bs )] ));
+      fill = 1;  /* start with characters that define fill values */
+      FT_TRACE5(( "  [overshoot values]\n" ));
 
       while ( *p )
       {
         FT_ULong    ch;
-        FT_UInt     glyph_index;
+        FT_ULong    glyph_index;
+        FT_Long     y_offset;
         FT_Pos      best_pos;       /* same as points.y or points.x, resp. */
         FT_Int      best_point;
         FT_Vector*  points;
@@ -287,8 +332,16 @@
 
         GET_UTF8_CHAR( ch, p );
 
+        /* switch to characters that define flat values */
+        if ( ch == '|' )
+        {
+          fill = 0;
+          FT_TRACE5(( "  [reference values]\n" ));
+          continue;
+        }
+
         /* load the character in the face -- skip unknown or empty ones */
-        glyph_index = FT_Get_Char_Index( face, ch );
+        af_get_char_index( &metrics->root, ch, &glyph_index, &y_offset );
         if ( glyph_index == 0 )
         {
           FT_TRACE5(( "  U+%04lX unavailable\n", ch ));
@@ -374,7 +427,7 @@
           FT_TRACE5(( "  U+%04lX: best_pos = %5ld\n", ch, best_pos ));
         }
 
-        if ( AF_CJK_IS_FILLED_BLUE( bs ) )
+        if ( fill )
           fills[num_fills++] = best_pos;
         else
           flats[num_flats++] = best_pos;
@@ -386,15 +439,15 @@
          *  we couldn't find a single glyph to compute this blue zone,
          *  we will simply ignore it then
          */
-        FT_TRACE5(( "    empty\n" ));
+        FT_TRACE5(( "  empty\n" ));
         continue;
       }
 
-      /* we have computed the contents of the `fill' and `flats' tables, */
-      /* now determine the reference position of the blue zone --        */
-      /* we simply take the median value after a simple sort             */
-      af_sort_pos( num_flats, flats );
+      /* we have computed the contents of the `fill' and `flats' tables,   */
+      /* now determine the reference and overshoot position of the blue -- */
+      /* we simply take the median value after a simple sort               */
       af_sort_pos( num_fills, fills );
+      af_sort_pos( num_flats, flats );
 
       blue       = &axis->blues[axis->blue_count];
       blue_ref   = &blue->ref.org;
@@ -433,7 +486,7 @@
           *blue_ref   =
           *blue_shoot = ( shoot + ref ) / 2;
 
-          FT_TRACE5(( "  [overshoot smaller than reference,"
+          FT_TRACE5(( "  [reference smaller than overshoot,"
                       " taking mean value]\n" ));
         }
       }
@@ -467,10 +520,11 @@
     /* digit `0' is 0x30 in all supported charmaps */
     for ( i = 0x30; i <= 0x39; i++ )
     {
-      FT_UInt  glyph_index;
+      FT_ULong  glyph_index;
+      FT_Long   y_offset;
 
 
-      glyph_index = FT_Get_Char_Index( face, i );
+      af_get_char_index( &metrics->root, i, &glyph_index, &y_offset );
       if ( glyph_index == 0 )
         continue;
 
@@ -1186,8 +1240,10 @@
         /* zone, check for left edges                                      */
         /*                                                                 */
         /* of course, that's for TrueType                                  */
-        is_top_right_blue = FT_BOOL( blue->flags & AF_CJK_BLUE_TOP );
-        is_major_dir      = FT_BOOL( edge->dir == axis->major_dir );
+        is_top_right_blue =
+          (FT_Byte)( ( blue->flags & AF_CJK_BLUE_TOP ) != 0 );
+        is_major_dir =
+          FT_BOOL( edge->dir == axis->major_dir );
 
         /* if it is a top zone, the edge must be against the major    */
         /* direction; if it is a bottom zone, it must be in the major */
@@ -1234,7 +1290,7 @@
     FT_UInt32       scaler_flags, other_flags;
 
 
-    af_glyph_hints_rescale( hints, (AF_ScriptMetrics)metrics );
+    af_glyph_hints_rescale( hints, (AF_StyleMetrics)metrics );
 
     /*
      *  correct x_scale and y_scale when needed, since they may have
@@ -1484,6 +1540,12 @@
 
 
     stem_edge->pos = base_edge->pos + fitted_width;
+
+    FT_TRACE5(( "  CJKLINK: edge %d @%d (opos=%.2f) linked to %.2f,"
+                " dist was %.2f, now %.2f\n",
+                stem_edge - hints->axis[dim].edges, stem_edge->fpos,
+                stem_edge->opos / 64.0, stem_edge->pos / 64.0,
+                dist / 64.0, fitted_width / 64.0 ));
   }
 
 
@@ -1665,9 +1727,9 @@
 #endif
 
 
-    FT_TRACE5(( "cjk %s edge hinting (script `%s')\n",
+    FT_TRACE5(( "cjk %s edge hinting (style `%s')\n",
                 dim == AF_DIMENSION_VERT ? "horizontal" : "vertical",
-                af_script_names[hints->metrics->script_class->script] ));
+                af_style_names[hints->metrics->style_class->style] ));
 
     /* we begin by aligning all stems relative to the blue zone */
 
@@ -2210,60 +2272,18 @@
 
     sizeof ( AF_CJKMetricsRec ),
 
-    (AF_Script_InitMetricsFunc) af_cjk_metrics_init,
-    (AF_Script_ScaleMetricsFunc)af_cjk_metrics_scale,
-    (AF_Script_DoneMetricsFunc) NULL,
+    (AF_WritingSystem_InitMetricsFunc) af_cjk_metrics_init,
+    (AF_WritingSystem_ScaleMetricsFunc)af_cjk_metrics_scale,
+    (AF_WritingSystem_DoneMetricsFunc) NULL,
 
-    (AF_Script_InitHintsFunc)   af_cjk_hints_init,
-    (AF_Script_ApplyHintsFunc)  af_cjk_hints_apply
+    (AF_WritingSystem_InitHintsFunc)   af_cjk_hints_init,
+    (AF_WritingSystem_ApplyHintsFunc)  af_cjk_hints_apply
   )
 
 
-  /* this corresponds to Unicode 6.0 */
-
-  /* XXX: this should probably fine tuned to differentiate better between */
-  /*      scripts...                                                      */
-
-  static const AF_Script_UniRangeRec  af_hani_uniranges[] =
-  {
-    AF_UNIRANGE_REC(  0x1100UL,  0x11FFUL ),  /* Hangul Jamo                             */
-    AF_UNIRANGE_REC(  0x2E80UL,  0x2EFFUL ),  /* CJK Radicals Supplement                 */
-    AF_UNIRANGE_REC(  0x2F00UL,  0x2FDFUL ),  /* Kangxi Radicals                         */
-    AF_UNIRANGE_REC(  0x2FF0UL,  0x2FFFUL ),  /* Ideographic Description Characters      */
-    AF_UNIRANGE_REC(  0x3000UL,  0x303FUL ),  /* CJK Symbols and Punctuation             */
-    AF_UNIRANGE_REC(  0x3040UL,  0x309FUL ),  /* Hiragana                                */
-    AF_UNIRANGE_REC(  0x30A0UL,  0x30FFUL ),  /* Katakana                                */
-    AF_UNIRANGE_REC(  0x3100UL,  0x312FUL ),  /* Bopomofo                                */
-    AF_UNIRANGE_REC(  0x3130UL,  0x318FUL ),  /* Hangul Compatibility Jamo               */
-    AF_UNIRANGE_REC(  0x3190UL,  0x319FUL ),  /* Kanbun                                  */
-    AF_UNIRANGE_REC(  0x31A0UL,  0x31BFUL ),  /* Bopomofo Extended                       */
-    AF_UNIRANGE_REC(  0x31C0UL,  0x31EFUL ),  /* CJK Strokes                             */
-    AF_UNIRANGE_REC(  0x31F0UL,  0x31FFUL ),  /* Katakana Phonetic Extensions            */
-    AF_UNIRANGE_REC(  0x3200UL,  0x32FFUL ),  /* Enclosed CJK Letters and Months         */
-    AF_UNIRANGE_REC(  0x3300UL,  0x33FFUL ),  /* CJK Compatibility                       */
-    AF_UNIRANGE_REC(  0x3400UL,  0x4DBFUL ),  /* CJK Unified Ideographs Extension A      */
-    AF_UNIRANGE_REC(  0x4DC0UL,  0x4DFFUL ),  /* Yijing Hexagram Symbols                 */
-    AF_UNIRANGE_REC(  0x4E00UL,  0x9FFFUL ),  /* CJK Unified Ideographs                  */
-    AF_UNIRANGE_REC(  0xA960UL,  0xA97FUL ),  /* Hangul Jamo Extended-A                  */
-    AF_UNIRANGE_REC(  0xAC00UL,  0xD7AFUL ),  /* Hangul Syllables                        */
-    AF_UNIRANGE_REC(  0xD7B0UL,  0xD7FFUL ),  /* Hangul Jamo Extended-B                  */
-    AF_UNIRANGE_REC(  0xF900UL,  0xFAFFUL ),  /* CJK Compatibility Ideographs            */
-    AF_UNIRANGE_REC(  0xFE10UL,  0xFE1FUL ),  /* Vertical forms                          */
-    AF_UNIRANGE_REC(  0xFE30UL,  0xFE4FUL ),  /* CJK Compatibility Forms                 */
-    AF_UNIRANGE_REC(  0xFF00UL,  0xFFEFUL ),  /* Halfwidth and Fullwidth Forms           */
-    AF_UNIRANGE_REC( 0x1B000UL, 0x1B0FFUL ),  /* Kana Supplement                         */
-    AF_UNIRANGE_REC( 0x1D300UL, 0x1D35FUL ),  /* Tai Xuan Hing Symbols                   */
-    AF_UNIRANGE_REC( 0x1F200UL, 0x1F2FFUL ),  /* Enclosed Ideographic Supplement         */
-    AF_UNIRANGE_REC( 0x20000UL, 0x2A6DFUL ),  /* CJK Unified Ideographs Extension B      */
-    AF_UNIRANGE_REC( 0x2A700UL, 0x2B73FUL ),  /* CJK Unified Ideographs Extension C      */
-    AF_UNIRANGE_REC( 0x2B740UL, 0x2B81FUL ),  /* CJK Unified Ideographs Extension D      */
-    AF_UNIRANGE_REC( 0x2F800UL, 0x2FA1FUL ),  /* CJK Compatibility Ideographs Supplement */
-    AF_UNIRANGE_REC(       0UL,       0UL )
-  };
-
-
 #else /* !AF_CONFIG_OPTION_CJK */
 
+
   AF_DEFINE_WRITING_SYSTEM_CLASS(
     af_cjk_writing_system_class,
 
@@ -2271,33 +2291,16 @@
 
     sizeof ( AF_CJKMetricsRec ),
 
-    (AF_Script_InitMetricsFunc) NULL,
-    (AF_Script_ScaleMetricsFunc)NULL,
-    (AF_Script_DoneMetricsFunc) NULL,
+    (AF_WritingSystem_InitMetricsFunc) NULL,
+    (AF_WritingSystem_ScaleMetricsFunc)NULL,
+    (AF_WritingSystem_DoneMetricsFunc) NULL,
 
-    (AF_Script_InitHintsFunc)   NULL,
-    (AF_Script_ApplyHintsFunc)  NULL
+    (AF_WritingSystem_InitHintsFunc)   NULL,
+    (AF_WritingSystem_ApplyHintsFunc)  NULL
   )
 
 
-  static const AF_Script_UniRangeRec  af_hani_uniranges[] =
-  {
-    AF_UNIRANGE_REC( 0UL, 0UL )
-  };
-
 #endif /* !AF_CONFIG_OPTION_CJK */
 
 
-  AF_DEFINE_SCRIPT_CLASS(
-    af_hani_script_class,
-
-    AF_SCRIPT_HANI,
-    AF_BLUE_STRINGSET_HANI,
-    AF_WRITING_SYSTEM_CJK,
-
-    af_hani_uniranges,
-    0x7530 /* 田 */
-  )
-
-
 /* END */
diff --git a/src/autofit/afcjk.h b/src/autofit/afcjk.h
index 6f5bdc5..4dd4f39 100644
--- a/src/autofit/afcjk.h
+++ b/src/autofit/afcjk.h
@@ -2,9 +2,9 @@
 /*                                                                         */
 /*  afcjk.h                                                                */
 /*                                                                         */
-/*    Auto-fitter hinting routines for CJK script (specification).         */
+/*    Auto-fitter hinting routines for CJK writing system (specification). */
 /*                                                                         */
-/*  Copyright 2006, 2007, 2011-2013 by                                     */
+/*  Copyright 2006, 2007, 2011-2014 by                                     */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -31,11 +31,6 @@
   AF_DECLARE_WRITING_SYSTEM_CLASS( af_cjk_writing_system_class )
 
 
-  /* the CJK-specific script classes */
-
-  AF_DECLARE_SCRIPT_CLASS( af_hani_script_class )
-
-
   /*************************************************************************/
   /*************************************************************************/
   /*****                                                               *****/
@@ -55,8 +50,6 @@
           ( (b)->properties & AF_BLUE_PROPERTY_CJK_TOP )
 #define AF_CJK_IS_HORIZ_BLUE( b ) \
           ( (b)->properties & AF_BLUE_PROPERTY_CJK_HORIZ )
-#define AF_CJK_IS_FILLED_BLUE( b ) \
-          ( (b)->properties & AF_BLUE_PROPERTY_CJK_FILL )
 #define AF_CJK_IS_RIGHT_BLUE  AF_CJK_IS_TOP_BLUE
 
 #define AF_CJK_MAX_WIDTHS  16
@@ -105,9 +98,9 @@
 
   typedef struct  AF_CJKMetricsRec_
   {
-    AF_ScriptMetricsRec  root;
-    FT_UInt              units_per_em;
-    AF_CJKAxisRec        axis[AF_DIMENSION_MAX];
+    AF_StyleMetricsRec  root;
+    FT_UInt             units_per_em;
+    AF_CJKAxisRec       axis[AF_DIMENSION_MAX];
 
   } AF_CJKMetricsRec, *AF_CJKMetrics;
 
diff --git a/src/autofit/afcover.h b/src/autofit/afcover.h
new file mode 100644
index 0000000..d5ac969
--- /dev/null
+++ b/src/autofit/afcover.h
@@ -0,0 +1,105 @@
+/***************************************************************************/
+/*                                                                         */
+/*  afcover.h                                                              */
+/*                                                                         */
+/*    Auto-fitter coverages (specification only).                          */
+/*                                                                         */
+/*  Copyright 2013, 2014 by                                                */
+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
+/*                                                                         */
+/*  This file is part of the FreeType project, and may only be used,       */
+/*  modified, and distributed under the terms of the FreeType project      */
+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
+/*  this file you indicate that you have read the license and              */
+/*  understand and accept it fully.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
+  /* This header file can be included multiple times. */
+  /* Define `COVERAGE' as needed.                     */
+
+
+  /* Add new coverages here.  The first and second arguments are the   */
+  /* coverage name in lowercase and uppercase, respectively, followed  */
+  /* by a description string.  The last four arguments are the four    */
+  /* characters defining the corresponding OpenType feature.           */
+
+#if 0
+  /* XXX: It's not possible to define blue zone characters in advance. */
+  COVERAGE( alternative_fractions, ALTERNATIVE_FRACTIONS,
+            "alternative fractions",
+            'a', 'f', 'r', 'c' )
+#endif
+
+  COVERAGE( petite_capitals_from_capitals, PETITE_CAPITALS_FROM_CAPITALS,
+            "petite capitals from capitals",
+            'c', '2', 'c', 'p' )
+
+  COVERAGE( small_capitals_from_capitals, SMALL_CAPITALS_FROM_CAPITALS,
+            "small capitals from capitals",
+            'c', '2', 's', 'c' )
+
+#if 0
+  /* XXX: Only digits are in this coverage, however, both normal style */
+  /*      and oldstyle representation forms are possible.              */
+  COVERAGE( denominators, DENOMINATORS,
+            "denominators",
+            'd', 'n', 'o', 'm' )
+#endif
+
+#if 0
+  /* XXX: It's not possible to define blue zone characters in advance. */
+  COVERAGE( fractions, FRACTIONS,
+            "fractions",
+            'f', 'r', 'a', 'c' )
+#endif
+
+#if 0
+  /* XXX: Only digits are in this coverage, however, both normal style */
+  /*      and oldstyle representation forms are possible.              */
+  COVERAGE( numerators, NUMERATORS,
+            "numerators",
+            'n', 'u', 'm', 'r' )
+#endif
+
+  COVERAGE( ordinals, ORDINALS,
+            "ordinals",
+            'o', 'r', 'd', 'n' )
+
+  COVERAGE( petite_capitals, PETITE_CAPITALS,
+            "petite capitals",
+            'p', 'c', 'a', 'p' )
+
+  COVERAGE( ruby, RUBY,
+            "ruby",
+            'r', 'u', 'b', 'y' )
+
+  COVERAGE( scientific_inferiors, SCIENTIFIC_INFERIORS,
+            "scientific inferiors",
+            's', 'i', 'n', 'f' )
+
+  COVERAGE( small_capitals, SMALL_CAPITALS,
+            "small capitals",
+            's', 'm', 'c', 'p' )
+
+  COVERAGE( subscript, SUBSCRIPT,
+            "subscript",
+            's', 'u', 'b', 's' )
+
+  COVERAGE( superscript, SUPERSCRIPT,
+            "superscript",
+            's', 'u', 'p', 's' )
+
+  COVERAGE( titling, TITLING,
+            "titling",
+            't', 'i', 't', 'l' )
+
+#if 0
+  /* to be always excluded */
+  COVERAGE(nalt, 'n', 'a', 'l', 't'); /* Alternate Annotation Forms (?) */
+  COVERAGE(ornm, 'o', 'r', 'n', 'm'); /* Ornaments (?) */
+#endif
+
+
+/* END */
diff --git a/src/autofit/afdummy.c b/src/autofit/afdummy.c
index b2b3a20..f8702a1 100644
--- a/src/autofit/afdummy.c
+++ b/src/autofit/afdummy.c
@@ -23,8 +23,8 @@
 
 
   static FT_Error
-  af_dummy_hints_init( AF_GlyphHints     hints,
-                       AF_ScriptMetrics  metrics )
+  af_dummy_hints_init( AF_GlyphHints    hints,
+                       AF_StyleMetrics  metrics )
   {
     af_glyph_hints_rescale( hints, metrics );
 
@@ -57,26 +57,14 @@
 
     AF_WRITING_SYSTEM_DUMMY,
 
-    sizeof ( AF_ScriptMetricsRec ),
+    sizeof ( AF_StyleMetricsRec ),
 
-    (AF_Script_InitMetricsFunc) NULL,
-    (AF_Script_ScaleMetricsFunc)NULL,
-    (AF_Script_DoneMetricsFunc) NULL,
+    (AF_WritingSystem_InitMetricsFunc) NULL,
+    (AF_WritingSystem_ScaleMetricsFunc)NULL,
+    (AF_WritingSystem_DoneMetricsFunc) NULL,
 
-    (AF_Script_InitHintsFunc)   af_dummy_hints_init,
-    (AF_Script_ApplyHintsFunc)  af_dummy_hints_apply
-  )
-
-
-  AF_DEFINE_SCRIPT_CLASS(
-    af_none_script_class,
-
-    AF_SCRIPT_NONE,
-    (AF_Blue_Stringset)0,
-    AF_WRITING_SYSTEM_DUMMY,
-
-    NULL,
-    '\0'
+    (AF_WritingSystem_InitHintsFunc)   af_dummy_hints_init,
+    (AF_WritingSystem_ApplyHintsFunc)  af_dummy_hints_apply
   )
 
 
diff --git a/src/autofit/afdummy.h b/src/autofit/afdummy.h
index 9a4d3c2..ad1b0d3 100644
--- a/src/autofit/afdummy.h
+++ b/src/autofit/afdummy.h
@@ -25,14 +25,10 @@
 
 FT_BEGIN_HEADER
 
- /*  A dummy writing system and script class used when no hinting should be
-  *  performed.
-  */
+  /* A dummy writing system used when no hinting should be performed. */
 
   AF_DECLARE_WRITING_SYSTEM_CLASS( af_dummy_writing_system_class )
 
-  AF_DECLARE_SCRIPT_CLASS( af_none_script_class )
-
 /* */
 
 FT_END_HEADER
diff --git a/src/autofit/afglobal.c b/src/autofit/afglobal.c
index c2151af..a54c20c 100644
--- a/src/autofit/afglobal.c
+++ b/src/autofit/afglobal.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auto-fitter routines to compute global hinting values (body).        */
 /*                                                                         */
-/*  Copyright 2003-2013 by                                                 */
+/*  Copyright 2003-2014 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -17,6 +17,20 @@
 
 
 #include "afglobal.h"
+#include "afranges.h"
+#include "hbshim.h"
+#include FT_INTERNAL_DEBUG_H
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
+  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
+  /* messages during execution.                                            */
+  /*                                                                       */
+#undef  FT_COMPONENT
+#define FT_COMPONENT  trace_afglobal
+
 
   /* get writing system specific header files */
 #undef  WRITING_SYSTEM
@@ -27,6 +41,30 @@
 #include "afpic.h"
 
 
+#undef  SCRIPT
+#define SCRIPT( s, S, d, h, sc1, sc2, sc3 ) \
+          AF_DEFINE_SCRIPT_CLASS(           \
+            af_ ## s ## _script_class,      \
+            AF_SCRIPT_ ## S,                \
+            af_ ## s ## _uniranges,         \
+            sc1, sc2, sc3 )
+
+#include "afscript.h"
+
+
+#undef  STYLE
+#define STYLE( s, S, d, ws, sc, ss, c )  \
+          AF_DEFINE_STYLE_CLASS(         \
+            af_ ## s ## _style_class,    \
+            AF_STYLE_ ## S,              \
+            ws,                          \
+            sc,                          \
+            ss,                          \
+            c )
+
+#include "afstyles.h"
+
+
 #ifndef FT_CONFIG_OPTION_PIC
 
 #undef  WRITING_SYSTEM
@@ -44,7 +82,7 @@
 
 
 #undef  SCRIPT
-#define SCRIPT( s, S, d )             \
+#define SCRIPT( s, S, d, h, sc1, sc2, sc3 ) \
           &af_ ## s ## _script_class,
 
   FT_LOCAL_ARRAY_DEF( AF_ScriptClass )
@@ -56,58 +94,76 @@
     NULL  /* do not remove */
   };
 
+
+#undef  STYLE
+#define STYLE( s, S, d, ws, sc, ss, c ) \
+          &af_ ## s ## _style_class,
+
+  FT_LOCAL_ARRAY_DEF( AF_StyleClass )
+  af_style_classes[] =
+  {
+
+#include "afstyles.h"
+
+    NULL  /* do not remove */
+  };
+
 #endif /* !FT_CONFIG_OPTION_PIC */
 
 
 #ifdef FT_DEBUG_LEVEL_TRACE
 
-#undef  SCRIPT
-#define SCRIPT( s, S, d )  #s,
+#undef  STYLE
+#define STYLE( s, S, d, ws, sc, ss, c )  #s,
 
   FT_LOCAL_ARRAY_DEF( char* )
-  af_script_names[] =
+  af_style_names[] =
   {
 
-#include "afscript.h"
+#include "afstyles.h"
 
   };
 
 #endif /* FT_DEBUG_LEVEL_TRACE */
 
 
-  /* Compute the script index of each glyph within a given face. */
+  /* Compute the style index of each glyph within a given face. */
 
   static FT_Error
-  af_face_globals_compute_script_coverage( AF_FaceGlobals  globals )
+  af_face_globals_compute_style_coverage( AF_FaceGlobals  globals )
   {
     FT_Error    error;
     FT_Face     face        = globals->face;
     FT_CharMap  old_charmap = face->charmap;
-    FT_Byte*    gscripts    = globals->glyph_scripts;
+    FT_Byte*    gstyles     = globals->glyph_styles;
     FT_UInt     ss;
     FT_UInt     i;
+    FT_UInt     dflt        = ~0U; /* a non-valid value */
 
 
-    /* the value AF_SCRIPT_UNASSIGNED means `uncovered glyph' */
-    FT_MEM_SET( globals->glyph_scripts,
-                AF_SCRIPT_UNASSIGNED,
+    /* the value AF_STYLE_UNASSIGNED means `uncovered glyph' */
+    FT_MEM_SET( globals->glyph_styles,
+                AF_STYLE_UNASSIGNED,
                 globals->glyph_count );
 
     error = FT_Select_Charmap( face, FT_ENCODING_UNICODE );
     if ( error )
     {
-     /*
-      *  Ignore this error; we simply use the fallback script.
-      *  XXX: Shouldn't we rather disable hinting?
-      */
+      /*
+       * Ignore this error; we simply use the fallback style.
+       * XXX: Shouldn't we rather disable hinting?
+       */
       error = FT_Err_Ok;
       goto Exit;
     }
 
-    /* scan each script in a Unicode charmap */
-    for ( ss = 0; AF_SCRIPT_CLASSES_GET[ss]; ss++ )
+    /* scan each style in a Unicode charmap */
+    for ( ss = 0; AF_STYLE_CLASSES_GET[ss]; ss++ )
     {
-      AF_ScriptClass      script_class = AF_SCRIPT_CLASSES_GET[ss];
+      AF_StyleClass       style_class =
+                            AF_STYLE_CLASSES_GET[ss];
+      AF_ScriptClass      script_class =
+                            AF_SCRIPT_CLASSES_GET[style_class->script];
       AF_Script_UniRange  range;
 
 
@@ -116,35 +172,60 @@
 
       /*
        *  Scan all Unicode points in the range and set the corresponding
-       *  glyph script index.
+       *  glyph style index.
        */
-      for ( range = script_class->script_uni_ranges;
-            range->first != 0;
-            range++ )
+      if ( style_class->coverage == AF_COVERAGE_DEFAULT )
       {
-        FT_ULong  charcode = range->first;
-        FT_UInt   gindex;
+        if ( (FT_UInt)style_class->script ==
+             globals->module->default_script )
+          dflt = ss;
 
-
-        gindex = FT_Get_Char_Index( face, charcode );
-
-        if ( gindex != 0                              &&
-             gindex < (FT_ULong)globals->glyph_count  &&
-             gscripts[gindex] == AF_SCRIPT_UNASSIGNED )
-          gscripts[gindex] = (FT_Byte)ss;
-
-        for (;;)
+        for ( range = script_class->script_uni_ranges;
+              range->first != 0;
+              range++ )
         {
-          charcode = FT_Get_Next_Char( face, charcode, &gindex );
+          FT_ULong  charcode = range->first;
+          FT_UInt   gindex;
 
-          if ( gindex == 0 || charcode > range->last )
-            break;
 
-          if ( gindex < (FT_ULong)globals->glyph_count  &&
-               gscripts[gindex] == AF_SCRIPT_UNASSIGNED )
-            gscripts[gindex] = (FT_Byte)ss;
+          gindex = FT_Get_Char_Index( face, charcode );
+
+          if ( gindex != 0                             &&
+               gindex < (FT_ULong)globals->glyph_count &&
+               gstyles[gindex] == AF_STYLE_UNASSIGNED  )
+            gstyles[gindex] = (FT_Byte)ss;
+
+          for (;;)
+          {
+            charcode = FT_Get_Next_Char( face, charcode, &gindex );
+
+            if ( gindex == 0 || charcode > range->last )
+              break;
+
+            if ( gindex < (FT_ULong)globals->glyph_count &&
+                 gstyles[gindex] == AF_STYLE_UNASSIGNED  )
+              gstyles[gindex] = (FT_Byte)ss;
+          }
         }
       }
+      else
+      {
+        /* get glyphs not directly addressable by cmap */
+        af_get_coverage( globals, style_class, gstyles );
+      }
+    }
+
+    /* handle the default OpenType features of the default script ... */
+    af_get_coverage( globals, AF_STYLE_CLASSES_GET[dflt], gstyles );
+
+    /* ... and the remaining default OpenType features */
+    for ( ss = 0; AF_STYLE_CLASSES_GET[ss]; ss++ )
+    {
+      AF_StyleClass  style_class = AF_STYLE_CLASSES_GET[ss];
+
+
+      if ( ss != dflt && style_class->coverage == AF_COVERAGE_DEFAULT )
+        af_get_coverage( globals, style_class, gstyles );
     }
 
     /* mark ASCII digits */
@@ -154,29 +235,68 @@
 
 
       if ( gindex != 0 && gindex < (FT_ULong)globals->glyph_count )
-        gscripts[gindex] |= AF_DIGIT;
+        gstyles[gindex] |= AF_DIGIT;
     }
 
   Exit:
     /*
-     *  By default, all uncovered glyphs are set to the fallback script.
+     *  By default, all uncovered glyphs are set to the fallback style.
      *  XXX: Shouldn't we disable hinting or do something similar?
      */
-    if ( globals->module->fallback_script != AF_SCRIPT_UNASSIGNED )
+    if ( globals->module->fallback_style != AF_STYLE_UNASSIGNED )
     {
       FT_Long  nn;
 
 
       for ( nn = 0; nn < globals->glyph_count; nn++ )
       {
-        if ( ( gscripts[nn] & ~AF_DIGIT ) == AF_SCRIPT_UNASSIGNED )
+        if ( ( gstyles[nn] & ~AF_DIGIT ) == AF_STYLE_UNASSIGNED )
         {
-          gscripts[nn] &= ~AF_SCRIPT_UNASSIGNED;
-          gscripts[nn] |= globals->module->fallback_script;
+          gstyles[nn] &= ~AF_STYLE_UNASSIGNED;
+          gstyles[nn] |= globals->module->fallback_style;
         }
       }
     }
 
+#ifdef FT_DEBUG_LEVEL_TRACE
+
+    FT_TRACE4(( "\n"
+                "style coverage\n"
+                "==============\n"
+                "\n" ));
+
+    for ( ss = 0; AF_STYLE_CLASSES_GET[ss]; ss++ )
+    {
+      AF_StyleClass  style_class = AF_STYLE_CLASSES_GET[ss];
+      FT_UInt        count       = 0;
+      FT_Long        idx;
+
+
+      FT_TRACE4(( "%s:\n", af_style_names[style_class->style] ));
+
+      for ( idx = 0; idx < globals->glyph_count; idx++ )
+      {
+        if ( ( gstyles[idx] & ~AF_DIGIT ) == style_class->style )
+        {
+          if ( !( count % 10 ) )
+            FT_TRACE4(( " " ));
+
+          FT_TRACE4(( " %d", idx ));
+          count++;
+
+          if ( !( count % 10 ) )
+            FT_TRACE4(( "\n" ));
+        }
+      }
+
+      if ( !count )
+        FT_TRACE4(( "  (none)\n" ));
+      if ( count % 10 )
+        FT_TRACE4(( "\n" ));
+    }
+
+#endif /* FT_DEBUG_LEVEL_TRACE */
+
     FT_Set_Charmap( face, old_charmap );
     return error;
   }
@@ -198,19 +318,23 @@
                             face->num_glyphs * sizeof ( FT_Byte ) ) )
       goto Exit;
 
-    globals->face          = face;
-    globals->glyph_count   = face->num_glyphs;
-    globals->glyph_scripts = (FT_Byte*)( globals + 1 );
-    globals->module        = module;
+    globals->face         = face;
+    globals->glyph_count  = face->num_glyphs;
+    globals->glyph_styles = (FT_Byte*)( globals + 1 );
+    globals->module       = module;
 
-    error = af_face_globals_compute_script_coverage( globals );
+#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
+    globals->hb_font = hb_ft_font_create( face, NULL );
+#endif
+
+    error = af_face_globals_compute_style_coverage( globals );
     if ( error )
     {
       af_face_globals_free( globals );
       globals = NULL;
     }
-
-    globals->increase_x_height = AF_PROP_INCREASE_X_HEIGHT_MAX;
+    else
+      globals->increase_x_height = AF_PROP_INCREASE_X_HEIGHT_MAX;
 
   Exit:
     *aglobals = globals;
@@ -227,26 +351,31 @@
       FT_UInt    nn;
 
 
-      for ( nn = 0; nn < AF_SCRIPT_MAX; nn++ )
+      for ( nn = 0; nn < AF_STYLE_MAX; nn++ )
       {
         if ( globals->metrics[nn] )
         {
-          AF_ScriptClass         script_class =
-            AF_SCRIPT_CLASSES_GET[nn];
+          AF_StyleClass          style_class =
+            AF_STYLE_CLASSES_GET[nn];
           AF_WritingSystemClass  writing_system_class =
-            AF_WRITING_SYSTEM_CLASSES_GET[script_class->writing_system];
+            AF_WRITING_SYSTEM_CLASSES_GET[style_class->writing_system];
 
 
-          if ( writing_system_class->script_metrics_done )
-            writing_system_class->script_metrics_done( globals->metrics[nn] );
+          if ( writing_system_class->style_metrics_done )
+            writing_system_class->style_metrics_done( globals->metrics[nn] );
 
           FT_FREE( globals->metrics[nn] );
         }
       }
 
-      globals->glyph_count   = 0;
-      globals->glyph_scripts = NULL;  /* no need to free this one! */
-      globals->face          = NULL;
+#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
+      hb_font_destroy( globals->hb_font );
+      globals->hb_font = NULL;
+#endif
+
+      globals->glyph_count  = 0;
+      globals->glyph_styles = NULL;  /* no need to free this one! */
+      globals->face         = NULL;
 
       FT_FREE( globals );
     }
@@ -254,16 +383,16 @@
 
 
   FT_LOCAL_DEF( FT_Error )
-  af_face_globals_get_metrics( AF_FaceGlobals     globals,
-                               FT_UInt            gindex,
-                               FT_UInt            options,
-                               AF_ScriptMetrics  *ametrics )
+  af_face_globals_get_metrics( AF_FaceGlobals    globals,
+                               FT_UInt           gindex,
+                               FT_UInt           options,
+                               AF_StyleMetrics  *ametrics )
   {
-    AF_ScriptMetrics  metrics = NULL;
+    AF_StyleMetrics  metrics = NULL;
 
-    AF_Script              script = (AF_Script)( options & 15 );
+    AF_Style               style = (AF_Style)options;
     AF_WritingSystemClass  writing_system_class;
-    AF_ScriptClass         script_class;
+    AF_StyleClass          style_class;
 
     FT_Error  error = FT_Err_Ok;
 
@@ -274,44 +403,44 @@
       goto Exit;
     }
 
-    /* if we have a forced script (via `options'), use it, */
-    /* otherwise look into `glyph_scripts' array           */
-    if ( script == AF_SCRIPT_NONE || script + 1 >= AF_SCRIPT_MAX )
-      script = (AF_Script)( globals->glyph_scripts[gindex] &
-                            AF_SCRIPT_UNASSIGNED           );
+    /* if we have a forced style (via `options'), use it, */
+    /* otherwise look into `glyph_styles' array           */
+    if ( style == AF_STYLE_NONE_DFLT || style + 1 >= AF_STYLE_MAX )
+      style = (AF_Style)( globals->glyph_styles[gindex] &
+                          AF_STYLE_UNASSIGNED           );
 
-    script_class         = AF_SCRIPT_CLASSES_GET[script];
+    style_class          = AF_STYLE_CLASSES_GET[style];
     writing_system_class = AF_WRITING_SYSTEM_CLASSES_GET
-                             [script_class->writing_system];
+                             [style_class->writing_system];
 
-    metrics = globals->metrics[script];
+    metrics = globals->metrics[style];
     if ( metrics == NULL )
     {
       /* create the global metrics object if necessary */
       FT_Memory  memory = globals->face->memory;
 
 
-      if ( FT_ALLOC( metrics, writing_system_class->script_metrics_size ) )
+      if ( FT_ALLOC( metrics, writing_system_class->style_metrics_size ) )
         goto Exit;
 
-      metrics->script_class = script_class;
-      metrics->globals      = globals;
+      metrics->style_class = style_class;
+      metrics->globals     = globals;
 
-      if ( writing_system_class->script_metrics_init )
+      if ( writing_system_class->style_metrics_init )
       {
-        error = writing_system_class->script_metrics_init( metrics,
-                                                           globals->face );
+        error = writing_system_class->style_metrics_init( metrics,
+                                                          globals->face );
         if ( error )
         {
-          if ( writing_system_class->script_metrics_done )
-            writing_system_class->script_metrics_done( metrics );
+          if ( writing_system_class->style_metrics_done )
+            writing_system_class->style_metrics_done( metrics );
 
           FT_FREE( metrics );
           goto Exit;
         }
       }
 
-      globals->metrics[script] = metrics;
+      globals->metrics[style] = metrics;
     }
 
   Exit:
@@ -326,7 +455,7 @@
                             FT_UInt         gindex )
   {
     if ( gindex < (FT_ULong)globals->glyph_count )
-      return (FT_Bool)( globals->glyph_scripts[gindex] & AF_DIGIT );
+      return (FT_Bool)( globals->glyph_styles[gindex] & AF_DIGIT );
 
     return (FT_Bool)0;
   }
diff --git a/src/autofit/afglobal.h b/src/autofit/afglobal.h
index c01b474..38d8d69 100644
--- a/src/autofit/afglobal.h
+++ b/src/autofit/afglobal.h
@@ -5,7 +5,7 @@
 /*    Auto-fitter routines to compute global hinting values                */
 /*    (specification).                                                     */
 /*                                                                         */
-/*  Copyright 2003-2005, 2007, 2009, 2011-2013 by                          */
+/*  Copyright 2003-2005, 2007, 2009, 2011-2014 by                          */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -23,6 +23,7 @@
 
 #include "aftypes.h"
 #include "afmodule.h"
+#include "hbshim.h"
 
 
 FT_BEGIN_HEADER
@@ -31,29 +32,50 @@
   FT_LOCAL_ARRAY( AF_WritingSystemClass )
   af_writing_system_classes[];
 
+
+#undef  SCRIPT
+#define SCRIPT( s, S, d, h, sc1, sc2, sc3 )                    \
+          AF_DECLARE_SCRIPT_CLASS( af_ ## s ## _script_class )
+
+#include "afscript.h"
+
   FT_LOCAL_ARRAY( AF_ScriptClass )
   af_script_classes[];
 
+
+#undef  STYLE
+#define STYLE( s, S, d, ws, sc, ss, c )                      \
+          AF_DECLARE_STYLE_CLASS( af_ ## s ## _style_class )
+
+#include "afstyles.h"
+
+  FT_LOCAL_ARRAY( AF_StyleClass )
+  af_style_classes[];
+
+
 #ifdef FT_DEBUG_LEVEL_TRACE
   FT_LOCAL_ARRAY( char* )
-  af_script_names[];
+  af_style_names[];
 #endif
 
+
   /*
    *  Default values and flags for both autofitter globals (found in
    *  AF_ModuleRec) and face globals (in AF_FaceGlobalsRec).
    */
 
-  /* index of fallback script in `af_script_classes' */
+  /* index of fallback style in `af_style_classes' */
 #ifdef AF_CONFIG_OPTION_CJK
-#define AF_SCRIPT_FALLBACK  AF_SCRIPT_HANI
+#define AF_STYLE_FALLBACK    AF_STYLE_HANI_DFLT
 #else
-#define AF_SCRIPT_FALLBACK  AF_SCRIPT_NONE
+#define AF_STYLE_FALLBACK    AF_STYLE_NONE_DFLT
 #endif
+  /* default script for OpenType; ignored if HarfBuzz isn't used */
+#define AF_SCRIPT_DEFAULT    AF_SCRIPT_LATN
   /* a bit mask indicating an uncovered glyph        */
-#define AF_SCRIPT_UNASSIGNED  0x7F
+#define AF_STYLE_UNASSIGNED  0x7F
   /* if this flag is set, we have an ASCII digit     */
-#define AF_DIGIT              0x80
+#define AF_DIGIT             0x80
 
   /* `increase-x-height' property */
 #define AF_PROP_INCREASE_X_HEIGHT_MIN  6
@@ -70,29 +92,33 @@
 
 
   /*
-   *  Note that glyph_scripts[] maps each glyph to an index into the
-   *  `af_script_classes' array.
+   *  Note that glyph_styles[] maps each glyph to an index into the
+   *  `af_style_classes' array.
    *
    */
   typedef struct  AF_FaceGlobalsRec_
   {
-    FT_Face           face;
-    FT_Long           glyph_count;    /* same as face->num_glyphs */
-    FT_Byte*          glyph_scripts;
+    FT_Face          face;
+    FT_Long          glyph_count;    /* same as face->num_glyphs */
+    FT_Byte*         glyph_styles;
+
+#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
+    hb_font_t*       hb_font;
+#endif
 
     /* per-face auto-hinter properties */
-    FT_UInt           increase_x_height;
+    FT_UInt          increase_x_height;
 
-    AF_ScriptMetrics  metrics[AF_SCRIPT_MAX];
+    AF_StyleMetrics  metrics[AF_STYLE_MAX];
 
-    AF_Module         module;         /* to access global properties */
+    AF_Module        module;         /* to access global properties */
 
   } AF_FaceGlobalsRec;
 
 
   /*
    *  model the global hints data for a given face, decomposed into
-   *  script-specific items
+   *  style-specific items
    */
 
   FT_LOCAL( FT_Error )
@@ -101,10 +127,10 @@
                        AF_Module        module );
 
   FT_LOCAL( FT_Error )
-  af_face_globals_get_metrics( AF_FaceGlobals     globals,
-                               FT_UInt            gindex,
-                               FT_UInt            options,
-                               AF_ScriptMetrics  *ametrics );
+  af_face_globals_get_metrics( AF_FaceGlobals    globals,
+                               FT_UInt           gindex,
+                               FT_UInt           options,
+                               AF_StyleMetrics  *ametrics );
 
   FT_LOCAL( void )
   af_face_globals_free( AF_FaceGlobals  globals );
diff --git a/src/autofit/afhints.c b/src/autofit/afhints.c
index ce504cc..88a97d4 100644
--- a/src/autofit/afhints.c
+++ b/src/autofit/afhints.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auto-fitter hinting routines (body).                                 */
 /*                                                                         */
-/*  Copyright 2003-2007, 2009-2013 by                                      */
+/*  Copyright 2003-2007, 2009-2014 by                                      */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -345,7 +345,9 @@
   af_glyph_hints_get_segment_offset( AF_GlyphHints  hints,
                                      FT_Int         dimension,
                                      FT_Int         idx,
-                                     FT_Pos*        offset )
+                                     FT_Pos        *offset,
+                                     FT_Bool       *is_blue,
+                                     FT_Pos        *blue_offset )
   {
     AF_Dimension  dim;
     AF_AxisHints  axis;
@@ -362,9 +364,18 @@
     if ( idx < 0 || idx >= axis->num_segments )
       return FT_THROW( Invalid_Argument );
 
-    seg     = &axis->segments[idx];
-    *offset = ( dim == AF_DIMENSION_HORZ ) ? seg->first->ox
-                                           : seg->first->oy;
+    seg      = &axis->segments[idx];
+    *offset  = ( dim == AF_DIMENSION_HORZ ) ? seg->first->ox
+                                            : seg->first->oy;
+    if ( seg->edge )
+      *is_blue = (FT_Bool)( seg->edge->blue_edge != 0 );
+    else
+      *is_blue = FALSE;
+
+    if ( *is_blue )
+      *blue_offset = seg->edge->blue_edge->cur;
+    else
+      *blue_offset = 0;
 
     return FT_Err_Ok;
   }
@@ -533,8 +544,8 @@
   /* Reset metrics. */
 
   FT_LOCAL_DEF( void )
-  af_glyph_hints_rescale( AF_GlyphHints     hints,
-                          AF_ScriptMetrics  metrics )
+  af_glyph_hints_rescale( AF_GlyphHints    hints,
+                          AF_StyleMetrics  metrics )
   {
     hints->metrics      = metrics;
     hints->scaler_flags = metrics->scaler.flags;
@@ -640,6 +651,9 @@
 
         for ( point = points; point < point_limit; point++, vec++, tag++ )
         {
+          point->in_dir  = (FT_Char)AF_DIR_NONE;
+          point->out_dir = (FT_Char)AF_DIR_NONE;
+
           point->fx = (FT_Short)vec->x;
           point->fy = (FT_Short)vec->y;
           point->ox = point->x = FT_MulFix( vec->x, x_scale ) + x_delta;
@@ -687,91 +701,186 @@
         }
       }
 
-      /* compute directions of in & out vectors */
       {
-        AF_Point      first  = points;
-        AF_Point      prev   = NULL;
-        FT_Pos        in_x   = 0;
-        FT_Pos        in_y   = 0;
-        AF_Direction  in_dir = AF_DIR_NONE;
+        /*
+         *  Compute directions of `in' and `out' vectors.
+         *
+         *  Note that distances between points that are very near to each
+         *  other are accumulated.  In other words, the auto-hinter
+         *  prepends the small vectors between near points to the first
+         *  non-near vector.  All intermediate points are tagged as
+         *  weak; the directions are adjusted also to be equal to the
+         *  accumulated one.
+         */
 
-        FT_Pos  last_good_in_x = 0;
-        FT_Pos  last_good_in_y = 0;
-
+        /* value 20 in `near_limit' is heuristic */
         FT_UInt  units_per_em = hints->metrics->scaler.face->units_per_EM;
         FT_Int   near_limit   = 20 * units_per_em / 2048;
+        FT_Int   near_limit2  = 2 * near_limit - 1;
 
+        AF_Point*  contour;
+        AF_Point*  contour_limit = hints->contours + hints->num_contours;
+
+
+        for ( contour = hints->contours; contour < contour_limit; contour++ )
+        {
+          AF_Point  first = *contour;
+          AF_Point  next, prev, curr;
+
+          FT_Pos  out_x, out_y;
+
+          FT_Bool  is_first;
+
+
+          /* since the first point of a contour could be part of a */
+          /* series of near points, go backwards to find the first */
+          /* non-near point and adjust `first'                     */
+
+          point = first;
+          prev  = first->prev;
+
+          while ( prev != first )
+          {
+            out_x = point->fx - prev->fx;
+            out_y = point->fy - prev->fy;
+
+            /*
+             *  We use Taxicab metrics to measure the vector length.
+             *
+             *  Note that the accumulated distances so far could have the
+             *  opposite direction of the distance measured here.  For this
+             *  reason we use `near_limit2' for the comparison to get a
+             *  non-near point even in the worst case.
+             */
+            if ( FT_ABS( out_x ) + FT_ABS( out_y ) >= near_limit2 )
+              break;
+
+            point = prev;
+            prev  = prev->prev;
+          }
+
+          /* adjust first point */
+          first = point;
+
+          /* now loop over all points of the contour to get */
+          /* `in' and `out' vector directions               */
+
+          curr  = first;
+
+          /*
+           *  We abuse the `u' and `v' fields to store index deltas to the
+           *  next and previous non-near point, respectively.
+           *
+           *  To avoid problems with not having non-near points, we point to
+           *  `first' by default as the next non-near point.
+           *
+           */
+          curr->u  = (FT_Pos)( first - curr );
+          first->v = -curr->u;
+
+          out_x = 0;
+          out_y = 0;
+
+          is_first = 1;
+
+          for ( point = first;
+                point != first || is_first;
+                point = point->next )
+          {
+            AF_Direction  out_dir;
+
+
+            is_first = 0;
+
+            next = point->next;
+
+            out_x += next->fx - point->fx;
+            out_y += next->fy - point->fy;
+
+            if ( FT_ABS( out_x ) + FT_ABS( out_y ) < near_limit )
+            {
+              next->flags |= AF_FLAG_WEAK_INTERPOLATION;
+              continue;
+            }
+
+            curr->u = (FT_Pos)( next - curr );
+            next->v = -curr->u;
+
+            out_dir = af_direction_compute( out_x, out_y );
+
+            /* adjust directions for all points inbetween; */
+            /* the loop also updates position of `curr'    */
+            curr->out_dir = (FT_Char)out_dir;
+            for ( curr = curr->next; curr != next; curr = curr->next )
+            {
+              curr->in_dir  = (FT_Char)out_dir;
+              curr->out_dir = (FT_Char)out_dir;
+            }
+            next->in_dir = (FT_Char)out_dir;
+
+            curr->u  = (FT_Pos)( first - curr );
+            first->v = -curr->u;
+
+            out_x = 0;
+            out_y = 0;
+          }
+        }
+
+        /*
+         *  The next step is to `simplify' an outline's topology so that we
+         *  can identify local extrema more reliably: A series of
+         *  non-horizontal or non-vertical vectors pointing into the same
+         *  quadrant are handled as a single, long vector.  From a
+         *  topological point of the view, the intermediate points are of no
+         *  interest and thus tagged as weak.
+         */
 
         for ( point = points; point < point_limit; point++ )
         {
-          AF_Point  next;
-          FT_Pos    out_x, out_y;
+          if ( point->flags & AF_FLAG_WEAK_INTERPOLATION )
+            continue;
 
-
-          if ( point == first )
+          if ( point->in_dir  == AF_DIR_NONE &&
+               point->out_dir == AF_DIR_NONE )
           {
-            prev = first->prev;
+            /* check whether both vectors point into the same quadrant */
 
-            in_x = first->fx - prev->fx;
-            in_y = first->fy - prev->fy;
+            FT_Pos  in_x, in_y;
+            FT_Pos  out_x, out_y;
 
-            last_good_in_x = in_x;
-            last_good_in_y = in_y;
+            AF_Point  next_u = point + point->u;
+            AF_Point  prev_v = point + point->v;
 
-            if ( FT_ABS( in_x ) + FT_ABS( in_y ) < near_limit )
+
+            in_x = point->fx - prev_v->fx;
+            in_y = point->fy - prev_v->fy;
+
+            out_x = next_u->fx - point->fx;
+            out_y = next_u->fy - point->fy;
+
+            if ( ( in_x ^ out_x ) >= 0 && ( in_y ^ out_y ) >= 0 )
             {
-              /* search first non-near point to get a good `in_dir' value */
+              /* yes, so tag current point as weak */
+              /* and update index deltas           */
 
-              AF_Point  point_ = prev;
+              point->flags |= AF_FLAG_WEAK_INTERPOLATION;
 
-
-              while ( point_ != first )
-              {
-                AF_Point  prev_ = point_->prev;
-
-                FT_Pos  in_x_ = point_->fx - prev_->fx;
-                FT_Pos  in_y_ = point_->fy - prev_->fy;
-
-
-                if ( FT_ABS( in_x_ ) + FT_ABS( in_y_ ) >= near_limit )
-                {
-                  last_good_in_x = in_x_;
-                  last_good_in_y = in_y_;
-
-                  break;
-                }
-
-                point_ = prev_;
-              }
+              prev_v->u = (FT_Pos)( next_u - prev_v );
+              next_u->v = -prev_v->u;
             }
-
-            in_dir = af_direction_compute( in_x, in_y );
-            first  = prev + 1;
           }
+        }
 
-          point->in_dir = (FT_Char)in_dir;
+        /*
+         *  Finally, check for remaining weak points.  Everything else not
+         *  collected in edges so far is then implicitly classified as strong
+         *  points.
+         */
 
-          /* check whether the current point is near to the previous one */
-          /* (value 20 in `near_limit' is heuristic; we use Taxicab      */
-          /* metrics for the test)                                       */
-
-          if ( FT_ABS( in_x ) + FT_ABS( in_y ) < near_limit )
-            point->flags |= AF_FLAG_NEAR;
-          else
-          {
-            last_good_in_x = in_x;
-            last_good_in_y = in_y;
-          }
-
-          next  = point->next;
-          out_x = next->fx - point->fx;
-          out_y = next->fy - point->fy;
-
-          in_dir         = af_direction_compute( out_x, out_y );
-          point->out_dir = (FT_Char)in_dir;
-
-          /* Check for weak points.  The remaining points not collected */
-          /* in edges are then implicitly classified as strong points.  */
+        for ( point = points; point < point_limit; point++ )
+        {
+          if ( point->flags & AF_FLAG_WEAK_INTERPOLATION )
+            continue;
 
           if ( point->flags & AF_FLAG_CONTROL )
           {
@@ -788,18 +897,25 @@
               goto Is_Weak_Point;
             }
 
-            /* test whether `in' and `out' direction is approximately */
-            /* the same (and use the last good `in' vector in case    */
-            /* the current point is near to the previous one)         */
-            if ( ft_corner_is_flat(
-                   point->flags & AF_FLAG_NEAR ? last_good_in_x : in_x,
-                   point->flags & AF_FLAG_NEAR ? last_good_in_y : in_y,
-                   out_x,
-                   out_y ) )
             {
-              /* current point lies on a straight, diagonal line */
-              /* (more or less)                                  */
-              goto Is_Weak_Point;
+              AF_Point  next_u = point + point->u;
+              AF_Point  prev_v = point + point->v;
+
+
+              if ( ft_corner_is_flat( point->fx  - prev_v->fx,
+                                      point->fy  - prev_v->fy,
+                                      next_u->fx - point->fx,
+                                      next_u->fy - point->fy ) )
+              {
+                /* either the `in' or the `out' vector is much more  */
+                /* dominant than the other one, so tag current point */
+                /* as weak and update index deltas                   */
+
+                prev_v->u = (FT_Pos)( next_u - prev_v );
+                next_u->v = -prev_v->u;
+
+                goto Is_Weak_Point;
+              }
             }
           }
           else if ( point->in_dir == -point->out_dir )
@@ -807,10 +923,6 @@
             /* current point forms a spike */
             goto Is_Weak_Point;
           }
-
-          in_x = out_x;
-          in_y = out_y;
-          prev = point;
         }
       }
     }
@@ -1224,8 +1336,6 @@
       }
     }
 
-    point = points;
-
     for ( ; contour < contour_limit; contour++ )
     {
       AF_Point  first_touched, last_touched;
@@ -1248,7 +1358,6 @@
       }
 
       first_touched = point;
-      last_touched  = point;
 
       for (;;)
       {
diff --git a/src/autofit/afhints.h b/src/autofit/afhints.h
index ce52325..c0ebd0d 100644
--- a/src/autofit/afhints.h
+++ b/src/autofit/afhints.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auto-fitter hinting routines (specification).                        */
 /*                                                                         */
-/*  Copyright 2003-2008, 2010-2012 by                                      */
+/*  Copyright 2003-2008, 2010-2012, 2014 by                                */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -27,7 +27,7 @@
 
   /*
    *  The definition of outline glyph hints.  These are shared by all
-   *  script analysis routines (until now).
+   *  writing system analysis routines (until now).
    */
 
   typedef enum  AF_Dimension_
@@ -236,10 +236,7 @@
     AF_FLAG_WEAK_INTERPOLATION = 1 << 8,
 
     /* all inflection points in the outline have this flag set */
-    AF_FLAG_INFLECTION = 1 << 9,
-
-    /* the current point is very near to another one */
-    AF_FLAG_NEAR = 1 << 10
+    AF_FLAG_INFLECTION = 1 << 9
 
   } AF_Flags;
 
@@ -247,10 +244,11 @@
   /* edge hint flags */
   typedef enum  AF_Edge_Flags_
   {
-    AF_EDGE_NORMAL = 0,
-    AF_EDGE_ROUND  = 1 << 0,
-    AF_EDGE_SERIF  = 1 << 1,
-    AF_EDGE_DONE   = 1 << 2
+    AF_EDGE_NORMAL  = 0,
+    AF_EDGE_ROUND   = 1 << 0,
+    AF_EDGE_SERIF   = 1 << 1,
+    AF_EDGE_DONE    = 1 << 2,
+    AF_EDGE_NEUTRAL = 1 << 3  /* set if edge aligns to a neutral blue zone */
 
   } AF_Edge_Flags;
 
@@ -343,31 +341,31 @@
 
   typedef struct  AF_GlyphHintsRec_
   {
-    FT_Memory         memory;
+    FT_Memory        memory;
 
-    FT_Fixed          x_scale;
-    FT_Pos            x_delta;
+    FT_Fixed         x_scale;
+    FT_Pos           x_delta;
 
-    FT_Fixed          y_scale;
-    FT_Pos            y_delta;
+    FT_Fixed         y_scale;
+    FT_Pos           y_delta;
 
-    FT_Int            max_points;    /* number of allocated points */
-    FT_Int            num_points;    /* number of used points      */
-    AF_Point          points;        /* points array               */
+    FT_Int           max_points;    /* number of allocated points */
+    FT_Int           num_points;    /* number of used points      */
+    AF_Point         points;        /* points array               */
 
-    FT_Int            max_contours;  /* number of allocated contours */
-    FT_Int            num_contours;  /* number of used contours      */
-    AF_Point*         contours;      /* contours array               */
+    FT_Int           max_contours;  /* number of allocated contours */
+    FT_Int           num_contours;  /* number of used contours      */
+    AF_Point*        contours;      /* contours array               */
 
-    AF_AxisHintsRec   axis[AF_DIMENSION_MAX];
+    AF_AxisHintsRec  axis[AF_DIMENSION_MAX];
 
-    FT_UInt32         scaler_flags;  /* copy of scaler flags     */
-    FT_UInt32         other_flags;   /* free for script-specific */
-                                     /* implementations          */
-    AF_ScriptMetrics  metrics;
+    FT_UInt32        scaler_flags;  /* copy of scaler flags    */
+    FT_UInt32        other_flags;   /* free for style-specific */
+                                    /* implementations         */
+    AF_StyleMetrics  metrics;
 
-    FT_Pos            xmin_delta;    /* used for warping */
-    FT_Pos            xmax_delta;
+    FT_Pos           xmin_delta;    /* used for warping */
+    FT_Pos           xmax_delta;
 
   } AF_GlyphHintsRec;
 
@@ -429,8 +427,8 @@
                        FT_Memory      memory );
 
   FT_LOCAL( void )
-  af_glyph_hints_rescale( AF_GlyphHints     hints,
-                          AF_ScriptMetrics  metrics );
+  af_glyph_hints_rescale( AF_GlyphHints    hints,
+                          AF_StyleMetrics  metrics );
 
   FT_LOCAL( FT_Error )
   af_glyph_hints_reload( AF_GlyphHints  hints,
diff --git a/src/autofit/afindic.c b/src/autofit/afindic.c
index ef8299f..197881b 100644
--- a/src/autofit/afindic.c
+++ b/src/autofit/afindic.c
@@ -2,7 +2,7 @@
 /*                                                                         */
 /*  afindic.c                                                              */
 /*                                                                         */
-/*    Auto-fitter hinting routines for Indic scripts (body).               */
+/*    Auto-fitter hinting routines for Indic writing system (body).        */
 /*                                                                         */
 /*  Copyright 2007, 2011-2013 by                                           */
 /*  Rahul Bhalerao <rahul.bhalerao@redhat.com>, <b.rahul.pm@gmail.com>.    */
@@ -104,32 +104,18 @@
 
     sizeof ( AF_CJKMetricsRec ),
 
-    (AF_Script_InitMetricsFunc) af_indic_metrics_init,
-    (AF_Script_ScaleMetricsFunc)af_indic_metrics_scale,
-    (AF_Script_DoneMetricsFunc) NULL,
+    (AF_WritingSystem_InitMetricsFunc) af_indic_metrics_init,
+    (AF_WritingSystem_ScaleMetricsFunc)af_indic_metrics_scale,
+    (AF_WritingSystem_DoneMetricsFunc) NULL,
 
-    (AF_Script_InitHintsFunc)   af_indic_hints_init,
-    (AF_Script_ApplyHintsFunc)  af_indic_hints_apply
+    (AF_WritingSystem_InitHintsFunc)   af_indic_hints_init,
+    (AF_WritingSystem_ApplyHintsFunc)  af_indic_hints_apply
   )
 
-  /* XXX: this should probably fine tuned to differentiate better between */
-  /*      scripts...                                                      */
-
-  static const AF_Script_UniRangeRec  af_deva_uniranges[] =
-  {
-    AF_UNIRANGE_REC(  0x0900UL,  0x0DFFUL ),  /* Indic Range  */
-    AF_UNIRANGE_REC(  0x0F00UL,  0x0FFFUL ),  /* Tibetan      */
-    AF_UNIRANGE_REC(  0x1900UL,  0x194FUL ),  /* Limbu        */
-    AF_UNIRANGE_REC(  0x1B80UL,  0x1BBFUL ),  /* Sundanese    */
-    AF_UNIRANGE_REC(  0x1C80UL,  0x1CDFUL ),  /* Meetei Mayak */
-    AF_UNIRANGE_REC(  0xA800UL,  0xA82FUL ),  /* Syloti Nagri */
-    AF_UNIRANGE_REC( 0x11800UL, 0x118DFUL ),  /* Sharada      */
-    AF_UNIRANGE_REC(       0UL,       0UL )
-  };
-
 
 #else /* !AF_CONFIG_OPTION_INDIC */
 
+
   AF_DEFINE_WRITING_SYSTEM_CLASS(
     af_indic_writing_system_class,
 
@@ -137,33 +123,16 @@
 
     sizeof ( AF_CJKMetricsRec ),
 
-    (AF_Script_InitMetricsFunc) NULL,
-    (AF_Script_ScaleMetricsFunc)NULL,
-    (AF_Script_DoneMetricsFunc) NULL,
+    (AF_WritingSystem_InitMetricsFunc) NULL,
+    (AF_WritingSystem_ScaleMetricsFunc)NULL,
+    (AF_WritingSystem_DoneMetricsFunc) NULL,
 
-    (AF_Script_InitHintsFunc)   NULL,
-    (AF_Script_ApplyHintsFunc)  NULL
+    (AF_WritingSystem_InitHintsFunc)   NULL,
+    (AF_WritingSystem_ApplyHintsFunc)  NULL
   )
 
 
-  static const AF_Script_UniRangeRec  af_deva_uniranges[] =
-  {
-    AF_UNIRANGE_REC( 0UL, 0UL )
-  };
-
 #endif /* !AF_CONFIG_OPTION_INDIC */
 
 
-  AF_DEFINE_SCRIPT_CLASS(
-    af_deva_script_class,
-
-    AF_SCRIPT_DEVA,
-    (AF_Blue_Stringset)0, /* XXX */
-    AF_WRITING_SYSTEM_INDIC,
-
-    af_deva_uniranges,
-    'o' /* XXX */
-  )
-
-
 /* END */
diff --git a/src/autofit/afindic.h b/src/autofit/afindic.h
index db38e96..9e13cf7 100644
--- a/src/autofit/afindic.h
+++ b/src/autofit/afindic.h
@@ -2,7 +2,8 @@
 /*                                                                         */
 /*  afindic.h                                                              */
 /*                                                                         */
-/*    Auto-fitter hinting routines for Indic scripts (specification).      */
+/*    Auto-fitter hinting routines for Indic writing system                */
+/*    (specification).                                                     */
 /*                                                                         */
 /*  Copyright 2007, 2012, 2013 by                                          */
 /*  Rahul Bhalerao <rahul.bhalerao@redhat.com>, <b.rahul.pm@gmail.com>.    */
@@ -30,11 +31,6 @@
   AF_DECLARE_WRITING_SYSTEM_CLASS( af_indic_writing_system_class )
 
 
-  /* the indic-specific script classes */
-
-  AF_DECLARE_SCRIPT_CLASS( af_deva_script_class )
-
-
 /* */
 
 FT_END_HEADER
diff --git a/src/autofit/aflatin.c b/src/autofit/aflatin.c
index 15a241e..a1f2b33 100644
--- a/src/autofit/aflatin.c
+++ b/src/autofit/aflatin.c
@@ -2,9 +2,9 @@
 /*                                                                         */
 /*  aflatin.c                                                              */
 /*                                                                         */
-/*    Auto-fitter hinting routines for latin script (body).                */
+/*    Auto-fitter hinting routines for latin writing system (body).        */
 /*                                                                         */
-/*  Copyright 2003-2013 by                                                 */
+/*  Copyright 2003-2014 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -21,6 +21,7 @@
 #include FT_INTERNAL_DEBUG_H
 
 #include "afglobal.h"
+#include "afpic.h"
 #include "aflatin.h"
 #include "aferrors.h"
 
@@ -61,10 +62,10 @@
 
 
     FT_TRACE5(( "\n"
-                "latin standard widths computation (script `%s')\n"
-                "=================================================\n"
+                "latin standard widths computation (style `%s')\n"
+                "=====================================================\n"
                 "\n",
-                af_script_names[metrics->root.script_class->script] ));
+                af_style_names[metrics->root.style_class->style] ));
 
     af_glyph_hints_init( hints, face->memory );
 
@@ -73,20 +74,66 @@
 
     {
       FT_Error            error;
-      FT_UInt             glyph_index;
+      FT_ULong            glyph_index;
+      FT_Long             y_offset;
       int                 dim;
       AF_LatinMetricsRec  dummy[1];
       AF_Scaler           scaler = &dummy->root.scaler;
 
+#ifdef FT_CONFIG_OPTION_PIC
+      AF_FaceGlobals  globals = metrics->root.globals;
+#endif
 
-      glyph_index = FT_Get_Char_Index(
-                      face,
-                      metrics->root.script_class->standard_char );
-      if ( glyph_index == 0 )
-        goto Exit;
+      AF_StyleClass   style_class  = metrics->root.style_class;
+      AF_ScriptClass  script_class = AF_SCRIPT_CLASSES_GET
+                                       [style_class->script];
+
+      FT_UInt32  standard_char;
+
+
+      /*
+       * We check more than a single standard character to catch features
+       * like `c2sc' (small caps from caps) that don't contain lowercase
+       * letters by definition, or other features that mainly operate on
+       * numerals.
+       */
+
+      standard_char = script_class->standard_char1;
+      af_get_char_index( &metrics->root,
+                         standard_char,
+                         &glyph_index,
+                         &y_offset );
+      if ( !glyph_index )
+      {
+        if ( script_class->standard_char2 )
+        {
+          standard_char = script_class->standard_char2;
+          af_get_char_index( &metrics->root,
+                             standard_char,
+                             &glyph_index,
+                             &y_offset );
+          if ( !glyph_index )
+          {
+            if ( script_class->standard_char3 )
+            {
+              standard_char = script_class->standard_char3;
+              af_get_char_index( &metrics->root,
+                                 standard_char,
+                                 &glyph_index,
+                                 &y_offset );
+              if ( !glyph_index )
+                goto Exit;
+            }
+            else
+              goto Exit;
+          }
+        }
+        else
+          goto Exit;
+      }
 
       FT_TRACE5(( "standard character: U+%04lX (glyph index %d)\n",
-                  metrics->root.script_class->standard_char, glyph_index ));
+                  standard_char, glyph_index ));
 
       error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE );
       if ( error || face->glyph->outline.n_points <= 0 )
@@ -105,7 +152,7 @@
       scaler->render_mode = FT_RENDER_MODE_NORMAL;
       scaler->flags       = 0;
 
-      af_glyph_hints_rescale( hints, (AF_ScriptMetrics)dummy );
+      af_glyph_hints_rescale( hints, (AF_StyleMetrics)dummy );
 
       error = af_glyph_hints_reload( hints, &face->glyph->outline );
       if ( error )
@@ -124,7 +171,15 @@
         if ( error )
           goto Exit;
 
+        /*
+         *  We assume that the glyphs selected for the stem width
+         *  computation are `featureless' enough so that the linking
+         *  algorithm works fine without adjustments of its scoring
+         *  function.
+         */
         af_latin_hints_link_segments( hints,
+                                      0,
+                                      NULL,
                                       (AF_Dimension)dim );
 
         seg   = axhints->segments;
@@ -214,12 +269,14 @@
     AF_LatinAxis  axis = &metrics->axis[AF_DIMENSION_VERT];
     FT_Outline    outline;
 
-    AF_Blue_Stringset         bss = metrics->root.script_class->blue_stringset;
+    AF_StyleClass  sc = metrics->root.style_class;
+
+    AF_Blue_Stringset         bss = sc->blue_stringset;
     const AF_Blue_StringRec*  bs  = &af_blue_stringsets[bss];
 
 
-    /* we walk over the blue character strings as specified in the  */
-    /* script's entry in the `af_blue_stringset' array              */
+    /* we walk over the blue character strings as specified in the */
+    /* style's entry in the `af_blue_stringset' array              */
 
     FT_TRACE5(( "latin blue zones computation\n"
                 "============================\n"
@@ -249,6 +306,14 @@
             have_flag = 1;
           }
 
+          if ( AF_LATIN_IS_NEUTRAL_BLUE( bs ) )
+          {
+            if ( have_flag )
+              FT_TRACE5(( ", " ));
+            FT_TRACE5(( "neutral" ));
+            have_flag = 1;
+          }
+
           if ( AF_LATIN_IS_X_HEIGHT_BLUE( bs ) )
           {
             if ( have_flag )
@@ -277,7 +342,8 @@
       while ( *p )
       {
         FT_ULong    ch;
-        FT_UInt     glyph_index;
+        FT_ULong    glyph_index;
+        FT_Long     y_offset;
         FT_Pos      best_y;                            /* same as points.y */
         FT_Int      best_point, best_contour_first, best_contour_last;
         FT_Vector*  points;
@@ -287,7 +353,7 @@
         GET_UTF8_CHAR( ch, p );
 
         /* load the character in the face -- skip unknown or empty ones */
-        glyph_index = FT_Get_Char_Index( face, ch );
+        af_get_char_index( &metrics->root, ch, &glyph_index, &y_offset );
         if ( glyph_index == 0 )
         {
           FT_TRACE5(( "  U+%04lX unavailable\n", ch ));
@@ -470,6 +536,13 @@
               FT_Int   last;
               FT_Bool  hit;
 
+              /* we intentionally declare these two variables        */
+              /* outside of the loop since various compilers emit    */
+              /* incorrect warning messages otherwise, talking about */
+              /* `possibly uninitialized variables'                  */
+              FT_Int  p_first = 0;            /* make compiler happy */
+              FT_Int  p_last  = 0;
+
               FT_Bool  left2right;
 
 
@@ -502,7 +575,6 @@
               {
                 FT_Bool  l2r;
                 FT_Pos   d;
-                FT_Int   p_first, p_last;
 
 
                 if ( !hit )
@@ -575,7 +647,10 @@
                       if ( FT_ABS( points[next].x - points[first].x ) <=
                              20 * dist )
                       {
-                        last--;
+                        if ( last > best_contour_first )
+                          last--;
+                        else
+                          last = best_contour_last;
                         break;
                       }
 
@@ -606,6 +681,12 @@
             }
           }
 
+          /* for computing blue zones, we add the y offset as returned */
+          /* by the currently used OpenType feature -- for example,    */
+          /* superscript glyphs might be identical to subscript glyphs */
+          /* with a vertical shift                                     */
+          best_y += y_offset;
+
           FT_TRACE5(( "  U+%04lX: best_y = %5ld", ch, best_y ));
 
           /* now set the `round' flag depending on the segment's kind: */
@@ -629,6 +710,13 @@
                       FT_CURVE_TAG( outline.tags[best_segment_last]  ) !=
                         FT_CURVE_TAG_ON                                   );
 
+          if ( round && AF_LATIN_IS_NEUTRAL_BLUE( bs ) )
+          {
+            /* only use flat segments for a neutral blue zone */
+            FT_TRACE5(( " (round, skipped)\n" ));
+            continue;
+          }
+
           FT_TRACE5(( " (%s)\n", round ? "round" : "flat" ));
         }
 
@@ -699,6 +787,8 @@
       blue->flags = 0;
       if ( AF_LATIN_IS_TOP_BLUE( bs ) )
         blue->flags |= AF_LATIN_BLUE_TOP;
+      if ( AF_LATIN_IS_NEUTRAL_BLUE( bs ) )
+        blue->flags |= AF_LATIN_BLUE_NEUTRAL;
 
       /*
        * The following flag is used later to adjust the y and x scales
@@ -733,10 +823,11 @@
     /* digit `0' is 0x30 in all supported charmaps */
     for ( i = 0x30; i <= 0x39; i++ )
     {
-      FT_UInt  glyph_index;
+      FT_ULong  glyph_index;
+      FT_Long   y_offset;
 
 
-      glyph_index = FT_Get_Char_Index( face, i );
+      af_get_char_index( &metrics->root, i, &glyph_index, &y_offset );
       if ( glyph_index == 0 )
         continue;
 
@@ -879,11 +970,11 @@
 
             FT_TRACE5((
               "af_latin_metrics_scale_dim:"
-              " x height alignment (script `%s'):\n"
+              " x height alignment (style `%s'):\n"
               "                           "
               " vertical scaling changed from %.4f to %.4f (by %d%%)\n"
               "\n",
-              af_script_names[metrics->root.script_class->script],
+              af_style_names[metrics->root.style_class->style],
               axis->org_scale / 65536.0,
               scale / 65536.0,
               ( fitted - scaled ) * 100 / scaled ));
@@ -906,9 +997,9 @@
       metrics->root.scaler.y_delta = delta;
     }
 
-    FT_TRACE5(( "%s widths (script `%s')\n",
+    FT_TRACE5(( "%s widths (style `%s')\n",
                 dim == AF_DIMENSION_HORZ ? "horizontal" : "vertical",
-                af_script_names[metrics->root.script_class->script] ));
+                af_style_names[metrics->root.style_class->style] ));
 
     /* scale the widths */
     for ( nn = 0; nn < axis->width_count; nn++ )
@@ -933,15 +1024,15 @@
 
 #ifdef FT_DEBUG_LEVEL_TRACE
     if ( axis->extra_light )
-      FT_TRACE5(( "`%s' script is extra light (at current resolution)\n"
+      FT_TRACE5(( "`%s' style is extra light (at current resolution)\n"
                   "\n",
-                  af_script_names[metrics->root.script_class->script] ));
+                  af_style_names[metrics->root.style_class->style] ));
 #endif
 
     if ( dim == AF_DIMENSION_VERT )
     {
-      FT_TRACE5(( "blue zones (script `%s')\n",
-                  af_script_names[metrics->root.script_class->script] ));
+      FT_TRACE5(( "blue zones (style `%s')\n",
+                  af_style_names[metrics->root.style_class->style] ));
 
       /* scale the blue zones */
       for ( nn = 0; nn < axis->blue_count; nn++ )
@@ -1277,25 +1368,40 @@
   }
 
 
-  /* Link segments to form stems and serifs. */
+  /* Link segments to form stems and serifs.  If `width_count' and      */
+  /* `widths' are non-zero, use them to fine-tune the scoring function. */
 
   FT_LOCAL_DEF( void )
   af_latin_hints_link_segments( AF_GlyphHints  hints,
+                                FT_UInt        width_count,
+                                AF_WidthRec*   widths,
                                 AF_Dimension   dim )
   {
     AF_AxisHints  axis          = &hints->axis[dim];
     AF_Segment    segments      = axis->segments;
     AF_Segment    segment_limit = segments + axis->num_segments;
-    FT_Pos        len_threshold, len_score;
+    FT_Pos        len_threshold, len_score, dist_score, max_width;
     AF_Segment    seg1, seg2;
 
 
+    if ( width_count )
+      max_width = widths[width_count - 1].org;
+    else
+      max_width = 0;
+
+    /* a heuristic value to set up a minimum value for overlapping */
     len_threshold = AF_LATIN_CONSTANT( hints->metrics, 8 );
     if ( len_threshold == 0 )
       len_threshold = 1;
 
+    /* a heuristic value to weight lengths */
     len_score = AF_LATIN_CONSTANT( hints->metrics, 6000 );
 
+    /* a heuristic value to weight distances (no call to    */
+    /* AF_LATIN_CONSTANT needed, since we work on multiples */
+    /* of the stem width)                                   */
+    dist_score = 3000;
+
     /* now compare each segment to the others */
     for ( seg1 = segments; seg1 < segment_limit; seg1++ )
     {
@@ -1315,10 +1421,9 @@
         if ( seg1->dir + seg2->dir == 0 && pos2 > pos1 )
         {
           /* compute distance between the two segments */
-          FT_Pos  dist = pos2 - pos1;
-          FT_Pos  min  = seg1->min_coord;
-          FT_Pos  max  = seg1->max_coord;
-          FT_Pos  len, score;
+          FT_Pos  min = seg1->min_coord;
+          FT_Pos  max = seg1->max_coord;
+          FT_Pos  len;
 
 
           if ( min < seg2->min_coord )
@@ -1328,15 +1433,49 @@
             max = seg2->max_coord;
 
           /* compute maximum coordinate difference of the two segments */
+          /* (this is, how much they overlap)                          */
           len = max - min;
           if ( len >= len_threshold )
           {
-            /* small coordinate differences cause a higher score, and     */
-            /* segments with a greater distance cause a higher score also */
-            score = dist + len_score / len;
+            /*
+             *  The score is the sum of two demerits indicating the
+             *  `badness' of a fit, measured along the segments' main axis
+             *  and orthogonal to it, respectively.
+             *
+             *  o The less overlapping along the main axis, the worse it
+             *    is, causing a larger demerit.
+             *
+             *  o The nearer the orthogonal distance to a stem width, the
+             *    better it is, causing a smaller demerit.  For simplicity,
+             *    however, we only increase the demerit for values that
+             *    exceed the largest stem width.
+             */
+
+            FT_Pos  dist = pos2 - pos1;
+
+            FT_Pos  dist_demerit, score;
+
+
+            if ( max_width )
+            {
+              /* distance demerits are based on multiples of `max_width'; */
+              /* we scale by 1024 for getting more precision              */
+              FT_Pos  delta = ( dist << 10 ) / max_width - ( 1 << 10 );
+
+
+              if ( delta > 10000 )
+                dist_demerit = 32000;
+              else if ( delta > 0 )
+                dist_demerit = delta * delta / dist_score;
+              else
+                dist_demerit = 0;
+            }
+            else
+              dist_demerit = dist; /* default if no widths available */
+
+            score = dist_demerit + len_score / len;
 
             /* and we search for the smallest score */
-            /* of the sum of the two values         */
             if ( score < seg1->score )
             {
               seg1->score = score;
@@ -1668,6 +1807,8 @@
 
   FT_LOCAL_DEF( FT_Error )
   af_latin_hints_detect_features( AF_GlyphHints  hints,
+                                  FT_UInt        width_count,
+                                  AF_WidthRec*   widths,
                                   AF_Dimension   dim )
   {
     FT_Error  error;
@@ -1676,7 +1817,7 @@
     error = af_latin_hints_compute_segments( hints, dim );
     if ( !error )
     {
-      af_latin_hints_link_segments( hints, dim );
+      af_latin_hints_link_segments( hints, width_count, widths, dim );
 
       error = af_latin_hints_compute_edges( hints, dim );
     }
@@ -1705,8 +1846,9 @@
     for ( ; edge < edge_limit; edge++ )
     {
       FT_UInt   bb;
-      AF_Width  best_blue = NULL;
-      FT_Pos    best_dist;  /* initial threshold */
+      AF_Width  best_blue            = NULL;
+      FT_Bool   best_blue_is_neutral = 0;
+      FT_Pos    best_dist;                 /* initial threshold */
 
 
       /* compute the initial threshold as a fraction of the EM size */
@@ -1720,24 +1862,26 @@
       for ( bb = 0; bb < latin->blue_count; bb++ )
       {
         AF_LatinBlue  blue = latin->blues + bb;
-        FT_Bool       is_top_blue, is_major_dir;
+        FT_Bool       is_top_blue, is_neutral_blue, is_major_dir;
 
 
         /* skip inactive blue zones (i.e., those that are too large) */
         if ( !( blue->flags & AF_LATIN_BLUE_ACTIVE ) )
           continue;
 
-        /* if it is a top zone, check for right edges -- if it is a bottom */
-        /* zone, check for left edges                                      */
-        /*                                                                 */
-        /* of course, that's for TrueType                                  */
-        is_top_blue  = (FT_Byte)( ( blue->flags & AF_LATIN_BLUE_TOP ) != 0 );
-        is_major_dir = FT_BOOL( edge->dir == axis->major_dir );
+        /* if it is a top zone, check for right edges (against the major */
+        /* direction); if it is a bottom zone, check for left edges (in  */
+        /* the major direction) -- this assumes the TrueType convention  */
+        /* for the orientation of contours                               */
+        is_top_blue =
+          (FT_Byte)( ( blue->flags & AF_LATIN_BLUE_TOP ) != 0 );
+        is_neutral_blue =
+          (FT_Byte)( ( blue->flags & AF_LATIN_BLUE_NEUTRAL ) != 0);
+        is_major_dir =
+          FT_BOOL( edge->dir == axis->major_dir );
 
-        /* if it is a top zone, the edge must be against the major    */
-        /* direction; if it is a bottom zone, it must be in the major */
-        /* direction                                                  */
-        if ( is_top_blue ^ is_major_dir )
+        /* neutral blue zones are handled for both directions */
+        if ( is_top_blue ^ is_major_dir || is_neutral_blue )
         {
           FT_Pos  dist;
 
@@ -1750,15 +1894,19 @@
           dist = FT_MulFix( dist, scale );
           if ( dist < best_dist )
           {
-            best_dist = dist;
-            best_blue = &blue->ref;
+            best_dist            = dist;
+            best_blue            = &blue->ref;
+            best_blue_is_neutral = is_neutral_blue;
           }
 
           /* now compare it to the overshoot position and check whether */
           /* the edge is rounded, and whether the edge is over the      */
           /* reference position of a top zone, or under the reference   */
-          /* position of a bottom zone                                  */
-          if ( edge->flags & AF_EDGE_ROUND && dist != 0 )
+          /* position of a bottom zone (provided we don't have a        */
+          /* neutral blue zone)                                         */
+          if ( edge->flags & AF_EDGE_ROUND &&
+               dist != 0                   &&
+               !is_neutral_blue            )
           {
             FT_Bool  is_under_ref = FT_BOOL( edge->fpos < blue->ref.org );
 
@@ -1772,8 +1920,9 @@
               dist = FT_MulFix( dist, scale );
               if ( dist < best_dist )
               {
-                best_dist = dist;
-                best_blue = &blue->shoot;
+                best_dist            = dist;
+                best_blue            = &blue->shoot;
+                best_blue_is_neutral = is_neutral_blue;
               }
             }
           }
@@ -1781,7 +1930,11 @@
       }
 
       if ( best_blue )
+      {
         edge->blue_edge = best_blue;
+        if ( best_blue_is_neutral )
+          edge->flags |= AF_EDGE_NEUTRAL;
+      }
     }
   }
 
@@ -1797,7 +1950,7 @@
     FT_Face         face = metrics->root.scaler.face;
 
 
-    af_glyph_hints_rescale( hints, (AF_ScriptMetrics)metrics );
+    af_glyph_hints_rescale( hints, (AF_StyleMetrics)metrics );
 
     /*
      *  correct x_scale and y_scale if needed, since they may have
@@ -2099,7 +2252,7 @@
 
     FT_TRACE5(( "  LINK: edge %d (opos=%.2f) linked to %.2f,"
                 " dist was %.2f, now %.2f\n",
-                stem_edge-hints->axis[dim].edges, stem_edge->opos / 64.0,
+                stem_edge - hints->axis[dim].edges, stem_edge->opos / 64.0,
                 stem_edge->pos / 64.0, dist / 64.0, fitted_width / 64.0 ));
   }
 
@@ -2148,9 +2301,9 @@
 #endif
 
 
-    FT_TRACE5(( "latin %s edge hinting (script `%s')\n",
+    FT_TRACE5(( "latin %s edge hinting (style `%s')\n",
                 dim == AF_DIMENSION_VERT ? "horizontal" : "vertical",
-                af_script_names[hints->metrics->script_class->script] ));
+                af_style_names[hints->metrics->style_class->style] ));
 
     /* we begin by aligning all stems relative to the blue zone */
     /* if needed -- that's only for horizontal edges            */
@@ -2166,14 +2319,41 @@
         if ( edge->flags & AF_EDGE_DONE )
           continue;
 
-        blue  = edge->blue_edge;
         edge1 = NULL;
         edge2 = edge->link;
 
+        /*
+         *  If a stem contains both a neutral and a non-neutral blue zone,
+         *  skip the neutral one.  Otherwise, outlines with different
+         *  directions might be incorrectly aligned at the same vertical
+         *  position.
+         *
+         *  If we have two neutral blue zones, skip one of them.
+         *
+         */
+        if ( edge->blue_edge && edge2 && edge2->blue_edge )
+        {
+          FT_Byte  neutral  = edge->flags  & AF_EDGE_NEUTRAL;
+          FT_Byte  neutral2 = edge2->flags & AF_EDGE_NEUTRAL;
+
+
+          if ( ( neutral && neutral2 ) || neutral2 )
+          {
+            edge2->blue_edge = NULL;
+            edge2->flags    &= ~AF_EDGE_NEUTRAL;
+          }
+          else if ( neutral )
+          {
+            edge->blue_edge = NULL;
+            edge->flags    &= ~AF_EDGE_NEUTRAL;
+          }
+        }
+
+        blue = edge->blue_edge;
         if ( blue )
           edge1 = edge;
 
-        /* flip edges if the other stem is aligned to a blue zone */
+        /* flip edges if the other edge is aligned to a blue zone */
         else if ( edge2 && edge2->blue_edge )
         {
           blue  = edge2->blue_edge;
@@ -2240,7 +2420,7 @@
       /* this should not happen, but it's better to be safe */
       if ( edge2->blue_edge )
       {
-        FT_TRACE5(( "  ASSERTION FAILED for edge %d\n", edge2-edges ));
+        FT_TRACE5(( "  ASSERTION FAILED for edge %d\n", edge2 - edges ));
 
         af_latin_align_linked_edge( hints, dim, edge2, edge );
         edge->flags |= AF_EDGE_DONE;
@@ -2629,6 +2809,8 @@
     FT_Error  error;
     int       dim;
 
+    AF_LatinAxis  axis;
+
 
     error = af_glyph_hints_reload( hints, outline );
     if ( error )
@@ -2642,14 +2824,22 @@
     if ( AF_HINTS_DO_HORIZONTAL( hints ) )
 #endif
     {
-      error = af_latin_hints_detect_features( hints, AF_DIMENSION_HORZ );
+      axis  = &metrics->axis[AF_DIMENSION_HORZ];
+      error = af_latin_hints_detect_features( hints,
+                                              axis->width_count,
+                                              axis->widths,
+                                              AF_DIMENSION_HORZ );
       if ( error )
         goto Exit;
     }
 
     if ( AF_HINTS_DO_VERTICAL( hints ) )
     {
-      error = af_latin_hints_detect_features( hints, AF_DIMENSION_VERT );
+      axis  = &metrics->axis[AF_DIMENSION_VERT];
+      error = af_latin_hints_detect_features( hints,
+                                              axis->width_count,
+                                              axis->widths,
+                                              AF_DIMENSION_VERT );
       if ( error )
         goto Exit;
 
@@ -2709,111 +2899,12 @@
 
     sizeof ( AF_LatinMetricsRec ),
 
-    (AF_Script_InitMetricsFunc) af_latin_metrics_init,
-    (AF_Script_ScaleMetricsFunc)af_latin_metrics_scale,
-    (AF_Script_DoneMetricsFunc) NULL,
+    (AF_WritingSystem_InitMetricsFunc) af_latin_metrics_init,
+    (AF_WritingSystem_ScaleMetricsFunc)af_latin_metrics_scale,
+    (AF_WritingSystem_DoneMetricsFunc) NULL,
 
-    (AF_Script_InitHintsFunc)   af_latin_hints_init,
-    (AF_Script_ApplyHintsFunc)  af_latin_hints_apply
-  )
-
-
-  /* XXX: this should probably fine tuned to differentiate better between */
-  /*      scripts...                                                      */
-
-  static const AF_Script_UniRangeRec  af_latn_uniranges[] =
-  {
-    AF_UNIRANGE_REC(  0x0020UL,  0x007FUL ),  /* Basic Latin (no control chars) */
-    AF_UNIRANGE_REC(  0x00A0UL,  0x00FFUL ),  /* Latin-1 Supplement (no control chars) */
-    AF_UNIRANGE_REC(  0x0100UL,  0x017FUL ),  /* Latin Extended-A */
-    AF_UNIRANGE_REC(  0x0180UL,  0x024FUL ),  /* Latin Extended-B */
-    AF_UNIRANGE_REC(  0x0250UL,  0x02AFUL ),  /* IPA Extensions */
-    AF_UNIRANGE_REC(  0x02B0UL,  0x02FFUL ),  /* Spacing Modifier Letters */
-    AF_UNIRANGE_REC(  0x0300UL,  0x036FUL ),  /* Combining Diacritical Marks */
-    AF_UNIRANGE_REC(  0x1D00UL,  0x1D7FUL ),  /* Phonetic Extensions */
-    AF_UNIRANGE_REC(  0x1D80UL,  0x1DBFUL ),  /* Phonetic Extensions Supplement */
-    AF_UNIRANGE_REC(  0x1DC0UL,  0x1DFFUL ),  /* Combining Diacritical Marks Supplement */
-    AF_UNIRANGE_REC(  0x1E00UL,  0x1EFFUL ),  /* Latin Extended Additional */
-    AF_UNIRANGE_REC(  0x2000UL,  0x206FUL ),  /* General Punctuation */
-    AF_UNIRANGE_REC(  0x2070UL,  0x209FUL ),  /* Superscripts and Subscripts */
-    AF_UNIRANGE_REC(  0x20A0UL,  0x20CFUL ),  /* Currency Symbols */
-    AF_UNIRANGE_REC(  0x2150UL,  0x218FUL ),  /* Number Forms */
-    AF_UNIRANGE_REC(  0x2460UL,  0x24FFUL ),  /* Enclosed Alphanumerics */
-    AF_UNIRANGE_REC(  0x2C60UL,  0x2C7FUL ),  /* Latin Extended-C */
-    AF_UNIRANGE_REC(  0x2E00UL,  0x2E7FUL ),  /* Supplemental Punctuation */
-    AF_UNIRANGE_REC(  0xA720UL,  0xA7FFUL ),  /* Latin Extended-D */
-    AF_UNIRANGE_REC(  0xFB00UL,  0xFB06UL ),  /* Alphab. Present. Forms (Latin Ligs) */
-    AF_UNIRANGE_REC( 0x1D400UL, 0x1D7FFUL ),  /* Mathematical Alphanumeric Symbols */
-    AF_UNIRANGE_REC( 0x1F100UL, 0x1F1FFUL ),  /* Enclosed Alphanumeric Supplement */
-    AF_UNIRANGE_REC(       0UL,       0UL )
-  };
-
-  static const AF_Script_UniRangeRec  af_grek_uniranges[] =
-  {
-    AF_UNIRANGE_REC(  0x0370UL,  0x03FFUL ),  /* Greek and Coptic */
-    AF_UNIRANGE_REC(  0x1F00UL,  0x1FFFUL ),  /* Greek Extended */
-    AF_UNIRANGE_REC(       0UL,       0UL )
-  };
-
-  static const AF_Script_UniRangeRec  af_cyrl_uniranges[] =
-  {
-    AF_UNIRANGE_REC(  0x0400UL,  0x04FFUL ),  /* Cyrillic */
-    AF_UNIRANGE_REC(  0x0500UL,  0x052FUL ),  /* Cyrillic Supplement */
-    AF_UNIRANGE_REC(  0x2DE0UL,  0x2DFFUL ),  /* Cyrillic Extended-A */
-    AF_UNIRANGE_REC(  0xA640UL,  0xA69FUL ),  /* Cyrillic Extended-B */
-    AF_UNIRANGE_REC(       0UL,       0UL )
-  };
-
-  static const AF_Script_UniRangeRec  af_hebr_uniranges[] =
-  {
-    AF_UNIRANGE_REC(  0x0590UL,  0x05FFUL ),  /* Hebrew */
-    AF_UNIRANGE_REC(  0xFB1DUL,  0xFB4FUL ),  /* Alphab. Present. Forms (Hebrew) */
-    AF_UNIRANGE_REC(       0UL,       0UL )
-  };
-
-
-  AF_DEFINE_SCRIPT_CLASS(
-    af_latn_script_class,
-
-    AF_SCRIPT_LATN,
-    AF_BLUE_STRINGSET_LATN,
-    AF_WRITING_SYSTEM_LATIN,
-
-    af_latn_uniranges,
-    'o'
-  )
-
-  AF_DEFINE_SCRIPT_CLASS(
-    af_grek_script_class,
-
-    AF_SCRIPT_GREK,
-    AF_BLUE_STRINGSET_GREK,
-    AF_WRITING_SYSTEM_LATIN,
-
-    af_grek_uniranges,
-    0x3BF /* ο */
-  )
-
-  AF_DEFINE_SCRIPT_CLASS(
-    af_cyrl_script_class,
-
-    AF_SCRIPT_CYRL,
-    AF_BLUE_STRINGSET_CYRL,
-    AF_WRITING_SYSTEM_LATIN,
-
-    af_cyrl_uniranges,
-    0x43E /* о */
-  )
-
-  AF_DEFINE_SCRIPT_CLASS(
-    af_hebr_script_class,
-
-    AF_SCRIPT_HEBR,
-    AF_BLUE_STRINGSET_HEBR,
-    AF_WRITING_SYSTEM_LATIN,
-
-    af_hebr_uniranges,
-    0x5DD /* ם */
+    (AF_WritingSystem_InitHintsFunc)   af_latin_hints_init,
+    (AF_WritingSystem_ApplyHintsFunc)  af_latin_hints_apply
   )
 
 
diff --git a/src/autofit/aflatin.h b/src/autofit/aflatin.h
index c06cbd9..2c0bfca 100644
--- a/src/autofit/aflatin.h
+++ b/src/autofit/aflatin.h
@@ -2,9 +2,10 @@
 /*                                                                         */
 /*  aflatin.h                                                              */
 /*                                                                         */
-/*    Auto-fitter hinting routines for latin script (specification).       */
+/*    Auto-fitter hinting routines for latin writing system                */
+/*    (specification).                                                     */
 /*                                                                         */
-/*  Copyright 2003-2007, 2009, 2011-2013 by                                */
+/*  Copyright 2003-2007, 2009, 2011-2014 by                                */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -29,17 +30,6 @@
   AF_DECLARE_WRITING_SYSTEM_CLASS( af_latin_writing_system_class )
 
 
-  /* the latin-specific script classes */
-
-  AF_DECLARE_SCRIPT_CLASS( af_cyrl_script_class )
-  AF_DECLARE_SCRIPT_CLASS( af_grek_script_class )
-  AF_DECLARE_SCRIPT_CLASS( af_latn_script_class )
-  AF_DECLARE_SCRIPT_CLASS( af_hebr_script_class )
-#if 0
-  AF_DECLARE_SCRIPT_CLASS( af_armn_script_class )
-#endif
-
-
   /* constants are given with units_per_em == 2048 in mind */
 #define AF_LATIN_CONSTANT( metrics, c )                                      \
   ( ( (c) * (FT_Long)( (AF_LatinMetrics)(metrics) )->units_per_em ) / 2048 )
@@ -56,13 +46,15 @@
 
   /*
    *  The following declarations could be embedded in the file `aflatin.c';
-   *  they have been made semi-public to allow alternate script hinters to
-   *  re-use some of them.
+   *  they have been made semi-public to allow alternate writing system
+   *  hinters to re-use some of them.
    */
 
 
 #define AF_LATIN_IS_TOP_BLUE( b ) \
           ( (b)->properties & AF_BLUE_PROPERTY_LATIN_TOP )
+#define AF_LATIN_IS_NEUTRAL_BLUE( b ) \
+          ( (b)->properties & AF_BLUE_PROPERTY_LATIN_NEUTRAL )
 #define AF_LATIN_IS_X_HEIGHT_BLUE( b ) \
           ( (b)->properties & AF_BLUE_PROPERTY_LATIN_X_HEIGHT )
 #define AF_LATIN_IS_LONG_BLUE( b ) \
@@ -73,10 +65,11 @@
 
   enum
   {
-    AF_LATIN_BLUE_ACTIVE     = 1 << 0,  /* set if zone height is <= 3/4px */
-    AF_LATIN_BLUE_TOP        = 1 << 1,  /* result of AF_LATIN_IS_TOP_BLUE */
-    AF_LATIN_BLUE_ADJUSTMENT = 1 << 2,  /* used for scale adjustment      */
-                                        /* optimization                   */
+    AF_LATIN_BLUE_ACTIVE     = 1 << 0, /* set if zone height is <= 3/4px   */
+    AF_LATIN_BLUE_TOP        = 1 << 1, /* set if we have a top blue zone   */
+    AF_LATIN_BLUE_NEUTRAL    = 1 << 2, /* set if we have neutral blue zone */
+    AF_LATIN_BLUE_ADJUSTMENT = 1 << 3, /* used for scale adjustment        */
+                                       /* optimization                     */
     AF_LATIN_BLUE_FLAG_MAX
   };
 
@@ -113,9 +106,9 @@
 
   typedef struct  AF_LatinMetricsRec_
   {
-    AF_ScriptMetricsRec  root;
-    FT_UInt              units_per_em;
-    AF_LatinAxisRec      axis[AF_DIMENSION_MAX];
+    AF_StyleMetricsRec  root;
+    FT_UInt             units_per_em;
+    AF_LatinAxisRec     axis[AF_DIMENSION_MAX];
 
   } AF_LatinMetricsRec, *AF_LatinMetrics;
 
@@ -171,7 +164,7 @@
 
   /*
    *  The next functions shouldn't normally be exported.  However, other
-   *  scripts might like to use these functions as-is.
+   *  writing systems might like to use these functions as-is.
    */
   FT_LOCAL( FT_Error )
   af_latin_hints_compute_segments( AF_GlyphHints  hints,
@@ -179,6 +172,8 @@
 
   FT_LOCAL( void )
   af_latin_hints_link_segments( AF_GlyphHints  hints,
+                                FT_UInt        width_count,
+                                AF_WidthRec*   widths,
                                 AF_Dimension   dim );
 
   FT_LOCAL( FT_Error )
@@ -187,6 +182,8 @@
 
   FT_LOCAL( FT_Error )
   af_latin_hints_detect_features( AF_GlyphHints  hints,
+                                  FT_UInt        width_count,
+                                  AF_WidthRec*   widths,
                                   AF_Dimension   dim );
 
 /* */
diff --git a/src/autofit/aflatin2.c b/src/autofit/aflatin2.c
index a6d564a..930fa98 100644
--- a/src/autofit/aflatin2.c
+++ b/src/autofit/aflatin2.c
@@ -2,7 +2,7 @@
 /*                                                                         */
 /*  aflatin2.c                                                             */
 /*                                                                         */
-/*    Auto-fitter hinting routines for latin script (body).                */
+/*    Auto-fitter hinting routines for latin writing system (body).        */
 /*                                                                         */
 /*  Copyright 2003-2013 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
@@ -78,7 +78,7 @@
 
       glyph_index = FT_Get_Char_Index(
                       face,
-                      metrics->root.script_class->standard_char );
+                      metrics->root.style_class->standard_char );
       if ( glyph_index == 0 )
         goto Exit;
 
@@ -95,7 +95,7 @@
       scaler->render_mode = FT_RENDER_MODE_NORMAL;
       scaler->flags       = 0;
 
-      af_glyph_hints_rescale( hints, (AF_ScriptMetrics)dummy );
+      af_glyph_hints_rescale( hints, (AF_StyleMetrics)dummy );
 
       error = af_glyph_hints_reload( hints, &face->glyph->outline );
       if ( error )
@@ -1501,7 +1501,7 @@
     FT_Face         face = metrics->root.scaler.face;
 
 
-    af_glyph_hints_rescale( hints, (AF_ScriptMetrics)metrics );
+    af_glyph_hints_rescale( hints, (AF_StyleMetrics)metrics );
 
     /*
      *  correct x_scale and y_scale if needed, since they may have
@@ -2387,61 +2387,12 @@
 
     sizeof ( AF_LatinMetricsRec ),
 
-    (AF_Script_InitMetricsFunc) af_latin2_metrics_init,
-    (AF_Script_ScaleMetricsFunc)af_latin2_metrics_scale,
-    (AF_Script_DoneMetricsFunc) NULL,
+    (AF_WritingSystem_InitMetricsFunc) af_latin2_metrics_init,
+    (AF_WritingSystem_ScaleMetricsFunc)af_latin2_metrics_scale,
+    (AF_WritingSystem_DoneMetricsFunc) NULL,
 
-    (AF_Script_InitHintsFunc)   af_latin2_hints_init,
-    (AF_Script_ApplyHintsFunc)  af_latin2_hints_apply
-  )
-
-
-  /* XXX: this should probably fine tuned to differentiate better between */
-  /*      scripts...                                                      */
-
-  static const AF_Script_UniRangeRec  af_ltn2_uniranges[] =
-  {
-    AF_UNIRANGE_REC(  0x0020UL,  0x007FUL ),  /* Basic Latin (no control chars) */
-    AF_UNIRANGE_REC(  0x00A0UL,  0x00FFUL ),  /* Latin-1 Supplement (no control chars) */
-    AF_UNIRANGE_REC(  0x0100UL,  0x017FUL ),  /* Latin Extended-A */
-    AF_UNIRANGE_REC(  0x0180UL,  0x024FUL ),  /* Latin Extended-B */
-    AF_UNIRANGE_REC(  0x0250UL,  0x02AFUL ),  /* IPA Extensions */
-    AF_UNIRANGE_REC(  0x02B0UL,  0x02FFUL ),  /* Spacing Modifier Letters */
-    AF_UNIRANGE_REC(  0x0300UL,  0x036FUL ),  /* Combining Diacritical Marks */
-    AF_UNIRANGE_REC(  0x0370UL,  0x03FFUL ),  /* Greek and Coptic */
-    AF_UNIRANGE_REC(  0x0400UL,  0x04FFUL ),  /* Cyrillic */
-    AF_UNIRANGE_REC(  0x0500UL,  0x052FUL ),  /* Cyrillic Supplement */
-    AF_UNIRANGE_REC(  0x1D00UL,  0x1D7FUL ),  /* Phonetic Extensions */
-    AF_UNIRANGE_REC(  0x1D80UL,  0x1DBFUL ),  /* Phonetic Extensions Supplement */
-    AF_UNIRANGE_REC(  0x1DC0UL,  0x1DFFUL ),  /* Combining Diacritical Marks Supplement */
-    AF_UNIRANGE_REC(  0x1E00UL,  0x1EFFUL ),  /* Latin Extended Additional */
-    AF_UNIRANGE_REC(  0x1F00UL,  0x1FFFUL ),  /* Greek Extended */
-    AF_UNIRANGE_REC(  0x2000UL,  0x206FUL ),  /* General Punctuation */
-    AF_UNIRANGE_REC(  0x2070UL,  0x209FUL ),  /* Superscripts and Subscripts */
-    AF_UNIRANGE_REC(  0x20A0UL,  0x20CFUL ),  /* Currency Symbols */
-    AF_UNIRANGE_REC(  0x2150UL,  0x218FUL ),  /* Number Forms */
-    AF_UNIRANGE_REC(  0x2460UL,  0x24FFUL ),  /* Enclosed Alphanumerics */
-    AF_UNIRANGE_REC(  0x2C60UL,  0x2C7FUL ),  /* Latin Extended-C */
-    AF_UNIRANGE_REC(  0x2DE0UL,  0x2DFFUL ),  /* Cyrillic Extended-A */
-    AF_UNIRANGE_REC(  0x2E00UL,  0x2E7FUL ),  /* Supplemental Punctuation */
-    AF_UNIRANGE_REC(  0xA640UL,  0xA69FUL ),  /* Cyrillic Extended-B */
-    AF_UNIRANGE_REC(  0xA720UL,  0xA7FFUL ),  /* Latin Extended-D */
-    AF_UNIRANGE_REC(  0xFB00UL,  0xFB06UL ),  /* Alphab. Present. Forms (Latin Ligs) */
-    AF_UNIRANGE_REC( 0x1D400UL, 0x1D7FFUL ),  /* Mathematical Alphanumeric Symbols */
-    AF_UNIRANGE_REC( 0x1F100UL, 0x1F1FFUL ),  /* Enclosed Alphanumeric Supplement */
-    AF_UNIRANGE_REC(       0UL,       0UL )
-  };
-
-
-  AF_DEFINE_SCRIPT_CLASS(
-    af_ltn2_script_class,
-
-    AF_SCRIPT_LTN2,
-    AF_BLUE_STRINGSET_LATN,
-    AF_WRITING_SYSTEM_LATIN2,
-
-    af_ltn2_uniranges,
-    'o'
+    (AF_WritingSystem_InitHintsFunc)   af_latin2_hints_init,
+    (AF_WritingSystem_ApplyHintsFunc)  af_latin2_hints_apply
   )
 
 
diff --git a/src/autofit/aflatin2.h b/src/autofit/aflatin2.h
index f7f6d8d..b5d252a 100644
--- a/src/autofit/aflatin2.h
+++ b/src/autofit/aflatin2.h
@@ -2,7 +2,8 @@
 /*                                                                         */
 /*  aflatin2.h                                                             */
 /*                                                                         */
-/*    Auto-fitter hinting routines for latin script (specification).       */
+/*    Auto-fitter hinting routines for latin writing system                */
+/*    (specification).                                                     */
 /*                                                                         */
 /*  Copyright 2003-2007, 2012, 2013 by                                     */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
@@ -30,17 +31,6 @@
   AF_DECLARE_WRITING_SYSTEM_CLASS( af_latin2_writing_system_class )
 
 
-  /* the latin-specific script classes */
-
-  AF_DECLARE_SCRIPT_CLASS( af_ltn2_script_class )  /* XXX */
-#if 0
-  AF_DECLARE_SCRIPT_CLASS( af_arm2_script_class )
-  AF_DECLARE_SCRIPT_CLASS( af_cyr2_script_class )
-  AF_DECLARE_SCRIPT_CLASS( af_grk2_script_class )
-  AF_DECLARE_SCRIPT_CLASS( af_hbr2_script_class )
-#endif
-
-
 /* */
 
 FT_END_HEADER
diff --git a/src/autofit/afloader.c b/src/autofit/afloader.c
index 400b01e..0fa3c12 100644
--- a/src/autofit/afloader.c
+++ b/src/autofit/afloader.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auto-fitter glyph loading routines (body).                           */
 /*                                                                         */
-/*  Copyright 2003-2009, 2011-2013 by                                      */
+/*  Copyright 2003-2009, 2011-2014 by                                      */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -109,7 +109,7 @@
     FT_Error          error;
     FT_Face           face     = loader->face;
     FT_GlyphLoader    gloader  = loader->gloader;
-    AF_ScriptMetrics  metrics  = loader->metrics;
+    AF_StyleMetrics   metrics  = loader->metrics;
     AF_GlyphHints     hints    = &loader->hints;
     FT_GlyphSlot      slot     = face->glyph;
     FT_Slot_Internal  internal = slot->internal;
@@ -183,17 +183,17 @@
       /* automatic hinting process                                 */
       {
 #ifdef FT_CONFIG_OPTION_PIC
-        AF_FaceGlobals         globals              = loader->globals;
+        AF_FaceGlobals         globals = loader->globals;
 #endif
+        AF_StyleClass          style_class = metrics->style_class;
         AF_WritingSystemClass  writing_system_class =
-                                 AF_WRITING_SYSTEM_CLASSES_GET
-                                   [metrics->script_class->writing_system];
+          AF_WRITING_SYSTEM_CLASSES_GET[style_class->writing_system];
 
 
-        if ( writing_system_class->script_hints_apply )
-          writing_system_class->script_hints_apply( hints,
-                                                    &gloader->current.outline,
-                                                    metrics );
+        if ( writing_system_class->style_hints_apply )
+          writing_system_class->style_hints_apply( hints,
+                                                   &gloader->current.outline,
+                                                   metrics );
       }
 
       /* we now need to adjust the metrics according to the change in */
@@ -318,12 +318,7 @@
           /* recompute subglyph pointer */
           subglyph = gloader->base.subglyphs + num_base_subgs + nn;
 
-          if ( subglyph->flags & FT_SUBGLYPH_FLAG_USE_MY_METRICS )
-          {
-            pp1 = loader->pp1;
-            pp2 = loader->pp2;
-          }
-          else
+          if ( !( subglyph->flags & FT_SUBGLYPH_FLAG_USE_MY_METRICS ) )
           {
             loader->pp1 = pp1;
             loader->pp2 = pp2;
@@ -529,14 +524,14 @@
     error = af_loader_reset( module, face );
     if ( !error )
     {
-      AF_ScriptMetrics  metrics;
-      FT_UInt           options = AF_SCRIPT_NONE;
+      AF_StyleMetrics  metrics;
+      FT_UInt          options = AF_STYLE_NONE_DFLT;
 
 
 #ifdef FT_OPTION_AUTOFIT2
       /* XXX: undocumented hook to activate the latin2 writing system */
       if ( load_flags & ( 1UL << 20 ) )
-        options = AF_SCRIPT_LTN2;
+        options = AF_STYLE_LTN2_DFLT;
 #endif
 
       error = af_face_globals_get_metrics( loader->globals, gindex,
@@ -544,27 +539,27 @@
       if ( !error )
       {
 #ifdef FT_CONFIG_OPTION_PIC
-        AF_FaceGlobals         globals              = loader->globals;
+        AF_FaceGlobals         globals = loader->globals;
 #endif
+        AF_StyleClass          style_class = metrics->style_class;
         AF_WritingSystemClass  writing_system_class =
-                                 AF_WRITING_SYSTEM_CLASSES_GET
-                                   [metrics->script_class->writing_system];
+          AF_WRITING_SYSTEM_CLASSES_GET[style_class->writing_system];
 
 
         loader->metrics = metrics;
 
-        if ( writing_system_class->script_metrics_scale )
-          writing_system_class->script_metrics_scale( metrics, &scaler );
+        if ( writing_system_class->style_metrics_scale )
+          writing_system_class->style_metrics_scale( metrics, &scaler );
         else
           metrics->scaler = scaler;
 
         load_flags |=  FT_LOAD_NO_SCALE | FT_LOAD_IGNORE_TRANSFORM;
         load_flags &= ~FT_LOAD_RENDER;
 
-        if ( writing_system_class->script_hints_init )
+        if ( writing_system_class->style_hints_init )
         {
-          error = writing_system_class->script_hints_init( &loader->hints,
-                                                           metrics );
+          error = writing_system_class->style_hints_init( &loader->hints,
+                                                          metrics );
           if ( error )
             goto Exit;
         }
diff --git a/src/autofit/afloader.h b/src/autofit/afloader.h
index 1f34d17..9601e24 100644
--- a/src/autofit/afloader.h
+++ b/src/autofit/afloader.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auto-fitter glyph loading routines (specification).                  */
 /*                                                                         */
-/*  Copyright 2003-2005, 2011-2012 by                                      */
+/*  Copyright 2003-2005, 2011-2013 by                                      */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -44,7 +44,7 @@
     /* current glyph data */
     FT_GlyphLoader    gloader;
     AF_GlyphHintsRec  hints;
-    AF_ScriptMetrics  metrics;
+    AF_StyleMetrics   metrics;
     FT_Bool           transformed;
     FT_Matrix         trans_matrix;
     FT_Vector         trans_delta;
diff --git a/src/autofit/afmodule.c b/src/autofit/afmodule.c
index b1bb5ee..181cf55 100644
--- a/src/autofit/afmodule.c
+++ b/src/autofit/afmodule.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auto-fitter module implementation (body).                            */
 /*                                                                         */
-/*  Copyright 2003-2006, 2009, 2011-2013 by                                */
+/*  Copyright 2003-2006, 2009, 2011-2014 by                                */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -45,7 +45,7 @@
 #define FT_COMPONENT  trace_afmodule
 
 
-  FT_Error
+  static FT_Error
   af_property_get_face_globals( FT_Face          face,
                                 AF_FaceGlobals*  aglobals,
                                 AF_Module        module )
@@ -60,8 +60,8 @@
     globals = (AF_FaceGlobals)face->autohint.data;
     if ( !globals )
     {
-      /* trigger computation of the global script data */
-      /* in case it hasn't been done yet               */
+      /* trigger computation of the global style data */
+      /* in case it hasn't been done yet              */
       error = af_face_globals_new( face, &globals, module );
       if ( !error )
       {
@@ -79,7 +79,7 @@
   }
 
 
-  FT_Error
+  static FT_Error
   af_property_set( FT_Module    ft_module,
                    const char*  property_name,
                    const void*  value )
@@ -92,8 +92,40 @@
     {
       FT_UInt*  fallback_script = (FT_UInt*)value;
 
+      FT_UInt  ss;
 
-      module->fallback_script = *fallback_script;
+
+      /* We translate the fallback script to a fallback style that uses */
+      /* `fallback-script' as its script and `AF_COVERAGE_NONE' as its  */
+      /* coverage value.                                                */
+      for ( ss = 0; AF_STYLE_CLASSES_GET[ss]; ss++ )
+      {
+        AF_StyleClass  style_class = AF_STYLE_CLASSES_GET[ss];
+
+
+        if ( (FT_UInt)style_class->script == *fallback_script &&
+             style_class->coverage == AF_COVERAGE_DEFAULT     )
+        {
+          module->fallback_style = ss;
+          break;
+        }
+      }
+
+      if ( !AF_STYLE_CLASSES_GET[ss] )
+      {
+        FT_TRACE0(( "af_property_set: Invalid value %d for property `%s'\n",
+                    fallback_script, property_name ));
+        return FT_THROW( Invalid_Argument );
+      }
+
+      return error;
+    }
+    else if ( !ft_strcmp( property_name, "default-script" ) )
+    {
+      FT_UInt*  default_script = (FT_UInt*)value;
+
+
+      module->default_script = *default_script;
 
       return error;
     }
@@ -116,14 +148,15 @@
   }
 
 
-  FT_Error
+  static FT_Error
   af_property_get( FT_Module    ft_module,
                    const char*  property_name,
                    void*        value )
   {
-    FT_Error   error           = FT_Err_Ok;
-    AF_Module  module          = (AF_Module)ft_module;
-    FT_UInt    fallback_script = module->fallback_script;
+    FT_Error   error          = FT_Err_Ok;
+    AF_Module  module         = (AF_Module)ft_module;
+    FT_UInt    fallback_style = module->fallback_style;
+    FT_UInt    default_script = module->default_script;
 
 
     if ( !ft_strcmp( property_name, "glyph-to-script-map" ) )
@@ -134,7 +167,7 @@
 
       error = af_property_get_face_globals( prop->face, &globals, module );
       if ( !error )
-        prop->map = globals->glyph_scripts;
+        prop->map = globals->glyph_styles;
 
       return error;
     }
@@ -142,8 +175,19 @@
     {
       FT_UInt*  val = (FT_UInt*)value;
 
+      AF_StyleClass  style_class = AF_STYLE_CLASSES_GET[fallback_style];
 
-      *val = fallback_script;
+
+      *val = style_class->script;
+
+      return error;
+    }
+    else if ( !ft_strcmp( property_name, "default-script" ) )
+    {
+      FT_UInt*  val = (FT_UInt*)value;
+
+
+      *val = default_script;
 
       return error;
     }
@@ -206,7 +250,8 @@
     AF_Module  module = (AF_Module)ft_module;
 
 
-    module->fallback_script = AF_SCRIPT_FALLBACK;
+    module->fallback_style = AF_STYLE_FALLBACK;
+    module->default_script = AF_SCRIPT_DEFAULT;
 
     return af_loader_init( module );
   }
diff --git a/src/autofit/afmodule.h b/src/autofit/afmodule.h
index c4e8f8f..20b7b9f 100644
--- a/src/autofit/afmodule.h
+++ b/src/autofit/afmodule.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auto-fitter module implementation (specification).                   */
 /*                                                                         */
-/*  Copyright 2003, 2004, 2005 by                                          */
+/*  Copyright 2003-2005, 2009, 2012, 2013 by                               */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -40,7 +40,8 @@
   {
     FT_ModuleRec  root;
 
-    FT_UInt       fallback_script;
+    FT_UInt       fallback_style;
+    FT_UInt       default_script;
 
     AF_LoaderRec  loader[1];
 
diff --git a/src/autofit/afpic.c b/src/autofit/afpic.c
index 92d696d..cb29fd7 100644
--- a/src/autofit/afpic.c
+++ b/src/autofit/afpic.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType position independent code services for autofit module.  */
 /*                                                                         */
-/*  Copyright 2009-2013 by                                                 */
+/*  Copyright 2009-2014 by                                                 */
 /*  Oran Agra and Mickey Gabel.                                            */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -20,6 +20,7 @@
 #include FT_FREETYPE_H
 #include FT_INTERNAL_OBJECTS_H
 #include "afpic.h"
+#include "afglobal.h"
 #include "aferrors.h"
 
 
@@ -42,7 +43,7 @@
     FT_AutoHinter_InterfaceRec*  clazz );
 
 
-  /* forward declaration of PIC init functions from script classes */
+  /* forward declaration of PIC init functions from writing system classes */
 #undef  WRITING_SYSTEM
 #define WRITING_SYSTEM( ws, WS )  /* empty */
 
@@ -97,15 +98,20 @@
 
     FT_Init_Class_af_service_properties( &container->af_service_properties );
 
-    for ( ss = 0; ss < AF_WRITING_SYSTEM_MAX - 1; ss++ )
+    for ( ss = 0; ss < AF_WRITING_SYSTEM_MAX; ss++ )
       container->af_writing_system_classes[ss] =
         &container->af_writing_system_classes_rec[ss];
-    container->af_writing_system_classes[AF_WRITING_SYSTEM_MAX - 1] = NULL;
+    container->af_writing_system_classes[AF_WRITING_SYSTEM_MAX] = NULL;
 
-    for ( ss = 0; ss < AF_SCRIPT_MAX - 1; ss++ )
+    for ( ss = 0; ss < AF_SCRIPT_MAX; ss++ )
       container->af_script_classes[ss] =
         &container->af_script_classes_rec[ss];
-    container->af_script_classes[AF_SCRIPT_MAX - 1] = NULL;
+    container->af_script_classes[AF_SCRIPT_MAX] = NULL;
+
+    for ( ss = 0; ss < AF_STYLE_MAX; ss++ )
+      container->af_style_classes[ss] =
+        &container->af_style_classes_rec[ss];
+    container->af_style_classes[AF_STYLE_MAX] = NULL;
 
 #undef  WRITING_SYSTEM
 #define WRITING_SYSTEM( ws, WS )                             \
@@ -116,13 +122,21 @@
 #include "afwrtsys.h"
 
 #undef  SCRIPT
-#define SCRIPT( s, S, d )                            \
+#define SCRIPT( s, S, d, h, sc1, sc2, sc3 )          \
         FT_Init_Class_af_ ## s ## _script_class(     \
           &container->af_script_classes_rec[ss++] );
 
     ss = 0;
 #include "afscript.h"
 
+#undef  STYLE
+#define STYLE( s, S, d, ws, sc, bss, c )            \
+        FT_Init_Class_af_ ## s ## _style_class(     \
+          &container->af_style_classes_rec[ss++] );
+
+    ss = 0;
+#include "afstyles.h"
+
     FT_Init_Class_af_autofitter_interface(
       library, &container->af_autofitter_interface );
 
diff --git a/src/autofit/afpic.h b/src/autofit/afpic.h
index 09f8258..9a68b4a 100644
--- a/src/autofit/afpic.h
+++ b/src/autofit/afpic.h
@@ -32,6 +32,7 @@
 
 #define AF_WRITING_SYSTEM_CLASSES_GET  af_writing_system_classes
 #define AF_SCRIPT_CLASSES_GET          af_script_classes
+#define AF_STYLE_CLASSES_GET           af_style_classes
 #define AF_INTERFACE_GET               af_autofitter_interface
 
 #else /* FT_CONFIG_OPTION_PIC */
@@ -48,14 +49,19 @@
     FT_Service_PropertiesRec    af_service_properties;
 
     AF_WritingSystemClass       af_writing_system_classes
-                                  [AF_WRITING_SYSTEM_MAX];
+                                  [AF_WRITING_SYSTEM_MAX + 1];
     AF_WritingSystemClassRec    af_writing_system_classes_rec
-                                  [AF_WRITING_SYSTEM_MAX - 1];
+                                  [AF_WRITING_SYSTEM_MAX];
 
     AF_ScriptClass              af_script_classes
-                                  [AF_SCRIPT_MAX];
+                                  [AF_SCRIPT_MAX + 1];
     AF_ScriptClassRec           af_script_classes_rec
-                                  [AF_SCRIPT_MAX - 1];
+                                  [AF_SCRIPT_MAX];
+
+    AF_StyleClass               af_style_classes
+                                  [AF_STYLE_MAX + 1];
+    AF_StyleClassRec            af_style_classes_rec
+                                  [AF_STYLE_MAX];
 
     FT_AutoHinter_InterfaceRec  af_autofitter_interface;
 
@@ -74,6 +80,8 @@
           ( GET_PIC( FT_FACE_LIBRARY( globals->face ) )->af_writing_system_classes )
 #define AF_SCRIPT_CLASSES_GET  \
           ( GET_PIC( FT_FACE_LIBRARY( globals->face ) )->af_script_classes )
+#define AF_STYLE_CLASSES_GET  \
+          ( GET_PIC( FT_FACE_LIBRARY( globals->face ) )->af_style_classes )
 #define AF_INTERFACE_GET  \
           ( GET_PIC( library )->af_autofitter_interface )
 
diff --git a/src/autofit/afranges.c b/src/autofit/afranges.c
new file mode 100644
index 0000000..139a4c1
--- /dev/null
+++ b/src/autofit/afranges.c
@@ -0,0 +1,210 @@
+/***************************************************************************/
+/*                                                                         */
+/*  afranges.c                                                             */
+/*                                                                         */
+/*    Auto-fitter Unicode script ranges (body).                            */
+/*                                                                         */
+/*  Copyright 2013, 2014 by                                                */
+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
+/*                                                                         */
+/*  This file is part of the FreeType project, and may only be used,       */
+/*  modified, and distributed under the terms of the FreeType project      */
+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
+/*  this file you indicate that you have read the license and              */
+/*  understand and accept it fully.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
+#include "afranges.h"
+
+
+  const AF_Script_UniRangeRec  af_cyrl_uniranges[] =
+  {
+    AF_UNIRANGE_REC(  0x0400UL,  0x04FFUL ),  /* Cyrillic            */
+    AF_UNIRANGE_REC(  0x0500UL,  0x052FUL ),  /* Cyrillic Supplement */
+    AF_UNIRANGE_REC(  0x2DE0UL,  0x2DFFUL ),  /* Cyrillic Extended-A */
+    AF_UNIRANGE_REC(  0xA640UL,  0xA69FUL ),  /* Cyrillic Extended-B */
+    AF_UNIRANGE_REC(       0UL,       0UL )
+  };
+
+  const AF_Script_UniRangeRec  af_deva_uniranges[] =
+  {
+    AF_UNIRANGE_REC(  0x0900UL,  0x097FUL ),  /* Devanagari       */
+    AF_UNIRANGE_REC(  0x20B9UL,  0x20B9UL ),  /* (new) Rupee sign */
+    AF_UNIRANGE_REC(       0UL,       0UL )
+  };
+
+  const AF_Script_UniRangeRec  af_grek_uniranges[] =
+  {
+    AF_UNIRANGE_REC(  0x0370UL,  0x03FFUL ),  /* Greek and Coptic */
+    AF_UNIRANGE_REC(  0x1F00UL,  0x1FFFUL ),  /* Greek Extended   */
+    AF_UNIRANGE_REC(       0UL,       0UL )
+  };
+
+  const AF_Script_UniRangeRec  af_hebr_uniranges[] =
+  {
+    AF_UNIRANGE_REC(  0x0590UL,  0x05FFUL ),  /* Hebrew                          */
+    AF_UNIRANGE_REC(  0xFB1DUL,  0xFB4FUL ),  /* Alphab. Present. Forms (Hebrew) */
+    AF_UNIRANGE_REC(       0UL,       0UL )
+  };
+
+  const AF_Script_UniRangeRec  af_latn_uniranges[] =
+  {
+    AF_UNIRANGE_REC(  0x0020UL,  0x007FUL ),  /* Basic Latin (no control chars)         */
+    AF_UNIRANGE_REC(  0x00A0UL,  0x00FFUL ),  /* Latin-1 Supplement (no control chars)  */
+    AF_UNIRANGE_REC(  0x0100UL,  0x017FUL ),  /* Latin Extended-A                       */
+    AF_UNIRANGE_REC(  0x0180UL,  0x024FUL ),  /* Latin Extended-B                       */
+    AF_UNIRANGE_REC(  0x0250UL,  0x02AFUL ),  /* IPA Extensions                         */
+    AF_UNIRANGE_REC(  0x02B0UL,  0x02FFUL ),  /* Spacing Modifier Letters               */
+    AF_UNIRANGE_REC(  0x0300UL,  0x036FUL ),  /* Combining Diacritical Marks            */
+    AF_UNIRANGE_REC(  0x1D00UL,  0x1D7FUL ),  /* Phonetic Extensions                    */
+    AF_UNIRANGE_REC(  0x1D80UL,  0x1DBFUL ),  /* Phonetic Extensions Supplement         */
+    AF_UNIRANGE_REC(  0x1DC0UL,  0x1DFFUL ),  /* Combining Diacritical Marks Supplement */
+    AF_UNIRANGE_REC(  0x1E00UL,  0x1EFFUL ),  /* Latin Extended Additional              */
+    AF_UNIRANGE_REC(  0x2000UL,  0x206FUL ),  /* General Punctuation                    */
+    AF_UNIRANGE_REC(  0x2070UL,  0x209FUL ),  /* Superscripts and Subscripts            */
+    AF_UNIRANGE_REC(  0x20A0UL,  0x20B8UL ),  /* Currency Symbols ...                   */
+    AF_UNIRANGE_REC(  0x20BAUL,  0x20CFUL ),  /* ... except new Rupee sign              */
+    AF_UNIRANGE_REC(  0x2150UL,  0x218FUL ),  /* Number Forms                           */
+    AF_UNIRANGE_REC(  0x2460UL,  0x24FFUL ),  /* Enclosed Alphanumerics                 */
+    AF_UNIRANGE_REC(  0x2C60UL,  0x2C7FUL ),  /* Latin Extended-C                       */
+    AF_UNIRANGE_REC(  0x2E00UL,  0x2E7FUL ),  /* Supplemental Punctuation               */
+    AF_UNIRANGE_REC(  0xA720UL,  0xA7FFUL ),  /* Latin Extended-D                       */
+    AF_UNIRANGE_REC(  0xFB00UL,  0xFB06UL ),  /* Alphab. Present. Forms (Latin Ligs)    */
+    AF_UNIRANGE_REC( 0x1D400UL, 0x1D7FFUL ),  /* Mathematical Alphanumeric Symbols      */
+    AF_UNIRANGE_REC( 0x1F100UL, 0x1F1FFUL ),  /* Enclosed Alphanumeric Supplement       */
+    AF_UNIRANGE_REC(       0UL,       0UL )
+  };
+
+  const AF_Script_UniRangeRec  af_none_uniranges[] =
+  {
+    AF_UNIRANGE_REC( 0UL, 0UL )
+  };
+
+#ifdef AF_CONFIG_OPTION_INDIC
+
+  const AF_Script_UniRangeRec  af_beng_uniranges[] =
+  {
+    AF_UNIRANGE_REC(  0x0980UL,  0x09FFUL ),  /* Bengali */
+    AF_UNIRANGE_REC(       0UL,       0UL )
+  };
+
+  const AF_Script_UniRangeRec  af_gujr_uniranges[] =
+  {
+    AF_UNIRANGE_REC(  0x0A80UL,  0x0AFFUL ),  /* Gujarati */
+    AF_UNIRANGE_REC(       0UL,       0UL )
+  };
+
+  const AF_Script_UniRangeRec  af_guru_uniranges[] =
+  {
+    AF_UNIRANGE_REC(  0x0A00UL,  0x0A7FUL ),  /* Gurmukhi */
+    AF_UNIRANGE_REC(       0UL,       0UL )
+  };
+
+  const AF_Script_UniRangeRec  af_knda_uniranges[] =
+  {
+    AF_UNIRANGE_REC(  0x0C80UL,  0x0CFFUL ),  /* Kannada */
+    AF_UNIRANGE_REC(       0UL,       0UL )
+  };
+
+  const AF_Script_UniRangeRec  af_limb_uniranges[] =
+  {
+    AF_UNIRANGE_REC(  0x1900UL,  0x194FUL ),  /* Limbu */
+    AF_UNIRANGE_REC(       0UL,       0UL )
+  };
+
+  const AF_Script_UniRangeRec  af_mlym_uniranges[] =
+  {
+    AF_UNIRANGE_REC(  0x0D00UL,  0x0D7FUL ),  /* Malayalam */
+    AF_UNIRANGE_REC(       0UL,       0UL )
+  };
+
+  const AF_Script_UniRangeRec  af_orya_uniranges[] =
+  {
+    AF_UNIRANGE_REC(  0x0B00UL,  0x0B7FUL ),  /* Oriya */
+    AF_UNIRANGE_REC(       0UL,       0UL )
+  };
+
+  const AF_Script_UniRangeRec  af_sinh_uniranges[] =
+  {
+    AF_UNIRANGE_REC(  0x0D80UL,  0x0DFFUL ),  /* Sinhala */
+    AF_UNIRANGE_REC(       0UL,       0UL )
+  };
+
+  const AF_Script_UniRangeRec  af_sund_uniranges[] =
+  {
+    AF_UNIRANGE_REC(  0x1B80UL,  0x1BBFUL ),  /* Sundanese */
+    AF_UNIRANGE_REC(       0UL,       0UL )
+  };
+
+  const AF_Script_UniRangeRec  af_sylo_uniranges[] =
+  {
+    AF_UNIRANGE_REC(  0xA800UL,  0xA82FUL ),  /* Syloti Nagri */
+    AF_UNIRANGE_REC(       0UL,       0UL )
+  };
+
+  const AF_Script_UniRangeRec  af_taml_uniranges[] =
+  {
+    AF_UNIRANGE_REC(  0x0B80UL,  0x0BFFUL ),  /* Tamil */
+    AF_UNIRANGE_REC(       0UL,       0UL )
+  };
+
+  const AF_Script_UniRangeRec  af_telu_uniranges[] =
+  {
+    AF_UNIRANGE_REC(  0x0C00UL,  0x0C7FUL ),  /* Telugu */
+    AF_UNIRANGE_REC(       0UL,       0UL )
+  };
+
+  const AF_Script_UniRangeRec  af_tibt_uniranges[] =
+  {
+    AF_UNIRANGE_REC(  0x0F00UL,  0x0FFFUL ),  /* Tibetan */
+    AF_UNIRANGE_REC(       0UL,       0UL )
+  };
+
+#endif /* !AF_CONFIG_OPTION_INDIC */
+
+#ifdef AF_CONFIG_OPTION_CJK
+
+  /* this corresponds to Unicode 6.0 */
+
+  const AF_Script_UniRangeRec  af_hani_uniranges[] =
+  {
+    AF_UNIRANGE_REC(  0x1100UL,  0x11FFUL ),  /* Hangul Jamo                             */
+    AF_UNIRANGE_REC(  0x2E80UL,  0x2EFFUL ),  /* CJK Radicals Supplement                 */
+    AF_UNIRANGE_REC(  0x2F00UL,  0x2FDFUL ),  /* Kangxi Radicals                         */
+    AF_UNIRANGE_REC(  0x2FF0UL,  0x2FFFUL ),  /* Ideographic Description Characters      */
+    AF_UNIRANGE_REC(  0x3000UL,  0x303FUL ),  /* CJK Symbols and Punctuation             */
+    AF_UNIRANGE_REC(  0x3040UL,  0x309FUL ),  /* Hiragana                                */
+    AF_UNIRANGE_REC(  0x30A0UL,  0x30FFUL ),  /* Katakana                                */
+    AF_UNIRANGE_REC(  0x3100UL,  0x312FUL ),  /* Bopomofo                                */
+    AF_UNIRANGE_REC(  0x3130UL,  0x318FUL ),  /* Hangul Compatibility Jamo               */
+    AF_UNIRANGE_REC(  0x3190UL,  0x319FUL ),  /* Kanbun                                  */
+    AF_UNIRANGE_REC(  0x31A0UL,  0x31BFUL ),  /* Bopomofo Extended                       */
+    AF_UNIRANGE_REC(  0x31C0UL,  0x31EFUL ),  /* CJK Strokes                             */
+    AF_UNIRANGE_REC(  0x31F0UL,  0x31FFUL ),  /* Katakana Phonetic Extensions            */
+    AF_UNIRANGE_REC(  0x3200UL,  0x32FFUL ),  /* Enclosed CJK Letters and Months         */
+    AF_UNIRANGE_REC(  0x3300UL,  0x33FFUL ),  /* CJK Compatibility                       */
+    AF_UNIRANGE_REC(  0x3400UL,  0x4DBFUL ),  /* CJK Unified Ideographs Extension A      */
+    AF_UNIRANGE_REC(  0x4DC0UL,  0x4DFFUL ),  /* Yijing Hexagram Symbols                 */
+    AF_UNIRANGE_REC(  0x4E00UL,  0x9FFFUL ),  /* CJK Unified Ideographs                  */
+    AF_UNIRANGE_REC(  0xA960UL,  0xA97FUL ),  /* Hangul Jamo Extended-A                  */
+    AF_UNIRANGE_REC(  0xAC00UL,  0xD7AFUL ),  /* Hangul Syllables                        */
+    AF_UNIRANGE_REC(  0xD7B0UL,  0xD7FFUL ),  /* Hangul Jamo Extended-B                  */
+    AF_UNIRANGE_REC(  0xF900UL,  0xFAFFUL ),  /* CJK Compatibility Ideographs            */
+    AF_UNIRANGE_REC(  0xFE10UL,  0xFE1FUL ),  /* Vertical forms                          */
+    AF_UNIRANGE_REC(  0xFE30UL,  0xFE4FUL ),  /* CJK Compatibility Forms                 */
+    AF_UNIRANGE_REC(  0xFF00UL,  0xFFEFUL ),  /* Halfwidth and Fullwidth Forms           */
+    AF_UNIRANGE_REC( 0x1B000UL, 0x1B0FFUL ),  /* Kana Supplement                         */
+    AF_UNIRANGE_REC( 0x1D300UL, 0x1D35FUL ),  /* Tai Xuan Hing Symbols                   */
+    AF_UNIRANGE_REC( 0x1F200UL, 0x1F2FFUL ),  /* Enclosed Ideographic Supplement         */
+    AF_UNIRANGE_REC( 0x20000UL, 0x2A6DFUL ),  /* CJK Unified Ideographs Extension B      */
+    AF_UNIRANGE_REC( 0x2A700UL, 0x2B73FUL ),  /* CJK Unified Ideographs Extension C      */
+    AF_UNIRANGE_REC( 0x2B740UL, 0x2B81FUL ),  /* CJK Unified Ideographs Extension D      */
+    AF_UNIRANGE_REC( 0x2F800UL, 0x2FA1FUL ),  /* CJK Compatibility Ideographs Supplement */
+    AF_UNIRANGE_REC(       0UL,       0UL )
+  };
+
+#endif /* !AF_CONFIG_OPTION_CJK */
+
+/* END */
diff --git a/src/autofit/afranges.h b/src/autofit/afranges.h
new file mode 100644
index 0000000..fe5b2aa
--- /dev/null
+++ b/src/autofit/afranges.h
@@ -0,0 +1,41 @@
+/***************************************************************************/
+/*                                                                         */
+/*  afranges.h                                                             */
+/*                                                                         */
+/*    Auto-fitter Unicode script ranges (specification).                   */
+/*                                                                         */
+/*  Copyright 2013, 2014 by                                                */
+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
+/*                                                                         */
+/*  This file is part of the FreeType project, and may only be used,       */
+/*  modified, and distributed under the terms of the FreeType project      */
+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
+/*  this file you indicate that you have read the license and              */
+/*  understand and accept it fully.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
+#ifndef __AFRANGES_H__
+#define __AFRANGES_H__
+
+
+#include "aftypes.h"
+
+
+FT_BEGIN_HEADER
+
+#undef  SCRIPT
+#define SCRIPT( s, S, d, h, sc1, sc2, sc3 )                             \
+          extern const AF_Script_UniRangeRec  af_ ## s ## _uniranges[];
+
+#include "afscript.h"
+
+ /* */
+
+FT_END_HEADER
+
+#endif /* __AFRANGES_H__ */
+
+
+/* END */
diff --git a/src/autofit/afscript.h b/src/autofit/afscript.h
index 32ec2ca..a418b05 100644
--- a/src/autofit/afscript.h
+++ b/src/autofit/afscript.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auto-fitter scripts (specification only).                            */
 /*                                                                         */
-/*  Copyright 2013 by                                                      */
+/*  Copyright 2013, 2014 by                                                */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -20,18 +20,119 @@
   /* Define `SCRIPT' as needed.                         */
 
 
-  /* Add new scripts here. */
+  /* Add new scripts here.  The first and second arguments are the    */
+  /* script name in lowercase and uppercase, respectively, followed   */
+  /* by a description string.  Then comes the corresponding HarfBuzz  */
+  /* script name tag, followed by a string of standard characters (to */
+  /* derive the standard width and height of stems).                  */
 
-  SCRIPT( cyrl, CYRL, "Cyrillic" )
-  SCRIPT( deva, DEVA, "Indic scripts" )
-  SCRIPT( none, NONE, "no script" )
-  SCRIPT( grek, GREK, "Greek" )
-  SCRIPT( hani, HANI, "CJKV ideographs" )
-  SCRIPT( hebr, HEBR, "Hebrew" )
-  SCRIPT( latn, LATN, "Latin" )
-#ifdef FT_OPTION_AUTOFIT2
-  SCRIPT( ltn2, LTN2, "Latin 2" )
-#endif
+  SCRIPT( cyrl, CYRL,
+          "Cyrillic",
+          HB_SCRIPT_CYRILLIC,
+          0x43E, 0x41E, 0x0 ) /* оО */
+
+  SCRIPT( deva, DEVA,
+          "Devanagari",
+          HB_SCRIPT_DEVANAGARI,
+          0x920, 0x935, 0x91F ) /* ठ व ट */
+
+  SCRIPT( grek, GREK,
+          "Greek",
+          HB_SCRIPT_GREEK,
+          0x3BF, 0x39F, 0x0 ) /* οΟ */
+
+  SCRIPT( hebr, HEBR,
+          "Hebrew",
+          HB_SCRIPT_HEBREW,
+          0x5DD, 0x0, 0x0 ) /* ם */
+
+  SCRIPT( latn, LATN,
+          "Latin",
+          HB_SCRIPT_LATIN,
+          'o', 'O', '0' )
+
+  SCRIPT( none, NONE,
+          "no script",
+          HB_SCRIPT_INVALID,
+          0x0, 0x0, 0x0 )
+
+#ifdef AF_CONFIG_OPTION_INDIC
+
+  SCRIPT( beng, BENG,
+          "Bengali",
+          HB_SCRIPT_BENGALI,
+          'o', 0x0, 0x0 ) /* XXX */
+
+  SCRIPT( gujr, GUJR,
+          "Gujarati",
+          HB_SCRIPT_GUJARATI,
+          'o', 0x0, 0x0 ) /* XXX */
+
+  SCRIPT( guru, GURU,
+          "Gurmukhi",
+          HB_SCRIPT_GURMUKHI,
+          'o', 0x0, 0x0 ) /* XXX */
+
+  SCRIPT( knda, KNDA,
+          "Kannada",
+          HB_SCRIPT_KANNADA,
+          'o', 0x0, 0x0 ) /* XXX */
+
+  SCRIPT( limb, LIMB,
+          "Limbu",
+          HB_SCRIPT_LIMBU,
+          'o', 0x0, 0x0 ) /* XXX */
+
+  SCRIPT( mlym, MLYM,
+          "Malayalam",
+          HB_SCRIPT_MALAYALAM,
+          'o', 0x0, 0x0 ) /* XXX */
+
+  SCRIPT( orya, ORYA,
+          "Oriya",
+          HB_SCRIPT_ORIYA,
+          'o', 0x0, 0x0 ) /* XXX */
+
+  SCRIPT( sinh, SINH,
+          "Sinhala",
+          HB_SCRIPT_SINHALA,
+          'o', 0x0, 0x0 ) /* XXX */
+
+  SCRIPT( sund, SUND,
+          "Sundanese",
+          HB_SCRIPT_SUNDANESE,
+          'o', 0x0, 0x0 ) /* XXX */
+
+  SCRIPT( sylo, SYLO,
+          "Syloti Nagri",
+          HB_SCRIPT_SYLOTI_NAGRI,
+          'o', 0x0, 0x0 ) /* XXX */
+
+  SCRIPT( taml, TAML,
+          "Tamil",
+          HB_SCRIPT_TAMIL,
+          'o', 0x0, 0x0 ) /* XXX */
+
+  SCRIPT( telu, TELU,
+          "Telugu",
+          HB_SCRIPT_TELUGU,
+          'o', 0x0, 0x0 ) /* XXX */
+
+  SCRIPT( tibt, TIBT,
+          "Tibetan",
+          HB_SCRIPT_TIBETAN,
+          'o', 0x0, 0x0 ) /* XXX */
+
+#endif /* AF_CONFIG_OPTION_INDIC */
+
+#ifdef AF_CONFIG_OPTION_CJK
+
+  SCRIPT( hani, HANI,
+          "CJKV ideographs",
+          HB_SCRIPT_HAN,
+          0x7530, 0x56D7, 0x0 ) /* 田囗 */
+
+#endif /* AF_CONFIG_OPTION_CJK */
 
 
 /* END */
diff --git a/src/autofit/afstyles.h b/src/autofit/afstyles.h
new file mode 100644
index 0000000..27fdd2e
--- /dev/null
+++ b/src/autofit/afstyles.h
@@ -0,0 +1,158 @@
+/***************************************************************************/
+/*                                                                         */
+/*  afstyles.h                                                             */
+/*                                                                         */
+/*    Auto-fitter styles (specification only).                             */
+/*                                                                         */
+/*  Copyright 2013, 2014 by                                                */
+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
+/*                                                                         */
+/*  This file is part of the FreeType project, and may only be used,       */
+/*  modified, and distributed under the terms of the FreeType project      */
+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
+/*  this file you indicate that you have read the license and              */
+/*  understand and accept it fully.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
+  /* The following part can be included multiple times. */
+  /* Define `STYLE' as needed.                          */
+
+
+  /* Add new styles here.  The first and second arguments are the  */
+  /* style name in lowercase and uppercase, respectively, followed */
+  /* by a description string.  The next arguments are the          */
+  /* corresponding writing system, script, blue stringset, and     */
+  /* coverage.                                                     */
+  /*                                                               */
+  /* Note that styles using `AF_COVERAGE_DEFAULT' should always    */
+  /* come after styles with other coverages.                       */
+  /*                                                               */
+  /* Example:                                                      */
+  /*                                                               */
+  /*   STYLE( cyrl_dflt, CYRL_DFLT,                                */
+  /*          "Cyrillic default style",                            */
+  /*          AF_WRITING_SYSTEM_LATIN,                             */
+  /*          AF_SCRIPT_CYRL,                                      */
+  /*          AF_BLUE_STRINGSET_CYRL,                              */
+  /*          AF_COVERAGE_DEFAULT )                                */
+
+#undef  STYLE_LATIN
+#define STYLE_LATIN( s, S, f, F, ds, df, C ) \
+          STYLE( s ## _ ## f, S ## _ ## F,   \
+                 ds " " df " style",         \
+                 AF_WRITING_SYSTEM_LATIN,    \
+                 AF_SCRIPT_ ## S,            \
+                 AF_BLUE_STRINGSET_ ## S,    \
+                 AF_COVERAGE_ ## C )
+
+#undef  META_STYLE_LATIN
+#define META_STYLE_LATIN( s, S, ds )                     \
+          STYLE_LATIN( s, S, c2cp, C2CP, ds,             \
+                       "petite capticals from capitals", \
+                       PETITE_CAPITALS_FROM_CAPITALS )   \
+          STYLE_LATIN( s, S, c2sc, C2SC, ds,             \
+                       "small capticals from capitals",  \
+                       SMALL_CAPITALS_FROM_CAPITALS )    \
+          STYLE_LATIN( s, S, ordn, ORDN, ds,             \
+                       "ordinals",                       \
+                       ORDINALS )                        \
+          STYLE_LATIN( s, S, pcap, PCAP, ds,             \
+                       "petite capitals",                \
+                       PETITE_CAPITALS )                 \
+          STYLE_LATIN( s, S, sinf, SINF, ds,             \
+                       "scientific inferiors",           \
+                       SCIENTIFIC_INFERIORS )            \
+          STYLE_LATIN( s, S, smcp, SMCP, ds,             \
+                       "small capitals",                 \
+                       SMALL_CAPITALS )                  \
+          STYLE_LATIN( s, S, subs, SUBS, ds,             \
+                       "subscript",                      \
+                       SUBSCRIPT )                       \
+          STYLE_LATIN( s, S, sups, SUPS, ds,             \
+                       "superscript",                    \
+                       SUPERSCRIPT )                     \
+          STYLE_LATIN( s, S, titl, TITL, ds,             \
+                       "titling",                        \
+                       TITLING )                         \
+          STYLE_LATIN( s, S, dflt, DFLT, ds,             \
+                       "default",                        \
+                       DEFAULT )
+
+  META_STYLE_LATIN( cyrl, CYRL, "Cyrillic" )
+
+  META_STYLE_LATIN( grek, GREK, "Greek" )
+
+  STYLE( hebr_dflt, HEBR_DFLT,
+         "Hebrew default style",
+         AF_WRITING_SYSTEM_LATIN,
+         AF_SCRIPT_HEBR,
+         AF_BLUE_STRINGSET_HEBR,
+         AF_COVERAGE_DEFAULT )
+  META_STYLE_LATIN( latn, LATN, "Latin" )
+
+  STYLE( deva_dflt, DEVA_DFLT,
+         "Devanagari default style",
+         AF_WRITING_SYSTEM_LATIN,
+         AF_SCRIPT_DEVA,
+         AF_BLUE_STRINGSET_DEVA,
+         AF_COVERAGE_DEFAULT )
+
+#ifdef FT_OPTION_AUTOFIT2
+  STYLE( ltn2_dflt, LTN2_DFLT,
+         "Latin 2 default style",
+         AF_WRITING_SYSTEM_LATIN2,
+         AF_SCRIPT_LATN,
+         AF_BLUE_STRINGSET_LATN,
+         AF_COVERAGE_DEFAULT )
+#endif
+
+  STYLE( none_dflt, NONE_DFLT,
+         "no style",
+         AF_WRITING_SYSTEM_DUMMY,
+         AF_SCRIPT_NONE,
+         (AF_Blue_Stringset)0,
+         AF_COVERAGE_DEFAULT )
+
+#ifdef AF_CONFIG_OPTION_INDIC
+
+  /* no blue stringset support for the Indic writing system yet */
+#undef  STYLE_DEFAULT_INDIC
+#define STYLE_DEFAULT_INDIC( s, S, d )    \
+          STYLE( s ## _dflt, S ## _DFLT,  \
+                 d " default style",      \
+                 AF_WRITING_SYSTEM_INDIC, \
+                 AF_SCRIPT_ ## S,         \
+                 (AF_Blue_Stringset)0,    \
+                 AF_COVERAGE_DEFAULT )
+
+  STYLE_DEFAULT_INDIC( beng, BENG, "Bengali" )
+  STYLE_DEFAULT_INDIC( gujr, GUJR, "Gujarati" )
+  STYLE_DEFAULT_INDIC( guru, GURU, "Gurmukhi" )
+  STYLE_DEFAULT_INDIC( knda, KNDA, "Kannada" )
+  STYLE_DEFAULT_INDIC( limb, LIMB, "Limbu" )
+  STYLE_DEFAULT_INDIC( mlym, MLYM, "Malayalam" )
+  STYLE_DEFAULT_INDIC( orya, ORYA, "Oriya" )
+  STYLE_DEFAULT_INDIC( sinh, SINH, "Sinhala" )
+  STYLE_DEFAULT_INDIC( sund, SUND, "Sundanese" )
+  STYLE_DEFAULT_INDIC( sylo, SYLO, "Syloti Nagri" )
+  STYLE_DEFAULT_INDIC( taml, TAML, "Tamil" )
+  STYLE_DEFAULT_INDIC( telu, TELU, "Telugu" )
+  STYLE_DEFAULT_INDIC( tibt, TIBT, "Tibetan" )
+
+#endif /* AF_CONFIG_OPTION_INDIC */
+
+#ifdef AF_CONFIG_OPTION_CJK
+
+  STYLE( hani_dflt, HANI_DFLT,
+         "CJKV ideographs default style",
+         AF_WRITING_SYSTEM_CJK,
+         AF_SCRIPT_HANI,
+         AF_BLUE_STRINGSET_HANI,
+         AF_COVERAGE_DEFAULT )
+
+#endif /* AF_CONFIG_OPTION_CJK */
+
+
+/* END */
diff --git a/src/autofit/aftypes.h b/src/autofit/aftypes.h
index cda1f89..61badd1 100644
--- a/src/autofit/aftypes.h
+++ b/src/autofit/aftypes.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auto-fitter types (specification only).                              */
 /*                                                                         */
-/*  Copyright 2003-2009, 2011-2013 by                                      */
+/*  Copyright 2003-2009, 2011-2014 by                                      */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -20,7 +20,7 @@
    *
    *  The auto-fitter is a complete rewrite of the old auto-hinter.
    *  Its main feature is the ability to differentiate between different
-   *  writing systems in order to apply script-specific rules.
+   *  writing systems and scripts in order to apply specific rules.
    *
    *  The code has also been compartmentized into several entities that
    *  should make algorithmic experimentation easier than with the old
@@ -197,55 +197,31 @@
             (a)->y_delta == (b)->y_delta )
 
 
-  /*************************************************************************/
-  /*************************************************************************/
-  /*****                                                               *****/
-  /*****                 S C R I P T   M E T R I C S                   *****/
-  /*****                                                               *****/
-  /*************************************************************************/
-  /*************************************************************************/
-
-  /* This is the main structure which combines writing systems and script */
-  /* data (for a given face object, see below).                           */
-
-  typedef struct AF_WritingSystemClassRec_ const*  AF_WritingSystemClass;
-  typedef struct AF_ScriptClassRec_ const*         AF_ScriptClass;
-  typedef struct AF_FaceGlobalsRec_*               AF_FaceGlobals;
-
-  typedef struct  AF_ScriptMetricsRec_
-  {
-    AF_ScriptClass  script_class;
-    AF_ScalerRec    scaler;
-    FT_Bool         digits_have_same_width;
-
-    AF_FaceGlobals  globals;    /* to access properties */
-
-  } AF_ScriptMetricsRec, *AF_ScriptMetrics;
-
+  typedef struct AF_StyleMetricsRec_*  AF_StyleMetrics;
 
   /*  This function parses an FT_Face to compute global metrics for
-   *  a specific script.
+   *  a specific style.
    */
   typedef FT_Error
-  (*AF_Script_InitMetricsFunc)( AF_ScriptMetrics  metrics,
-                                FT_Face           face );
+  (*AF_WritingSystem_InitMetricsFunc)( AF_StyleMetrics  metrics,
+                                       FT_Face          face );
 
   typedef void
-  (*AF_Script_ScaleMetricsFunc)( AF_ScriptMetrics  metrics,
-                                 AF_Scaler         scaler );
+  (*AF_WritingSystem_ScaleMetricsFunc)( AF_StyleMetrics  metrics,
+                                        AF_Scaler        scaler );
 
   typedef void
-  (*AF_Script_DoneMetricsFunc)( AF_ScriptMetrics  metrics );
+  (*AF_WritingSystem_DoneMetricsFunc)( AF_StyleMetrics  metrics );
 
 
   typedef FT_Error
-  (*AF_Script_InitHintsFunc)( AF_GlyphHints     hints,
-                              AF_ScriptMetrics  metrics );
+  (*AF_WritingSystem_InitHintsFunc)( AF_GlyphHints    hints,
+                                     AF_StyleMetrics  metrics );
 
   typedef void
-  (*AF_Script_ApplyHintsFunc)( AF_GlyphHints     hints,
-                               FT_Outline*       outline,
-                               AF_ScriptMetrics  metrics );
+  (*AF_WritingSystem_ApplyHintsFunc)( AF_GlyphHints    hints,
+                                      FT_Outline*      outline,
+                                      AF_StyleMetrics  metrics );
 
 
   /*************************************************************************/
@@ -257,14 +233,14 @@
   /*************************************************************************/
 
   /*
-   *  In FreeType, a writing system consists of multiple scripts which can
-   *  be handled similarly *in a typographical way*; the relationship is not
-   *  based on history.  For example, both the Greek and the unrelated
+   *  For the auto-hinter, a writing system consists of multiple scripts that
+   *  can be handled similarly *in a typographical way*; the relationship is
+   *  not based on history.  For example, both the Greek and the unrelated
    *  Armenian scripts share the same features like ascender, descender,
    *  x-height, etc.  Essentially, a writing system is covered by a
    *  submodule of the auto-fitter; it contains
    *
-   *  - a specific global analyzer which computes global metrics specific to
+   *  - a specific global analyzer that computes global metrics specific to
    *    the script (based on script-specific characters to identify ascender
    *    height, x-height, etc.),
    *
@@ -297,16 +273,18 @@
   {
     AF_WritingSystem  writing_system;
 
-    FT_Offset                   script_metrics_size;
-    AF_Script_InitMetricsFunc   script_metrics_init;
-    AF_Script_ScaleMetricsFunc  script_metrics_scale;
-    AF_Script_DoneMetricsFunc   script_metrics_done;
+    FT_Offset                          style_metrics_size;
+    AF_WritingSystem_InitMetricsFunc   style_metrics_init;
+    AF_WritingSystem_ScaleMetricsFunc  style_metrics_scale;
+    AF_WritingSystem_DoneMetricsFunc   style_metrics_done;
 
-    AF_Script_InitHintsFunc     script_hints_init;
-    AF_Script_ApplyHintsFunc    script_hints_apply;
+    AF_WritingSystem_InitHintsFunc     style_hints_init;
+    AF_WritingSystem_ApplyHintsFunc    style_hints_apply;
 
   } AF_WritingSystemClassRec;
 
+  typedef const AF_WritingSystemClassRec*  AF_WritingSystemClass;
+
 
   /*************************************************************************/
   /*************************************************************************/
@@ -317,15 +295,15 @@
   /*************************************************************************/
 
   /*
-   *  Each script is associated with a set of Unicode ranges which gets used
-   *  to test whether the font face supports the script.  It also references
-   *  the writing system it belongs to.
+   *  Each script is associated with a set of Unicode ranges that gets used
+   *  to test whether the font face supports the script.
    *
-   *  We use four-letter script tags from the OpenType specification.
+   *  We use four-letter script tags from the OpenType specification,
+   *  extended by `NONE', which indicates `no script'.
    */
 
 #undef  SCRIPT
-#define SCRIPT( s, S, d ) \
+#define SCRIPT( s, S, d, h, sc1, sc2, sc3 ) \
           AF_SCRIPT_ ## S,
 
   /* The list of known scripts. */
@@ -353,15 +331,147 @@
 
   typedef struct  AF_ScriptClassRec_
   {
-    AF_Script          script;
-    AF_Blue_Stringset  blue_stringset;
-    AF_WritingSystem   writing_system;
+    AF_Script  script;
 
     AF_Script_UniRange  script_uni_ranges; /* last must be { 0, 0 }        */
-    FT_UInt32           standard_char;     /* for default width and height */
+
+    FT_UInt32  standard_char1;             /* for default width and height */
+    FT_UInt32  standard_char2;             /* ditto                        */
+    FT_UInt32  standard_char3;             /* ditto                        */
 
   } AF_ScriptClassRec;
 
+  typedef const AF_ScriptClassRec*  AF_ScriptClass;
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*****                                                               *****/
+  /*****                      C O V E R A G E S                        *****/
+  /*****                                                               *****/
+  /*************************************************************************/
+  /*************************************************************************/
+
+  /*
+   *  Usually, a font contains more glyphs than can be addressed by its
+   *  character map.
+   *
+   *  In the PostScript font world, encoding vectors specific to a given
+   *  task are used to select such glyphs, and these glyphs can be often
+   *  recognized by having a suffix in its glyph names.  For example, a
+   *  superscript glyph `A' might be called `A.sup'.  Unfortunately, this
+   *  naming scheme is not standardized and thus unusable for us.
+   *
+   *  In the OpenType world, a better solution was invented, namely
+   *  `features', which cleanly separate a character's input encoding from
+   *  the corresponding glyph's appearance, and which don't use glyph names
+   *  at all.  For our purposes, and slightly generalized, an OpenType
+   *  feature is a name of a mapping that maps character codes to
+   *  non-standard glyph indices (features get used for other things also).
+   *  For example, the `sups' feature provides superscript glyphs, thus
+   *  mapping character codes like `A' or `B' to superscript glyph
+   *  representation forms.  How this mapping happens is completely
+   *  uninteresting to us.
+   *
+   *  For the auto-hinter, a `coverage' represents all glyphs of an OpenType
+   *  feature collected in a set (as listed below) that can be hinted
+   *  together.  To continue the above example, superscript glyphs must not
+   *  be hinted together with normal glyphs because the blue zones
+   *  completely differ.
+   *
+   *  Note that FreeType itself doesn't compute coverages; it only provides
+   *  the glyphs addressable by the default Unicode character map.  Instead,
+   *  we use the HarfBuzz library (if available), which has many functions
+   *  exactly for this purpose.
+   *
+   *  AF_COVERAGE_DEFAULT is special: It should cover everything that isn't
+   *  listed separately (including the glyphs addressable by the character
+   *  map).  In case HarfBuzz isn't available, it exactly covers the glyphs
+   *  addressable by the character map.
+   *
+   */
+
+#undef  COVERAGE
+#define COVERAGE( name, NAME, description, \
+                  tag1, tag2, tag3, tag4 ) \
+          AF_COVERAGE_ ## NAME,
+
+
+  typedef enum  AF_Coverage_
+  {
+#include "afcover.h"
+
+    AF_COVERAGE_DEFAULT
+
+  } AF_Coverage;
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*****                                                               *****/
+  /*****                         S T Y L E S                           *****/
+  /*****                                                               *****/
+  /*************************************************************************/
+  /*************************************************************************/
+
+  /*
+   *  The topmost structure for modelling the auto-hinter glyph input data
+   *  is a `style class', grouping everything together.
+   */
+
+#undef  STYLE
+#define STYLE( s, S, d, ws, sc, ss, c ) \
+          AF_STYLE_ ## S,
+
+  /* The list of known styles. */
+  typedef enum  AF_Style_
+  {
+
+#include "afstyles.h"
+
+    AF_STYLE_MAX   /* do not remove */
+
+  } AF_Style;
+
+
+  typedef struct  AF_StyleClassRec_
+  {
+    AF_Style  style;
+
+    AF_WritingSystem   writing_system;
+    AF_Script          script;
+    AF_Blue_Stringset  blue_stringset;
+    AF_Coverage        coverage;
+
+  } AF_StyleClassRec;
+
+  typedef const AF_StyleClassRec*  AF_StyleClass;
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*****                                                               *****/
+  /*****                   S T Y L E   M E T R I C S                   *****/
+  /*****                                                               *****/
+  /*************************************************************************/
+  /*************************************************************************/
+
+  typedef struct AF_FaceGlobalsRec_*  AF_FaceGlobals;
+
+  /* This is the main structure that combines everything.  Autofit modules */
+  /* specific to writing systems derive their structures from it, for      */
+  /* example `AF_LatinMetrics'.                                            */
+
+  typedef struct  AF_StyleMetricsRec_
+  {
+    AF_StyleClass   style_class;
+    AF_ScalerRec    scaler;
+    FT_Bool         digits_have_same_width;
+
+    AF_FaceGlobals  globals;    /* to access properties */
+
+  } AF_StyleMetricsRec;
+
 
   /* Declare and define vtables for classes */
 #ifndef FT_CONFIG_OPTION_PIC
@@ -401,19 +511,41 @@
 
 #define AF_DEFINE_SCRIPT_CLASS(           \
           script_class,                   \
-          script_,                        \
-          blue_stringset_,                \
-          writing_system_,                \
+          script,                         \
           ranges,                         \
-          std_char )                      \
+          std_char1,                      \
+          std_char2,                      \
+          std_char3 )                     \
   FT_CALLBACK_TABLE_DEF                   \
   const AF_ScriptClassRec  script_class = \
   {                                       \
-    script_,                              \
-    blue_stringset_,                      \
-    writing_system_,                      \
+    script,                               \
     ranges,                               \
-    std_char                              \
+    std_char1,                            \
+    std_char2,                            \
+    std_char3                             \
+  };
+
+
+#define AF_DECLARE_STYLE_CLASS( style_class ) \
+  FT_CALLBACK_TABLE const AF_StyleClassRec    \
+  style_class;
+
+#define AF_DEFINE_STYLE_CLASS(          \
+          style_class,                  \
+          style,                        \
+          writing_system,               \
+          script,                       \
+          blue_stringset,               \
+          coverage )                    \
+  FT_CALLBACK_TABLE_DEF                 \
+  const AF_StyleClassRec  style_class = \
+  {                                     \
+    style,                              \
+    writing_system,                     \
+    script,                             \
+    blue_stringset,                     \
+    coverage                            \
   };
 
 #else /* FT_CONFIG_OPTION_PIC */
@@ -434,16 +566,16 @@
   FT_LOCAL_DEF( void )                                                    \
   FT_Init_Class_ ## writing_system_class( AF_WritingSystemClassRec*  ac ) \
   {                                                                       \
-    ac->writing_system       = system;                                    \
+    ac->writing_system      = system;                                     \
                                                                           \
-    ac->script_metrics_size  = m_size;                                    \
+    ac->style_metrics_size  = m_size;                                     \
                                                                           \
-    ac->script_metrics_init  = m_init;                                    \
-    ac->script_metrics_scale = m_scale;                                   \
-    ac->script_metrics_done  = m_done;                                    \
+    ac->style_metrics_init  = m_init;                                     \
+    ac->style_metrics_scale = m_scale;                                    \
+    ac->style_metrics_done  = m_done;                                     \
                                                                           \
-    ac->script_hints_init    = h_init;                                    \
-    ac->script_hints_apply   = h_apply;                                   \
+    ac->style_hints_init    = h_init;                                     \
+    ac->style_hints_apply   = h_apply;                                    \
   }
 
 
@@ -454,18 +586,40 @@
 #define AF_DEFINE_SCRIPT_CLASS(                            \
           script_class,                                    \
           script_,                                         \
-          blue_string_set_,                                \
-          writing_system_,                                 \
           ranges,                                          \
-          std_char )                                       \
+          std_char1,                                       \
+          std_char2,                                       \
+          std_char3 )                                      \
   FT_LOCAL_DEF( void )                                     \
   FT_Init_Class_ ## script_class( AF_ScriptClassRec*  ac ) \
   {                                                        \
     ac->script            = script_;                       \
-    ac->blue_stringset    = blue_stringset_;               \
-    ac->writing_system    = writing_system_;               \
     ac->script_uni_ranges = ranges;                        \
-    ac->standard_char     = std_char;                      \
+    ac->standard_char1    = std_char1;                     \
+    ac->standard_char2    = std_char2;                     \
+    ac->standard_char3    = std_char3;                     \
+  }
+
+
+#define AF_DECLARE_STYLE_CLASS( style_class )             \
+  FT_LOCAL( void )                                        \
+  FT_Init_Class_ ## style_class( AF_StyleClassRec*  ac );
+
+#define AF_DEFINE_STYLE_CLASS(                           \
+          style_class,                                   \
+          style_,                                        \
+          writing_system_,                               \
+          script_,                                       \
+          blue_stringset_,                               \
+          coverage_ )                                    \
+  FT_LOCAL_DEF( void )                                   \
+  FT_Init_Class_ ## style_class( AF_StyleClassRec*  ac ) \
+  {                                                      \
+    ac->style          = style_;                         \
+    ac->writing_system = writing_system_;                \
+    ac->script         = script_;                        \
+    ac->blue_stringset = blue_stringset_;                \
+    ac->coverage       = coverage_;                      \
   }
 
 #endif /* FT_CONFIG_OPTION_PIC */
diff --git a/src/autofit/afwrtsys.h b/src/autofit/afwrtsys.h
index 602c558..8aa2ed9 100644
--- a/src/autofit/afwrtsys.h
+++ b/src/autofit/afwrtsys.h
@@ -37,7 +37,8 @@
   /* Define `WRITING_SYSTEM' as needed.                 */
 
 
-  /* Add new writing systems here. */
+  /* Add new writing systems here.  The arguments are the writing system */
+  /* name in lowercase and uppercase, respectively.                      */
 
   WRITING_SYSTEM( dummy,  DUMMY  )
   WRITING_SYSTEM( latin,  LATIN  )
diff --git a/src/autofit/autofit.c b/src/autofit/autofit.c
index b23374a..e2b9934 100644
--- a/src/autofit/autofit.c
+++ b/src/autofit/autofit.c
@@ -24,6 +24,8 @@
 #include "afglobal.c"
 #include "afhints.c"
 
+#include "afranges.c"
+
 #include "afdummy.c"
 #include "aflatin.c"
 #ifdef FT_OPTION_AUTOFIT2
@@ -32,6 +34,8 @@
 #include "afcjk.c"
 #include "afindic.c"
 
+#include "hbshim.c"
+
 #include "afloader.c"
 #include "afmodule.c"
 
diff --git a/src/autofit/hbshim.c b/src/autofit/hbshim.c
new file mode 100644
index 0000000..cc04815
--- /dev/null
+++ b/src/autofit/hbshim.c
@@ -0,0 +1,545 @@
+/***************************************************************************/
+/*                                                                         */
+/*  hbshim.c                                                               */
+/*                                                                         */
+/*    HarfBuzz interface for accessing OpenType features (body).           */
+/*                                                                         */
+/*  Copyright 2013, 2014 by                                                */
+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
+/*                                                                         */
+/*  This file is part of the FreeType project, and may only be used,       */
+/*  modified, and distributed under the terms of the FreeType project      */
+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
+/*  this file you indicate that you have read the license and              */
+/*  understand and accept it fully.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include "afglobal.h"
+#include "aftypes.h"
+#include "hbshim.h"
+
+#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
+  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
+  /* messages during execution.                                            */
+  /*                                                                       */
+#undef  FT_COMPONENT
+#define FT_COMPONENT  trace_afharfbuzz
+
+
+  /*
+   * We use `sets' (in the HarfBuzz sense, which comes quite near to the
+   * usual mathematical meaning) to manage both lookups and glyph indices.
+   *
+   * 1. For each coverage, collect lookup IDs in a set.  Note that an
+   *    auto-hinter `coverage' is represented by one `feature', and a
+   *    feature consists of an arbitrary number of (font specific) `lookup's
+   *    that actually do the mapping job.  Please check the OpenType
+   *    specification for more details on features and lookups.
+   *
+   * 2. Create glyph ID sets from the corresponding lookup sets.
+   *
+   * 3. The glyph set corresponding to AF_COVERAGE_DEFAULT is computed
+   *    with all lookups specific to the OpenType script activated.  It
+   *    relies on the order of AF_DEFINE_STYLE_CLASS entries so that
+   *    special coverages (like `oldstyle figures') don't get overwritten.
+   *
+   */
+
+
+  /* load coverage tags */
+#undef  COVERAGE
+#define COVERAGE( name, NAME, description,             \
+                  tag1, tag2, tag3, tag4 )             \
+          static const hb_tag_t  name ## _coverage[] = \
+          {                                            \
+            HB_TAG( tag1, tag2, tag3, tag4 ),          \
+            HB_TAG_NONE                                \
+          };
+
+
+#include "afcover.h"
+
+
+  /* define mapping between coverage tags and AF_Coverage */
+#undef  COVERAGE
+#define COVERAGE( name, NAME, description, \
+                  tag1, tag2, tag3, tag4 ) \
+          name ## _coverage,
+
+
+  static const hb_tag_t*  coverages[] =
+  {
+#include "afcover.h"
+
+    NULL /* AF_COVERAGE_DEFAULT */
+  };
+
+
+  /* load HarfBuzz script tags */
+#undef  SCRIPT
+#define SCRIPT( s, S, d, h, sc1, sc2, sc3 )  h,
+
+
+  static const hb_script_t  scripts[] =
+  {
+#include "afscript.h"
+  };
+
+
+  FT_Error
+  af_get_coverage( AF_FaceGlobals  globals,
+                   AF_StyleClass   style_class,
+                   FT_Byte*        gstyles )
+  {
+    hb_face_t*  face;
+
+    hb_set_t*  gsub_lookups;  /* GSUB lookups for a given script */
+    hb_set_t*  gsub_glyphs;   /* glyphs covered by GSUB lookups  */
+    hb_set_t*  gpos_lookups;  /* GPOS lookups for a given script */
+    hb_set_t*  gpos_glyphs;   /* glyphs covered by GPOS lookups  */
+
+    hb_script_t      script;
+    const hb_tag_t*  coverage_tags;
+    hb_tag_t         script_tags[] = { HB_TAG_NONE,
+                                       HB_TAG_NONE,
+                                       HB_TAG_NONE,
+                                       HB_TAG_NONE };
+
+    hb_codepoint_t  idx;
+#ifdef FT_DEBUG_LEVEL_TRACE
+    int             count;
+#endif
+
+
+    if ( !globals || !style_class || !gstyles )
+      return FT_THROW( Invalid_Argument );
+
+    face = hb_font_get_face( globals->hb_font );
+
+    gsub_lookups = hb_set_create();
+    gsub_glyphs  = hb_set_create();
+    gpos_lookups = hb_set_create();
+    gpos_glyphs  = hb_set_create();
+
+    coverage_tags = coverages[style_class->coverage];
+    script        = scripts[style_class->script];
+
+    /* Convert a HarfBuzz script tag into the corresponding OpenType */
+    /* tag or tags -- some Indic scripts like Devanagari have an old */
+    /* and a new set of features.                                    */
+    hb_ot_tags_from_script( script,
+                            &script_tags[0],
+                            &script_tags[1] );
+
+    /* `hb_ot_tags_from_script' usually returns HB_OT_TAG_DEFAULT_SCRIPT */
+    /* as the second tag.  We change that to HB_TAG_NONE except for the  */
+    /* default script.                                                   */
+    if ( style_class->script == globals->module->default_script &&
+         style_class->coverage == AF_COVERAGE_DEFAULT           )
+    {
+      if ( script_tags[0] == HB_TAG_NONE )
+        script_tags[0] = HB_OT_TAG_DEFAULT_SCRIPT;
+      else
+      {
+        if ( script_tags[1] == HB_TAG_NONE )
+          script_tags[1] = HB_OT_TAG_DEFAULT_SCRIPT;
+        else if ( script_tags[1] != HB_OT_TAG_DEFAULT_SCRIPT )
+          script_tags[2] = HB_OT_TAG_DEFAULT_SCRIPT;
+      }
+    }
+    else
+    {
+      if ( script_tags[1] == HB_OT_TAG_DEFAULT_SCRIPT )
+        script_tags[1] = HB_TAG_NONE;
+    }
+
+    hb_ot_layout_collect_lookups( face,
+                                  HB_OT_TAG_GSUB,
+                                  script_tags,
+                                  NULL,
+                                  coverage_tags,
+                                  gsub_lookups );
+
+    if ( hb_set_is_empty( gsub_lookups ) )
+      goto Exit; /* nothing to do */
+
+    hb_ot_layout_collect_lookups( face,
+                                  HB_OT_TAG_GPOS,
+                                  script_tags,
+                                  NULL,
+                                  coverage_tags,
+                                  gpos_lookups );
+
+    FT_TRACE4(( "GSUB lookups (style `%s'):\n"
+                " ",
+                af_style_names[style_class->style] ));
+
+#ifdef FT_DEBUG_LEVEL_TRACE
+    count = 0;
+#endif
+
+    for ( idx = -1; hb_set_next( gsub_lookups, &idx ); )
+    {
+#ifdef FT_DEBUG_LEVEL_TRACE
+      FT_TRACE4(( " %d", idx ));
+      count++;
+#endif
+
+      /* get output coverage of GSUB feature */
+      hb_ot_layout_lookup_collect_glyphs( face,
+                                          HB_OT_TAG_GSUB,
+                                          idx,
+                                          NULL,
+                                          NULL,
+                                          NULL,
+                                          gsub_glyphs );
+    }
+
+#ifdef FT_DEBUG_LEVEL_TRACE
+    if ( !count )
+      FT_TRACE4(( " (none)" ));
+    FT_TRACE4(( "\n\n" ));
+#endif
+
+    FT_TRACE4(( "GPOS lookups (style `%s'):\n"
+                " ",
+                af_style_names[style_class->style] ));
+
+#ifdef FT_DEBUG_LEVEL_TRACE
+    count = 0;
+#endif
+
+    for ( idx = -1; hb_set_next( gpos_lookups, &idx ); )
+    {
+#ifdef FT_DEBUG_LEVEL_TRACE
+      FT_TRACE4(( " %d", idx ));
+      count++;
+#endif
+
+      /* get input coverage of GPOS feature */
+      hb_ot_layout_lookup_collect_glyphs( face,
+                                          HB_OT_TAG_GPOS,
+                                          idx,
+                                          NULL,
+                                          gpos_glyphs,
+                                          NULL,
+                                          NULL );
+    }
+
+#ifdef FT_DEBUG_LEVEL_TRACE
+    if ( !count )
+      FT_TRACE4(( " (none)" ));
+    FT_TRACE4(( "\n\n" ));
+#endif
+
+    /*
+     * We now check whether we can construct blue zones, using glyphs
+     * covered by the feature only.  In case there is not a single zone
+     * (this is, not a single character is covered), we skip this coverage.
+     *
+     */
+    if ( style_class->coverage != AF_COVERAGE_DEFAULT )
+    {
+      AF_Blue_Stringset         bss = style_class->blue_stringset;
+      const AF_Blue_StringRec*  bs  = &af_blue_stringsets[bss];
+
+      FT_Bool  found = 0;
+
+
+      for ( ; bs->string != AF_BLUE_STRING_MAX; bs++ )
+      {
+        const char*  p = &af_blue_strings[bs->string];
+
+
+        while ( *p )
+        {
+          hb_codepoint_t  ch;
+
+
+          GET_UTF8_CHAR( ch, p );
+
+          for ( idx = -1; hb_set_next( gsub_lookups, &idx ); )
+          {
+            hb_codepoint_t  gidx = FT_Get_Char_Index( globals->face, ch );
+
+
+            if ( hb_ot_layout_lookup_would_substitute( face, idx,
+                                                       &gidx, 1, 1 ) )
+            {
+              found = 1;
+              break;
+            }
+          }
+        }
+      }
+
+      if ( !found )
+      {
+        FT_TRACE4(( "  no blue characters found; style skipped\n" ));
+        goto Exit;
+      }
+    }
+
+    /*
+     * Various OpenType features might use the same glyphs at different
+     * vertical positions; for example, superscript and subscript glyphs
+     * could be the same.  However, the auto-hinter is completely
+     * agnostic of OpenType features after the feature analysis has been
+     * completed: The engine then simply receives a glyph index and returns a
+     * hinted and usually rendered glyph.
+     *
+     * Consider the superscript feature of font `pala.ttf': Some of the
+     * glyphs are `real', this is, they have a zero vertical offset, but
+     * most of them are small caps glyphs shifted up to the superscript
+     * position (this is, the `sups' feature is present in both the GSUB and
+     * GPOS tables).  The code for blue zones computation actually uses a
+     * feature's y offset so that the `real' glyphs get correct hints.  But
+     * later on it is impossible to decide whether a glyph index belongs to,
+     * say, the small caps or superscript feature.
+     *
+     * For this reason, we don't assign a style to a glyph if the current
+     * feature covers the glyph in both the GSUB and the GPOS tables.  This
+     * is quite a broad condition, assuming that
+     *
+     *   (a) glyphs that get used in multiple features are present in a
+     *       feature without vertical shift,
+     *
+     * and
+     *
+     *   (b) a feature's GPOS data really moves the glyph vertically.
+     *
+     * Not fulfilling condition (a) makes a font larger; it would also
+     * reduce the number of glyphs that could be addressed directly without
+     * using OpenType features, so this assumption is rather strong.
+     *
+     * Condition (b) is much weaker, and there might be glyphs which get
+     * missed.  However, the OpenType features we are going to handle are
+     * primarily located in GSUB, and HarfBuzz doesn't provide an API to
+     * directly get the necessary information from the GPOS table.  A
+     * possible solution might be to directly parse the GPOS table to find
+     * out whether a glyph gets shifted vertically, but this is something I
+     * would like to avoid if not really necessary.
+     *
+     * Note that we don't follow this logic for the default coverage. 
+     * Complex scripts like Devanagari have mandatory GPOS features to
+     * position many glyph elements, using mark-to-base or mark-to-ligature
+     * tables; the number of glyphs missed due to condition (b) would be far
+     * too large.
+     *
+     */
+    if ( style_class->coverage != AF_COVERAGE_DEFAULT )
+      hb_set_subtract( gsub_glyphs, gpos_glyphs );
+
+#ifdef FT_DEBUG_LEVEL_TRACE
+    FT_TRACE4(( "  glyphs without GPOS data (`*' means already assigned)" ));
+    count = 0;
+#endif
+
+    for ( idx = -1; hb_set_next( gsub_glyphs, &idx ); )
+    {
+#ifdef FT_DEBUG_LEVEL_TRACE
+      if ( !( count % 10 ) )
+        FT_TRACE4(( "\n"
+                    "   " ));
+
+      FT_TRACE4(( " %d", idx ));
+      count++;
+#endif
+
+      /* glyph indices returned by `hb_ot_layout_lookup_collect_glyphs' */
+      /* can be arbitrary: some fonts use fake indices for processing   */
+      /* internal to GSUB or GPOS, which is fully valid                 */
+      if ( idx >= (hb_codepoint_t)globals->glyph_count )
+        continue;
+
+      if ( gstyles[idx] == AF_STYLE_UNASSIGNED )
+        gstyles[idx] = (FT_Byte)style_class->style;
+#ifdef FT_DEBUG_LEVEL_TRACE
+      else
+        FT_TRACE4(( "*" ));
+#endif
+    }
+
+#ifdef FT_DEBUG_LEVEL_TRACE
+    if ( !count )
+      FT_TRACE4(( "\n"
+                  "    (none)" ));
+    FT_TRACE4(( "\n\n" ));
+#endif
+
+  Exit:
+    hb_set_destroy( gsub_lookups );
+    hb_set_destroy( gsub_glyphs  );
+    hb_set_destroy( gpos_lookups );
+    hb_set_destroy( gpos_glyphs  );
+
+    return FT_Err_Ok;
+  }
+
+
+  /* construct HarfBuzz features */
+#undef  COVERAGE
+#define COVERAGE( name, NAME, description,                \
+                  tag1, tag2, tag3, tag4 )                \
+          static const hb_feature_t  name ## _feature[] = \
+          {                                               \
+            {                                             \
+              HB_TAG( tag1, tag2, tag3, tag4 ),           \
+              1, 0, (unsigned int)-1                      \
+            }                                             \
+          };
+
+
+#include "afcover.h"
+
+
+  /* define mapping between HarfBuzz features and AF_Coverage */
+#undef  COVERAGE
+#define COVERAGE( name, NAME, description, \
+                  tag1, tag2, tag3, tag4 ) \
+          name ## _feature,
+
+
+  static const hb_feature_t*  features[] =
+  {
+#include "afcover.h"
+
+    NULL /* AF_COVERAGE_DEFAULT */
+  };
+
+
+  FT_Error
+  af_get_char_index( AF_StyleMetrics  metrics,
+                     FT_ULong         charcode,
+                     FT_ULong        *codepoint,
+                     FT_Long         *y_offset )
+  {
+    AF_StyleClass  style_class;
+
+    const hb_feature_t*  feature;
+
+    FT_ULong  in_idx, out_idx;
+
+
+    if ( !metrics )
+      return FT_THROW( Invalid_Argument );
+
+    in_idx = FT_Get_Char_Index( metrics->globals->face, charcode );
+
+    style_class = metrics->style_class;
+
+    feature = features[style_class->coverage];
+
+    if ( feature )
+    {
+      FT_UInt  upem = metrics->globals->face->units_per_EM;
+
+      hb_font_t*    font = metrics->globals->hb_font;
+      hb_buffer_t*  buf  = hb_buffer_create();
+
+      uint32_t  c = (uint32_t)charcode;
+
+      hb_glyph_info_t*      ginfo;
+      hb_glyph_position_t*  gpos;
+      unsigned int          gcount;
+
+
+      /* we shape at a size of units per EM; this means font units */
+      hb_font_set_scale( font, upem, upem );
+
+      /* XXX: is this sufficient for a single character of any script? */
+      hb_buffer_set_direction( buf, HB_DIRECTION_LTR );
+      hb_buffer_set_script( buf, scripts[style_class->script] );
+
+      /* we add one character to `buf' ... */
+      hb_buffer_add_utf32( buf, &c, 1, 0, 1 );
+
+      /* ... and apply one feature */
+      hb_shape( font, buf, feature, 1 );
+
+      ginfo = hb_buffer_get_glyph_infos( buf, &gcount );
+      gpos  = hb_buffer_get_glyph_positions( buf, &gcount );
+
+      out_idx = ginfo[0].codepoint;
+
+      /* getting the same index indicates no substitution,         */
+      /* which means that the glyph isn't available in the feature */
+      if ( in_idx == out_idx )
+      {
+        *codepoint = 0;
+        *y_offset  = 0;
+      }
+      else
+      {
+        *codepoint = out_idx;
+        *y_offset  = gpos[0].y_offset;
+      }
+
+      hb_buffer_destroy( buf );
+
+#ifdef FT_DEBUG_LEVEL_TRACE
+      if ( gcount > 1 )
+        FT_TRACE1(( "af_get_char_index:"
+                    " input character mapped to multiple glyphs\n" ));
+#endif
+    }
+    else
+    {
+      *codepoint = in_idx;
+      *y_offset  = 0;
+    }
+
+    return FT_Err_Ok;
+  }
+
+
+#else /* !FT_CONFIG_OPTION_USE_HARFBUZZ */
+
+
+  FT_Error
+  af_get_coverage( AF_FaceGlobals  globals,
+                   AF_StyleClass   style_class,
+                   FT_Byte*        gstyles )
+  {
+    FT_UNUSED( globals );
+    FT_UNUSED( style_class );
+    FT_UNUSED( gstyles );
+
+    return FT_Err_Ok;
+  }
+
+
+  FT_Error
+  af_get_char_index( AF_StyleMetrics  metrics,
+                     FT_ULong         charcode,
+                     FT_ULong        *codepoint,
+                     FT_Long         *y_offset )
+  {
+    FT_Face  face;
+
+
+    if ( !metrics )
+      return FT_THROW( Invalid_Argument );
+
+    face = metrics->globals->face;
+
+    *codepoint = FT_Get_Char_Index( face, charcode );
+    *y_offset  = 0;
+
+    return FT_Err_Ok;
+  }
+
+
+#endif /* !FT_CONFIG_OPTION_USE_HARFBUZZ */
+
+
+/* END */
diff --git a/src/autofit/hbshim.h b/src/autofit/hbshim.h
new file mode 100644
index 0000000..02f1513
--- /dev/null
+++ b/src/autofit/hbshim.h
@@ -0,0 +1,56 @@
+/***************************************************************************/
+/*                                                                         */
+/*  hbshim.h                                                               */
+/*                                                                         */
+/*    HarfBuzz interface for accessing OpenType features (specification).  */
+/*                                                                         */
+/*  Copyright 2013 by                                                      */
+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
+/*                                                                         */
+/*  This file is part of the FreeType project, and may only be used,       */
+/*  modified, and distributed under the terms of the FreeType project      */
+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
+/*  this file you indicate that you have read the license and              */
+/*  understand and accept it fully.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
+#ifndef __HBSHIM_H__
+#define __HBSHIM_H__
+
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+
+
+#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
+
+#include <hb.h>
+#include <hb-ot.h>
+#include <hb-ft.h>
+
+#endif
+
+
+FT_BEGIN_HEADER
+
+  FT_Error
+  af_get_coverage( AF_FaceGlobals  globals,
+                   AF_StyleClass   style_class,
+                   FT_Byte*        gstyles );
+
+  FT_Error
+  af_get_char_index( AF_StyleMetrics  metrics,
+                     FT_ULong         charcode,
+                     FT_ULong        *codepoint,
+                     FT_Long         *y_offset );
+
+ /* */
+
+FT_END_HEADER
+
+#endif /* __HBSHIM_H__ */
+
+
+/* END */
diff --git a/src/base/basepic.c b/src/base/basepic.c
index 0af770e..aeb6fd5 100644
--- a/src/base/basepic.c
+++ b/src/base/basepic.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType position independent code services for base.            */
 /*                                                                         */
-/*  Copyright 2009, 2012 by                                                */
+/*  Copyright 2009, 2012, 2013 by                                          */
 /*  Oran Agra and Mickey Gabel.                                            */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -35,7 +35,7 @@
   /* forward declaration of PIC init function from ftrfork.c */
   /* (not modularized)                                       */
   void
-  FT_Init_Table_raccess_guess_table( ft_raccess_guess_rec*  record );
+  FT_Init_Table_ft_raccess_guess_table( ft_raccess_guess_rec*  record );
 #endif
 
   /* forward declaration of PIC init functions from ftinit.c */
@@ -92,7 +92,7 @@
     FT_Init_Class_ft_bitmap_glyph_class(
       &container->ft_bitmap_glyph_class );
 #ifdef FT_CONFIG_OPTION_MAC_FONTS
-    FT_Init_Table_raccess_guess_table(
+    FT_Init_Table_ft_raccess_guess_table(
       (ft_raccess_guess_rec*)&container->ft_raccess_guess_table );
 #endif
 
diff --git a/src/base/ftbitmap.c b/src/base/ftbitmap.c
index 182b1cc..6542c79 100644
--- a/src/base/ftbitmap.c
+++ b/src/base/ftbitmap.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType utility functions for bitmaps (body).                       */
 /*                                                                         */
-/*  Copyright 2004-2009, 2011, 2013 by                                     */
+/*  Copyright 2004-2009, 2011, 2013, 2014 by                               */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -375,14 +375,11 @@
   }
 
 
-  FT_Byte
+  static FT_Byte
   ft_gray_for_premultiplied_srgb_bgra( const FT_Byte*  bgra )
   {
-    FT_Long  a = bgra[3];
-    FT_Long  b = bgra[0];
-    FT_Long  g = bgra[1];
-    FT_Long  r = bgra[2];
-    FT_Long  l;
+    FT_Byte   a = bgra[3];
+    FT_ULong  l;
 
 
     /* Short-circuit transparent color to avoid div-by-zero. */
@@ -397,38 +394,30 @@
      *
      * http://accessibility.kde.org/hsl-adjusted.php
      *
-     * We do the computation with integers only.
+     * We do the computation with integers only, applying a gamma of 2.0.
+     * The following will never overflow 32 bits; it is a scaled-up
+     * luminosity with premultiplication not yet undone. 
+     *
      */
 
-    /* Undo premultification, get the number in a 16.16 form. */
-    b = FT_MulDiv( b, 65536, a );
-    g = FT_MulDiv( g, 65536, a );
-    r = FT_MulDiv( r, 65536, a );
-    a = a * 256;
-
-    /* Apply gamma of 2.0 instead of 2.2. */
-    b = FT_MulFix( b, b );
-    g = FT_MulFix( g, g );
-    r = FT_MulFix( r, r );
-
-    /* Apply coefficients. */
-    b = FT_MulFix( b,  4731 /* 0.0722 * 65536 */ );
-    g = FT_MulFix( g, 46871 /* 0.7152 * 65536 */ );
-    r = FT_MulFix( r, 13933 /* 0.2126 * 65536 */ );
-
-    l = r + g + b;
+    l =  4731UL /* 0.0722 * 65536 */ * bgra[0] * bgra[0] +
+        46871UL /* 0.7152 * 65536 */ * bgra[1] * bgra[1] +
+        13933UL /* 0.2126 * 65536 */ * bgra[2] * bgra[2];
 
     /*
-     * Final transparency can be determined this way:
+     * Final transparency can be determined as follows.
      *
      * - If alpha is zero, we want 0.
      * - If alpha is zero and luminosity is zero, we want 255.
      * - If alpha is zero and luminosity is one, we want 0.
      *
-     * So the formula is a * (1 - l).
+     * So the formula is a * (1 - l) = a - l * a.
+     *
+     * In the actual code, we undo premultiplication and scale down again.
+     *
      */
 
-    return (FT_Byte)( FT_MulFix( 65535 - l, a ) >> 8 );
+    return a - (FT_Byte)( ( l / a ) >> 16 );
   }
 
 
diff --git a/src/base/ftcalc.c b/src/base/ftcalc.c
index b23b4d4..4db43e0 100644
--- a/src/base/ftcalc.c
+++ b/src/base/ftcalc.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Arithmetic computations (body).                                      */
 /*                                                                         */
-/*  Copyright 1996-2006, 2008, 2012-2013 by                                */
+/*  Copyright 1996-2006, 2008, 2012-2014 by                                */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -39,6 +39,235 @@
 #include FT_INTERNAL_DEBUG_H
 #include FT_INTERNAL_OBJECTS_H
 
+
+#ifndef  FT_CONFIG_OPTION_NO_ASSEMBLER
+  /* Provide assembler fragments for performance-critical functions. */
+  /* These must be defined `static __inline__' with GCC.             */
+
+#if defined( __CC_ARM ) || defined( __ARMCC__ )  /* RVCT */
+
+#define FT_MULFIX_ASSEMBLER  FT_MulFix_arm
+
+  /* documentation is in freetype.h */
+
+  static __inline FT_Int32
+  FT_MulFix_arm( FT_Int32  a,
+                 FT_Int32  b )
+  {
+    register FT_Int32  t, t2;
+
+
+    __asm
+    {
+      smull t2, t,  b,  a           /* (lo=t2,hi=t) = a*b */
+      mov   a,  t,  asr #31         /* a   = (hi >> 31) */
+      add   a,  a,  #0x8000         /* a  += 0x8000 */
+      adds  t2, t2, a               /* t2 += a */
+      adc   t,  t,  #0              /* t  += carry */
+      mov   a,  t2, lsr #16         /* a   = t2 >> 16 */
+      orr   a,  a,  t,  lsl #16     /* a  |= t << 16 */
+    }
+    return a;
+  }
+
+#endif /* __CC_ARM || __ARMCC__ */
+
+
+#ifdef __GNUC__
+
+#if defined( __arm__ )                                 && \
+    ( !defined( __thumb__ ) || defined( __thumb2__ ) ) && \
+    !( defined( __CC_ARM ) || defined( __ARMCC__ ) )
+
+#define FT_MULFIX_ASSEMBLER  FT_MulFix_arm
+
+  /* documentation is in freetype.h */
+
+  static __inline__ FT_Int32
+  FT_MulFix_arm( FT_Int32  a,
+                 FT_Int32  b )
+  {
+    register FT_Int32  t, t2;
+
+
+    __asm__ __volatile__ (
+      "smull  %1, %2, %4, %3\n\t"       /* (lo=%1,hi=%2) = a*b */
+      "mov    %0, %2, asr #31\n\t"      /* %0  = (hi >> 31) */
+#if defined( __clang__ ) && defined( __thumb2__ )
+      "add.w  %0, %0, #0x8000\n\t"      /* %0 += 0x8000 */
+#else
+      "add    %0, %0, #0x8000\n\t"      /* %0 += 0x8000 */
+#endif
+      "adds   %1, %1, %0\n\t"           /* %1 += %0 */
+      "adc    %2, %2, #0\n\t"           /* %2 += carry */
+      "mov    %0, %1, lsr #16\n\t"      /* %0  = %1 >> 16 */
+      "orr    %0, %0, %2, lsl #16\n\t"  /* %0 |= %2 << 16 */
+      : "=r"(a), "=&r"(t2), "=&r"(t)
+      : "r"(a), "r"(b)
+      : "cc" );
+    return a;
+  }
+
+#endif /* __arm__                      && */
+       /* ( __thumb2__ || !__thumb__ ) && */
+       /* !( __CC_ARM || __ARMCC__ )      */
+
+
+#if defined( __i386__ )
+
+#define FT_MULFIX_ASSEMBLER  FT_MulFix_i386
+
+  /* documentation is in freetype.h */
+
+  static __inline__ FT_Int32
+  FT_MulFix_i386( FT_Int32  a,
+                  FT_Int32  b )
+  {
+    register FT_Int32  result;
+
+
+    __asm__ __volatile__ (
+      "imul  %%edx\n"
+      "movl  %%edx, %%ecx\n"
+      "sarl  $31, %%ecx\n"
+      "addl  $0x8000, %%ecx\n"
+      "addl  %%ecx, %%eax\n"
+      "adcl  $0, %%edx\n"
+      "shrl  $16, %%eax\n"
+      "shll  $16, %%edx\n"
+      "addl  %%edx, %%eax\n"
+      : "=a"(result), "=d"(b)
+      : "a"(a), "d"(b)
+      : "%ecx", "cc" );
+    return result;
+  }
+
+#endif /* i386 */
+
+#endif /* __GNUC__ */
+
+
+#ifdef _MSC_VER /* Visual C++ */
+
+#ifdef _M_IX86
+
+#define FT_MULFIX_ASSEMBLER  FT_MulFix_i386
+
+  /* documentation is in freetype.h */
+
+  static __inline FT_Int32
+  FT_MulFix_i386( FT_Int32  a,
+                  FT_Int32  b )
+  {
+    register FT_Int32  result;
+
+    __asm
+    {
+      mov eax, a
+      mov edx, b
+      imul edx
+      mov ecx, edx
+      sar ecx, 31
+      add ecx, 8000h
+      add eax, ecx
+      adc edx, 0
+      shr eax, 16
+      shl edx, 16
+      add eax, edx
+      mov result, eax
+    }
+    return result;
+  }
+
+#endif /* _M_IX86 */
+
+#endif /* _MSC_VER */
+
+
+#if defined( __GNUC__ ) && defined( __x86_64__ )
+
+#define FT_MULFIX_ASSEMBLER  FT_MulFix_x86_64
+
+  static __inline__ FT_Int32
+  FT_MulFix_x86_64( FT_Int32  a,
+                    FT_Int32  b )
+  {
+    /* Temporarily disable the warning that C90 doesn't support */
+    /* `long long'.                                             */
+#if ( __GNUC__ > 4 ) || ( ( __GNUC__ == 4 ) && ( __GNUC_MINOR__ >= 6 ) )
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wlong-long"
+#endif
+
+#if 1
+    /* Technically not an assembly fragment, but GCC does a really good */
+    /* job at inlining it and generating good machine code for it.      */
+    long long  ret, tmp;
+
+
+    ret  = (long long)a * b;
+    tmp  = ret >> 63;
+    ret += 0x8000 + tmp;
+
+    return (FT_Int32)( ret >> 16 );
+#else
+
+    /* For some reason, GCC 4.6 on Ubuntu 12.04 generates invalid machine  */
+    /* code from the lines below.  The main issue is that `wide_a' is not  */
+    /* properly initialized by sign-extending `a'.  Instead, the generated */
+    /* machine code assumes that the register that contains `a' on input   */
+    /* can be used directly as a 64-bit value, which is wrong most of the  */
+    /* time.                                                               */
+    long long  wide_a = (long long)a;
+    long long  wide_b = (long long)b;
+    long long  result;
+
+
+    __asm__ __volatile__ (
+      "imul %2, %1\n"
+      "mov %1, %0\n"
+      "sar $63, %0\n"
+      "lea 0x8000(%1, %0), %0\n"
+      "sar $16, %0\n"
+      : "=&r"(result), "=&r"(wide_a)
+      : "r"(wide_b)
+      : "cc" );
+
+    return (FT_Int32)result;
+#endif
+
+#if ( __GNUC__ > 4 ) || ( ( __GNUC__ == 4 ) && ( __GNUC_MINOR__ >= 6 ) )
+#pragma GCC diagnostic pop
+#endif
+  }
+
+#endif /* __GNUC__ && __x86_64__ */
+
+#if defined( __GNUC__ )
+#if ( __GNUC__ > 3 ) || ( ( __GNUC__ == 3 ) && ( __GNUC_MINOR__ >= 4 ) )
+
+#if FT_SIZEOF_INT == 4
+
+#define FT_MSB_BUILTIN( x )  ( 31 - __builtin_clz( x ) )
+
+#elif FT_SIZEOF_LONG == 4
+
+#define FT_MSB_BUILTIN( x )  ( 31 - __builtin_clzl( x ) )
+
+#endif
+
+#endif
+#endif /* __GNUC__ */
+
+#endif /* !FT_CONFIG_OPTION_NO_ASSEMBLER */
+
+
+#ifdef FT_CONFIG_OPTION_INLINE_MULFIX
+#ifdef FT_MULFIX_ASSEMBLER
+#define FT_MULFIX_INLINED  FT_MULFIX_ASSEMBLER
+#endif
+#endif
+
 #ifdef FT_MULFIX_INLINED
 #undef FT_MulFix
 #endif
@@ -103,6 +332,12 @@
   FT_BASE_DEF ( FT_Int )
   FT_MSB( FT_UInt32 z )
   {
+#ifdef FT_MSB_BUILTIN
+
+    return FT_MSB_BUILTIN( z );
+
+#else
+
     FT_Int shift = 0;
 
     /* determine msb bit index in `shift' */
@@ -128,11 +363,13 @@
     }
     if ( z >= ( 1L << 1 ) )
     {
-      z     >>= 1;
+   /* z     >>= 1; */
       shift  += 1;
     }
 
     return shift;
+
+#endif /* FT_MSB_BUILTIN */
   }
 
 
@@ -358,20 +595,26 @@
   /* documentation is in freetype.h */
 
   /* The FT_MulDiv function has been optimized thanks to ideas from      */
-  /* Graham Asher.  The trick is to optimize computation when everything */
-  /* fits within 32-bits (a rather common case).                         */
+  /* Graham Asher and Alexei Podtelezhnikov.  The trick is to optimize   */
+  /* a rather common case when everything fits within 32-bits.           */
   /*                                                                     */
-  /*  we compute 'a*b+c/2', then divide it by 'c'. (positive values)     */
+  /*  We compute 'a*b+c/2', then divide it by 'c'. (positive values)     */
   /*                                                                     */
-  /*  46340 is FLOOR(SQRT(2^31-1)).                                      */
+  /*  The product of two positive numbers never exceeds the square of    */
+  /*  their mean.  Therefore, we always avoid the overflow by imposing   */
   /*                                                                     */
-  /*  if ( a <= 46340 && b <= 46340 ) then ( a*b <= 0x7FFEA810 )         */
+  /*  ( a + b ) / 2 <= sqrt( X - c/2 )                                   */
   /*                                                                     */
-  /*  0x7FFFFFFF - 0x7FFEA810 = 0x157F0                                  */
+  /*  where X = 2^31 - 1.  Now we replace sqrt with a linear function    */
+  /*  that is smaller or equal in the entire range of c from 0 to X;     */
+  /*  it should be equal to sqrt(X) and sqrt(X/2) at the range termini.  */
+  /*  Substituting the linear solution and explicit numbers we get       */
   /*                                                                     */
-  /*  if ( c < 0x157F0*2 ) then ( a*b+c/2 <= 0x7FFFFFFF )                */
+  /*  a + b <= 92681.9 - c / 79108.95                                    */
   /*                                                                     */
-  /*  and 2*0x157F0 = 176096                                             */
+  /*  In practice we use a faster and even stronger inequality           */
+  /*                                                                     */
+  /*  a + b <= 92681 - (c >> 16)                                         */
   /*                                                                     */
 
   FT_EXPORT_DEF( FT_Long )
@@ -390,7 +633,7 @@
     s ^= b; b = FT_ABS( b );
     s ^= c; c = FT_ABS( c );
 
-    if ( a <= 46340L && b <= 46340L && c <= 176095L && c > 0 )
+    if ( (FT_ULong)a + (FT_ULong)b <= 92681UL - ( c >> 16 ) && c > 0 )
       a = ( a * b + ( c >> 1 ) ) / c;
 
     else if ( (FT_Int32)c > 0 )
@@ -427,7 +670,7 @@
     s ^= b; b = FT_ABS( b );
     s ^= c; c = FT_ABS( c );
 
-    if ( a <= 46340L && b <= 46340L && c > 0 )
+    if ( (FT_ULong)a + (FT_ULong)b <= 92681UL && c > 0 )
       a = a * b / c;
 
     else if ( (FT_Int32)c > 0 )
diff --git a/src/base/ftlcdfil.c b/src/base/ftlcdfil.c
index 852fb32..4aefb68 100644
--- a/src/base/ftlcdfil.c
+++ b/src/base/ftlcdfil.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType API for color filtering of subpixel bitmap glyphs (body).   */
 /*                                                                         */
-/*  Copyright 2006, 2008-2010, 2013 by                                     */
+/*  Copyright 2006, 2008-2010, 2013, 2014 by                               */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -46,9 +46,12 @@
       FT_Byte*  line = bitmap->buffer;
 
 
+      /* `fir' and `pix' must be at least 32 bit wide, since the sum of */
+      /* the values in `weights' can exceed 0xFF                        */
+
       for ( ; height > 0; height--, line += bitmap->pitch )
       {
-        FT_UInt  fir[5];
+        FT_UInt  fir[4];        /* below, `pix' is used as the 5th element */
         FT_UInt  val1, xx;
 
 
@@ -57,7 +60,6 @@
         fir[1] = weights[3] * val1;
         fir[2] = weights[4] * val1;
         fir[3] = 0;
-        fir[4] = 0;
 
         val1    = line[1];
         fir[0] += weights[1] * val1;
@@ -78,7 +80,7 @@
           fir[3] =          weights[4] * val;
 
           pix        >>= 8;
-          pix         |= -( pix >> 8 );
+          pix         |= (FT_UInt)-(FT_Int)( pix >> 8 );
           line[xx - 2] = (FT_Byte)pix;
         }
 
@@ -87,11 +89,11 @@
 
 
           pix          = fir[0] >> 8;
-          pix         |= -( pix >> 8 );
+          pix         |= (FT_UInt)-(FT_Int)( pix >> 8 );
           line[xx - 2] = (FT_Byte)pix;
 
           pix          = fir[1] >> 8;
-          pix         |= -( pix >> 8 );
+          pix         |= (FT_UInt)-(FT_Int)( pix >> 8 );
           line[xx - 1] = (FT_Byte)pix;
         }
       }
@@ -107,7 +109,7 @@
       for ( ; width > 0; width--, column++ )
       {
         FT_Byte*  col = column;
-        FT_UInt   fir[5];
+        FT_UInt   fir[4];       /* below, `pix' is used as the 5th element */
         FT_UInt   val1, yy;
 
 
@@ -116,7 +118,6 @@
         fir[1] = weights[3] * val1;
         fir[2] = weights[4] * val1;
         fir[3] = 0;
-        fir[4] = 0;
         col   += pitch;
 
         val1    = col[0];
@@ -139,7 +140,7 @@
           fir[3] =          weights[4] * val;
 
           pix           >>= 8;
-          pix            |= -( pix >> 8 );
+          pix            |= (FT_UInt)-(FT_Int)( pix >> 8 );
           col[-2 * pitch] = (FT_Byte)pix;
           col            += pitch;
         }
@@ -149,11 +150,11 @@
 
 
           pix             = fir[0] >> 8;
-          pix            |= -( pix >> 8 );
+          pix            |= (FT_UInt)-(FT_Int)( pix >> 8 );
           col[-2 * pitch] = (FT_Byte)pix;
 
           pix         = fir[1] >> 8;
-          pix        |= -( pix >> 8 );
+          pix        |= (FT_UInt)-(FT_Int)( pix >> 8 );
           col[-pitch] = (FT_Byte)pix;
         }
       }
diff --git a/src/base/ftobjs.c b/src/base/ftobjs.c
index bd0c66e..cc56105 100644
--- a/src/base/ftobjs.c
+++ b/src/base/ftobjs.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType private base classes (body).                            */
 /*                                                                         */
-/*  Copyright 1996-2013 by                                                 */
+/*  Copyright 1996-2014 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -1801,9 +1801,10 @@
     if ( error )
       return error;
 
+    /* POST resources must be sorted to concatenate properly */
     error = FT_Raccess_Get_DataOffsets( library, stream,
                                         map_offset, rdara_pos,
-                                        TTAG_POST,
+                                        TTAG_POST, TRUE,
                                         &data_offsets, &count );
     if ( !error )
     {
@@ -1816,9 +1817,11 @@
       return error;
     }
 
+    /* sfnt resources should not be sorted to preserve the face order by
+       QuickDraw API */
     error = FT_Raccess_Get_DataOffsets( library, stream,
                                         map_offset, rdara_pos,
-                                        TTAG_sfnt,
+                                        TTAG_sfnt, FALSE,
                                         &data_offsets, &count );
     if ( !error )
     {
@@ -3357,6 +3360,7 @@
     FT_UInt   gindex = 0;
 
 
+    /* only do something if we have a charmap, and we have glyphs at all */
     if ( face && face->charmap && face->num_glyphs )
     {
       gindex = FT_Get_Char_Index( face, 0 );
@@ -3943,11 +3947,17 @@
   static void
   ft_remove_renderer( FT_Module  module )
   {
-    FT_Library   library = module->library;
-    FT_Memory    memory  = library->memory;
+    FT_Library   library;
+    FT_Memory    memory;
     FT_ListNode  node;
 
 
+    library = module->library;
+    if ( !library )
+      return;
+
+    memory = library->memory;
+
     node = FT_List_Find( &library->renderers, module );
     if ( node )
     {
@@ -4463,7 +4473,7 @@
   }
 
 
-  FT_Error
+  static FT_Error
   ft_property_do( FT_Library        library,
                   const FT_String*  module_name,
                   const FT_String*  property_name,
@@ -4871,6 +4881,8 @@
       *p_arg1      = subg->arg1;
       *p_arg2      = subg->arg2;
       *p_transform = subg->transform;
+
+      error = FT_Err_Ok;
     }
 
     return error;
diff --git a/src/base/ftoutln.c b/src/base/ftoutln.c
index 35df0cd..4a39dcd 100644
--- a/src/base/ftoutln.c
+++ b/src/base/ftoutln.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType outline management (body).                                  */
 /*                                                                         */
-/*  Copyright 1996-2008, 2010, 2012-2013 by                                */
+/*  Copyright 1996-2008, 2010, 2012-2014 by                                */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -128,7 +128,7 @@
           v_start.x = ( v_start.x + v_last.x ) / 2;
           v_start.y = ( v_start.y + v_last.y ) / 2;
 
-          v_last = v_start;
+       /* v_last = v_start; */
         }
         point--;
         tags--;
diff --git a/src/base/ftrfork.c b/src/base/ftrfork.c
index 8049117..5352970 100644
--- a/src/base/ftrfork.c
+++ b/src/base/ftrfork.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Embedded resource forks accessor (body).                             */
 /*                                                                         */
-/*  Copyright 2004-2010, 2013 by                                           */
+/*  Copyright 2004-2010, 2013, 2014 by                                     */
 /*  Masatake YAMATO and Redhat K.K.                                        */
 /*                                                                         */
 /*  FT_Raccess_Get_HeaderInfo() and raccess_guess_darwin_hfsplus() are     */
@@ -29,6 +29,7 @@
 #include FT_INTERNAL_STREAM_H
 #include FT_INTERNAL_RFORK_H
 #include "basepic.h"
+#include "ftbase.h"
 
 #undef  FT_COMPONENT
 #define FT_COMPONENT  trace_raccess
@@ -151,6 +152,7 @@
                               FT_Long     map_offset,
                               FT_Long     rdata_pos,
                               FT_Long     tag,
+                              FT_Bool     sort_by_res_id,
                               FT_Long   **offsets,
                               FT_Long    *count )
   {
@@ -163,6 +165,7 @@
     FT_RFork_Ref  *ref = NULL;
 
 
+    FT_TRACE3(( "\n" ));
     error = FT_Stream_Seek( stream, map_offset );
     if ( error )
       return error;
@@ -183,6 +186,8 @@
                   (char)( 0xff & ( tag_internal >> 16 ) ),
                   (char)( 0xff & ( tag_internal >>  8 ) ),
                   (char)( 0xff & ( tag_internal >>  0 ) ) ));
+      FT_TRACE3(( "             : subcount=%d, suboffset=0x%04x\n",
+                  subcnt, rpos ));
 
       if ( tag_internal == tag )
       {
@@ -208,11 +213,24 @@
             goto Exit;
 
           ref[j].offset = temp & 0xFFFFFFL;
+          FT_TRACE3(( "             [%d]:"
+                      " resource_id=0x%04x, offset=0x%08x\n",
+                      j, ref[j].res_id, ref[j].offset ));
         }
 
-        ft_qsort( ref, *count, sizeof ( FT_RFork_Ref ),
-                  ( int(*)(const void*, const void*) )
-                  ft_raccess_sort_ref_by_id );
+        if (sort_by_res_id)
+        {
+          ft_qsort( ref, *count, sizeof ( FT_RFork_Ref ),
+                    ( int(*)(const void*, const void*) )
+                    ft_raccess_sort_ref_by_id );
+
+          FT_TRACE3(( "             -- sort resources by their ids --\n" ));
+          for ( j = 0; j < *count; ++ j ) {
+            FT_TRACE3(( "             [%d]:"
+                        " resource_id=0x%04x, offset=0x%08x\n",
+                        j, ref[j].res_id, ref[j].offset ));
+          }
+        }
 
         if ( FT_NEW_ARRAY( offsets_internal, *count ) )
           goto Exit;
diff --git a/src/base/ftutil.c b/src/base/ftutil.c
index 879d027..9f37189 100644
--- a/src/base/ftutil.c
+++ b/src/base/ftutil.c
@@ -411,26 +411,4 @@
   }
 
 
-  FT_BASE_DEF( FT_UInt32 )
-  ft_highpow2( FT_UInt32  value )
-  {
-    FT_UInt32  value2;
-
-
-    /*
-     *  We simply clear the lowest bit in each iteration.  When
-     *  we reach 0, we know that the previous value was our result.
-     */
-    for ( ;; )
-    {
-      value2 = value & (value - 1);  /* clear lowest bit */
-      if ( value2 == 0 )
-        break;
-
-      value = value2;
-    }
-    return value;
-  }
-
-
 /* END */
diff --git a/src/cache/ftcbasic.c b/src/cache/ftcbasic.c
index 84d336d..01be88c 100644
--- a/src/cache/ftcbasic.c
+++ b/src/cache/ftcbasic.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType basic cache interface (body).                           */
 /*                                                                         */
-/*  Copyright 2003-2007, 2009-2011, 2013 by                                */
+/*  Copyright 2003-2007, 2009-2011, 2013, 2014 by                          */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -229,7 +229,7 @@
   *
   */
 
-  FT_CALLBACK_TABLE_DEF
+  static
   const FTC_IFamilyClassRec  ftc_basic_image_family_class =
   {
     {
@@ -243,7 +243,7 @@
   };
 
 
-  FT_CALLBACK_TABLE_DEF
+  static
   const FTC_GCacheClassRec  ftc_basic_image_cache_class =
   {
     {
@@ -415,7 +415,7 @@
    *
    */
 
-  FT_CALLBACK_TABLE_DEF
+  static
   const FTC_SFamilyClassRec  ftc_basic_sbit_family_class =
   {
     {
@@ -430,7 +430,7 @@
   };
 
 
-  FT_CALLBACK_TABLE_DEF
+  static
   const FTC_GCacheClassRec  ftc_basic_sbit_cache_class =
   {
     {
diff --git a/src/cache/ftccmap.c b/src/cache/ftccmap.c
index 848349b..b2e9609 100644
--- a/src/cache/ftccmap.c
+++ b/src/cache/ftccmap.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType CharMap cache (body)                                        */
 /*                                                                         */
-/*  Copyright 2000-2013 by                                                 */
+/*  Copyright 2000-2014 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -202,7 +202,7 @@
   /*************************************************************************/
 
 
-  FT_CALLBACK_TABLE_DEF
+  static
   const FTC_CacheClassRec  ftc_cmap_cache_class =
   {
     ftc_cmap_node_new,
diff --git a/src/cff/cf2blues.c b/src/cff/cf2blues.c
index eec589e..250f89e 100644
--- a/src/cff/cf2blues.c
+++ b/src/cff/cf2blues.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Adobe's code for handling Blue Zones (body).                         */
 /*                                                                         */
-/*  Copyright 2009-2013 Adobe Systems Incorporated.                        */
+/*  Copyright 2009-2014 Adobe Systems Incorporated.                        */
 /*                                                                         */
 /*  This software, and all works of authorship, whether in source or       */
 /*  object code form as indicated by the copyright notice(s) included      */
@@ -408,11 +408,10 @@
       /* Note: constant changed from 0.5 to 0.6 to avoid a problem with */
       /*       10ppem Arial                                             */
 
-      blues->boost = FT_MulFix(
-                       cf2_floatToFixed( .6 ),
-                       ( cf2_intToFixed( 1 ) -
-                         FT_DivFix( blues->scale,
-                                    blues->blueScale ) ) );
+      blues->boost = cf2_floatToFixed( .6 ) -
+                       FT_MulDiv( cf2_floatToFixed ( .6 ),
+                                  blues->scale,
+                                  blues->blueScale );
       if ( blues->boost > 0x7FFF )
       {
         /* boost must remain less than 0.5, or baseline could go negative */
diff --git a/src/cff/cf2font.c b/src/cff/cf2font.c
index 718d1e2..6e99dc2 100644
--- a/src/cff/cf2font.c
+++ b/src/cff/cf2font.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Adobe's code for font instances (body).                              */
 /*                                                                         */
-/*  Copyright 2007-2013 Adobe Systems Incorporated.                        */
+/*  Copyright 2007-2014 Adobe Systems Incorporated.                        */
 /*                                                                         */
 /*  This software, and all works of authorship, whether in source or       */
 /*  object code form as indicated by the copyright notice(s) included      */
@@ -167,7 +167,7 @@
         if ( !xdelta )
           goto Try_x3;
 
-        *darkenAmount = FT_MulFix( x, FT_DivFix( ydelta, xdelta ) ) +
+        *darkenAmount = FT_MulDiv( x, ydelta, xdelta ) +
                           FT_DivFix( cf2_intToFixed( y1 ), ppem );
       }
 
@@ -184,7 +184,7 @@
           if ( !xdelta )
             goto Try_x4;
 
-          *darkenAmount = FT_MulFix( x, FT_DivFix( ydelta, xdelta ) ) +
+          *darkenAmount = FT_MulDiv( x, ydelta, xdelta ) +
                             FT_DivFix( cf2_intToFixed( y2 ), ppem );
         }
       }
@@ -202,7 +202,7 @@
           if ( !xdelta )
             goto Use_y4;
 
-          *darkenAmount = FT_MulFix( x, FT_DivFix( ydelta, xdelta ) ) +
+          *darkenAmount = FT_MulDiv( x, ydelta, xdelta ) +
                             FT_DivFix( cf2_intToFixed( y3 ), ppem );
         }
       }
@@ -233,13 +233,14 @@
     /* pointer to parsed font object */
     CFF_Decoder*  decoder = font->decoder;
 
-    FT_Bool  needExtraSetup;
+    FT_Bool  needExtraSetup = FALSE;
 
     /* character space units */
     CF2_Fixed  boldenX = font->syntheticEmboldeningAmountX;
     CF2_Fixed  boldenY = font->syntheticEmboldeningAmountY;
 
-    CF2_Fixed  ppem;
+    CFF_SubFont  subFont;
+    CF2_Fixed    ppem;
 
 
     /* clear previous error */
@@ -247,8 +248,12 @@
 
     /* if a CID fontDict has changed, we need to recompute some cached */
     /* data                                                            */
-    needExtraSetup =
-      (FT_Bool)( font->lastSubfont != cf2_getSubfont( decoder ) );
+    subFont = cf2_getSubfont( decoder );
+    if ( font->lastSubfont != subFont )
+    {
+      font->lastSubfont = subFont;
+      needExtraSetup    = TRUE;
+    }
 
     /* if ppem has changed, we need to recompute some cached data         */
     /* note: because of CID font matrix concatenation, ppem and transform */
diff --git a/src/cff/cf2ft.c b/src/cff/cf2ft.c
index 4abbc9d..cb8d31c 100644
--- a/src/cff/cf2ft.c
+++ b/src/cff/cf2ft.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType Glue Component to Adobe's Interpreter (body).               */
 /*                                                                         */
-/*  Copyright 2013 Adobe Systems Incorporated.                             */
+/*  Copyright 2013-2014 Adobe Systems Incorporated.                        */
 /*                                                                         */
 /*  This software, and all works of authorship, whether in source or       */
 /*  object code form as indicated by the copyright notice(s) included      */
@@ -61,7 +61,9 @@
 
     FT_ASSERT( unitsPerEm > 0 );
 
-    FT_ASSERT( transform->a > 0 && transform->d > 0 );
+    if ( transform->a <= 0 || transform->d <= 0 )
+      return FT_THROW( Invalid_Size_Handle );
+
     FT_ASSERT( transform->b == 0 && transform->c == 0 );
     FT_ASSERT( transform->tx == 0 && transform->ty == 0 );
 
@@ -236,10 +238,8 @@
 
     if ( *hinted )
     {
-      *x_scale = FT_DivFix( decoder->builder.glyph->x_scale,
-                            cf2_intToFixed( 64 ) );
-      *y_scale = FT_DivFix( decoder->builder.glyph->y_scale,
-                            cf2_intToFixed( 64 ) );
+      *x_scale = ( decoder->builder.glyph->x_scale + 32 ) / 64;
+      *y_scale = ( decoder->builder.glyph->y_scale + 32 ) / 64;
     }
     else
     {
@@ -357,9 +357,12 @@
       /* also get units per em to validate scale */
       font->unitsPerEm = (CF2_Int)cf2_getUnitsPerEm( decoder );
 
-      error2 = cf2_checkTransform( &transform, font->unitsPerEm );
-      if ( error2 )
-        return error2;
+      if ( scaled )
+      {
+        error2 = cf2_checkTransform( &transform, font->unitsPerEm );
+        if ( error2 )
+          return error2;
+      }
 
       error2 = cf2_getGlyphOutline( font, &buf, &transform, &glyphWidth );
       if ( error2 )
@@ -389,8 +392,16 @@
     FT_ASSERT( decoder                          &&
                decoder->builder.face            &&
                decoder->builder.face->root.size );
-    FT_ASSERT( decoder->builder.face->root.size->metrics.y_ppem );
 
+    /*
+     * Note that `y_ppem' can be zero if there wasn't a call to
+     * `FT_Set_Char_Size' or something similar.  However, this isn't a
+     * problem since we come to this place in the code only if
+     * FT_LOAD_NO_SCALE is set (the other case gets caught by
+     * `cf2_checkTransform').  The ppem value is needed to compute the stem
+     * darkening, which is disabled for getting the unscaled outline.
+     *
+     */
     return cf2_intToFixed(
              decoder->builder.face->root.size->metrics.y_ppem );
   }
@@ -508,7 +519,7 @@
                               CF2_UInt      idx,
                               CF2_Buffer    buf )
   {
-    FT_ASSERT( decoder && decoder->globals );
+    FT_ASSERT( decoder );
 
     FT_ZERO( buf );
 
@@ -516,6 +527,8 @@
     if ( idx >= decoder->num_globals )
       return TRUE;     /* error */
 
+    FT_ASSERT( decoder->globals );
+
     buf->start =
     buf->ptr   = decoder->globals[idx];
     buf->end   = decoder->globals[idx + 1];
@@ -581,7 +594,7 @@
                              CF2_UInt      idx,
                              CF2_Buffer    buf )
   {
-    FT_ASSERT( decoder && decoder->locals );
+    FT_ASSERT( decoder );
 
     FT_ZERO( buf );
 
@@ -589,6 +602,8 @@
     if ( idx >= decoder->num_locals )
       return TRUE;     /* error */
 
+    FT_ASSERT( decoder->locals );
+
     buf->start =
     buf->ptr   = decoder->locals[idx];
     buf->end   = decoder->locals[idx + 1];
diff --git a/src/cff/cf2hints.c b/src/cff/cf2hints.c
index 5f44161..81049f4 100644
--- a/src/cff/cf2hints.c
+++ b/src/cff/cf2hints.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Adobe's code for handling CFF hints (body).                          */
 /*                                                                         */
-/*  Copyright 2007-2013 Adobe Systems Incorporated.                        */
+/*  Copyright 2007-2014 Adobe Systems Incorporated.                        */
 /*                                                                         */
 /*  This software, and all works of authorship, whether in source or       */
 /*  object code form as indicated by the copyright notice(s) included      */
@@ -781,6 +781,8 @@
       cf2_hintmask_setAll( hintMask,
                            cf2_arrstack_size( hStemHintArray ) +
                              cf2_arrstack_size( vStemHintArray ) );
+      if ( !cf2_hintmask_isValid( hintMask ) )
+          return;                   /* too many stem hints */
     }
 
     /* begin by clearing the map */
@@ -1558,7 +1560,7 @@
         {
           /* -y */
           *x = -glyphpath->xOffset;
-          *y = glyphpath->xOffset;
+          *y = glyphpath->yOffset;
         }
         else
         {
diff --git a/src/cff/cffload.c b/src/cff/cffload.c
index ff271f3..d9bec59 100644
--- a/src/cff/cffload.c
+++ b/src/cff/cffload.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    OpenType and CFF data/program tables loader (body).                  */
 /*                                                                         */
-/*  Copyright 1996-2013 by                                                 */
+/*  Copyright 1996-2014 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -689,6 +689,13 @@
       if ( FT_READ_USHORT( num_ranges ) )
         goto Exit;
 
+      if ( !num_ranges )
+      {
+        FT_TRACE0(( "CFF_Load_FD_Select: empty FDSelect array\n" ));
+        error = FT_THROW( Invalid_File_Format );
+        goto Exit;
+      }
+
       fdselect->data_size = num_ranges * 3 + 2;
 
     Load_Data:
@@ -719,7 +726,7 @@
       break;
 
     case 3:
-      /* first, compare to cache */
+      /* first, compare to the cache */
       if ( (FT_UInt)( glyph_index - fdselect->cache_first ) <
                         fdselect->cache_count )
       {
@@ -727,7 +734,7 @@
         break;
       }
 
-      /* then, lookup the ranges array */
+      /* then, look up the ranges array */
       {
         FT_Byte*  p       = fdselect->data;
         FT_Byte*  p_limit = p + fdselect->data_size;
@@ -750,7 +757,7 @@
 
             /* update cache */
             fdselect->cache_first = first;
-            fdselect->cache_count = limit-first;
+            fdselect->cache_count = limit - first;
             fdselect->cache_fd    = fd2;
             break;
           }
diff --git a/src/cff/cffobjs.c b/src/cff/cffobjs.c
index 29c3691..cac4ac2 100644
--- a/src/cff/cffobjs.c
+++ b/src/cff/cffobjs.c
@@ -866,7 +866,7 @@
           flags |= FT_FACE_FLAG_KERNING;
 #endif
 
-        cffface->face_flags = flags;
+        cffface->face_flags |= flags;
 
         /*******************************************************************/
         /*                                                                 */
diff --git a/src/cff/cffparse.c b/src/cff/cffparse.c
index 9622212..91bd532 100644
--- a/src/cff/cffparse.c
+++ b/src/cff/cffparse.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    CFF token stream parser (body)                                       */
 /*                                                                         */
-/*  Copyright 1996-2004, 2007-2013 by                                      */
+/*  Copyright 1996-2004, 2007-2014 by                                      */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -66,7 +66,6 @@
         goto Bad;
 
       val = (FT_Short)( ( (FT_UShort)p[0] << 8 ) | p[1] );
-      p  += 2;
     }
     else if ( v == 29 )
     {
@@ -77,7 +76,6 @@
                        ( (FT_ULong)p[1] << 16 ) |
                        ( (FT_ULong)p[2] <<  8 ) |
                          (FT_ULong)p[3]         );
-      p += 4;
     }
     else if ( v < 247 )
     {
@@ -89,7 +87,6 @@
         goto Bad;
 
       val = ( v - 247 ) * 256 + p[0] + 108;
-      p++;
     }
     else
     {
@@ -97,7 +94,6 @@
         goto Bad;
 
       val = -( v - 251 ) * 256 - p[0] - 108;
-      p++;
     }
 
   Exit:
diff --git a/src/pfr/pfrload.c b/src/pfr/pfrload.c
index c19fceb..97c130a 100644
--- a/src/pfr/pfrload.c
+++ b/src/pfr/pfrload.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType PFR loader (body).                                          */
 /*                                                                         */
-/*  Copyright 2002-2005, 2007, 2009, 2010, 2013 by                         */
+/*  Copyright 2002-2005, 2007, 2009, 2010, 2013, 2014 by                   */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -813,7 +813,6 @@
           phy_font->ascent  = PFR_NEXT_SHORT( q );
           phy_font->descent = PFR_NEXT_SHORT( q );
           phy_font->leading = PFR_NEXT_SHORT( q );
-          q += 16;
           break;
 
         case 3:
diff --git a/src/psaux/psobjs.c b/src/psaux/psobjs.c
index dd976d3..b4b7d45 100644
--- a/src/psaux/psobjs.c
+++ b/src/psaux/psobjs.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auxiliary functions for PostScript fonts (body).                     */
 /*                                                                         */
-/*  Copyright 1996-2013 by                                                 */
+/*  Copyright 1996-2014 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -847,6 +847,8 @@
   /* first character must be a delimiter or a part of a number */
   /* NB: `values' can be NULL if we just want to skip the      */
   /*     array; in this case we ignore `max_values'            */
+  /*                                                           */
+  /* return number of successfully parsed values               */
 
   static FT_Int
   ps_tofixedarray( FT_Byte*  *acur,
@@ -1200,7 +1202,7 @@
 
           result = ps_tofixedarray( &cur, limit, 4, temp, 0 );
 
-          if ( result < 0 )
+          if ( result < 4 )
           {
             FT_ERROR(( "ps_parser_load_field:"
                        " expected four integers in bounding box\n" ));
@@ -1230,7 +1232,7 @@
           {
             result = ps_tofixedarray( &cur, limit, max_objects,
                                       temp + i * max_objects, 0 );
-            if ( result < 0 )
+            if ( result < 0 || (FT_UInt)result < max_objects )
             {
               FT_ERROR(( "ps_parser_load_field:"
                          " expected %d integers in the %s subarray\n"
diff --git a/src/pshinter/pshalgo.c b/src/pshinter/pshalgo.c
index 343472d..644c76d 100644
--- a/src/pshinter/pshalgo.c
+++ b/src/pshinter/pshalgo.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    PostScript hinting algorithm (body).                                 */
 /*                                                                         */
-/*  Copyright 2001-2010, 2012, 2013 by                                     */
+/*  Copyright 2001-2010, 2012-2014 by                                      */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used        */
@@ -1406,7 +1406,6 @@
 
       point  = first;
       before = point;
-      after  = point;
 
       do
       {
@@ -2079,8 +2078,6 @@
       start = first;
       do
       {
-        point = first;
-
         /* skip consecutive fitted points */
         for (;;)
         {
diff --git a/src/raster/ftraster.c b/src/raster/ftraster.c
index 8aa1113..abbecb7 100644
--- a/src/raster/ftraster.c
+++ b/src/raster/ftraster.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType glyph rasterizer (body).                                */
 /*                                                                         */
-/*  Copyright 1996-2003, 2005, 2007-2013 by                                */
+/*  Copyright 1996-2003, 2005, 2007-2014 by                                */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -1874,7 +1874,7 @@
         v_start.x = ( v_start.x + v_last.x ) / 2;
         v_start.y = ( v_start.y + v_last.y ) / 2;
 
-        v_last = v_start;
+     /* v_last = v_start; */
       }
       point--;
       tags--;
@@ -2284,6 +2284,8 @@
     Long   e1, e2;
     Byte*  target;
 
+    Int  dropOutControl = left->flags & 7;
+
     FT_UNUSED( y );
     FT_UNUSED( left );
     FT_UNUSED( right );
@@ -2293,7 +2295,8 @@
 
     e1 = TRUNC( CEILING( x1 ) );
 
-    if ( x2 - x1 - ras.precision <= ras.precision_jitter )
+    if ( dropOutControl != 2                             &&
+         x2 - x1 - ras.precision <= ras.precision_jitter )
       e2 = e1;
     else
       e2 = TRUNC( FLOOR( x2 ) );
diff --git a/src/sfnt/pngshim.c b/src/sfnt/pngshim.c
index 878de1f..9afbe5a 100644
--- a/src/sfnt/pngshim.c
+++ b/src/sfnt/pngshim.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    PNG Bitmap glyph support.                                            */
 /*                                                                         */
-/*  Copyright 2013 by Google, Inc.                                         */
+/*  Copyright 2013, 2014 by Google, Inc.                                   */
 /*  Written by Stuart Gill and Behdad Esfahbod.                            */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -129,7 +129,7 @@
 
     *error = FT_THROW( Out_Of_Memory );
 #ifdef PNG_SETJMP_SUPPORTED
-    longjmp( png_jmpbuf( png ), 1 );
+    ft_longjmp( png_jmpbuf( png ), 1 );
 #endif
     /* if we get here, then we have no choice but to abort ... */
   }
diff --git a/src/sfnt/sfdriver.c b/src/sfnt/sfdriver.c
index e0132c9..e4fcda5 100644
--- a/src/sfnt/sfdriver.c
+++ b/src/sfnt/sfdriver.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    High-level SFNT driver interface (body).                             */
 /*                                                                         */
-/*  Copyright 1996-2007, 2009-2013 by                                      */
+/*  Copyright 1996-2007, 2009-2014 by                                      */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -266,7 +266,7 @@
       {
         FT_Stream   stream = face->name_table.stream;
         FT_String*  r      = (FT_String*)result;
-        FT_Byte*    p      = (FT_Byte*)name->string;
+        FT_Byte*    p;
 
 
         if ( FT_STREAM_SEEK( name->stringOffset ) ||
diff --git a/src/sfnt/sfobjs.c b/src/sfnt/sfobjs.c
index a31c77c..44aa467 100644
--- a/src/sfnt/sfobjs.c
+++ b/src/sfnt/sfobjs.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    SFNT object management (base).                                       */
 /*                                                                         */
-/*  Copyright 1996-2008, 2010-2013 by                                      */
+/*  Copyright 1996-2008, 2010-2014 by                                      */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -348,29 +348,22 @@
   }
 
 
-#define WRITE_BYTE( p, v )     \
-          do                   \
-          {                    \
-            *(p)++ = (v) >> 0; \
-                               \
+#define WRITE_USHORT( p, v )                \
+          do                                \
+          {                                 \
+            *(p)++ = (FT_Byte)( (v) >> 8 ); \
+            *(p)++ = (FT_Byte)( (v) >> 0 ); \
+                                            \
           } while ( 0 )
 
-#define WRITE_USHORT( p, v )   \
-          do                   \
-          {                    \
-            *(p)++ = (v) >> 8; \
-            *(p)++ = (v) >> 0; \
-                               \
-          } while ( 0 )
-
-#define WRITE_ULONG( p, v )     \
-          do                    \
-          {                     \
-            *(p)++ = (v) >> 24; \
-            *(p)++ = (v) >> 16; \
-            *(p)++ = (v) >>  8; \
-            *(p)++ = (v) >>  0; \
-                                \
+#define WRITE_ULONG( p, v )                  \
+          do                                 \
+          {                                  \
+            *(p)++ = (FT_Byte)( (v) >> 24 ); \
+            *(p)++ = (FT_Byte)( (v) >> 16 ); \
+            *(p)++ = (FT_Byte)( (v) >>  8 ); \
+            *(p)++ = (FT_Byte)( (v) >>  0 ); \
+                                             \
           } while ( 0 )
 
 
@@ -661,6 +654,8 @@
       }
       else
       {
+#ifdef FT_CONFIG_OPTION_USE_ZLIB
+
         /* Uncompress with zlib. */
         FT_ULong  output_len = table->OrigLength;
 
@@ -675,6 +670,13 @@
           error = FT_THROW( Invalid_Table );
           goto Exit;
         }
+
+#else /* !FT_CONFIG_OPTION_USE_ZLIB */
+
+        error = FT_THROW( Unimplemented_Feature );
+        goto Exit;
+
+#endif /* !FT_CONFIG_OPTION_USE_ZLIB */
       }
 
       FT_FRAME_EXIT();
@@ -717,7 +719,6 @@
   }
 
 
-#undef WRITE_BYTE
 #undef WRITE_USHORT
 #undef WRITE_ULONG
 
diff --git a/src/sfnt/ttcmap.c b/src/sfnt/ttcmap.c
index 9b7856b..f9acf5d 100644
--- a/src/sfnt/ttcmap.c
+++ b/src/sfnt/ttcmap.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    TrueType character mapping table (cmap) support (body).              */
 /*                                                                         */
-/*  Copyright 2002-2010, 2012, 2013 by                                     */
+/*  Copyright 2002-2010, 2012-2014 by                                      */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -88,10 +88,16 @@
   tt_cmap0_validate( FT_Byte*      table,
                      FT_Validator  valid )
   {
-    FT_Byte*  p      = table + 2;
-    FT_UInt   length = TT_NEXT_USHORT( p );
+    FT_Byte*  p;
+    FT_UInt   length;
 
 
+    if ( table + 2 + 2 > valid->limit )
+      FT_INVALID_TOO_SHORT;
+
+    p      = table + 2;           /* skip format */
+    length = TT_NEXT_USHORT( p );
+
     if ( table + length > valid->limit || length < 262 )
       FT_INVALID_TOO_SHORT;
 
@@ -279,13 +285,20 @@
   tt_cmap2_validate( FT_Byte*      table,
                      FT_Validator  valid )
   {
-    FT_Byte*  p      = table + 2;           /* skip format */
-    FT_UInt   length = TT_PEEK_USHORT( p );
-    FT_UInt   n, max_subs;
-    FT_Byte*  keys;                         /* keys table */
-    FT_Byte*  subs;                         /* sub-headers */
-    FT_Byte*  glyph_ids;                    /* glyph ID array */
+    FT_Byte*  p;
+    FT_UInt   length;
 
+    FT_UInt   n, max_subs;
+    FT_Byte*  keys;        /* keys table     */
+    FT_Byte*  subs;        /* sub-headers    */
+    FT_Byte*  glyph_ids;   /* glyph ID array */
+
+
+    if ( table + 2 + 2 > valid->limit )
+      FT_INVALID_TOO_SHORT;
+
+    p      = table + 2;           /* skip format */
+    length = TT_NEXT_USHORT( p );
 
     if ( table + length > valid->limit || length < 6 + 512 )
       FT_INVALID_TOO_SHORT;
@@ -818,13 +831,20 @@
   tt_cmap4_validate( FT_Byte*      table,
                      FT_Validator  valid )
   {
-    FT_Byte*  p      = table + 2;               /* skip format */
-    FT_UInt   length = TT_NEXT_USHORT( p );
+    FT_Byte*  p;
+    FT_UInt   length;
+
     FT_Byte   *ends, *starts, *offsets, *deltas, *glyph_ids;
     FT_UInt   num_segs;
     FT_Error  error = FT_Err_Ok;
 
 
+    if ( table + 2 + 2 > valid->limit )
+      FT_INVALID_TOO_SHORT;
+
+    p      = table + 2;           /* skip format */
+    length = TT_NEXT_USHORT( p );
+
     if ( length < 16 )
       FT_INVALID_TOO_SHORT;
 
@@ -2044,9 +2064,9 @@
   tt_cmap12_validate( FT_Byte*      table,
                       FT_Validator  valid )
   {
-    FT_Byte*   p;
-    FT_ULong   length;
-    FT_ULong   num_groups;
+    FT_Byte*  p;
+    FT_ULong  length;
+    FT_ULong  num_groups;
 
 
     if ( table + 16 > valid->limit )
@@ -2110,8 +2130,6 @@
 
     char_code = cmap->cur_charcode + 1;
 
-    n = cmap->cur_group;
-
     for ( n = cmap->cur_group; n < cmap->num_groups; n++ )
     {
       p        = cmap->cmap.data + 16 + 12 * n;
@@ -2434,8 +2452,6 @@
 
     char_code = cmap->cur_charcode + 1;
 
-    n = cmap->cur_group;
-
     for ( n = cmap->cur_group; n < cmap->num_groups; n++ )
     {
       p        = cmap->cmap.data + 16 + 12 * n;
@@ -2758,11 +2774,18 @@
   tt_cmap14_validate( FT_Byte*      table,
                       FT_Validator  valid )
   {
-    FT_Byte*  p             = table + 2;
-    FT_ULong  length        = TT_NEXT_ULONG( p );
-    FT_ULong  num_selectors = TT_NEXT_ULONG( p );
+    FT_Byte*  p;
+    FT_ULong  length;
+    FT_ULong  num_selectors;
 
 
+    if ( table + 2 + 4 + 4 > valid->limit )
+      FT_INVALID_TOO_SHORT;
+
+    p             = table + 2;
+    length        = TT_NEXT_ULONG( p );
+    num_selectors = TT_NEXT_ULONG( p );
+
     if ( length > (FT_ULong)( valid->limit - table ) ||
          length < 10 + 11 * num_selectors            )
       FT_INVALID_TOO_SHORT;
@@ -3450,10 +3473,9 @@
     /* only recognize format 0 */
     if ( TT_NEXT_USHORT( p ) != 0 )
     {
-      p -= 2;
       FT_ERROR(( "tt_face_build_cmaps:"
                  " unsupported `cmap' table format = %d\n",
-                 TT_PEEK_USHORT( p ) ));
+                 TT_PEEK_USHORT( p - 2) ));
       return FT_THROW( Invalid_Table );
     }
 
diff --git a/src/sfnt/ttpost.c b/src/sfnt/ttpost.c
index 47a85c0..99d8005 100644
--- a/src/sfnt/ttpost.c
+++ b/src/sfnt/ttpost.c
@@ -5,7 +5,7 @@
 /*    Postcript name table processing for TrueType and OpenType fonts      */
 /*    (body).                                                              */
 /*                                                                         */
-/*  Copyright 1996-2003, 2006-2010, 2013 by                                */
+/*  Copyright 1996-2003, 2006-2010, 2013, 2014 by                          */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -64,12 +64,12 @@
 
 #define MAC_NAME( x )  ( (FT_String*)tt_post_default_names[x] )
 
-  /* the 258 default Mac PS glyph names */
+  /* the 258 default Mac PS glyph names; see file `tools/glnames.py' */
 
   static const FT_String* const  tt_post_default_names[258] =
   {
     /*   0 */
-    ".notdef", ".null", "CR", "space", "exclam",
+    ".notdef", ".null", "nonmarkingreturn", "space", "exclam",
     "quotedbl", "numbersign", "dollar", "percent", "ampersand",
     /*  10 */
     "quotesingle", "parenleft", "parenright", "asterisk", "plus",
@@ -120,7 +120,7 @@
     "ae", "oslash", "questiondown", "exclamdown", "logicalnot",
     "radical", "florin", "approxequal", "Delta", "guillemotleft",
     /* 170 */
-    "guillemotright", "ellipsis", "nbspace", "Agrave", "Atilde",
+    "guillemotright", "ellipsis", "nonbreakingspace", "Agrave", "Atilde",
     "Otilde", "OE", "oe", "endash", "emdash",
     /* 180 */
     "quotedblleft", "quotedblright", "quoteleft", "quoteright", "divide",
@@ -144,8 +144,8 @@
     "multiply", "onesuperior", "twosuperior", "threesuperior", "onehalf",
     "onequarter", "threequarters", "franc", "Gbreve", "gbreve",
     /* 250 */
-    "Idot", "Scedilla", "scedilla", "Cacute", "cacute",
-    "Ccaron", "ccaron", "dmacron",
+    "Idotaccent", "Scedilla", "scedilla", "Cacute", "cacute",
+    "Ccaron", "ccaron", "dcroat",
   };
 
 
diff --git a/src/sfnt/ttsbit.c b/src/sfnt/ttsbit.c
index 7469ff1..180d559 100644
--- a/src/sfnt/ttsbit.c
+++ b/src/sfnt/ttsbit.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    TrueType and OpenType embedded bitmap support (body).                */
 /*                                                                         */
-/*  Copyright 2005-2009, 2013 by                                           */
+/*  Copyright 2005-2009, 2013, 2014 by                                     */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  Copyright 2013 by Google, Inc.                                         */
@@ -256,7 +256,8 @@
     case TT_SBIT_TABLE_TYPE_SBIX:
       {
         FT_Stream       stream = face->root.stream;
-        FT_UInt         offset, ppem, resolution, upem;
+        FT_UInt         offset, upem;
+        FT_UShort       ppem, resolution;
         TT_HoriHeader  *hori;
         FT_ULong        table_size;
 
@@ -800,12 +801,12 @@
     FT_Error  error = FT_Err_Ok;
     FT_UInt   num_components, nn;
 
-    FT_Char  horiBearingX = decoder->metrics->horiBearingX;
-    FT_Char  horiBearingY = decoder->metrics->horiBearingY;
-    FT_Byte  horiAdvance  = decoder->metrics->horiAdvance;
-    FT_Char  vertBearingX = decoder->metrics->vertBearingX;
-    FT_Char  vertBearingY = decoder->metrics->vertBearingY;
-    FT_Byte  vertAdvance  = decoder->metrics->vertAdvance;
+    FT_Char  horiBearingX = (FT_Char)decoder->metrics->horiBearingX;
+    FT_Char  horiBearingY = (FT_Char)decoder->metrics->horiBearingY;
+    FT_Byte  horiAdvance  = (FT_Byte)decoder->metrics->horiAdvance;
+    FT_Char  vertBearingX = (FT_Char)decoder->metrics->vertBearingX;
+    FT_Char  vertBearingY = (FT_Char)decoder->metrics->vertBearingY;
+    FT_Byte  vertAdvance  = (FT_Byte)decoder->metrics->vertAdvance;
 
 
     if ( p + 2 > limit )
@@ -967,7 +968,6 @@
         break;
 
       case 2:
-      case 5:
       case 7:
         {
           /* Don't trust `glyph_format'.  For example, Apple's main Korean */
@@ -997,6 +997,10 @@
         }
         break;
 
+      case 5:
+        loader = tt_sbit_decoder_load_bit_aligned;
+        break;
+
       case 8:
         if ( p + 1 > p_limit )
           goto Fail;
@@ -1013,10 +1017,11 @@
       case 19: /* metrics in EBLC, PNG image data */
 #ifdef FT_CONFIG_OPTION_USE_PNG
         loader = tt_sbit_decoder_load_png;
+        break;
 #else
         error = FT_THROW( Unimplemented_Feature );
+        goto Fail;
 #endif /* FT_CONFIG_OPTION_USE_PNG */
-        break;
 
       default:
         error = FT_THROW( Invalid_Table );
@@ -1243,11 +1248,11 @@
                            FT_Bitmap           *map,
                            TT_SBit_MetricsRec  *metrics )
   {
-    FT_UInt     sbix_pos, strike_offset, glyph_start, glyph_end;
-    FT_ULong    table_size, data_size;
-    FT_Int      originOffsetX, originOffsetY;
-    FT_Tag      graphicType;
-    FT_Int      recurse_depth = 0;
+    FT_UInt   sbix_pos, strike_offset, glyph_start, glyph_end;
+    FT_ULong  table_size;
+    FT_Int    originOffsetX, originOffsetY;
+    FT_Tag    graphicType;
+    FT_Int    recurse_depth = 0;
 
     FT_Error  error;
     FT_Byte*  p;
@@ -1298,7 +1303,6 @@
     originOffsetY = FT_GET_SHORT();
 
     graphicType = FT_GET_TAG4();
-    data_size   = glyph_end - glyph_start - 8;
 
     switch ( graphicType )
     {
@@ -1322,7 +1326,7 @@
                              metrics,
                              stream->memory,
                              stream->cursor,
-                             data_size,
+                             glyph_end - glyph_start - 8,
                              TRUE );
 #else
       error = FT_THROW( Unimplemented_Feature );
@@ -1349,10 +1353,11 @@
 
       tt_face_get_metrics( face, FALSE, glyph_index, &abearing, &aadvance );
 
-      metrics->horiBearingX = originOffsetX;
-      metrics->horiBearingY = -originOffsetY + metrics->height;
-      metrics->horiAdvance  = aadvance * face->root.size->metrics.x_ppem /
-                                face->header.Units_Per_EM;
+      metrics->horiBearingX = (FT_Short)originOffsetX;
+      metrics->horiBearingY = (FT_Short)( -originOffsetY + metrics->height );
+      metrics->horiAdvance  = (FT_Short)( aadvance *
+                                          face->root.size->metrics.x_ppem /
+                                          face->header.Units_Per_EM );
     }
 
     return error;
diff --git a/src/smooth/ftgrays.c b/src/smooth/ftgrays.c
index 2c51e9f..27be966 100644
--- a/src/smooth/ftgrays.c
+++ b/src/smooth/ftgrays.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    A new `perfect' anti-aliasing renderer (body).                       */
 /*                                                                         */
-/*  Copyright 2000-2003, 2005-2013 by                                      */
+/*  Copyright 2000-2003, 2005-2014 by                                      */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -98,6 +98,9 @@
 #define FT_ERR_XCAT( x, y )  x ## y
 #define FT_ERR_CAT( x, y )   FT_ERR_XCAT( x, y )
 
+#define FT_BEGIN_STMNT  do {
+#define FT_END_STMNT    } while ( 0 )
+
 
   /* define this to dump debugging information */
 /* #define FT_DEBUG_LEVEL_TRACE */
@@ -1364,7 +1367,6 @@
         ras.num_gray_spans = 0;
         ras.span_y         = (int)y;
 
-        count = 0;
         span  = ras.gray_spans;
       }
       else
diff --git a/src/truetype/ttgload.c b/src/truetype/ttgload.c
index b10e390..ff2b339 100644
--- a/src/truetype/ttgload.c
+++ b/src/truetype/ttgload.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    TrueType Glyph Loader (body).                                        */
 /*                                                                         */
-/*  Copyright 1996-2013                                                    */
+/*  Copyright 1996-2014                                                    */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -99,13 +99,13 @@
 
     else if ( face->os2.version != 0xFFFFU )
     {
-      *tsb = face->os2.sTypoAscender - yMax;
+      *tsb = (FT_Short)( face->os2.sTypoAscender - yMax );
       *ah  = face->os2.sTypoAscender - face->os2.sTypoDescender;
     }
 
     else
     {
-      *tsb = face->horizontal.Ascender - yMax;
+      *tsb = (FT_Short)( face->horizontal.Ascender - yMax );
       *ah  = face->horizontal.Ascender - face->horizontal.Descender;
     }
 
@@ -2120,7 +2120,7 @@
       FT_Bool  reexecute = FALSE;
 
 
-      if ( !size->cvt_ready )
+      if ( size->bytecode_ready < 0 || size->cvt_ready < 0 )
       {
         FT_Error  error = tt_size_ready_bytecode( size, pedantic );
 
@@ -2128,6 +2128,10 @@
         if ( error )
           return error;
       }
+      else if ( size->bytecode_ready )
+        return size->bytecode_ready;
+      else if ( size->cvt_ready )
+        return size->cvt_ready;
 
       /* query new execution context */
       exec = size->debug ? size->context
@@ -2238,12 +2242,15 @@
 
       if ( reexecute )
       {
-        FT_UInt  i;
+        FT_UInt   i;
+        FT_Error  error;
 
 
         for ( i = 0; i < size->cvt_size; i++ )
           size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale );
-        tt_size_run_prep( size, pedantic );
+        error = tt_size_run_prep( size, pedantic );
+        if ( error )
+          return error;
       }
 
       /* see whether the cvt program has disabled hinting */
@@ -2346,8 +2353,6 @@
     TT_LoaderRec  loader;
 
 
-    error = FT_Err_Ok;
-
     FT_TRACE1(( "TT_Load_Glyph: glyph index %d\n", glyph_index ));
 
 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
diff --git a/src/truetype/ttinterp.c b/src/truetype/ttinterp.c
index 3f110c2..9491533 100644
--- a/src/truetype/ttinterp.c
+++ b/src/truetype/ttinterp.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    TrueType bytecode interpreter (body).                                */
 /*                                                                         */
-/*  Copyright 1996-2013                                                    */
+/*  Copyright 1996-2014                                                    */
 /*  by David Turner, Robert Wilhelm, and Werner Lemberg.                   */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -796,16 +796,13 @@
   FT_EXPORT_DEF( TT_ExecContext )
   TT_New_Context( TT_Driver  driver )
   {
-    TT_ExecContext  exec;
-    FT_Memory       memory;
+    FT_Memory  memory = driver->root.root.memory;
 
 
-    memory = driver->root.root.memory;
-    exec   = driver->context;
-
     if ( !driver->context )
     {
-      FT_Error  error;
+      FT_Error        error;
+      TT_ExecContext  exec;
 
 
       /* allocate object */
@@ -1470,7 +1467,7 @@
     __asm__ __volatile__ (
       "smull  %1, %2, %4, %3\n\t"       /* (lo=%1,hi=%2) = a*b */
       "mov    %0, %2, asr #31\n\t"      /* %0  = (hi >> 31) */
-#ifdef __clang__
+#if defined( __clang__ ) && defined( __thumb2__ )
       "add.w  %0, %0, #0x2000\n\t"      /* %0 += 0x2000 */
 #else
       "add    %0, %0, #0x2000\n\t"      /* %0 += 0x2000 */
@@ -7169,7 +7166,7 @@
         org_dist = CUR_fast_dualproj( &vec );
       }
 
-      cur_dist = CUR_Func_project ( &CUR.zp2.cur[point], cur_base );
+      cur_dist = CUR_Func_project( &CUR.zp2.cur[point], cur_base );
 
       if ( org_dist )
       {
@@ -7180,14 +7177,20 @@
           /* This is the same as what MS does for the invalid case:  */
           /*                                                         */
           /*   delta = (Original_Pt - Original_RP1) -                */
-          /*           (Current_Pt - Current_RP1)                    */
+          /*           (Current_Pt - Current_RP1)         ;          */
           /*                                                         */
           /* In FreeType speak:                                      */
           /*                                                         */
-          /*   new_dist = cur_dist -                                 */
-          /*              org_dist - cur_dist;                       */
+          /*   delta = org_dist - cur_dist          .                */
+          /*                                                         */
+          /* We move `point' by `new_dist - cur_dist' after leaving  */
+          /* this block, thus we have                                */
+          /*                                                         */
+          /*   new_dist - cur_dist = delta                   ,       */
+          /*   new_dist - cur_dist = org_dist - cur_dist     ,       */
+          /*              new_dist = org_dist                .       */
 
-          new_dist = -org_dist;
+          new_dist = org_dist;
         }
       }
       else
@@ -7593,9 +7596,9 @@
             else if ( CUR.ignore_x_mode )
             {
               if ( CUR.GS.freeVector.y != 0 )
-                B1 = CUR.zp0.cur[A].y;
+                B1 = (FT_UShort)CUR.zp0.cur[A].y;
               else
-                B1 = CUR.zp0.cur[A].x;
+                B1 = (FT_UShort)CUR.zp0.cur[A].x;
 
 #if 0
               /* Standard Subpixel Hinting: Allow y move.       */
@@ -7612,7 +7615,7 @@
                    !( CUR.sph_tweak_flags & SPH_TWEAK_ALWAYS_SKIP_DELTAP ) )
               {
                 /* save the y value of the point now; compare after move */
-                B1 = CUR.zp0.cur[A].y;
+                B1 = (FT_UShort)CUR.zp0.cur[A].y;
 
                 if ( CUR.sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES )
                   B = FT_PIX_ROUND( B1 + B ) - B1;
@@ -7624,7 +7627,7 @@
                   CUR_Func_move( &CUR.zp0, A, B );
               }
 
-              B2 = CUR.zp0.cur[A].y;
+              B2 = (FT_UShort)CUR.zp0.cur[A].y;
 
               /* Reverse this move if it results in a disallowed move */
               if ( CUR.GS.freeVector.y != 0                           &&
@@ -9032,10 +9035,13 @@
     /* If any errors have occurred, function tables may be broken. */
     /* Force a re-execution of `prep' and `fpgm' tables if no      */
     /* bytecode debugger is run.                                   */
-    if ( CUR.error && !CUR.instruction_trap )
+    if ( CUR.error
+         && !CUR.instruction_trap
+         && CUR.curRange == tt_coderange_glyph )
     {
       FT_TRACE1(( "  The interpreter returned error 0x%x\n", CUR.error ));
-      exc->size->cvt_ready      = FALSE;
+      exc->size->bytecode_ready = -1;
+      exc->size->cvt_ready      = -1;
     }
 
     return CUR.error;
diff --git a/src/truetype/ttobjs.c b/src/truetype/ttobjs.c
index 4adba58..05a121c 100644
--- a/src/truetype/ttobjs.c
+++ b/src/truetype/ttobjs.c
@@ -813,6 +813,8 @@
     else
       error = FT_Err_Ok;
 
+    size->bytecode_ready = error;
+
     if ( !error )
       TT_Save_Context( exec, size );
 
@@ -884,6 +886,8 @@
     else
       error = FT_Err_Ok;
 
+    size->cvt_ready = error;
+
     /* UNDOCUMENTED!  The MS rasterizer doesn't allow the following */
     /* graphics state variables to be modified by the CVT program.  */
 
@@ -912,10 +916,6 @@
     return error;
   }
 
-#endif /* TT_USE_BYTECODE_INTERPRETER */
-
-
-#ifdef TT_USE_BYTECODE_INTERPRETER
 
   static void
   tt_size_done_bytecode( FT_Size  ftsize )
@@ -953,8 +953,8 @@
     size->max_func = 0;
     size->max_ins  = 0;
 
-    size->bytecode_ready = 0;
-    size->cvt_ready      = 0;
+    size->bytecode_ready = -1;
+    size->cvt_ready      = -1;
   }
 
 
@@ -974,8 +974,8 @@
     TT_MaxProfile*  maxp = &face->max_profile;
 
 
-    size->bytecode_ready = 1;
-    size->cvt_ready      = 0;
+    size->bytecode_ready = -1;
+    size->cvt_ready      = -1;
 
     size->max_function_defs    = maxp->maxFunctionDefs;
     size->max_instruction_defs = maxp->maxInstructionDefs;
@@ -1052,15 +1052,14 @@
     FT_Error  error = FT_Err_Ok;
 
 
-    if ( !size->bytecode_ready )
-    {
+    if ( size->bytecode_ready < 0 )
       error = tt_size_init_bytecode( (FT_Size)size, pedantic );
-      if ( error )
-        goto Exit;
-    }
+
+    if ( error || size->bytecode_ready )
+      goto Exit;
 
     /* rescale CVT when needed */
-    if ( !size->cvt_ready )
+    if ( size->cvt_ready < 0 )
     {
       FT_UInt  i;
       TT_Face  face = (TT_Face)size->root.face;
@@ -1087,8 +1086,6 @@
       size->GS = tt_default_graphics_state;
 
       error = tt_size_run_prep( size, pedantic );
-      if ( !error )
-        size->cvt_ready = 1;
     }
 
   Exit:
@@ -1119,8 +1116,8 @@
     FT_Error  error = FT_Err_Ok;
 
 #ifdef TT_USE_BYTECODE_INTERPRETER
-    size->bytecode_ready = 0;
-    size->cvt_ready      = 0;
+    size->bytecode_ready = -1;
+    size->cvt_ready      = -1;
 #endif
 
     size->ttmetrics.valid = FALSE;
@@ -1148,7 +1145,7 @@
 
 
 #ifdef TT_USE_BYTECODE_INTERPRETER
-    if ( size->bytecode_ready )
+    if ( size->bytecode_ready >= 0 )
       tt_size_done_bytecode( ttsize );
 #endif
 
@@ -1229,7 +1226,7 @@
     }
 
 #ifdef TT_USE_BYTECODE_INTERPRETER
-    size->cvt_ready = 0;
+    size->cvt_ready = -1;
 #endif /* TT_USE_BYTECODE_INTERPRETER */
 
     if ( !error )
diff --git a/src/truetype/ttobjs.h b/src/truetype/ttobjs.h
index a11dd37..47d50d9 100644
--- a/src/truetype/ttobjs.h
+++ b/src/truetype/ttobjs.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Objects manager (specification).                                     */
 /*                                                                         */
-/*  Copyright 1996-2009, 2011-2013 by                                      */
+/*  Copyright 1996-2009, 2011-2014 by                                      */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -333,8 +333,10 @@
     FT_Bool            debug;
     TT_ExecContext     context;
 
-    FT_Bool            bytecode_ready;
-    FT_Bool            cvt_ready;
+    /* if negative, `fpgm' (resp. `prep'), wasn't executed yet; */
+    /* otherwise it is the returned error code                  */
+    FT_Error           bytecode_ready;
+    FT_Error           cvt_ready;
 
 #endif /* TT_USE_BYTECODE_INTERPRETER */
 
diff --git a/src/truetype/ttsubpix.c b/src/truetype/ttsubpix.c
index 28470ad..9871994 100644
--- a/src/truetype/ttsubpix.c
+++ b/src/truetype/ttsubpix.c
@@ -956,7 +956,7 @@
       if ( loader->exec->rasterizer_version != TT_INTERPRETER_VERSION_35 )
       {
         loader->exec->rasterizer_version = TT_INTERPRETER_VERSION_35;
-        loader->exec->size->cvt_ready    = FALSE;
+        loader->exec->size->cvt_ready    = -1;
 
         tt_size_ready_bytecode(
           loader->exec->size,
@@ -971,7 +971,7 @@
            SPH_OPTION_SET_RASTERIZER_VERSION )
       {
         loader->exec->rasterizer_version = SPH_OPTION_SET_RASTERIZER_VERSION;
-        loader->exec->size->cvt_ready    = FALSE;
+        loader->exec->size->cvt_ready    = -1;
 
         tt_size_ready_bytecode(
           loader->exec->size,