shithub: freetype+ttf2subf

Download patch

ref: 28534d616be45a45767e5cfa65164a863d068eea
parent: 7981fe2a0f9b79d384e98e8868bdeeaf9ec6b5f0
author: David Turner <[email protected]>
date: Mon Sep 1 17:35:21 EDT 2008

* include/freetype/ftadvanc.h, src/base/ftadvanc.c,
    include/freetype/config/ftheader.h, include/freetype/freetype.h,
    src/base/Jamfile, src/base/rules.mk, src/cff/cffdrivr.c,
    src/cff/cffgload.c, src/cff/cffgload.h, src/truetype/ttdriver.c,
    src/truetype/ttgload.h, src/truetype/ttgload.c, src/type1/t1driver.c,
    src/type1/t1gload.h, src/type1/t1gload.c:
    Add a new header named FT_ADVANCES_H declaring some new APIs
    to extract the advances of one or more glyphs without necessarily
    loading their outlines. Also provide 'fast loaders' for the
    TrueType, Type1 and CFF font drivers (more to come later)

    * autogen.sh: add checks for minimum version of the 'autotools'
    stuff.

git/fs: mount .git/fs: mount/attach disallowed
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2008-09-01  david turner <[email protected]>
+
+	* include/freetype/ftadvanc.h, src/base/ftadvanc.c,
+	include/freetype/config/ftheader.h, include/freetype/freetype.h,
+	src/base/Jamfile, src/base/rules.mk, src/cff/cffdrivr.c,
+	src/cff/cffgload.c, src/cff/cffgload.h, src/truetype/ttdriver.c,
+	src/truetype/ttgload.h, src/truetype/ttgload.c, src/type1/t1driver.c,
+	src/type1/t1gload.h, src/type1/t1gload.c:
+	Add a new header named FT_ADVANCES_H declaring some new APIs
+	to extract the advances of one or more glyphs without necessarily
+	loading their outlines. Also provide 'fast loaders' for the
+	TrueType, Type1 and CFF font drivers (more to come later) 
+
+	* autogen.sh: add checks for minimum version of the 'autotools'
+	stuff.
+
 2008-08-29  suzuki toshiya <[email protected]>
 
 	* src/sfnt/sfobjs.c (sfnt_open_font): Use TTAG_OTTO defined in
--- a/README.CVS
+++ b/README.CVS
@@ -13,17 +13,13 @@
 should work too, of course.   Note that autogen.sh also sets up proper
 file permissions for the `configure' and auxiliary scripts.
 
-A very common problem is that this script complains that the `aclocal'
-program doesn't accept a `--force' option:
+The autogen.sh script now checks the version of your installed auto tools
+to see if they match the numbers above. If not, it will complain and suggest
+either upgrading or using an environment variable to point to a more recent
+version of the required tool(s).
 
-  generating `configure.ac'
-  running `aclocal -I . --force'
-  aclocal: unrecognized option -- `--force'
-  Try `aclocal --help' for more information.
-  error while running `aclocal -I . --force'
-
-This  means that  your version  of the  automake package  is  too old.
-Please update it before trying to build FreeType.
+Note that 'aclocal' is provided by the 'automake' package on Linux, and
+that 'libtoolize' is called 'glibtoolize' on Darwin (OS X)
 
 
 For static builds which  don't use platform specific optimizations, no
--- a/autogen.sh
+++ b/autogen.sh
@@ -20,12 +20,119 @@
   fi
 }
 
+# extract major version
+get_major_version ()
+{
+    echo $1 | sed -e 's/\([0-9]\+\)\..*/\1/g'
+}
+
+get_minor_version ()
+{
+    echo $1 | sed -e 's/[0-9]\+\.\([0-9]\+\).*/\1/g'
+}
+
+get_patch_version ()
+{
+    # tricky, some version numbers don't include a patch
+    # separated with a point, but something like 1.4-p6
+    #
+    patch=`echo $1 | sed -e 's/[0-9]\+\.[0-9]\+\.\([0-9]\+\).*/\1/g'`
+    if test "$patch" = "$1"; then
+      patch=`echo $1 | sed -e 's/[0-9]\+\.[0-9]\+\-p\([0-9]\+\).*/\1/g'`
+      # if there isn't any patch number, default to 0
+      if test "$patch" = "$1"; then
+        patch=0
+      fi
+    fi
+    echo $patch
+}
+
+# $1: version to check
+# $2: minimum version
+compare_to_minimum_version ()
+{
+    MAJOR1=`get_major_version $1`
+    MAJOR2=`get_major_version $2`
+    if test $MAJOR1 -lt $MAJOR2; then
+      echo 0
+      return
+    else 
+      if test $MAJOR1 -gt $MAJOR2; then
+        echo 1
+        return
+      fi
+    fi
+
+    MINOR1=`get_minor_version $1`
+    MINOR2=`get_minor_version $2`
+    if test $MINOR1 -lt $MINOR2; then
+      echo 0
+      return
+    else 
+      if test $MINOR1 -gt $MINOR2; then
+        echo 1
+        return
+      fi
+    fi
+
+    PATCH1=`get_patch_version $1`
+    PATCH2=`get_patch_version $2`
+    if test $PATCH1 -lt $PATCH2; then
+        echo 0
+    else
+        echo 1
+    fi
+}
+
+
+# check that version of a given tool against a minimum version number
+# $1: tool path
+# $2: tool usual name (e.g. 'aclocal')
+# $3: tool variable  (e.g. 'ACLOCAL')
+# $4: minimum version to check against
+# $5: option field index used to extract the tool version from the output of --version
+#
+check_tool_version ()
+{
+  field=$5
+  if test "$field"x = x; then
+    field=4  # default to 4 for all GNU autotools
+  fi
+  version=`$1 --version | head -1 | cut -d ' ' -f $field`
+  version_check=`compare_to_minimum_version $version $4`
+  if test "$version_check"x = 0x; then
+      echo "ERROR: You $2 version is too old. minimum version $4 is required (yours is $version)"
+      echo "please upgrade or use the $3 variable to point to a more recent one"
+      echo ""
+      exit 1
+  fi
+}
+
 if test ! -f ./builds/unix/configure.raw; then
-  echo "You must be in the same directory as \`autogen.sh'."
-  echo "Bootstrapping doesn't work if srcdir != builddir."
-  exit 1
+ echo "You must be in the same directory as \`autogen.sh'."
+ echo "Bootstrapping doesn't work if srcdir != builddir."
+ exit 1
 fi
 
+# On MacOS X, the GNU libtool is named `glibtool'.
+HOSTOS=`uname`
+LIBTOOLIZE=libtoolize
+if test "$HOSTOS"x = Darwinx; then
+  LIBTOOLIZE=glibtoolize
+fi
+
+if test "$ACLOCAL"x = x; then
+  ACLOCAL=aclocal
+fi
+
+if test "$AUTOCONF"x = x; then
+  AUTOCONF=autoconf
+fi
+
+check_tool_version $ACLOCAL    aclocal ACLOCAL  1.10.1
+check_tool_version $LIBTOOLIZE libtoolize LIBTOOLIZE 2.2.4
+check_tool_version $AUTOCONF autoconf AUTOCONF 2.62
+
 # This sets freetype_major, freetype_minor, and freetype_patch.
 eval `sed -nf version.sed include/freetype/freetype.h`
 
@@ -39,13 +146,6 @@
 echo "generating \`configure.ac'"
 sed -e "s;@VERSION@;$freetype_major$freetype_minor$freetype_patch;" \
     < configure.raw > configure.ac
-
-# On MacOS X, the GNU libtool is named `glibtool'.
-HOSTOS=`uname`
-LIBTOOLIZE=libtoolize
-if test "$HOSTOS"x = Darwinx; then
-  LIBTOOLIZE=glibtoolize
-fi
 
 run aclocal -I . --force
 run $LIBTOOLIZE --force --copy --install
--- a/include/freetype/config/ftheader.h
+++ b/include/freetype/config/ftheader.h
@@ -728,6 +728,16 @@
    */
 #define FT_GASP_H  <freetype/ftgasp.h>
 
+  /*************************************************************************
+   *
+   * @macro:
+   *   FT_ADVANCES_H
+   *
+   * @description:
+   *   A macro used in #include statements to name the file containing the
+   *   FreeType~2 API which returns individual and ranged glyph advances
+   */
+#define FT_ADVANCES_H             <freetype/ftadvanc.h>
 
   /* */
 
--- a/include/freetype/freetype.h
+++ b/include/freetype/freetype.h
@@ -2431,8 +2431,11 @@
 #define FT_LOAD_IGNORE_TRANSFORM             0x800
 #define FT_LOAD_MONOCHROME                   0x1000
 #define FT_LOAD_LINEAR_DESIGN                0x2000
-#define FT_LOAD_SBITS_ONLY                   0x4000   /* temporary hack! */
 #define FT_LOAD_NO_AUTOHINT                  0x8000U
