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

📄 cffload.c

📁 source code: Covert TXT to PDF
💻 C
📖 第 1 页 / 共 3 页
字号:
                    FT_ULong      offset )  {    FT_Memory  memory     = stream->memory;    FT_Error   error      = 0;    FT_UShort  glyph_sid;    charset->offset = base_offset + offset;    /* Get the format of the table. */    if ( FILE_Seek( charset->offset ) ||         READ_Byte( charset->format ) )      goto Exit;    /* If the the offset is greater than 2, we have to parse the */    /* charset table.                                            */    if ( offset > 2 )    {      FT_UInt  j;      /* Allocate memory for sids. */      if ( ALLOC( charset->sids, num_glyphs * sizeof ( FT_UShort ) ) )        goto Exit;      /* assign the .notdef glyph */      charset->sids[0] = 0;      switch ( charset->format )      {      case 0:        for ( j = 1; j < num_glyphs; j++ )        {          if ( READ_UShort( glyph_sid ) )            goto Exit;          charset->sids[j] = glyph_sid;        }        break;      case 1:      case 2:        {          FT_UInt  nleft;          FT_UInt  i;          j = 1;          while ( j < num_glyphs )          {            /* Read the first glyph sid of the range. */            if ( READ_UShort( glyph_sid ) )              goto Exit;            /* Read the number of glyphs in the range.  */            if ( charset->format == 2 )            {              if ( READ_UShort( nleft ) )                goto Exit;            }            else            {              if ( READ_Byte( nleft ) )                goto Exit;            }            /* Fill in the range of sids -- `nleft + 1' glyphs. */            for ( i = 0; i <= nleft; i++, j++, glyph_sid++ )              charset->sids[j] = glyph_sid;          }        }        break;      default:        FT_ERROR(( "CFF_Load_Charset: invalid table format!\n" ));        error = CFF_Err_Invalid_File_Format;        goto Exit;      }    }    else    {      /* Parse default tables corresponding to offset == 0, 1, or 2.  */      /* CFF specification intimates the following:                   */      /*                                                              */      /* In order to use a predefined charset, the following must be  */      /* true: The charset constructed for the glyphs in the font's   */      /* charstrings dictionary must match the predefined charset in  */      /* the first num_glyphs, and hence must match the predefined    */      /* charset *exactly*.                                           */      switch ( offset )      {      case 0:        if ( num_glyphs != 229 )        {          FT_ERROR(("CFF_Load_Charset: implicit charset not equal to\n"                    "predefined charset (Adobe ISO-Latin)!\n" ));          error = CFF_Err_Invalid_File_Format;          goto Exit;        }        /* Allocate memory for sids. */        if ( ALLOC( charset->sids, num_glyphs * sizeof ( FT_UShort ) ) )          goto Exit;        /* Copy the predefined charset into the allocated memory. */        MEM_Copy( charset->sids, cff_isoadobe_charset,                  num_glyphs * sizeof ( FT_UShort ) );        break;      case 1:        if ( num_glyphs != 166 )        {          FT_ERROR(( "CFF_Load_Charset: implicit charset not equal to\n"                     "predefined charset (Adobe Expert)!\n" ));          error = CFF_Err_Invalid_File_Format;          goto Exit;        }        /* Allocate memory for sids. */        if ( ALLOC( charset->sids, num_glyphs * sizeof ( FT_UShort ) ) )          goto Exit;        /* Copy the predefined charset into the allocated memory.     */        MEM_Copy( charset->sids, cff_expert_charset,                  num_glyphs * sizeof ( FT_UShort ) );        break;      case 2:        if ( num_glyphs != 87 )        {          FT_ERROR(( "CFF_Load_Charset: implicit charset not equal to\n"                     "predefined charset (Adobe Expert Subset)!\n" ));          error = CFF_Err_Invalid_File_Format;          goto Exit;        }        /* Allocate memory for sids. */        if ( ALLOC( charset->sids, num_glyphs * sizeof ( FT_UShort ) ) )          goto Exit;        /* Copy the predefined charset into the allocated memory.     */        MEM_Copy( charset->sids, cff_expertsubset_charset,                  num_glyphs * sizeof ( FT_UShort ) );        break;      default:        error = CFF_Err_Invalid_File_Format;        goto Exit;      }    }  Exit:    /* Clean up if there was an error. */    if ( error )      if ( charset->sids )      {        if ( charset->sids )          FREE( charset->sids );        charset->format = 0;        charset->offset = 0;        charset->sids   = 0;      }    return error;  }  static FT_Error  CFF_Load_Encoding( CFF_Encoding*  encoding,                     CFF_Charset*   charset,                     FT_UInt        num_glyphs,                     FT_Stream      stream,                     FT_ULong       base_offset,                     FT_ULong       offset )  {    FT_Memory   memory = stream->memory;    FT_Error    error  = 0;    FT_UInt     count;    FT_UInt     j;    FT_UShort   glyph_sid;    FT_Byte     glyph_code;    /* Check for charset->sids.  If we do not have this, we fail. */    if ( !charset->sids )    {      error = CFF_Err_Invalid_File_Format;      goto Exit;    }    /* Allocate memory for sids/codes -- there are at most 256 sids/codes */    /* for an encoding.                                                   */    if ( ALLOC( encoding->sids,  256 * sizeof ( FT_UShort ) ) ||         ALLOC( encoding->codes, 256 * sizeof ( FT_UShort ) ) )      goto Exit;    /* Zero out the code to gid/sid mappings. */    for ( j = 0; j < 255; j++ )    {      encoding->sids [j] = 0;      encoding->codes[j] = 0;    }    /* Note: The encoding table in a CFF font is indexed by glyph index,  */    /* where the first encoded glyph index is 1.  Hence, we read the char */    /* code (`glyph_code') at index j and make the assignment:            */    /*                                                                    */    /*    encoding->codes[glyph_code] = j + 1                             */    /*                                                                    */    /* We also make the assignment:                                       */    /*                                                                    */    /*    encoding->sids[glyph_code] = charset->sids[j + 1]               */    /*                                                                    */    /* This gives us both a code to GID and a code to SID mapping.        */    if ( offset > 1 )    {      encoding->offset = base_offset + offset;      /* we need to parse the table to determine its size */      if ( FILE_Seek( encoding->offset ) ||           READ_Byte( encoding->format ) ||           READ_Byte( count )            )        goto Exit;      switch ( encoding->format & 0x7F )      {      case 0:        for ( j = 1; j <= count; j++ )        {          if ( READ_Byte( glyph_code ) )            goto Exit;          /* Make sure j is not too big. */          if ( j > num_glyphs )            goto Exit;          /* Assign code to GID mapping. */          encoding->codes[glyph_code] = (FT_UShort)j;          /* Assign code to SID mapping. */          encoding->sids[glyph_code] = charset->sids[j];        }        break;      case 1:        {          FT_Byte  nleft;          FT_UInt  i = 1;          FT_UInt  k;          /* Parse the Format1 ranges. */          for ( j = 0;  j < count; j++, i += nleft )          {            /* Read the first glyph code of the range. */            if ( READ_Byte( glyph_code ) )              goto Exit;            /* Read the number of codes in the range. */            if ( READ_Byte( nleft ) )              goto Exit;            /* Increment nleft, so we read `nleft + 1' codes/sids. */            nleft++;            /* Fill in the range of codes/sids. */            for ( k = i; k < nleft + i; k++, glyph_code++ )            {              /* Make sure k is not too big. */              if ( k > num_glyphs )                goto Exit;              /* Assign code to GID mapping. */              encoding->codes[glyph_code] = (FT_UShort)k;              /* Assign code to SID mapping. */              encoding->sids[glyph_code] = charset->sids[k];            }          }        }        break;      default:        FT_ERROR(( "CFF_Load_Encoding: invalid table format!\n" ));        error = CFF_Err_Invalid_File_Format;        goto Exit;      }      /* Parse supplemental encodings, if any. */      if ( encoding->format & 0x80 )      {        FT_UInt glyph_id;        /* count supplements */        if ( READ_Byte( count ) )          goto Exit;        for ( j = 0; j < count; j++ )        {          /* Read supplemental glyph code. */          if ( READ_Byte( glyph_code ) )            goto Exit;          /* Read the SID associated with this glyph code. */          if ( READ_UShort( glyph_sid ) )            goto Exit;          /* Assign code to SID mapping. */          encoding->sids[glyph_code] = glyph_sid;          /* First, lookup GID which has been assigned to */          /* SID glyph_sid.                               */          for ( glyph_id = 0; glyph_id < num_glyphs; glyph_id++ )          {            if ( charset->sids[glyph_id] == glyph_sid )              break;          }          /* Now, make the assignment. */          encoding->codes[glyph_code] = (FT_UShort)glyph_id;        }      }    }    else    {      FT_UInt i;      /* We take into account the fact a CFF font can use a predefined  */      /* encoding without containing all of the glyphs encoded by this  */      /* encoding (see the note at the end of section 12 in the CFF     */      /* specification).                                                */      switch ( offset )      {      case 0:        /* First, copy the code to SID mapping. */        MEM_Copy( encoding->sids, cff_standard_encoding,                  256 * sizeof ( FT_UShort ) );        /* Construct code to GID mapping from code */        /* to SID mapping and charset.             */        for ( j = 0; j < 256; j++ )        {          /* If j is encoded, find the GID for it. */          if ( encoding->sids[j] )          {            for ( i = 1; i < num_glyphs; i++ )              /* We matched, so break. */              if ( charset->sids[i] == encoding->sids[j] )                break;            /* i will be equal to num_glyphs if we exited the above */            /* loop without a match.  In this case, we also have to */            /* fix the code to SID mapping.                         */            if ( i == num_glyphs )            {              encoding->codes[j] = 0;              encoding->sids [j] = 0;            }            else              encoding->codes[j] = (FT_UShort)i;          }        }        break;      case 1:        /* First, copy the code to SID mapping. */        MEM_Copy( encoding->sids, cff_expert_encoding,                  256 * sizeof ( FT_UShort ) );        /* Construct code to GID mapping from code to SID mapping */        /* and charset.                                           */        for ( j = 0; j < 256; j++ )        {          /* If j is encoded, find the GID for it. */          if ( encoding->sids[j] )          {            for ( i = 1; i < num_glyphs; i++ )              /* We matched, so break. */              if ( charset->sids[i] == encoding->sids[j] )                break;            /* i will be equal to num_glyphs if we exited the above */            /* loop without a match.  In this case, we also have to */            /* fix the code to SID mapping.                         */            if ( i == num_glyphs )            {              encoding->codes[j] = 0;              encoding->sids [j] = 0;            }            else              encoding->codes[j] = (FT_UShort)i;          }        }        break;      default:        FT_ERROR(( "CFF_Load_Encoding: invalid table format!\n" ));        error = CFF_Err_Invalid_File_Format;        goto Exit;      }    }  Exit:    /* Clean up if there was an error. */    if ( error )    {      if ( encoding->sids || encoding->codes )      {        if ( encoding->sids )          FREE( encoding->sids );        if ( encoding->codes )          FREE( encoding->codes );        charset->format = 0;        charset->offset = 0;        charset->sids   = 0;      }    }    return error;  }  static FT_Error  CFF_Load_SubFont( CFF_SubFont*  font,                    CFF_Index*    index,                    FT_UInt       font_index,                    FT_Stream     stream,                    FT_ULong      base_offset )  {    FT_Error        error;    CFF_Parser      parser;    FT_Byte*        dict;    FT_ULong        dict_len;    CFF_Font_Dict*  top  = &font->font_dict;    CFF_Private*    priv = &font->private_dict;    CFF_Parser_Init( &parser, CFF_CODE_TOPDICT, &font->font_dict );    /* set defaults */    MEM_Set( top, 0, sizeof ( *top ) );    top->underline_position  = -100;    top->underline_thickness = 50;    top->charstring_type     = 2;    top->font_matrix.xx      = 0x10000L;    top->font_matrix.yy      = 0x10000L;    top->cid_count           = 8720;    error = CFF_Access_Element( index, font_index, &dict, &dict_len ) ||            CFF_Parser_Run( &parser, dict, dict + dict_len );    CFF_Forget_Element( index, &dict );    if ( error )      goto Exit;    /* if it is a CID font, we stop there */    if ( top->cid_registry )      goto Exit;    /* parse the private dictionary, if any */    if ( top->private_offset && top->private_size )    {      /* set defaults */      MEM_Set( priv, 0, sizeof ( *priv ) );      priv->blue_shift       = 7;      priv->blue_fuzz        = 1;      priv->lenIV            = -1;      priv->expansion_factor = (FT_Fixed)0.06 * 0x10000L;      priv->blue_scale       = (FT_Fixed)0.039625 * 0x10000L;      CFF_Parser_Init( &parser, CFF_CODE_PRIVATE, priv );      if ( FILE_Seek( base_offset + font->font_dict.private_offset ) ||           ACCESS_Frame( font->font_dict.private_size )              )        goto Exit;      error = CFF_Parser_Run( &parser,                             (FT_Byte*)stream->cursor,                             (FT_Byte*)stream->limit );      FORGET_Frame();      if ( error )        goto Exit;    }    /* read the local subrs, if any */    if ( priv->local_subrs_offset )    {      if ( FILE_Seek( base_offset + top->private_offset +                      priv->local_subrs_offset ) )        goto Exit;      error = cff_new_index( &font->local_subrs_index, stream, 1 );      if ( error )        goto Exit;      font->num_local_subrs = font->local_subrs_index.count;      error = cff_explicit_index( &font->local_subrs_index,                                     &font->local_subrs );      if ( error )        goto Exit;    }  Exit:    return error;  }  static void  CFF_Done_SubFont( FT_Memory     memory,                    CFF_SubFont*  subfont )  {    if ( subfont )    {      cff_done_index( &subfont->local_subrs_index );      FREE( subfont->local_subrs );    }  }  FT_LOCAL_DEF FT_Error  CFF_Load_Font( FT_Stream  stream,                 FT_Int     face_index,                 CFF_Font*  font )  {    static const FT_Frame_Field  cff_header_fields[] =    {#undef  FT_STRUCTURE#define FT_STRUCTURE  CFF_Font      FT_FRAME_START( 4 ),        FT_FRAME_BYTE( version_major ),        FT_FRAME_BYTE( version_minor ),        FT_FRAME_BYTE( header_size ),        FT_FRAME_BYTE( absolute_offsize ),      FT_FRAME_END    };    FT_Error        error;    FT_Memory       memory = stream->memory;    FT_ULong        base_offset;    CFF_Font_Dict*  dict;    MEM_Set( font, 0, sizeof ( *font ) );    font->stream = stream;    font->memory = memory;    dict         = &font->top_font.font_dict;    base_offset  = FILE_Pos();    /* read CFF font header */    if ( READ_Fields( cff_header_fields, font ) )      goto Exit;    /* check format */    if ( font->version_major   != 1 ||         font->header_size      < 4 ||         font->absolute_offsize > 4 )    {      FT_TRACE2(( "[not a CFF font header!]\n" ));      error = CFF_Err_Unknown_File_Format;      goto Exit;    }    /* skip the rest of the header */    if ( FILE_Skip( font->header_size - 4 ) )      goto Exit;    /* read the name, top dict, string and global subrs index */    if ( FT_SET_ERROR( cff_new_index( &font->name_index,         stream, 0 )) ||         FT_SET_ERROR( cff_new_index( &font->font_dict_index,    stream, 0 )) ||         FT_SET_ERROR( cff_new_index( &font->string_index,       stream, 0 )) ||         FT_SET_ERROR( cff_new_index( &font->global_subrs_index, stream, 1 )) )      goto Exit;    /* well, we don't really forget the `disabled' fonts... */    font->num_faces = font->name_index.count;    if ( face_index >= (FT_Int)font->num_faces )    {      FT_ERROR(( "CFF_Load_Font: incorrect face index = %d\n",                 face_index ));      error = CFF_Err_Invalid_Argument;    }    /* in case of a font format check, simply exit now */    if ( face_index < 0 )      goto Exit;    /* now, parse the top-level font dictionary */    error = CFF_Load_SubFont( &font->top_font,                              &font->font_dict_index,                              face_index,                              stream,                              base_offset );    if ( error )      goto Exit;    /* now, check for a CID font */    if ( dict->cid_registry )    {      CFF_Index     fd_index;      CFF_SubFont*  sub;      FT_UInt       index;      /* this is a CID-keyed font, we must now allocate a table of */      /* sub-fonts, then load each of them separately              */      if ( FILE_Seek( base_offset + dict->cid_fd_array_offset ) )        goto Exit;      error = cff_new_index( &fd_index, stream, 0 );      if ( error )        goto Exit;      if ( fd_index.count > CFF_MAX_CID_FONTS )      {        FT_ERROR(( "CFF_Load_Font: FD array too large in CID font\n" ));        goto Fail_CID;      }      /* allocate & read each font dict independently */      font->num_subfonts = fd_index.count;      if ( ALLOC_ARRAY( sub, fd_index.count, CFF_SubFont ) )        goto Fail_CID;      /* setup pointer table */      for ( index = 0; index < fd_index.count; index++ )        font->subfonts[index] = sub + index;      /* now load each sub font independently */      for ( index = 0; index < fd_index.count; index++ )      {        sub = font->subfonts[index];        error = CFF_Load_SubFont( sub, &fd_index, index,                                  stream, base_offset );        if ( error )          goto Fail_CID;      }      /* now load the FD Select array */      error = CFF_Load_FD_Select( &font->fd_select,                                  dict->cid_count,                                  stream,                                  base_offset + dict->cid_fd_select_offset );    Fail_CID:      cff_done_index( &fd_index );      if ( error )        goto Exit;    }    else      font->num_subfonts = 0;    /* read the charstrings index now */    if ( dict->charstrings_offset == 0 )    {      FT_ERROR(( "CFF_Load_Font: no charstrings offset!\n" ));      error = CFF_Err_Unknown_File_Format;      goto Exit;    }    if ( FILE_Seek( base_offset + dict->charstrings_offset ) )      goto Exit;    error = cff_new_index( &font->charstrings_index, stream, 0 );    if ( error )      goto Exit;    /* explicit the global subrs */    font->num_global_subrs = font->global_subrs_index.count;    font->num_glyphs       = font->charstrings_index.count;    error = cff_explicit_index( &font->global_subrs_index,                                &font->global_subrs ) ;    if ( error )      goto Exit;    /* read the Charset and Encoding tables when available */    error = CFF_Load_Charset( &font->charset, font->num_glyphs, stream,                              base_offset, dict->charset_offset );    if ( error )      goto Exit;    error = CFF_Load_Encoding( &font->encoding,                               &font->charset,                               font->num_glyphs,                               stream,                               base_offset,                               dict->encoding_offset );    if ( error )      goto Exit;    /* get the font name */    font->font_name = CFF_Get_Name( &font->name_index, face_index );  Exit:    return error;  }  FT_LOCAL_DEF void  CFF_Done_Font( CFF_Font*  font )  {    FT_Memory  memory = font->memory;    FT_UInt    index;    cff_done_index( &font->global_subrs_index );    cff_done_index( &font->string_index );    cff_done_index( &font->font_dict_index );    cff_done_index( &font->name_index );    cff_done_index( &font->charstrings_index );    /* release font dictionaries, but only if working with */    /* a CID keyed CFF font                                */    if ( font->num_subfonts > 0 )    {      for ( index = 0; index < font->num_subfonts; index++ )        CFF_Done_SubFont( memory, font->subfonts[index] );      FREE( font->subfonts );    }    CFF_Done_Encoding( &font->encoding, font->stream );    CFF_Done_Charset( &font->charset, font->stream );    CFF_Done_SubFont( memory, &font->top_font );    CFF_Done_FD_Select( &font->fd_select, font->stream );    FREE( font->global_subrs );    FREE( font->font_name );  }/* END */

⌨️ 快捷键说明

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