⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 t1load.c

📁 qt-embedded-2.3.8.tar.gz源码
💻 C
📖 第 1 页 / 共 4 页
字号:
/***************************************************************************//*                                                                         *//*  t1load.c                                                               *//*                                                                         *//*    Type 1 font loader (body).                                           *//*                                                                         *//*  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.                                        *//*                                                                         *//***************************************************************************/  /*************************************************************************/  /*                                                                       */  /* This is the new and improved Type 1 data loader for FreeType 2.  The  */  /* old loader has several problems: it is slow, complex, difficult to    */  /* maintain, and contains incredible hacks to make it accept some        */  /* ill-formed Type 1 fonts without hiccup-ing.  Moreover, about 5% of    */  /* the Type 1 fonts on my machine still aren't loaded correctly by it.   */  /*                                                                       */  /* This version is much simpler, much faster and also easier to read and */  /* maintain by a great order of magnitude.  The idea behind it is to     */  /* _not_ try to read the Type 1 token stream with a state machine (i.e.  */  /* a Postscript-like interpreter) but rather to perform simple pattern   */  /* matching.                                                             */  /*                                                                       */  /* Indeed, nearly all data definitions follow a simple pattern like      */  /*                                                                       */  /*  ... /Field <data> ...                                                */  /*                                                                       */  /* where <data> can be a number, a boolean, a string, or an array of     */  /* numbers.  There are a few exceptions, namely the encoding, font name, */  /* charstrings, and subrs; they are handled with a special pattern       */  /* matching routine.                                                     */  /*                                                                       */  /* All other common cases are handled very simply.  The matching rules   */  /* are defined in the file `t1tokens.h' through the use of several       */  /* macros calls PARSE_XXX.                                               */  /*                                                                       */  /* This file is included twice here; the first time to generate parsing  */  /* callback functions, the second to generate a table of keywords (with  */  /* pointers to the associated callback).                                 */  /*                                                                       */  /* The function `parse_dict' simply scans *linearly* a given dictionary  */  /* (either the top-level or private one) and calls the appropriate       */  /* callback when it encounters an immediate keyword.                     */  /*                                                                       */  /* This is by far the fastest way one can find to parse and read all     */  /* data.                                                                 */  /*                                                                       */  /* This led to tremendous code size reduction.  Note that later, the     */  /* glyph loader will also be _greatly_ simplified, and the automatic     */  /* hinter will replace the clumsy `t1hinter'.                            */  /*                                                                       */  /*************************************************************************/#include <freetype/internal/ftdebug.h>#include <freetype/config/ftconfig.h>#include <freetype/ftmm.h>#include <freetype/internal/t1types.h>#include <freetype/internal/t1errors.h>#ifdef FT_FLAT_COMPILE#include "t1load.h"#else#include <type1/t1load.h>#endif#include <string.h>     /* for strncmp(), strcmp() */#include <ctype.h>      /* for isalnum()           */  /*************************************************************************/  /*                                                                       */  /* 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_t1load#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT  /*************************************************************************/  /*************************************************************************/  /*****                                                               *****/  /*****                    MULTIPLE MASTERS SUPPORT                   *****/  /*****                                                               *****/  /*************************************************************************/  /*************************************************************************/  static  FT_Error  t1_allocate_blend( T1_Face  face,                               FT_UInt  num_designs,                               FT_UInt  num_axis )  {    T1_Blend*  blend;    FT_Memory  memory = face->root.memory;    FT_Error   error  = 0;    blend = face->blend;    if ( !blend )    {      if ( ALLOC( blend, sizeof ( *blend ) ) )        goto Exit;      face->blend = blend;    }    /* allocate design data if needed */    if ( num_designs > 0 )    {      if ( blend->num_designs == 0 )      {        FT_UInt  nn;        /* allocate the blend `private' and `font_info' dictionaries */        if ( ALLOC_ARRAY( blend->font_infos[1], num_designs, T1_FontInfo )  ||             ALLOC_ARRAY( blend->privates[1], num_designs, T1_Private )     ||             ALLOC_ARRAY( blend->weight_vector, num_designs * 2, FT_Fixed ) )          goto Exit;        blend->default_weight_vector = blend->weight_vector + num_designs;        blend->font_infos[0] = &face->type1.font_info;        blend->privates  [0] = &face->type1.private_dict;        for ( nn = 2; nn <= num_designs; nn++ )        {          blend->privates[nn]   = blend->privates  [nn - 1] + 1;          blend->font_infos[nn] = blend->font_infos[nn - 1] + 1;        }        blend->num_designs   = num_designs;      }      else if ( blend->num_designs != num_designs )        goto Fail;    }    /* allocate axis data if needed */    if ( num_axis > 0 )    {      if ( blend->num_axis != 0 && blend->num_axis != num_axis )        goto Fail;      blend->num_axis = num_axis;    }    /* allocate the blend design pos table if needed */    num_designs = blend->num_designs;    num_axis    = blend->num_axis;    if ( num_designs && num_axis && blend->design_pos[0] == 0 )    {      FT_UInt  n;      if ( ALLOC_ARRAY( blend->design_pos[0],                        num_designs * num_axis, FT_Fixed ) )        goto Exit;      for ( n = 1; n < num_designs; n++ )        blend->design_pos[n] = blend->design_pos[0] + num_axis * n;    }  Exit:    return error;  Fail:    error = -1;    goto Exit;  }  FT_LOCAL_DEF  FT_Error  T1_Get_Multi_Master( T1_Face           face,                                 FT_Multi_Master*  master )  {    T1_Blend*  blend = face->blend;    FT_UInt    n;    FT_Error   error;    error = T1_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;  }  FT_LOCAL_DEF  FT_Error  T1_Set_MM_Blend( T1_Face    face,                             FT_UInt    num_coords,                             FT_Fixed*  coords )  {    T1_Blend*  blend = face->blend;    FT_Error   error;    FT_UInt    n, m;    error = T1_Err_Invalid_Argument;    if ( blend && blend->num_axis == num_coords )    {      /* recompute the weight vector from the blend coordinates */      error = FT_Err_Ok;      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 = FT_Err_Ok;    }    return error;  }  FT_LOCAL_DEF  FT_Error  T1_Set_MM_Design( T1_Face   face,                              FT_UInt   num_coords,                              FT_Long*  coords )  {    T1_Blend*  blend = face->blend;    FT_Error   error;    FT_UInt    n, p;    error = T1_Err_Invalid_Argument;    if ( blend && blend->num_axis == num_coords )    {      /* compute the blend coordinates through the blend design map */      FT_Fixed  final_blends[T1_MAX_MM_DESIGNS];      for ( n = 0; n < blend->num_axis; n++ )      {        FT_Long        design  = coords[n];        FT_Fixed       the_blend;        T1_DesignMap*  map     = blend->design_map + n;        FT_Fixed*      designs = map->design_points;        FT_Fixed*      blends  = map->blend_points;        FT_Int         before  = -1, after = -1;        for ( p = 0; p < (FT_UInt)map->num_points; p++ )        {          FT_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;  }  FT_LOCAL_DEF  void  T1_Done_Blend( T1_Face  face )  {    FT_Memory  memory = face->root.memory;    T1_Blend*  blend  = face->blend;    if ( blend )    {      FT_UInt  num_designs = blend->num_designs;      FT_UInt  num_axis    = blend->num_axis;      FT_UInt  n;      /* release design pos table */      FREE( blend->design_pos[0] );      for ( n = 1; n < num_designs; n++ )        blend->design_pos[n] = 0;      /* release blend `private' and `font info' dictionaries */      FREE( blend->privates[1] );      FREE( blend->font_infos[1] );      for ( n = 0; n < num_designs; n++ )      {        blend->privates  [n] = 0;        blend->font_infos[n] = 0;      }      /* release weight vectors */      FREE( blend->weight_vector );      blend->default_weight_vector = 0;      /* release axis names */      for ( n = 0; n < num_axis; n++ )        FREE( blend->axis_names[n] );      /* release design map */      for ( n = 0; n < num_axis; n++ )      {        T1_DesignMap*  dmap = blend->design_map + n;        FREE( dmap->design_points );        dmap->num_points = 0;      }      FREE( face->blend );    }  }  static  void  parse_blend_axis_types( T1_Face     face,                                T1_Loader*  loader )  {    T1_Token   axis_tokens[ T1_MAX_MM_AXIS ];    FT_Int     n, num_axis;    FT_Error   error = 0;    T1_Blend*  blend;    FT_Memory  memory;    /* take an array of objects */    T1_ToTokenArray( &loader->parser, axis_tokens,                     T1_MAX_MM_AXIS, &num_axis );    if ( num_axis <= 0 || num_axis > T1_MAX_MM_AXIS )    {      FT_ERROR(( "parse_blend_axis_types: incorrect number of axes: %d\n",                 num_axis ));      error = T1_Err_Invalid_File_Format;      goto Exit;    }    /* allocate blend if necessary */    error = t1_allocate_blend( face, 0, (FT_UInt)num_axis );    if ( error )      goto Exit;    blend  = face->blend;    memory = face->root.memory;    /* each token is an immediate containing the name of the axis */    for ( n = 0; n < num_axis; n++ )    {      T1_Token*  token = axis_tokens + n;      FT_Byte*   name;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -