shithub: freetype+ttf2subf

Download patch

ref: 89a2a4b531cec490761ac971c7a222d2bcec441f
parent: 8def3c897f3dc31797796220c443fffd625e55dc
author: David Turner <[email protected]>
date: Wed Dec 14 15:38:15 EST 2005

* include/freetype/config/ftoption.h,
        include/freetype/config/ftstdlib.h,
        include/freetype/internal/tttypes.h,
        src/sfnt/Jamfile, src/sfnt/rules.mk, src/sfnt/sfdriver.c,
        src/sfnt/ttbdf.h, src/sfnt/ttbdf.c, src/sfnt/sfobjs.c:

        Added support for an embedded 'BDF ' table within SFNT-based
        bitmap font files. This is used to store atoms & properties from
        the original BDF fonts that were used to generate the font file.

        the feature is controled by TT_CONFIG_OPTION_BDF within 'ftoption.h'
        and is used to implement FT_Get_BDF_Property for these font files.

        At the moment, this is still experimental, the BDF table format isn't
        cast into stone yet.

git/fs: mount .git/fs: mount/attach disallowed
--- a/ChangeLog
+++ b/ChangeLog
@@ -12,6 +12,8 @@
         same location than other generated objects (i.e. within the 'objs'
         directory of the current dir)
 
+        * src/sfnt/
+
 2005-12-07  Werner Lemberg  <[email protected]>
 
 	* src/sfnt/sfobjc.c (sfnt_init_face): Move tag check to...
--- a/include/freetype/config/ftoption.h
+++ b/include/freetype/config/ftoption.h
@@ -101,9 +101,7 @@
   /*                                                                       */
   /*   FreeType now handles font files that have been compressed with the  */
   /*   'compress' program.  This is mostly used to parse many of the PCF   */
-  /*   files that come with various X11 distributions.  The implementation */
-  /*   uses NetBSD's `zopen' to partially uncompress the file on the fly   */
-  /*   (see src/lzw/ftgzip.c).                                             */
+  /*   files that come with various X11 distributions.                     */
   /*                                                                       */
   /*   Define this macro if you want to enable this `feature'.             */
   /*                                                                       */
@@ -494,7 +492,14 @@
 
 
   /*************************************************************************/
+  /*                                                                       */
+  /* Define TT_CONFIG_OPTION_BDF if upi want to include support for        */
+  /* an embedded 'BDF' table within SFNT-based bitmap formats.             */
+  /*                                                                       */
+#define TT_CONFIG_OPTION_BDF
+
   /*************************************************************************/
+  /*************************************************************************/
   /****                                                                 ****/
   /****      T Y P E 1   D R I V E R    C O N F I G U R A T I O N       ****/
   /****                                                                 ****/
@@ -546,6 +551,7 @@
   /* driver.                                                               */
   /*                                                                       */
 #undef T1_CONFIG_OPTION_NO_MM_SUPPORT
+
 
  /* */
 
--- a/include/freetype/config/ftstdlib.h
+++ b/include/freetype/config/ftstdlib.h
@@ -92,6 +92,7 @@
 #define ft_memcpy   memcpy
 #define ft_memmove  memmove
 #define ft_memset   memset
+#define ft_memchr   memchr
 #define ft_strcat   strcat
 #define ft_strcmp   strcmp
 #define ft_strcpy   strcpy
--- a/include/freetype/internal/tttypes.h
+++ b/include/freetype/internal/tttypes.h
@@ -843,7 +843,69 @@
   typedef struct GX_BlendRec_  *GX_Blend;
 #endif
 
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+  /***                                                                   ***/
+  /***                                                                   ***/
+  /***       EMBEDDED BDF PROPERTIES TABLE SUPPORT                       ***/
+  /***                                                                   ***/
+  /***                                                                   ***/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
 
+/* these types are used to support a 'BDF' table that isn't part of the
+ * official TrueType specification. It is mainly used in SFNT-based bitmap
+ * fonts that were generated from a set of BDF fonts
+ *
+ * the format of the table is the following:
+ *
+ *   USHORT   version      'BDF' table version number, should be 0x0001
+ *   USHORT   strikeCount  number of strikes (bitmap sizes) in this table
+ *   ULONG    stringTable  offset (froms start of BDF table) to string table
+ *
+ * followed by an array of 'strikeCount' descriptors that look like:
+ *
+ *   USHORT   ppem         vertical pixels per EM for this strike
+ *   USHORT   numItems     number of items for this strike (properties and
+ *                         atoms), max is 255
+ *
+ * this array is followed by 'strikeCount' value sets. Each "value set"
+ * is an array of 'numItems' items that look like the following:
+ *
+ *   ULONG    item_name     offset in string table to item name
+ *   USHORT   item_type     0 => string (e.g. COMMENT)
+ *                          1 => atom   (e.g. FONT or even SIZE)
+ *                          2 => int32
+ *                          3 => uint32
+ *                       0x10 => flag for properties, ored with above values
+ *
+ *   ULONG    item_value    for strings => offset in string table without
+ *                                         the corresponding double quotes
+ *
+ *                              atoms   => offset in string table
+ *
+ *                              integers => direct value
+ *
+ * all strings in the string table are 8-bit, zero-terminated
+ */
+
+#ifdef TT_CONFIG_OPTION_BDF
+
+  typedef struct TT_BDFRec_
+  {
+    FT_Byte*       table;
+    FT_Byte*       table_end;
+    FT_Byte*       strings;
+    FT_UInt32      strings_size;
+    FT_UInt        num_strikes;
+    FT_Bool        loaded;
+
+  } TT_BDFRec, *TT_BDF;
+
+#endif /* TT_CONFIG_OPTION_BDF */
+
   /*************************************************************************/
   /*************************************************************************/
   /*************************************************************************/
