shithub: freetype+ttf2subf

Download patch

ref: 11187206791326f7e851b62e13107723ce2c6505
parent: fea68c680017286953caccd14ecb5188a732d0e6
author: David Turner <[email protected]>
date: Fri May 26 13:13:23 EDT 2000

finalised the multiple masters support
fixed some nasty little bugs too

git/fs: mount .git/fs: mount/attach disallowed
--- a/CHANGES
+++ b/CHANGES
@@ -1,5 +1,14 @@
 LATEST_CHANGES
 
+  - added support for Multiple Master fonts in "type1z". There is also
+    a new file named <freetype/ftmm.h> which defines functions to
+    manage them from client applications.
+    
+    The new file "src/base/ftmm.c" is also optional to the engine..
+
+  - various formatting changes (e.g. EXPORT_DEF -> FT_EXPORT_DEF) +
+    small bug fixes in FT_Load_Glyph, the "type1" driver, etc..
+
   - a minor fix to the Type 1 driver to let them apply the font matrix
     correctly (used for many oblique fonts..)
 
--- a/include/freetype/freetype.h
+++ b/include/freetype/freetype.h
@@ -733,7 +733,18 @@
   /*                                                                       */
 #define FT_FACE_FLAG_FAST_GLYPHS  0x80
 
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Constant>                                                            */
+  /*    FT_FACE_FLAG_MULTIPLE_MASTERS                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A bit-field constant, used to indicate that the font contains      */
+  /*    multiple masters and is capable of interpolating between them..    */
+  /*                                                                       */
+#define FT_FACE_FLAG_MULTIPLE_MASTERS  0x100
 
+
 #define FT_HAS_HORIZONTAL(face)  (face->face_flags & FT_FACE_FLAG_HORIZONTAL)
 #define FT_HAS_VERTICAL(face)    (face->face_flags & FT_FACE_FLAG_VERTICAL)
 #define FT_HAS_KERNING(face)     (face->face_flags & FT_FACE_FLAG_KERNING)
@@ -743,6 +754,8 @@
 #define FT_HAS_FIXED_SIZES(face) (face->face_flags & FT_FACE_FLAG_FIXED_SIZES)
 #define FT_HAS_FAST_GLYPHS(face) (face->face_flags & FT_FACE_FLAG_FAST_GLYPHS)
 
+#define FT_HAS_MULTIPLE_MASTERS(face) \
+          (face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS)
 
   /*************************************************************************/
   /*                                                                       */
@@ -1964,7 +1977,7 @@
   /*    application if you want something simpler.                         */
   /*                                                                       */
   FT_EXPORT_DEF(FT_Error)  FT_Outline_Done( FT_Library   library,
-                                         FT_Outline*  outline );
+                                            FT_Outline*  outline );
 
   /*************************************************************************/
   /*                                                                       */