+#define FT_LOAD_ADVANCE_ONLY                 0x10000U
+
+  /* used internally only by certain font drivers ! */
+#define FT_LOAD_SBITS_ONLY                   0x4000
 
   /* */
 
--- a/include/freetype/internal/ftdriver.h
+++ b/include/freetype/internal/ftdriver.h
@@ -97,7 +97,6 @@
                              FT_UInt     right_glyph,
                              FT_Vector*  kerning );
 
-
   typedef FT_Error
   (*FT_Face_AttachFunc)( FT_Face    face,
                          FT_Stream  stream );
@@ -104,11 +103,11 @@
 
 
   typedef FT_Error
-  (*FT_Face_GetAdvancesFunc)( FT_Face     face,
-                              FT_UInt     first,
-                              FT_UInt     count,
-                              FT_Bool     vertical,
-                              FT_UShort*  advances );
+  (*FT_Face_GetAdvancesFunc)( FT_Face    face,
+                              FT_UInt    first,
+                              FT_UInt    count,
+                              FT_UInt    flags,
+                              FT_Fixed*  advances );
 
 
   /*************************************************************************/
--- a/src/base/Jamfile
+++ b/src/base/Jamfile
@@ -34,7 +34,7 @@
   local  _sources =  system  init    glyph  mm      bdf
                      bbox    debug   xf86   type1   pfr
                      stroke  winfnt  otval  bitmap  synth
-                     gxval   lcdfil  gasp   patent
+                     gxval   lcdfil  gasp   patent  advanc
                      ;
 
   Library  $(FT2_LIB) : ft$(_sources).c ;
--- a/src/base/rules.mk
+++ b/src/base/rules.mk
@@ -44,7 +44,9 @@
             $(BASE_DIR)/ftrfork.c  \
             $(BASE_DIR)/ftstream.c \
             $(BASE_DIR)/fttrigon.c \
-            $(BASE_DIR)/ftutil.c
+            $(BASE_DIR)/ftutil.c   \
+            $(BASE_DIR)/ftadvanc.c
+
 
 # Base layer `extensions' sources
 #
--- a/src/cff/cffdrivr.c
+++ b/src/cff/cffdrivr.c
@@ -187,6 +187,32 @@
   }
 
 
+  FT_CALLBACK_DEF(FT_Error)
+  cff_get_advances( FT_Face    ftface,
+                    FT_UInt    start,
+                    FT_UInt    count,
+                    FT_UInt    flags,
+                    FT_Fixed*  advances )
+  {
+    CFF_Face      face = (CFF_Face) ftface;
+    FT_UInt       nn;
+    FT_Error      error = 0;
+    FT_GlyphSlot  slot = face->root.glyph;
+
+    flags |= FT_LOAD_ADVANCE_ONLY;
+
+    for (nn = 0; nn < count; nn++)
+    {
+      error = Load_Glyph( slot, face->root.size, start+nn, flags );
+      if (error) break;
+
+      advances[nn] = (flags & FT_LOAD_VERTICAL_LAYOUT)
+                   ? slot->advance.y
+                   : slot->advance.x;
+    }
+    return error;
+  }
+
   /*
    *  GLYPH DICT SERVICE
    *
@@ -570,7 +596,7 @@
 
     cff_get_kerning,
     0,                      /* FT_Face_AttachFunc      */
-    0,                      /* FT_Face_GetAdvancesFunc */
+    cff_get_advances,       /* FT_Face_GetAdvancesFunc */
 
     cff_size_request,
 
--- a/src/cff/cffgload.c
+++ b/src/cff/cffgload.c
@@ -384,6 +384,11 @@
     decoder->hint_mode    = hint_mode;
   }
 
+  FT_LOCAL_DEF( void )
+  cff_decoder_set_width_only( CFF_Decoder*  decoder )
+  {
+    decoder->width_only = 1;
+  }
 
   /* this function is used to select the subfont */
   /* and the locals subrs array                  */
@@ -1200,6 +1205,12 @@
               decoder->glyph_width = decoder->nominal_width +
                                        ( stack[0] >> 16 );
 
+              if (decoder->width_only)
+              {
+                /* we only want the advance width, stop here */
+                break;
+              }
+
               /* Consumed an argument. */
               num_args--;
             }
@@ -2558,6 +2569,9 @@
 
       cff_decoder_init( &decoder, face, size, glyph, hinting,
                         FT_LOAD_TARGET_MODE( load_flags ) );
+
+      if ((load_flags & FT_LOAD_ADVANCE_ONLY) != 0)
+        cff_decoder_set_width_only( &decoder );
 
       decoder.builder.no_recurse =
         (FT_Bool)( ( load_flags & FT_LOAD_NO_RECURSE ) != 0 );