@@ -1341,6 +1403,10 @@
     FT_Bool               doblend;
     GX_Blend              blend;
 #endif
+
+#ifdef TT_CONFIG_OPTION_BDF
+    TT_BDFRec        bdf;
+#endif /* TT_CONFIG_OPTION_BDF */
 
     /***********************************************************************/
     /*                                                                     */
--- a/include/freetype/tttags.h
+++ b/include/freetype/tttags.h
@@ -36,6 +36,7 @@
 #define TTAG_avar  FT_MAKE_TAG( 'a', 'v', 'a', 'r' )
 #define TTAG_BASE  FT_MAKE_TAG( 'B', 'A', 'S', 'E' )
 #define TTAG_bdat  FT_MAKE_TAG( 'b', 'd', 'a', 't' )
+#define TTAG_BDF   FT_MAKE_TAG( 'B', 'D', 'F', ' ' )
 #define TTAG_bhed  FT_MAKE_TAG( 'b', 'h', 'e', 'd' )
 #define TTAG_bloc  FT_MAKE_TAG( 'b', 'l', 'o', 'c' )
 #define TTAG_bsln  FT_MAKE_TAG( 'b', 's', 'l', 'n' )
--- a/src/sfnt/Jamfile
+++ b/src/sfnt/Jamfile
@@ -16,7 +16,7 @@
 
   if $(FT2_MULTI)
   {
-    _sources = sfobjs sfdriver ttcmap ttpost ttload ttsbit ttkern ;
+    _sources = sfobjs sfdriver ttcmap ttpost ttload ttsbit ttkern ttbdf ;
   }
   else
   {
--- a/src/sfnt/rules.mk
+++ b/src/sfnt/rules.mk
@@ -30,6 +30,7 @@
                 $(SFNT_DIR)/ttsbit.c   \
                 $(SFNT_DIR)/ttpost.c   \
                 $(SFNT_DIR)/ttkern.c   \
+                $(SFNT_DIR)/ttbdf.c    \
                 $(SFNT_DIR)/sfobjs.c   \
                 $(SFNT_DIR)/sfdriver.c
 
--- a/src/sfnt/sfdriver.c
+++ b/src/sfnt/sfdriver.c
@@ -34,6 +34,11 @@
 #include "ttpost.h"
 #endif
 
+#ifdef TT_CONFIG_OPTION_BDF
+#include "ttbdf.h"
+#include FT_SERVICE_BDF_H
+#endif
+
 #include "ttcmap.h"
 #include "ttkern.h"
 
@@ -293,7 +298,52 @@
     (TT_CMap_Info_GetFunc)tt_get_cmap_info
   };
 
+#ifdef TT_CONFIG_OPTION_BDF
 
