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

📄 ttload.c

📁 一个类似windows
💻 C
📖 第 1 页 / 共 5 页
字号:
/***************************************************************************/
/*                                                                         */
/*  ttload.c                                                               */
/*                                                                         */
/*    Load the basic TrueType tables, i.e., tables that can be either in   */
/*    TTF or OTF fonts (body).                                             */
/*                                                                         */
/*  Copyright 1996-2001, 2002, 2003, 2004, 2005 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.                                        */
/*                                                                         */
/***************************************************************************/


#include <ft2build.h>
#include FT_INTERNAL_DEBUG_H
#include FT_INTERNAL_STREAM_H
#include FT_TRUETYPE_TAGS_H
#include "ttload.h"

#include "sferrors.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_ttload


  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
  /*    tt_face_lookup_table                                               */
  /*                                                                       */
  /* <Description>                                                         */
  /*    Looks for a TrueType table by name.                                */
  /*                                                                       */
  /* <Input>                                                               */
  /*    face :: A face object handle.                                      */
  /*                                                                       */
  /*    tag  :: The searched tag.                                          */
  /*                                                                       */
  /* <Return>                                                              */
  /*    A pointer to the table directory entry.  0 if not found.           */
  /*                                                                       */
  FT_LOCAL_DEF( TT_Table  )
  tt_face_lookup_table( TT_Face   face,
                        FT_ULong  tag  )
  {
    TT_Table  entry;
    TT_Table  limit;


    FT_TRACE3(( "tt_face_lookup_table: %08p, `%c%c%c%c' -- ",
                face,
                (FT_Char)( tag >> 24 ),
                (FT_Char)( tag >> 16 ),
                (FT_Char)( tag >> 8  ),
                (FT_Char)( tag       ) ));

    entry = face->dir_tables;
    limit = entry + face->num_tables;

    for ( ; entry < limit; entry++ )
    {
      /* For compatibility with Windows, we consider 0-length */
      /* tables the same as missing tables.                   */
      if ( entry->Tag == tag && entry->Length != 0 )
      {
        FT_TRACE3(( "found table.\n" ));
        return entry;
      }
    }

    FT_TRACE3(( "could not find table!\n" ));
    return 0;
  }


  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
  /*    tt_face_goto_table                                                 */
  /*                                                                       */
  /* <Description>                                                         */
  /*    Looks for a TrueType table by name, then seek a stream to it.      */
  /*                                                                       */
  /* <Input>                                                               */
  /*    face   :: A face object handle.                                    */
  /*                                                                       */
  /*    tag    :: The searched tag.                                        */
  /*                                                                       */
  /*    stream :: The stream to seek when the table is found.              */
  /*                                                                       */
  /* <Output>                                                              */
  /*    length :: The length of the table if found, undefined otherwise.   */
  /*                                                                       */
  /* <Return>                                                              */
  /*    FreeType error code.  0 means success.                             */
  /*                                                                       */
  FT_LOCAL_DEF( FT_Error )
  tt_face_goto_table( TT_Face    face,
                      FT_ULong   tag,
                      FT_Stream  stream,
                      FT_ULong*  length )
  {
    TT_Table  table;
    FT_Error  error;


    table = tt_face_lookup_table( face, tag );
    if ( table )
    {
      if ( length )
        *length = table->Length;

      if ( FT_STREAM_SEEK( table->Offset ) )
       goto Exit;
    }
    else
      error = SFNT_Err_Table_Missing;

  Exit:
    return error;
  }


  /* In theory, we should check the values of `search_range',              */
  /* `entry_selector', and `range_shift' to detect non-SFNT based files    */
  /* whose header might also start with 0x100000L (yes, these exist).      */
  /*                                                                       */
  /* Very unfortunately, many TrueType fonts don't have these fields       */
  /* set correctly and we must ignore them to support them.  An            */
  /* alternative way to check the font file is thus to:                    */
  /*                                                                       */
  /* - check that `num_tables' is valid                                    */
  /* - look for a "head" table, check its size, and parse it to            */
  /*   see if its "magic" field is correctly set                           */
  /*                                                                       */
  /* When checking directory entries, ignore the tables `glyx' and `locx'  */
  /* which are hacked-out versions of `glyf' and `loca' in some PostScript */
  /* Type 42 fonts, and will generally be invalid.                         */
  /*                                                                       */
  static FT_Error
  sfnt_dir_check( FT_Stream  stream,
                  FT_ULong   offset,
                  FT_UInt    num_tables )
   {
    FT_Error        error;
    FT_UInt         nn, has_head = 0;

    const FT_ULong  glyx_tag = FT_MAKE_TAG( 'g', 'l', 'y', 'x' );
    const FT_ULong  locx_tag = FT_MAKE_TAG( 'l', 'o', 'c', 'x' );

    static const FT_Frame_Field  sfnt_dir_entry_fields[] =
    {
#undef  FT_STRUCTURE
#define FT_STRUCTURE  TT_TableRec

      FT_FRAME_START( 16 ),
        FT_FRAME_ULONG( Tag ),
        FT_FRAME_ULONG( CheckSum ),
        FT_FRAME_ULONG( Offset ),
        FT_FRAME_ULONG( Length ),
      FT_FRAME_END
    };


    /* if 'num_tables' is 0, read the table count from the file */
    if ( num_tables == 0 )
    {
      if ( FT_STREAM_SEEK( offset )     ||
           FT_STREAM_SKIP( 4 )          ||
           FT_READ_USHORT( num_tables ) ||
           FT_STREAM_SKIP( 6 )          )
        goto Bad_Format;

      if ( offset + 12 + num_tables*16 > stream->size )
        goto Bad_Format;
    }
    else if ( FT_STREAM_SEEK( offset + 12 ) )
      goto Bad_Format;

    for ( nn = 0; nn < num_tables; nn++ )
    {
      TT_TableRec  table;


      if ( FT_STREAM_READ_FIELDS( sfnt_dir_entry_fields, &table ) )
        goto Bad_Format;

      if ( table.Offset + table.Length > stream->size     &&
           table.Tag != glyx_tag && table.Tag != locx_tag )
        goto Bad_Format;

      if ( table.Tag == TTAG_head )
      {
        FT_UInt32  magic;


#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
      head_retry:
#endif  /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */

        has_head = 1;

        /* The table length should be 0x36, but certain font tools
         * make it 0x38, so we will just check that it is greater.
         *
         * Note that according to the specification,
         * the table must be padded to 32-bit lengths, but this doesn't
         * apply to the value of its "Length" field!
         */
        if ( table.Length < 0x36                 ||
             FT_STREAM_SEEK( table.Offset + 12 ) ||
             FT_READ_ULONG( magic )              ||
             magic != 0x5F0F3CF5UL               )
          goto Bad_Format;

        if ( FT_STREAM_SEEK( offset + 28 + 16*nn ) )
          goto Bad_Format;
      }
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
      else if ( table.Tag == TTAG_bhed )
        goto head_retry;
#endif  /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */      
    }

    if ( has_head == 0 )
      goto Bad_Format;

  Exit:
    return error;

  Bad_Format:
    error = SFNT_Err_Unknown_File_Format;
    goto Exit;
  }


  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
  /*    tt_face_load_sfnt_header                                           */
  /*                                                                       */
  /* <Description>                                                         */
  /*    Loads the header of a SFNT font file.  Supports collections.       */
  /*                                                                       */
  /* <Input>                                                               */
  /*    face       :: A handle to the target face object.                  */
  /*                                                                       */
  /*    stream     :: The input stream.                                    */
  /*                                                                       */
  /*    face_index :: If the font is a collection, the number of the font  */
  /*                  in the collection.  Must be zero otherwise.          */
  /*                                                                       */
  /* <Output>                                                              */
  /*    sfnt       :: The SFNT header.                                     */
  /*                                                                       */
  /* <Return>                                                              */
  /*    FreeType error code.  0 means success.                             */
  /*                                                                       */
  /* <Note>                                                                */
  /*    The stream cursor must be at the font file's origin.               */
  /*                                                                       */
  /*    This function recognizes fonts embedded in a `TrueType collection' */
  /*                                                                       */
  /*    The header will be checked whether it is valid by looking at the   */
  /*    values of `search_range', `entry_selector', and `range_shift'.     */
  /*                                                                       */
  FT_LOCAL_DEF( FT_Error )
  tt_face_load_sfnt_header( TT_Face      face,
                            FT_Stream    stream,
                            FT_Long      face_index,
                            SFNT_Header  sfnt )
  {
    FT_Error   error;
    FT_ULong   font_format_tag, format_tag, offset;
    FT_Memory  memory = stream->memory;

    static const FT_Frame_Field  sfnt_header_fields[] =
    {
#undef  FT_STRUCTURE
#define FT_STRUCTURE  SFNT_HeaderRec

      FT_FRAME_START( 8 ),
        FT_FRAME_USHORT( num_tables ),
        FT_FRAME_USHORT( search_range ),
        FT_FRAME_USHORT( entry_selector ),
        FT_FRAME_USHORT( range_shift ),
      FT_FRAME_END
    };

    static const FT_Frame_Field  ttc_header_fields[] =
    {
#undef  FT_STRUCTURE
#define FT_STRUCTURE  TTC_HeaderRec

      FT_FRAME_START( 8 ),
        FT_FRAME_LONG( version ),
        FT_FRAME_LONG( count   ),
      FT_FRAME_END
    };


    FT_TRACE2(( "tt_face_load_sfnt_header: %08p, %ld\n",
                face, face_index ));

    face->ttc_header.tag     = 0;
    face->ttc_header.version = 0;
    face->ttc_header.count   = 0;

    face->num_tables = 0;

    /* First of all, read the first 4 bytes.  If it is `ttcf', then the   */
    /* file is a TrueType collection, otherwise it is a single-face font. */
    /*                                                                    */
    offset = FT_STREAM_POS();

    if ( FT_READ_ULONG( font_format_tag ) )
      goto Exit;

    format_tag = font_format_tag;

    if ( font_format_tag == TTAG_ttcf )
    {
      FT_Int  n;

⌨️ 快捷键说明

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