--- /dev/null
+++ b/include/freetype/ftmm.h
@@ -1,0 +1,163 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ftmm.h                                                                 */
+/*                                                                         */
+/*    FreeType Multiple-Master interface.                                  */
+/*                                                                         */
+/*                                                                         */
+/*  Copyright 1996-2000 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 FTMM_H
+#define FTMM_H
+
+#include <freetype/t1tables.h>
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+ /**********************************************************************
+  *
+  * <Struct>
+  *    FT_MM_Axis
+  *
+  * <Description>
+  *    A simple structure used to model a given axis in design space
+  *    for multiple masters fonts..
+  *
+  * <Fields>
+  *    name     :: axis' name
+  *    minimum  :: axis' minimum design coordinate
+  *    maximum  :: axis's maximum design coordinate
+  *
+  */
+  typedef struct FT_MM_Axis_
+  {
+    FT_String*  name;
+    FT_Long     minimum;
+    FT_Long     maximum;
+  
+  } FT_MM_Axis;
+
+ /**********************************************************************
+  *
+  * <Struct>
+  *    FT_Multi_Master
+  *
+  * <Description>
+  *    A structure used to model the axis and space of a multiple    
+  *    masters font.               
+  *
+  * <Fields>
+  *    num_axis    :: number of axis. cannot exceed 4
+  *
+  *    num_designs :: number of designs, should ne normally 2^num_axis
+  *                   even though the Type 1 specification strangely
+  *                   allows for intermediate designs to be present
+  *                   this number cannot exceed 16
+  *
+  *    axis        :: an table of axis descriptors..
+  *
+  */
+  typedef struct FT_Multi_Master_
+  {
+    FT_UInt     num_axis;
+    FT_UInt     num_designs;
+    FT_MM_Axis  axis[ T1_MAX_MM_AXIS ];
+  
+  } FT_Multi_Master;
+
+
+  typedef  FT_Error  (*FT_Get_MM_Func)( FT_Face  face, FT_Multi_Master* master );
+  
+  typedef  FT_Error  (*FT_Set_MM_Design_Func)( FT_Face   face,
+                                               FT_UInt   num_coords,
+                                               FT_Long*  coords );
+
+  typedef  FT_Error  (*FT_Set_MM_Blend_Func)( FT_Face   face,
+                                              FT_UInt   num_coords,
+                                              FT_Long*  coords );
+
+ /*************************************************************************
+  *
+  *  <Function>
+  *     FT_Get_Multi_Master
+  *
+  *  <Description>
+  *     Retrieves the multiple master descriptor of a given font
+  *
+  *  <Input>
+  *     face    :: handle to source face
+  *
+  *  <Output>
+  *     master  :: multiple masters descriptor
+  *
+  *  <Return>
+  *     Error code. 0 means success.
+  *
+  */
+  FT_EXPORT_DEF(FT_Error)   FT_Get_Multi_Master( FT_Face           face,
+                                                 FT_Multi_Master*  master );
+
+
+ /*************************************************************************
+  *
+  *  <Function>
+  *     FT_Set_MM_Design_Coordinates
+  *
+  *  <Description>
+  *     For multiple masters fonts, choose an interpolated font design
+  *     through design coordinates
+  *
+  *  <Input>
+  *     face       :: handle to source face
+  *     num_coords :: number of design coordinates (must be equal to the
+  *                   number of axis in the font).
+  *     coords     :: design coordinates
+  *
+  *  <Return>
+  *     Error code. 0 means success.
+  *
+  */
+  FT_EXPORT_DEF(FT_Error)   FT_Set_MM_Design_Coordinates( FT_Face  face,
+                                                          FT_UInt  num_coords,
+                                                          FT_Long* coords );
+
+ /*************************************************************************
+  *
+  *  <Function>
+  *     FT_Set_MM_Blend_Coordinates
+  *
+  *  <Description>
+  *     For multiple masters fonts, choose an interpolated font design
+  *     through normalized blend coordinates
+  *
+  *  <Input>
+  *     face       :: handle to source face
+  *     num_coords :: number of design coordinates (must be equal to the
+  *                   number of axis in the font).
+  *     coords     :: design coordinates (each one must be between 0 and 1.0)
+  *
+  *  <Return>
+  *     Error code. 0 means success.
+  *
+  */
+  FT_EXPORT_DEF(FT_Error)   FT_Set_MM_Blend_Coordinates( FT_Face   face,
+                                                         FT_UInt   num_coords,
+                                                         FT_Fixed* coords );
+
+#ifdef __cplusplus
+  }
+#endif
+
+#endif /* FTMM_H */
+/* END */
--- /dev/null
+++ b/src/base/ftmm.c
@@ -1,0 +1,66 @@
+#include <freetype/ftmm.h>
+#include <freetype/internal/ftobjs.h>
+
+  FT_EXPORT_FUNC(FT_Error)   FT_Get_Multi_Master( FT_Face           face,
+                                                  FT_Multi_Master*  master )
+  {
+    FT_Error  error;
+    
+    error = FT_Err_Invalid_Argument;
+    if (face && FT_HAS_MULTIPLE_MASTERS(face))
+    {
+      FT_Driver       driver = face->driver;
+      FT_Get_MM_Func  func;
+
+      func   = (FT_Get_MM_Func)driver->interface.get_interface(
+                                                   driver, "get_mm" );
+      if (func)
+        error = func(face,master);
+    }
+      
+    return error;
+  }                                                  
+
+
+  FT_EXPORT_FUNC(FT_Error)   FT_Set_MM_Design_Coordinates( FT_Face  face,
+                                                           FT_UInt  num_coords,
+                                                           FT_Long* coords )
+  {
+    FT_Error  error;
+    
+    error = FT_Err_Invalid_Argument;
+    if (face && FT_HAS_MULTIPLE_MASTERS(face))
+    {
+      FT_Driver              driver = face->driver;
+      FT_Set_MM_Design_Func  func;
+
+      func = (FT_Set_MM_Design_Func)driver->interface.get_interface(
+                                             driver, "set_mm_design" );
+      if (func)
+        error = func(face,num_coords,coords);
+    }
+      
+    return error;
+  }                                                           
+
+  FT_EXPORT_FUNC(FT_Error)   FT_Set_MM_Blend_Coordinates( FT_Face   face,
+                                                          FT_UInt   num_coords,
+                                                          FT_Fixed* coords )
+  {                                                          
+    FT_Error  error;
+    
+    error = FT_Err_Invalid_Argument;
+    if (face && FT_HAS_MULTIPLE_MASTERS(face))
+    {
+      FT_Driver              driver = face->driver;
+      FT_Set_MM_Blend_Func  func;
+
+      func = (FT_Set_MM_Blend_Func)driver->interface.get_interface(
+                                             driver, "set_mm_blend" );
+      if (func)
+        error = func(face,num_coords,coords);
+    }
+      
+    return error;
+  }
+
--- a/src/base/ftobjs.c
+++ b/src/base/ftobjs.c
@@ -1638,6 +1638,12 @@
     memory    = driver->memory;
 
     /* default processing - this can be overriden by the driver */