+  static FT_Error
+  sfnt_get_charset_id( TT_Face       face,
+                       const char*  *acharset_encoding,
+                       const char*  *acharset_registry )
+  {
+    BDF_PropertyRec   encoding, registry;
+    FT_Error          error;
+
+   /* XXX: I don't know if this is correct, since tt_face_find_bdf_prop
+    *      will only return something correct if we have previously
+    *      selected a size that is listed in the BDF table.
+    *      should we change the BDF table format to include single
+    *      offsets for "CHARSET_REGISTRY" and "CHARSET_ENCODING" ?
+    */
+    error = tt_face_find_bdf_prop( face, "CHARSET_REGISTRY", &registry );
+    if ( !error )
+    {
+      error = tt_face_find_bdf_prop( face, "CHARSET_ENCODING", &encoding );
+      if ( !error )
+      {
+        if ( registry.type == BDF_PROPERTY_TYPE_ATOM &&
+             encoding.type == BDF_PROPERTY_TYPE_ATOM )
+        {
+          *acharset_encoding = encoding.u.atom;
+          *acharset_registry = registry.u.atom;
+        }
+        else
+          error = FT_Err_Invalid_Argument;
+      }
+    }
+
+    return error;
+  }
+
+
+  static const FT_Service_BDFRec  sfnt_service_bdf =
+  {
+    (FT_BDF_GetCharsetIdFunc) sfnt_get_charset_id,
+    (FT_BDF_GetPropertyFunc)  tt_face_find_bdf_prop,
+  };
+
+#endif /* TT_CONFIG_OPTION_BDF */
+
+
  /*
   *  SERVICE LIST
   *
@@ -305,6 +355,9 @@
     { FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &sfnt_service_ps_name },
 #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
     { FT_SERVICE_ID_GLYPH_DICT,           &sfnt_service_glyph_dict },
+#endif
+#ifdef TT_CONFIG_OPTION_BDF
+    { FT_SERVICE_ID_BDF,                  &sfnt_service_bdf },
 #endif
     { FT_SERVICE_ID_TT_CMAP,              &tt_service_get_cmap_info },
 
--- a/src/sfnt/sfnt.c
+++ b/src/sfnt/sfnt.c
@@ -33,5 +33,8 @@
 #include "ttpost.c"
 #endif
 
+#ifdef TT_CONFIG_OPTION_BDF
+#include "ttbdf.c"
+#endif
 
 /* END */
--- a/src/sfnt/sfobjs.c
+++ b/src/sfnt/sfobjs.c
@@ -27,6 +27,9 @@
 #include FT_SERVICE_POSTSCRIPT_CMAPS_H
 #include "sferrors.h"
 
+#ifdef TT_CONFIG_OPTION_BDF
+#include "ttbdf.h"
+#endif
 
   /*************************************************************************/
   /*                                                                       */
@@ -751,6 +754,11 @@
       if ( sfnt->free_sbits )
         sfnt->free_sbits( face );
     }
+
+#ifdef TT_CONFIG_OPTION_BDF
+    /* freeing the embedded BDF properties */
+    tt_face_free_bdf_props( face );
+#endif
 
     /* freeing the kerning table */
     tt_face_done_kern( face );
--- /dev/null
+++ b/src/sfnt/ttbdf.c
@@ -1,0 +1,237 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ttbdf.c                                                                */
+/*                                                                         */
+/*    TrueType and OpenType embedded BDF properties (body).                */
+/*                                                                         */
+/*  Copyright 2005 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_INTERNAL_DEBUG_H
+#include FT_INTERNAL_STREAM_H
+#include FT_TRUETYPE_TAGS_H
+#include "ttbdf.h"
+
+#include "sferrors.h"
+
+#ifdef TT_CONFIG_OPTION_BDF
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* 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_ttbdf
+
+FT_LOCAL_DEF( void )
+tt_face_free_bdf_props( TT_Face  face )
+{
+  TT_BDF   bdf = &face->bdf;
+
+  if ( bdf->loaded )
+  {
+    FT_Stream  stream = FT_FACE(face)->stream;
+
+    if ( bdf->table != NULL )
+      FT_FRAME_RELEASE( bdf->table );
+
+    bdf->table_end    = NULL;
+    bdf->strings      = NULL;
+    bdf->strings_size = 0;
+  }
+}
+
+
+static FT_Error
+tt_face_load_bdf_props( TT_Face    face,
+                        FT_Stream  stream )
+{
+  TT_BDF    bdf = &face->bdf;
+  FT_ULong  length;
+  FT_Error  error;
+
+  FT_ZERO( bdf );
+
+  error = tt_face_goto_table( face, TTAG_BDF, stream, &length );
+  if ( error                                  ||
+       length < 8                             ||
+       FT_FRAME_EXTRACT( length, bdf->table ) )
+  {
+    error = FT_Err_Invalid_Table;
+    goto Exit;
+  }
+
+  bdf->table_end = bdf->table + length;
+
+  {
+    FT_Byte*  p           = bdf->table;
+    FT_UInt   version     = FT_NEXT_USHORT(p);
+    FT_UInt   num_strikes = FT_NEXT_USHORT(p);
+    FT_UInt32 strings     = FT_NEXT_ULONG(p);
+
+    if ( version != 0x0001           ||
+         strings < 8                 ||
+         (strings-8)/4 < num_strikes ||
+         strings+1 > length          )
+    {
+    BadTable:
+      FT_FRAME_RELEASE( bdf->table );
+      FT_ZERO( bdf );
+      error = FT_Err_Invalid_Table;
+      goto Exit;
+    }
+
+    bdf->num_strikes  = num_strikes;
+    bdf->strings      = bdf->table + strings;
+    bdf->strings_size = length - strings;
+  }
+
+ /* check the strike descriptors
+  */
+  {
+    FT_UInt   count  = bdf->num_strikes;
+    FT_Byte*  p      = bdf->table + 8;
+    FT_Byte*  strike = p + count*4;
+
+    for ( ; count > 0; count-- )
+    {
+      FT_UInt  num_items = FT_PEEK_USHORT(p+2);
+
+     /* we don't need to check the value sets themselves, since this
+      * is done later
+      */
+      strike += 10*num_items;
+
+      p += 4;
+    }
+
+    if ( strike > bdf->strings )
+      goto BadTable;
+  }
+
+  bdf->loaded = 1;
+
+Exit:
+  return error;
+}
+
+
+FT_LOCAL_DEF( FT_Error )
+tt_face_find_bdf_prop( TT_Face           face,
+                       const char*       property_name,
+                       BDF_PropertyRec  *aprop )
+{
+  TT_BDF    bdf   = &face->bdf;
+  FT_Size   size  = FT_FACE(face)->size;
+  FT_Error  error = 0;
+  FT_Byte*  p;
+  FT_UInt   count;
+  FT_Byte*  strike;
+  FT_UInt   property_len;
+
+  aprop->type = BDF_PROPERTY_TYPE_NONE;
+
+  if ( bdf->loaded == 0 )
+  {
+    error = tt_face_load_bdf_props( face, FT_FACE(face)->stream );
+    if ( error )
+      goto Exit;
+  }
+
+  count  = bdf->num_strikes;
+  p      = bdf->table + 8;
+  strike = p + 4*count;
+
+  error = FT_Err_Invalid_Argument;
+
+  if ( size == NULL || property_name == NULL )
+    goto Exit;
+
+  property_len = ft_strlen( property_name );
+  if ( property_len == 0 )
+    goto Exit;
+
+  for ( ; count > 0; count-- )
+  {
+    FT_UInt   _ppem  = FT_NEXT_USHORT(p);
+    FT_UInt   _count = FT_NEXT_USHORT(p);
+
+    if ( _ppem == size->metrics.y_ppem )
+    {
+      count = _count;
+      goto FoundStrike;
+    }
+
+    strike += 10*_count;
+  }
+  goto Exit;
+
+FoundStrike:
+  p = strike;
+  for ( ; count > 0; count-- )
+  {
+    FT_UInt   type = FT_PEEK_USHORT(p+4);
+
+    if ( (type & 0x10) != 0 )
+    {
+      FT_UInt32  name_offset = FT_PEEK_ULONG(p);
+      FT_UInt32  value       = FT_PEEK_ULONG(p+6);
+
+      /* be a bit paranoid for invalid entries here */
+      if ( name_offset < bdf->strings_size                        &&
+           property_len < bdf->strings_size - name_offset         &&
+           ft_strncmp( property_name, (const char*)bdf->strings + name_offset,
+                       bdf->strings_size - name_offset ) == 0     )
+      {
+        switch ( type & 0x0F )
+        {
+          case 0x00:  /* string */
+          case 0x01:  /* atoms */
+            /* check that the content is really 0-terminated */
+            if ( value < bdf->strings_size &&
+                 ft_memchr( bdf->strings + value, 0, bdf->strings_size ) )
+            {
+              aprop->type   = BDF_PROPERTY_TYPE_ATOM;
+              aprop->u.atom = (const char*) bdf->strings + value;
+              error         = 0;
+              goto Exit;
+            }
+            break;
+
+          case 0x02:
+            aprop->type      = BDF_PROPERTY_TYPE_INTEGER;
+            aprop->u.integer = (FT_Int32)value;
+            error            = 0;
+            goto Exit;
+
+          case 0x03:
+            aprop->type       = BDF_PROPERTY_TYPE_CARDINAL;
+            aprop->u.cardinal = value;
+            error             = 0;
+            goto Exit;
+
+          default:
+            ;
+        }
+      }
+    }
+    p += 10;
+  }
+
+Exit:
+  return error;
+}
+
+#endif /* TT_CONFIG_OPTION_BDF */
--- /dev/null
+++ b/src/sfnt/ttbdf.h
@@ -1,0 +1,46 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ttbdf.h                                                                */
+/*                                                                         */
+/*    TrueType and OpenType embedded BDF properties (specification).       */
+/*                                                                         */
+/*  Copyright 2005 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 __TTBDF_H__
+#define __TTBDF_H__
+
+
+#include <ft2build.h>
+#include "ttload.h"
+#include FT_BDF_H
+
+
+FT_BEGIN_HEADER
+
+
+  FT_LOCAL( void )
+  tt_face_free_bdf_props( TT_Face  face );
+
+
+  FT_LOCAL( FT_Error )
+  tt_face_find_bdf_prop( TT_Face           face,
+                         const char*       property_name,
+                         BDF_PropertyRec  *aprop );
+
+
+FT_END_HEADER
+
+#endif /* __TTBDF_H__ */
+
+
+/* END */