--- a/src/cff/cffgload.h
+++ b/src/cff/cffgload.h
@@ -139,6 +139,7 @@
     FT_Pos             nominal_width;
 
     FT_Bool            read_width;
+    FT_Bool            width_only;
     FT_Int             num_hints;
     FT_Fixed*          buildchar;
     FT_Int             len_buildchar;
@@ -167,6 +168,9 @@
                     CFF_GlyphSlot   slot,
                     FT_Bool         hinting,
                     FT_Render_Mode  hint_mode );
+
+  FT_LOCAL( void )
+  cff_decoder_set_width_only( CFF_Decoder*  decoder );
 
   FT_LOCAL( FT_Error )
   cff_decoder_prepare( CFF_Decoder*  decoder,
--- a/src/truetype/ttdriver.c
+++ b/src/truetype/ttdriver.c
@@ -125,6 +125,44 @@
 #undef PAIR_TAG
 
 
+  static FT_Error
+  tt_get_advances( FT_Face    ttface,
+                   FT_UInt    start,
+                   FT_UInt    count,
+                   FT_UInt    flags,
+                   FT_Fixed  *advances )
+  {
+    FT_UInt  nn;
+    TT_Face  face  = (TT_Face) ttface;
+    FT_Bool  check = FT_BOOL(!(flags & FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH));
+
+    /* XXX: TODO: check for sbits */
+
+    if (flags & FT_LOAD_VERTICAL_LAYOUT)
+    {
+      for (nn = 0; nn < count; nn++)
+      {
+        FT_Short   tsb;
+        FT_UShort  ah;
+
+        TT_Get_VMetrics( face, start + nn, check, &tsb, &ah );
+        advances[nn] = ah;
+      }
+    }
+    else
+    {
+      for (nn = 0; nn < count; nn++)
+      {
+        FT_Short   lsb;
+        FT_UShort  aw;
+
+        TT_Get_HMetrics( face, start + nn, check, &lsb, &aw );
+        advances[nn] = aw;
+      }
+    }
+    return 0;
+  }
+
   /*************************************************************************/
   /*************************************************************************/
   /*************************************************************************/
@@ -404,7 +442,7 @@
 
     tt_get_kerning,
     0,                      /* FT_Face_AttachFunc      */
-    0,                      /* FT_Face_GetAdvancesFunc */
+    tt_get_advances,
 
     tt_size_request,
 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
--- a/src/truetype/ttgload.c
+++ b/src/truetype/ttgload.c
@@ -69,12 +69,12 @@
   /* `check' is true, take care of monospaced fonts by returning the       */
   /* advance width maximum.                                                */
   /*                                                                       */
-  static void
-  Get_HMetrics( TT_Face     face,
-                FT_UInt     idx,
-                FT_Bool     check,
-                FT_Short*   lsb,
-                FT_UShort*  aw )
+  FT_LOCAL_DEF(void)
+  TT_Get_HMetrics( TT_Face     face,
+                   FT_UInt     idx,
+                   FT_Bool     check,
+                   FT_Short*   lsb,
+                   FT_UShort*  aw )
   {
     ( (SFNT_Service)face->sfnt )->get_metrics( face, 0, idx, lsb, aw );
 
@@ -96,12 +96,12 @@
   /* The monospace `check' is probably not meaningful here, but we leave   */
   /* it in for a consistent interface.                                     */
   /*                                                                       */
-  static void
-  Get_VMetrics( TT_Face     face,
-                FT_UInt     idx,
-                FT_Bool     check,
-                FT_Short*   tsb,
-                FT_UShort*  ah )
+  FT_LOCAL_DEF(void)
+  TT_Get_VMetrics( TT_Face     face,
+                   FT_UInt     idx,
+                   FT_Bool     check,
+                   FT_Short*   tsb,
+                   FT_UShort*  ah )
   {
     FT_UNUSED( check );
 
@@ -1143,16 +1143,16 @@
       FT_UShort  advance_width = 0, advance_height = 0;
 
 
-      Get_HMetrics( face, glyph_index,
-                    (FT_Bool)!( loader->load_flags &
-                                FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ),
-                    &left_bearing,
-                    &advance_width );
-      Get_VMetrics( face, glyph_index,
-                    (FT_Bool)!( loader->load_flags &
-                                FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ),
-                    &top_bearing,
-                    &advance_height );
+      TT_Get_HMetrics( face, glyph_index,
+                       (FT_Bool)!( loader->load_flags &
+                                   FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ),
+                       &left_bearing,
+                       &advance_width );
+      TT_Get_VMetrics( face, glyph_index,
+                       (FT_Bool)!( loader->load_flags &
+                                   FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ),
+                       &top_bearing,
+                       &advance_height );
 
 #ifdef FT_CONFIG_OPTION_INCREMENTAL
 
--- a/src/truetype/ttgload.h
+++ b/src/truetype/ttgload.h
@@ -34,6 +34,20 @@
   FT_LOCAL( void )
   TT_Init_Glyph_Loading( TT_Face  face );
 
+  FT_LOCAL(void)
+  TT_Get_HMetrics( TT_Face     face,
+                   FT_UInt     idx,
+                   FT_Bool     check,
+                   FT_Short*   lsb,
+                   FT_UShort*  aw );
+
+  FT_LOCAL(void)
+  TT_Get_VMetrics( TT_Face     face,
+                   FT_UInt     idx,
+                   FT_Bool     check,
+                   FT_Short*   tsb,
+                   FT_UShort*  ah );
+
   FT_LOCAL( FT_Error )
   TT_Load_Glyph( TT_Size       size,
                  TT_GlyphSlot  glyph,
--- a/src/type1/t1driver.c
+++ b/src/type1/t1driver.c
@@ -304,7 +304,7 @@
     (FT_Face_GetKerningFunc)  Get_Kerning,
     (FT_Face_AttachFunc)      T1_Read_Metrics,
 #endif
-    (FT_Face_GetAdvancesFunc) 0,
+    (FT_Face_GetAdvancesFunc) T1_Get_Advances,
     (FT_Size_RequestFunc)     T1_Size_Request,
     (FT_Size_SelectFunc)      0
   };
--- a/src/type1/t1gload.c
+++ b/src/type1/t1gload.c
@@ -203,6 +203,63 @@
 
 
   FT_LOCAL_DEF( FT_Error )
+  T1_Get_Advances( T1_Face    face,
+                   FT_UInt    first,
+                   FT_UInt    count,
+                   FT_ULong   load_flags,
+                   FT_Fixed*  advances )
+  {
+    T1_DecoderRec  decoder;
+    T1_Font        type1 = &face->type1;
+    PSAux_Service  psaux = (PSAux_Service)face->psaux;
+    FT_UInt        nn;
+    FT_Error       error;
+
+    if (load_flags & FT_LOAD_VERTICAL_LAYOUT)
+    {
+        for (nn = 0; nn < count; nn++)
+            advances[nn] = 0;
+
+        return T1_Err_Ok;
+    }
+
+    error = psaux->t1_decoder_funcs->init( &decoder,
+                                           (FT_Face)face,
+                                           0, /* size       */
+                                           0, /* glyph slot */
+                                           (FT_Byte**)type1->glyph_names,
+                                           face->blend,
+                                           0,
+                                           FT_RENDER_MODE_NORMAL,
+                                           T1_Parse_Glyph );
+    if ( error )
+      return error;
+
+    FT_UNUSED(load_flags);
+
+    decoder.builder.metrics_only = 1;
+    decoder.builder.load_points  = 0;
+
+    decoder.num_subrs     = type1->num_subrs;
+    decoder.subrs         = type1->subrs;
+    decoder.subrs_len     = type1->subrs_len;
+
+    decoder.buildchar     = face->buildchar;
+    decoder.len_buildchar = face->len_buildchar;
+
+    for ( nn = 0; nn < count; nn++ )
+    {
+      error = T1_Parse_Glyph( &decoder, first + nn );
+      if (!error)
+        advances[nn] = decoder.builder.advance.x;
+      else
+        advances[nn] = 0;
+    }
+    return T1_Err_Ok;
+  }
+
+
+  FT_LOCAL_DEF( FT_Error )
   T1_Load_Glyph( T1_GlyphSlot  glyph,
                  T1_Size       size,
                  FT_UInt       glyph_index,
--- a/src/type1/t1gload.h
+++ b/src/type1/t1gload.h
@@ -32,6 +32,13 @@
                           FT_Pos*  max_advance );
 
   FT_LOCAL( FT_Error )
+  T1_Get_Advances( T1_Face    face,
+                   FT_UInt    first,
+                   FT_UInt    count,
+                   FT_ULong   load_flags,
+                   FT_Fixed*  advances );
+
+  FT_LOCAL( FT_Error )
   T1_Load_Glyph( T1_GlyphSlot  glyph,
                  T1_Size       size,
                  FT_UInt       glyph_index,