+    if (pixel_width == 0)
+      pixel_width = pixel_height;
+      
+    else if (pixel_height == 0)
+      pixel_height = pixel_width;
+      
     if ( pixel_width  < 1 ) pixel_width  = 1;
     if ( pixel_height < 1 ) pixel_height = 1;
 
--- a/src/base/rules.mk
+++ b/src/base/rules.mk
@@ -56,6 +56,7 @@
 #
 BASE_EXT_SRC := $(BASE_)ftraster.c \
                 $(BASE_)ftglyph.c  \
+                $(BASE_)ftmm.c     \
                 $(BASE_)ftgrays.c
 
 # Base layer extensions headers
--- a/src/sfnt/sfdriver.c
+++ b/src/sfnt/sfdriver.c
@@ -1,4 +1,5 @@
 #include <freetype/internal/sfnt.h>
+#include <freetype/internal/ftobjs.h>
 #include <sfdriver.h>
 #include <ttload.h>
 #include <ttsbit.h>
--- a/src/type1z/t1driver.c
+++ b/src/type1z/t1driver.c
@@ -26,7 +26,6 @@
 #undef  FT_COMPONENT
 #define FT_COMPONENT  trace_t1driver
 
-#ifndef T1_CONFIG_OPTION_NO_AFM
   /*************************************************************************/
   /*                                                                       */
   /* <Function>                                                            */
@@ -59,15 +58,28 @@
                                      const FT_String*  interface )
   {
     UNUSED(driver);
-
+    UNUSED(interface);
+    
+#ifndef T1_CONFIG_OPTION_NO_AFM
     if ( strcmp( (const char*)interface, "attach_file" ) == 0 )
       return (FTDriver_Interface)T1_Read_AFM;
+#endif
 
+#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT
+    if ( strcmp( (const char*)interface, "get_mm" ) == 0 )
+      return (FTDriver_Interface)T1_Get_Multi_Master;
+      
+    if ( strcmp( (const char*)interface, "set_mm_design") == 0 )
+      return (FTDriver_Interface)T1_Set_MM_Design;      
+
+    if ( strcmp( (const char*)interface, "set_mm_blend") == 0 )
+      return (FTDriver_Interface)T1_Set_MM_Blend;      
+#endif
     return 0;
   }
 
 
-
+#ifndef T1_CONFIG_OPTION_NO_AFM
   /*************************************************************************/
   /*                                                                       */
   /* <Function>                                                            */
@@ -375,11 +387,7 @@
     (FTDriver_initDriver)           T1_Init_Driver,
     (FTDriver_doneDriver)           T1_Done_Driver,
 
-#ifdef T1_CONFIG_OPTION_NO_AFM
-    (FTDriver_getInterface)         0,
-#else
     (FTDriver_getInterface)         Get_Interface,
-#endif
 
     (FTDriver_initFace)             T1_Init_Face,
     (FTDriver_doneFace)             T1_Done_Face,
--- a/src/type1z/t1load.c
+++ b/src/type1z/t1load.c
@@ -61,6 +61,7 @@
 
 #include <freetype/internal/ftdebug.h>
 #include <freetype/config/ftconfig.h>
+#include <freetype/ftmm.h>
 
 #include <freetype/internal/t1types.h>
 #include <t1errors.h>
@@ -70,6 +71,7 @@
 #undef  FT_COMPONENT
 #define FT_COMPONENT  trace_t1load
 
+#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT
  /***************************************************************************/
  /***************************************************************************/
  /*****                                                                 *****/
@@ -146,7 +148,135 @@
    goto Exit;
  }                                  
 
+ LOCAL_FUNC  FT_Error  T1_Get_Multi_Master( T1_Face          face,
+                                            FT_Multi_Master* master )
+ {
+   T1_Blend*  blend = face->blend;
+   T1_UInt    n;
+   FT_Error   error;
+   
+   error = FT_Err_Invalid_Argument;
+   if (blend)
+   {
+     master->num_axis    = blend->num_axis;
+     master->num_designs = blend->num_designs;
+     for ( n = 0; n < blend->num_axis; n++ )
+     {
+       FT_MM_Axis*    axis = master->axis + n;
+       T1_DesignMap*  map = blend->design_map + n;
+       
+       axis->name    = blend->axis_names[n];
+       axis->minimum = map->design_points[0];
+       axis->maximum = map->design_points[map->num_points-1];
+     }
+     error = 0;
+   }
+   return error;
+ }                                            
 
