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

📄 t1load.c

📁 奇趣公司比较新的qt/emd版本
💻 C
📖 第 1 页 / 共 5 页
字号:
/***************************************************************************//*                                                                         *//*  t1load.c                                                               *//*                                                                         *//*    Type 1 font loader (body).                                           *//*                                                                         *//*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 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 time to       */  /* generate a table of keywords (with pointers to the associated         */  /* callback functions).                                                  */  /*                                                                       */  /* 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 <ft2build.h>#include FT_INTERNAL_DEBUG_H#include FT_CONFIG_CONFIG_H#include FT_MULTIPLE_MASTERS_H#include FT_INTERNAL_TYPE1_TYPES_H#include "t1load.h"#include "t1errors.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_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 )  {    PS_Blend   blend;    FT_Memory  memory = face->root.memory;    FT_Error   error  = T1_Err_Ok;    blend = face->blend;    if ( !blend )    {      if ( FT_NEW( blend ) )        goto Exit;      blend->num_default_design_vector = 0;      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 ( FT_NEW_ARRAY( blend->font_infos[1], num_designs     ) ||             FT_NEW_ARRAY( blend->privates[1], num_designs       ) ||             FT_NEW_ARRAY( blend->bboxes[1], num_designs         ) ||             FT_NEW_ARRAY( blend->weight_vector, num_designs * 2 ) )          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;        blend->bboxes    [0] = &face->type1.font_bbox;        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->bboxes[nn]     = blend->bboxes    [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 ( FT_NEW_ARRAY( blend->design_pos[0], num_designs * num_axis ) )        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 = T1_Err_Invalid_File_Format;    goto Exit;  }  FT_LOCAL_DEF( FT_Error )  T1_Get_Multi_Master( T1_Face           face,                       FT_Multi_Master*  master )  {    PS_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;        PS_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 = T1_Err_Ok;    }    return error;  }#define FT_INT_TO_FIXED( a )  ( (a) << 16 )#define FT_FIXED_TO_INT( a )  ( FT_RoundFix( a ) >> 16 )  /*************************************************************************/  /*                                                                       */  /* Given a normalized (blend) coordinate, figure out the design          */  /* coordinate appropriate for that value.                                */  /*                                                                       */  FT_LOCAL_DEF( FT_Fixed )  mm_axis_unmap( PS_DesignMap  axismap,                 FT_Fixed      ncv )  {    int  j;    if ( ncv <= axismap->blend_points[0] )      return axismap->design_points[0];    for ( j = 1; j < axismap->num_points; ++j )    {      if ( ncv <= axismap->blend_points[j] )      {        FT_Fixed  t = FT_MulDiv( ncv - axismap->blend_points[j - 1],                                 0x10000L,                                 axismap->blend_points[j] -                                   axismap->blend_points[j - 1] );        return axismap->design_points[j - 1] +                 FT_MulDiv( t,                            axismap->design_points[j] -                              axismap->design_points[j - 1],                            1L );      }    }    return axismap->design_points[axismap->num_points - 1];  }  /*************************************************************************/  /*                                                                       */  /* Given a vector of weights, one for each design, figure out the        */  /* normalized axis coordinates which gave rise to those weights.         */  /*                                                                       */  FT_LOCAL_DEF( void )  mm_weights_unmap( FT_Fixed*  weights,                    FT_Fixed*  axiscoords,                    FT_UInt    axis_count )  {    FT_ASSERT( axis_count <= T1_MAX_MM_AXIS );    if ( axis_count == 1 )      axiscoords[0] = weights[1];    else if ( axis_count == 2 )    {      axiscoords[0] = weights[3] + weights[1];      axiscoords[1] = weights[3] + weights[2];    }    else if ( axis_count == 3 )    {      axiscoords[0] = weights[7] + weights[5] + weights[3] + weights[1];      axiscoords[1] = weights[7] + weights[6] + weights[3] + weights[2];      axiscoords[2] = weights[7] + weights[6] + weights[5] + weights[4];    }    else    {      axiscoords[0] = weights[15] + weights[13] + weights[11] + weights[9] +                        weights[7] + weights[5] + weights[3] + weights[1];      axiscoords[1] = weights[15] + weights[14] + weights[11] + weights[10] +                        weights[7] + weights[6] + weights[3] + weights[2];      axiscoords[2] = weights[15] + weights[14] + weights[13] + weights[12] +                        weights[7] + weights[6] + weights[5] + weights[4];      axiscoords[3] = weights[15] + weights[14] + weights[13] + weights[12] +                        weights[11] + weights[10] + weights[9] + weights[8];    }  }  /*************************************************************************/  /*                                                                       */  /* Just a wrapper around T1_Get_Multi_Master to support the different    */  /*  arguments needed by the GX var distortable fonts.                    */  /*                                                                       */  FT_LOCAL_DEF( FT_Error )  T1_Get_MM_Var( T1_Face      face,                 FT_MM_Var*  *master )  {    FT_Memory        memory = face->root.memory;    FT_MM_Var       *mmvar;    FT_Multi_Master  mmaster;    FT_Error         error;    FT_UInt          i;    FT_Fixed         axiscoords[T1_MAX_MM_AXIS];    PS_Blend         blend = face->blend;    error = T1_Get_Multi_Master( face, &mmaster );    if ( error )      goto Exit;    if ( FT_ALLOC( mmvar,                   sizeof ( FT_MM_Var ) +                     mmaster.num_axis * sizeof ( FT_Var_Axis ) ) )      goto Exit;    mmvar->num_axis        = mmaster.num_axis;    mmvar->num_designs     = mmaster.num_designs;    mmvar->num_namedstyles = (FT_UInt)-1;                /* Does not apply */    mmvar->axis            = (FT_Var_Axis*)&mmvar[1];                                      /* Point to axes after MM_Var struct */    mmvar->namedstyle      = NULL;    for ( i = 0 ; i < mmaster.num_axis; ++i )    {      mmvar->axis[i].name    = mmaster.axis[i].name;      mmvar->axis[i].minimum = FT_INT_TO_FIXED( mmaster.axis[i].minimum);      mmvar->axis[i].maximum = FT_INT_TO_FIXED( mmaster.axis[i].maximum);      mmvar->axis[i].def     = ( mmvar->axis[i].minimum +                                   mmvar->axis[i].maximum ) / 2;                            /* Does not apply.  But this value is in range */      mmvar->axis[i].strid   = 0xFFFFFFFFUL;   /* Does not apply */      mmvar->axis[i].tag     = 0xFFFFFFFFUL;   /* Does not apply */      if ( ft_strcmp( mmvar->axis[i].name, "Weight" ) == 0 )        mmvar->axis[i].tag = FT_MAKE_TAG( 'w', 'g', 'h', 't' );      else if ( ft_strcmp( mmvar->axis[i].name, "Width" ) == 0 )        mmvar->axis[i].tag = FT_MAKE_TAG( 'w', 'd', 't', 'h' );      else if ( ft_strcmp( mmvar->axis[i].name, "OpticalSize" ) == 0 )        mmvar->axis[i].tag = FT_MAKE_TAG( 'o', 'p', 's', 'z' );    }    if ( blend->num_designs == 1U << blend->num_axis )    {      mm_weights_unmap( blend->default_weight_vector,                        axiscoords,                        blend->num_axis );      for ( i = 0; i < mmaster.num_axis; ++i )        mmvar->axis[i].def =          FT_INT_TO_FIXED( mm_axis_unmap( &blend->design_map[i],                                          axiscoords[i] ) );    }    *master = mmvar;  Exit:    return error;  }  FT_LOCAL_DEF( FT_Error )  T1_Set_MM_Blend( T1_Face    face,                   FT_UInt    num_coords,                   FT_Fixed*  coords )  {    PS_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 = T1_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 = T1_Err_Ok;    }    return error;  }  FT_LOCAL_DEF( FT_Error )  T1_Set_MM_Design( T1_Face   face,                    FT_UInt   num_coords,                    FT_Long*  coords )  {    PS_Blend  blend = face->blend;

⌨️ 快捷键说明

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