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

📄 t1parse.c

📁 Qt/Embedded是一个多平台的C++图形用户界面应用程序框架
💻 C
📖 第 1 页 / 共 2 页
字号:
/******************************************************************* * *  t1parse.c                                                   2.0 * *    Type1 parser. * *  Copyright 1996-1998 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. * *  The Type 1 parser is in charge of the following: * *   - provide an implementation of a growing sequence of *     objects called a T1_Table (used to build various tables *     needed by the loader). * *   - opening .pfb and .pfa files to extract their top-level *     and private dictionaries * *   - read numbers, arrays & strings from any dictionary * *  See "t1load.c" to see how data is loaded from the font file * ******************************************************************/ #include <ftdebug.h>#include <ftcalc.h>#include <ftobjs.h>#include <ftstream.h>#include <t1errors.h>#include <t1parse.h>#undef FT_COMPONENT#define FT_COMPONENT  trace_t1load/*************************************************************************//*                                                                       *//* <Function> T1_New_Table                                               *//*                                                                       *//* <Description>                                                         *//*    Initialise a T1_Table.                                             *//*                                                                       *//* <Input>                                                               *//*    table  :: address of target table                                  *//*    count  :: table size = maximum number of elements                  *//*    memory :: memory object to use for all subsequent reallocations    *//*                                                                       *//* <Return>                                                              *//*    Error code. 0 means success                                        *//*                                                                       */  LOCAL_FUNC  T1_Error  T1_New_Table( T1_Table*  table,                          T1_Int     count,                          FT_Memory  memory )  {	 T1_Error  error;	 table->memory = memory;	 if ( ALLOC_ARRAY( table->elements, count, T1_Byte*  ) ||          ALLOC_ARRAY( table->lengths, count, T1_Byte* ) )       goto Exit;	table->max_elems = count;    table->init      = 0xdeadbeef;	table->num_elems = 0;	table->block     = 0;	table->capacity  = 0;	table->cursor    = 0;  Exit:    if (error) FREE(table->elements);      	return error;  }/*************************************************************************//*                                                                       *//* <Function> T1_Add_Table                                               *//*                                                                       *//* <Description>                                                         *//*    Adds an object to a T1_Table, possibly growing its memory block    *//*                                                                       *//* <Input>                                                               *//*    table  :: target table                                             *//*    index  :: index of object in table                                 *//*    object :: address of object to copy in memory                      *//*    length :: length in bytes of source object                         *//*                                                                       *//* <Return>                                                              *//*    Error code. 0 means success. An error is returned when a           *//*    realloc failed..                                                   *//*                                                                       */      static void  shift_elements( T1_Table*  table, T1_Byte*  old_base )      {        T1_Long    delta  = table->block - old_base;        T1_Byte**  offset = table->elements;        T1_Byte**  limit  = offset + table->max_elems;            if (delta)          for ( ; offset < limit; offset++ )          {            if (offset[0])              offset[0] += delta;          }      }        static      T1_Error  reallocate_t1_table( T1_Table*  table,                                     T1_Int     new_size )      {        FT_Memory  memory   = table->memory;        T1_Byte*   old_base = table->block;        T1_Error   error;          /* realloc the base block */        if ( REALLOC( table->block, table->capacity, new_size ) )          return error;          table->capacity = new_size;          /* shift all offsets when needed */        if (old_base)          shift_elements( table, old_base );          return T1_Err_Ok;      }  LOCAL_FUNC  T1_Error  T1_Add_Table( T1_Table*  table,                          T1_Int     index,                          void*      object,                          T1_Int     length )  {	if (index < 0 || index > table->max_elems)    {	  FT_ERROR(( "T1.Add_Table: invalid index\n" ));	  return T1_Err_Syntax_Error;    }    /* grow the base block if needed */    if ( table->cursor + length > table->capacity )    {      T1_Error  error;      T1_Int    new_size = table->capacity;      while ( new_size < table->cursor+length )        new_size += 1024;      error = reallocate_t1_table( table, new_size );      if (error) return error;    }    /* add the object to the base block and adjust offset */    table->elements[ index ] = table->block + table->cursor;    table->lengths [ index ] = length;    MEM_Copy( table->block + table->cursor, object, length );    table->cursor += length;    return T1_Err_Ok;  }/*************************************************************************//*                                                                       *//* <Function> T1_Done_Table                                              *//*                                                                       *//* <Description>                                                         *//*    Finalise a T1_Table. (realloc it to its current cursor).           *//*                                                                       *//* <Input>                                                               *//*    table :: target table                                              *//*                                                                       *//* <Note>                                                                *//*    This function does NOT release the heap's memory block. It is up   *//*    to the caller to clean it, or reference it in its own structures.  *//*                                                                       */#if 0  LOCAL_FUNC  void  T1_Done_Table( T1_Table*  table )  {    FT_Memory  memory = table->memory;    T1_Error   error;    T1_Byte*   old_base;    /* should never fail, as rec.cursor <= rec.size */    old_base = table->block;    if (!old_base)      return;        (void)REALLOC( table->block, table->capacity, table->cursor );    table->capacity = table->cursor;        if (old_base != table->block)      shift_elements( table, old_base );  }#endif  LOCAL_FUNC  void  T1_Release_Table( T1_Table*  table )  {    FT_Memory  memory = table->memory;        if (table->init == 0xdeadbeef)    {      FREE( table->block );      FREE( table->elements );      FREE( table->lengths );      table->init = 0;    }  }  static  T1_Long  t1_toint( T1_Byte* *cursor,                     T1_Byte*  limit )  {    T1_Long  result = 0;    T1_Byte* cur    = *cursor;    T1_Byte  c, d;        for (; cur < limit; cur++)    {      c = *cur;      d = (T1_Byte)(c - '0');      if (d < 10) break;            if ( c=='-' )      {        cur++;        break;      }    }        if (cur < limit)    {      do      {        d = (T1_Byte)(cur[0] - '0');        if (d >= 10)          break;                  result = result*10 + d;        cur++;              } while (cur < limit);            if (c == '-')        result = -result;    }        *cursor = cur;    return result;  }  static  T1_Long  t1_tofixed( T1_Byte* *cursor,                       T1_Byte*  limit,                       T1_Long   power_ten )  {    T1_Byte* cur    = *cursor;    T1_Long  num, divider, result;    T1_Int   sign   = 0;    T1_Byte  d;        if (cur >= limit) return 0;        /* first of all, read the integer part */    result  = t1_toint( &cur, limit ) << 16;    num     = 0;    divider = 1;        if (result < 0)    {      sign   = 1;      result = -result;    }    if (cur >= limit) goto Exit;        /* read decimal part, if any */    if (*cur == '.' && cur+1 < limit)    {      cur++;            for (;;)      {        d = (T1_Byte)(*cur - '0');        if (d >= 10) break;        if (divider < 10000000L)        {          num      = num*10 + d;          divider *= 10;        }        cur++;        if (cur >= limit) break;      }    }        /* read exponent, if any */    if ( cur+1 < limit && (*cur == 'e' || *cur == 'E'))    {      cur++;      power_ten += t1_toint( &cur, limit );    }      Exit:    /* raise to power of ten if needed */    while (power_ten > 0)    {      result = result*10;      num    = num*10;      power_ten--;    }        while (power_ten < 0)    {      result  = result/10;      divider = divider*10;      power_ten++;    }    if (num)      result += FT_DivFix( num, divider );    if (sign)      result = -result;          *cursor = cur;    return result;  }  static  T1_Int  t1_tocoordarray( T1_Byte*  *cursor,                           T1_Byte*   limit,                           T1_Int     max_coords,                           T1_Short*  coords )  {    T1_Byte*  cur   = *cursor;    T1_Int    count = 0;    T1_Byte   c, ender;        if (cur >= limit) goto Exit;        /* check for the beginning of an array. If not, only one number will be read */    c     = *cur;    ender = 0;        if (c == '[')      ender = ']';          if (c == '{')      ender = '}';          if (ender)      cur++;    /* now, read the coordinates */    for ( ; cur < limit; )    {      /* skip whitespace in front of data */      for (;;)      {        c = *cur;        if ( c != ' ' && c != '\t' ) break;                cur++;        if (cur >= limit) goto Exit;      }            if (count >= max_coords || c == ender)        break;            coords[count] = (T1_Short)(t1_tofixed(&cur,limit,0) >> 16);      count++;            if (!ender)        break;    }      Exit:    *cursor = cur;    return count;  }  static  T1_Int  t1_tofixedarray( T1_Byte*  *cursor,                           T1_Byte*   limit,                            T1_Int     max_values,                           T1_Fixed*  values,                           T1_Int     power_ten )  {    T1_Byte*  cur   = *cursor;    T1_Int    count = 0;    T1_Byte   c, ender;        if (cur >= limit) goto Exit;        /* check for the beginning of an array. If not, only one number will be read */    c     = *cur;    ender = 0;        if (c == '[')      ender = ']';          if (c == '{')      ender = '}';          if (ender)      cur++;    /* now, read the values */    for ( ; cur < limit; )    {      /* skip whitespace in front of data */      for (;;)      {        c = *cur;        if ( c != ' ' && c != '\t' ) break;                cur++;        if (cur >= limit) goto Exit;      }      if (count >= max_values || c == ender)        break;            values[count] = t1_tofixed(&cur,limit,power_ten);      count++;            if (!ender)        break;    }      Exit:    *cursor = cur;    return count;  }  static  T1_String*  t1_tostring( T1_Byte* *cursor, T1_Byte* limit, FT_Memory memory )  {    T1_Byte*    cur = *cursor;    T1_Int      len = 0;    T1_Int      count;    T1_String*  result;    FT_Error    error;    /* XXX : some stupid fonts have a "Notice" or "Copyright" string     */    /*       that simply doesn't begin with an opening parenthesis, even */    /*       though they have a closing one !!! E.g. "amuncial.pfb"      */

⌨️ 快捷键说明

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