+
+ LOCAL_FUNC  FT_Error  T1_Set_MM_Blend( T1_Face    face,
+                                        T1_UInt    num_coords,
+                                        T1_Fixed*  coords )
+ {
+   T1_Blend*  blend = face->blend;
+   FT_Error   error;
+   T1_UInt    n, m;
+   
+   error = FT_Err_Invalid_Argument;
+   if (blend && blend->num_axis == num_coords)
+   {
+     /* recompute the weight vector from the blend coordinates */
+     error = 0;
+     for ( n = 0; n < blend->num_designs; n++ )
+     {
+       FT_Fixed  result = 0x10000L;  /* 1.0 fixed */
+       for ( m = 0; m < blend->num_axis; m++ )
+       {
+         FT_Fixed  factor;
+
+         /* get current blend axis position */
+         factor = coords[m];
+         if (factor < 0) factor = 0;
+         if (factor > 0x10000L) factor = 0x10000L;
+         
+         if ((n & (1 << m)) == 0)
+           factor = 0x10000L - factor;
+           
+         result = FT_MulFix( result, factor );
+       }
+       blend->weight_vector[n] = result;
+     }
+     error = 0;
+   }
+   return error;
+ }
+ 
+
+ LOCAL_FUNC  FT_Error  T1_Set_MM_Design( T1_Face   face,
+                                         T1_UInt   num_coords,
+                                         T1_Long*  coords )
+ {
+   T1_Blend*  blend = face->blend;
+   FT_Error   error;
+   T1_UInt    n, p;
+   
+   error = FT_Err_Invalid_Argument;
+   if (blend && blend->num_axis == num_coords)
+   {
+     /* compute the blend coordinates through the blend design map */
+     T1_Fixed  final_blends[ T1_MAX_MM_DESIGNS ];
+     
+     for ( n = 0; n < blend->num_axis; n++ )
+     {
+       T1_Long        design = coords[n];
+       T1_Fixed       the_blend;
+       T1_DesignMap*  map     = blend->design_map + n;
+       T1_Fixed*      designs = map->design_points;
+       T1_Fixed*      blends  = map->blend_points;
+       T1_Int         before = -1, after = -1;
+       
+       for ( p = 0; p < map->num_points; p++ )
+       {
+         T1_Fixed  p_design = designs[p];
+         
+         /* exact match ? */
+         if (design == p_design)
+         {
+           the_blend = blends[p];
+           goto Found;
+         }
+         
+         if (design < p_design)
+         {
+           after = p;
+           break;
+         }
+         
+         before = p;
+       }
+       
+       /* now, interpolate if needed */
+       if (before < 0)
+         the_blend = blends[0];
+         
+       else if (after < 0)
+         the_blend = blends[map->num_points-1];
+         
+       else
+         the_blend = FT_MulDiv( design         - designs[before],
+                                blends [after] - blends [before],
+                                designs[after] - designs[before] );
+     Found:
+       final_blends[n] = the_blend;
+     }
+
+     error = T1_Set_MM_Blend( face, num_coords, final_blends );     
+   }
+   return error;
+ }
+
+ 
  LOCAL_FUNC  void T1_Done_Blend( T1_Face  face )
  {
    FT_Memory  memory = face->root.memory;
@@ -193,6 +323,7 @@
  }
 
 
+
  static  void  parse_blend_axis_types( T1_Face  face, T1_Loader*  loader )
  {
    T1_Token_Rec  axis_tokens[ T1_MAX_MM_AXIS ];
@@ -446,6 +577,7 @@
    parser->cursor = parser->limit;
    parser->error  = 0;
  }
+#endif
  
  /***************************************************************************/
  /***************************************************************************/
--- a/src/type1z/t1load.h
+++ b/src/type1z/t1load.h
@@ -48,6 +48,18 @@
 
 #ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT
   LOCAL_DEF
+  FT_Error  T1_Get_Multi_Master( T1_Face          face,
+                                 FT_Multi_Master* master );
+
+  LOCAL_DEF  FT_Error  T1_Set_MM_Blend( T1_Face    face,
+                                        T1_UInt    num_coords,
+                                        T1_Fixed*  coords );
+
+  LOCAL_DEF  FT_Error  T1_Set_MM_Design( T1_Face   face,
+                                         T1_UInt   num_coords,
+                                         T1_Long*  coords );
+
+  LOCAL_DEF
   void T1_Done_Blend( T1_Face  face );
 #endif