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

📄 t1parse.c

📁 Qt/Embedded是一个多平台的C++图形用户界面应用程序框架
💻 C
📖 第 1 页 / 共 2 页
字号:
    /*                                                                   */    /*       We must deal with these ill-fated cases there. Note that    */    /*       these fonts didn't work with the old Type 1 driver as the   */    /*       notice/copyright was not recognized as a valid string token */    /*       and made the old token parser commit errors..               */    while ( cur < limit && (*cur == ' ' || *cur == '\t')) cur++;    if (cur+1 >= limit) return 0;        if (*cur == '(') cur++;  /* skip the opening parenthesis, if there is one */        *cursor = cur;    count   = 0;        /* then, count its length */    for ( ; cur < limit; cur++ )    {      if (*cur == '(')        count++;              else if (*cur == ')')      {        count--;        if (count < 0)          break;      }    }    len = cur - *cursor;        if (cur >= limit || ALLOC(result,len+1)) return 0;        /* now copy the string */    MEM_Copy( result, *cursor, len );    result[len] = '\0';    *cursor = cur;    return result;      }  static  int  t1_tobool( T1_Byte* *cursor, T1_Byte* limit )  {    T1_Byte*  cur    = *cursor;    T1_Bool   result = 0;        /* return 1 if we find a "true", 0 otherwise */    if ( cur+3 < limit &&         cur[0] == 't' &&         cur[1] == 'r' &&         cur[2] == 'u' &&         cur[3] == 'e' )    {      result = 1;      cur   += 5;    }    else if ( cur+4 < limit &&              cur[0] == 'f' &&              cur[1] == 'a' &&              cur[2] == 'l' &&              cur[3] == 's' &&              cur[4] == 'e' )    {      result = 0;      cur   += 6;    }    *cursor = cur;    return result;  }  LOCAL_FUNC  T1_Long  T1_ToInt  ( T1_Parser*  parser )  {    return t1_toint( &parser->cursor, parser->limit );  }  LOCAL_FUNC  T1_Long  T1_ToFixed( T1_Parser*  parser, T1_Int power_ten )  {    return t1_tofixed( &parser->cursor, parser->limit, power_ten );  }  LOCAL_FUNC  T1_Int  T1_ToCoordArray( T1_Parser* parser,                           T1_Int     max_coords,                           T1_Short*  coords )  {    return t1_tocoordarray( &parser->cursor, parser->limit, max_coords, coords );  }  LOCAL_FUNC  T1_Int  T1_ToFixedArray( T1_Parser* parser,                           T1_Int     max_values,                           T1_Fixed*  values,                           T1_Int     power_ten )  {    return t1_tofixedarray( &parser->cursor, parser->limit, max_values, values, power_ten );  }  LOCAL_FUNC  T1_String*  T1_ToString( T1_Parser* parser )  {    return t1_tostring( &parser->cursor, parser->limit, parser->memory );  }  LOCAL_FUNC  T1_Bool   T1_ToBool( T1_Parser* parser )  {    return t1_tobool( &parser->cursor, parser->limit );  }  static  FT_Error  read_pfb_tag( FT_Stream  stream, T1_UShort *tag, T1_Long*  size )  {    FT_Error  error;        if (READ_UShort(*tag)) goto Exit;    if (*tag == 0x8001 || *tag == 0x8002)    {      FT_Long  asize;            if (READ_ULong(asize)) goto Exit;            /* swap between big and little endianness */      *size  = ((asize & 0xFF000000) >> 24) |               ((asize & 0x00FF0000) >> 8 ) |               ((asize & 0x0000FF00) << 8 ) |               ((asize & 0x000000FF) << 24);    }      Exit:    return error;  }  LOCAL_FUNC  T1_Error  T1_New_Parser( T1_Parser*  parser,                           FT_Stream   stream,                           FT_Memory   memory )  {    FT_Error  error;    T1_UShort tag;    T1_Long   size;      parser->stream       = stream;    parser->memory       = memory;    parser->base_len     = 0;    parser->base_dict    = 0;    parser->private_len  = 0;    parser->private_dict = 0;    parser->in_pfb       = 0;    parser->in_memory    = 0;    parser->single_block = 0;        parser->cursor       = 0;    parser->limit        = 0;        /******************************************************************/    /*                                                                */    /* Here's a short summary of what is going on :                   */    /*                                                                */    /*   When creating a new Type 1 parser, we try to locate and      */    /*   load the base dictionary when this is possible (i.e. for     */    /*   .pfb files). Otherwise, we load the whole font in memory.    */    /*                                                                */    /*   When "loading" the base dictionary, we only setup pointers   */    /*   in the case of a memory-based stream. Otherwise, we allocate */    /*   and load the base dict in it.                                */    /*                                                                */    /*   parser->in_pfb is set when we are in a binary (".pfb") font  */    /*   parser->in_memory is set when we have a memory stream.       */    /*                                                                */        /* try to compute the size of the base dictionary    */    /* look for a Postscript binary file tag, i.e 0x8001 */    if ( FILE_Seek(0L) )      goto Exit;          error = read_pfb_tag( stream, &tag, &size );    if (error) goto Exit;    if (tag != 0x8001)    {      /* assume that this is a PFA file for now, an error will */      /* be produced later when more things are checked        */      (void)FILE_Seek(0L);      size = stream->size;    }    else      parser->in_pfb = 1;    /* now, try to load the "size" bytes of the "base" dictionary we */    /* found previously                                              */     /* if it's a memory-based resource, set up pointers */    if ( !stream->read )    {      parser->base_dict = (T1_Byte*)stream->base + stream->pos;      parser->base_len  = size;      parser->in_memory = 1;       /* check that the "size" field is valid */      if ( FILE_Skip(size) ) goto Exit;    }    else    {      /* read segment in memory */      if ( ALLOC( parser->base_dict, size )     ||           FILE_Read( parser->base_dict, size ) )        goto Exit;      parser->base_len = size;    }     /* Now check font format, we must see a '%!PS-AdobeFont-1' */    /* or a '%!FontType'                                       */    {      if ( size <= 16 ||           ( strncmp( (const char*)parser->base_dict, "%!PS-AdobeFont-1", 16 ) &&             strncmp( (const char*)parser->base_dict, "%!FontType", 10 )       ) )      {        FT_TRACE2(( "Not a Type1 font\n" ));        error = T1_Err_Invalid_File_Format;      }      else      {        parser->cursor = parser->base_dict;        parser->limit  = parser->cursor + parser->base_len;      }    }  Exit:    if (error && !parser->in_memory)      FREE( parser->base_dict );    return error;  }  LOCAL_FUNC  void  T1_Done_Parser( T1_Parser*  parser )  {    FT_Memory   memory = parser->memory;    /* always free the private dictionary */    FREE( parser->private_dict );    /* free the base dictionary only when we have a disk stream */    if (!parser->in_memory)      FREE( parser->base_dict );  } /* return the value of an hexadecimal digit */ static int  hexa_value( char c ) {   unsigned int  d;   d = (unsigned int)(c-'0');   if ( d <= 9 ) return (int)d;   d = (unsigned int)(c-'a');   if ( d <= 5 ) return (int)(d+10);   d = (unsigned int)(c-'A');   if ( d <= 5 ) return (int)(d+10);   return -1; }  LOCAL_FUNC  void  T1_Decrypt( T1_Byte*   buffer,                    T1_Int     length,                    T1_UShort  seed )  {    while ( length > 0 )    {      T1_Byte  plain;      plain     = (*buffer ^ (seed >> 8));      seed      = (*buffer+seed)*52845+22719;      *buffer++ = plain;      length--;    }  }  LOCAL_FUNC  T1_Error  T1_Get_Private_Dict( T1_Parser*  parser )  {    FT_Stream  stream = parser->stream;    FT_Memory  memory = parser->memory;    FT_Error   error  = 0;    T1_Long    size;        if (parser->in_pfb)    {      /* in the case of the PFB format, the private dictionary can be  */      /* made of several segments. We thus first read the number of    */      /* segments to compute the total size of the private dictionary  */      /* then re-read them into memory..                               */      T1_Long    start_pos    = FILE_Pos();      T1_UShort  tag;      T1_Long    size;      parser->private_len = 0;            for (;;)      {        error = read_pfb_tag(stream, &tag, &size);        if (error) goto Fail;                if (tag != 0x8002)          break;                  parser->private_len += size;        if ( FILE_Skip(size) )          goto Fail;      }      /* Check that we have a private dictionary there */      /* and allocate private dictionary buffer        */      if ( parser->private_len == 0 )      {        FT_ERROR(( "T1.Open_Private: invalid private dictionary section\n" ));        error = T1_Err_Invalid_File_Format;        goto Fail;      }      if ( FILE_Seek( start_pos )                             ||           ALLOC( parser->private_dict, parser->private_len ) )        goto Fail;      parser->private_len = 0;      for (;;)      {        error = read_pfb_tag( stream, &tag, &size );        if (error || tag != 0x8002) { error = 0; break; }        if ( FILE_Read( parser->private_dict + parser->private_len, size ) )          goto Fail;        parser->private_len += size;      }    }    else    {      /* we have already "loaded" the whole PFA font file in memory */      /* if this is a memory resource, allocate a new block to hold */      /* the private dict. Otherwise, simply overwrite into the     */      /* base dict block in the heap..                              */      /* first of all, look at the "eexec" keyword */      FT_Byte*  cur   = parser->base_dict;      FT_Byte*  limit = cur + parser->base_len;            FT_Byte   c;            for (;;)      {        c = cur[0];        if (c == 'e' && cur+9 < limit)  /* 9 = 5 letters for 'eexec' + newline + 4 chars */        {          if ( cur[1] == 'e' && cur[2] == 'x' &&               cur[3] == 'e' && cur[4] == 'c' )          {            cur += 6; /* we skip the newling after the "eexec" */            break;          }        }        cur++;        if (cur >= limit)        {          FT_ERROR(("T1.Open_Private: could not find 'eexec' keyword\n"));          error = FT_Err_Invalid_File_Format;          goto Exit;        }      }            /* now determine wether where to write the _encrypted_ binary private    */      /* dictionary. We overwrite the base dictionary for disk-based resources */      /* and allocate a new block otherwise                                    */            size = parser->base_len - (cur-parser->base_dict);             if ( parser->in_memory )      {        /* note that we allocate one more byte to put a terminating '0' */        if (ALLOC( parser->private_dict, size+1 )) goto Fail;        parser->private_len = size;      }      else      {        parser->single_block = 1;                parser->private_dict = parser->base_dict;        parser->private_len  = size;        parser->base_dict    = 0;        parser->base_len     = 0;      }            /* now determine wether the private dictionary is encoded in binary */      /* or hexadecimal ASCII format..                                    */      /* and decode it accordingly                                        */      /* we need to access the next 4 bytes (after the final \r following */      /* the 'eexec' keyword..) if they all are hexadecimal digits, then  */      /*we have a case of ASCII storage..                                 */      if ( ( hexa_value( cur[0] ) | hexa_value( cur[1] ) |             hexa_value( cur[2] ) | hexa_value( cur[3] ) ) < 0 )      {       /* binary encoding - "simply" copy the private dict */       MEM_Copy( parser->private_dict, cur, size );      }      else      {              /* ASCII hexadecimal encoding.. This blows goats !!.. */               T1_Byte*  write;        T1_Int    count;        write = parser->private_dict;        count = 0;               for ( ;cur < limit; cur++)        {          int  hex1;                   /* check for newline */          if (cur[0] == '\r' || cur[0] == '\n')            continue;                     /* exit if we have a non-hexadecimal digit that isn't a newline */          hex1 = hexa_value(cur[0]);          if (hex1 < 0 || cur+1 >= limit)            break;                   /* otherwise, store byte */          *write++ = (hex1 << 4) | hexa_value(cur[1]);          count++;          cur++;        }               /* put a safeguard */        parser->private_len = write - parser->private_dict;        *write++ = 0;      }    }       /* we now decrypt the encoded binary private dictionary */    T1_Decrypt( parser->private_dict, parser->private_len, 55665 );    parser->cursor = parser->private_dict;    parser->limit  = parser->cursor + parser->private_len;  Fail:  Exit:    return error;  }  

⌨️ 快捷键说明

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