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

📄 ftvalid.c

📁 freetype库的应用demo,里面包含freetype的很多实例
💻 C
字号:
/****************************************************************************//*                                                                          *//*  The FreeType project -- a free and portable quality font engine         *//*                                                                          *//*  Copyright 2005 by                                                       *//*  D. Turner, R.Wilhelm, and W. Lemberg                                    *//*                                                                          *//*  ftvalid: Validates layout related tables of OpenType.  This program     *//*           calls `FT_OpenType_Validate' on a given file, and reports      *//*           the validation result.                                         *//*                                                                          *//*  written by YAMATO Masatake and SUZUKI Toshiya.                          *//*                                                                          *//****************************************************************************/#include <ft2build.h>#include FT_FREETYPE_H#include FT_INTERNAL_DEBUG_H#include FT_INTERNAL_VALIDATE_H#include FT_TRUETYPE_TABLES_H#include FT_TRUETYPE_TAGS_H#include FT_INTERNAL_MEMORY_H#include FT_INTERNAL_OBJECTS_H#include FT_OPENTYPE_VALIDATE_H#include "common.h"#include <stdio.h>#include <string.h>#include <stdlib.h>  static char*  execname;    typedef struct  TableSpecRec_  {    FT_UInt  tag;    FT_UInt  validation_flag;  } TableSpecRec, *TableSpec;  typedef enum   { #define OT_VALIDATOR_SYMBOL "ot"     OT_VALIDATE = 0,  } ValidatorType;  static const char*  validator_symbols[] = { OT_VALIDATOR_SYMBOL, };  static ValidatorType  validator;  #define MAKE_TABLE_SPEC( x ) { TTAG_##x, FT_VALIDATE_##x }  static const TableSpecRec  ot_table_spec[] =   {    MAKE_TABLE_SPEC( BASE ),    MAKE_TABLE_SPEC( GDEF ),    MAKE_TABLE_SPEC( GPOS ),    MAKE_TABLE_SPEC( GSUB ),    MAKE_TABLE_SPEC( JSTF ),  };#define N_OT_TABLE_SPEC  ( sizeof ( ot_table_spec ) / sizeof ( TableSpecRec ) )  static void  panic( int          error,         const char*  message )  {    fprintf( stderr, "%s\n  error = 0x%04x\n", message, error );    exit( 1 );  }  static char*  make_tag_chararray ( char     chararray[4],                       FT_UInt  tag )  {    chararray[0] = (char)( ( tag >> 24 ) & 0xFF );    chararray[1] = (char)( ( tag >> 16 ) & 0xFF );    chararray[2] = (char)( ( tag >> 8  ) & 0xFF );    chararray[3] = (char)( ( tag >> 0  ) & 0xFF );    return chararray;  }  static void  print_tag ( FILE*    stream,              FT_UInt  tag )  {    char  buffer[5];    buffer[4] = '\0';    fprintf( stream, "%s", make_tag_chararray( buffer, tag ) );  }  static void  print_usage( void )  {    unsigned int i;    fprintf( stderr, "\n" );    fprintf( stderr, "ftvalid: layout table validator -- part of the FreeType project\n" );    fprintf( stderr, "---------------------------------------------------------------\n" );    fprintf( stderr, "\n" );    fprintf( stderr, "Usage: %s [options] fontfile\n", execname );    fprintf( stderr, "\n" );    fprintf( stderr, "  -t validator              select validator. \n");    fprintf( stderr, "                            Currently only \"ot\" is available.\n" );    fprintf( stderr, "\n" );    fprintf( stderr, "  -T \"sfnt:tabl:enam:es  \"  select snft table names to be validated.\n" );    fprintf( stderr, "                            `:' is for separating table names.\n" );    fprintf( stderr, "                            Supported tables in ot validator are:\n" );    fprintf( stderr, "                            " );    for ( i = 0; i < N_OT_TABLE_SPEC; i++ )    {      print_tag( stderr, ot_table_spec[i].tag );      fprintf( stderr, " " );    }    fprintf( stderr, "\n" );    fprintf( stderr, "\n" );    fprintf( stderr, "  -L                        list the layout related SFNT tables\n" );    fprintf( stderr, "                            available in the font file. Choice of\n" );    fprintf( stderr, "                            validator with -t option affects on the\n" );    fprintf( stderr, "                            listing.\n" );    fprintf( stderr, "\n" );    fprintf( stderr, "  -v validation_level       validation level. \n" );    fprintf( stderr, "                            validation_level = 0...2\n" );    fprintf( stderr, "                            (0: default, 1: tight, 2: paranoid)\n" );#if 0    fprintf( stderr, "  -l trace_level            trace level for debug information.\n" );    fprintf( stderr, "                            trace_level = 1...7\n" );#endif /* 0 */    fprintf( stderr, "-------------------------------------------------------------------\n" );    fprintf( stderr, "\n" );    fprintf( stderr, "Environment variable\n" );    fprintf( stderr, "FT2_DEBUG: You can specify trace components and their levels[1-7]\n" );    fprintf( stderr, "           to it like FT2_DEBUG=\"module1:level module2:level...\".\n" );    fprintf( stderr, "           Available components for ot validator:\n" );    fprintf( stderr, "           otvmodule otvcommon otvbase otvgdef otvgpos otvgsub otvjstf\n" );    fprintf( stderr, "\n" );    exit( 1 );  }  static FT_Error  try_load( FT_Face   face,            FT_ULong  tag )  {    FT_ULong  length;    length = 0;    return FT_Load_Sfnt_Table( face, tag, 0, NULL, &length );  }  static FT_UInt  find_validation_flag( FT_UInt             tag,                        const TableSpecRec  spec[],                        int                 spec_count )  {    int i;    for ( i = 0; i < spec_count; i++ )    {      if ( tag == spec[i].tag )        return spec[i].validation_flag;    }        fprintf( stderr, "*** Wrong table name: " );    print_tag( stderr, tag );    fprintf( stderr, "\n" );    print_usage();    return 0;  }  static FT_UInt  parse_table_specs( const char*         tables,                     const TableSpecRec  spec[],                     int                 spec_count )  {    FT_UInt  validation_flags;    size_t   len;    unsigned int  i;    char          tag[4];        validation_flags = 0;    len = strlen( tables );    if (( len % 5 ) != 4 )    {      fprintf( stderr, "*** Wrong length of table names\n" );      print_usage();    }        for ( i = 0; i < len; i++ )    {      if ( ( ( i % 5 ) == 4 ) )      {        if ( tables[i] != ':' )        {          fprintf( stderr, "*** Wrong table separator: %c\n", tables[i] );          print_usage();        }        i++;      }      tag[i % 5] = tables[i];      if ( ( i % 5 ) == 3 )        validation_flags |= find_validation_flag( FT_MAKE_TAG( tag[0],                                                               tag[1],                                                               tag[2],                                                               tag[3] ),                                                   spec,                                                   spec_count );    }    return validation_flags;  }  static FT_UInt  list_face_tables( FT_Face             face,                    const TableSpecRec  spec[],                    int                 spec_count )  {    FT_Error  error;    FT_UInt  validation_flags;    int      i;    FT_UInt  tag;        validation_flags = 0;        for ( i = 0; i < spec_count; i++ )    {      tag   = spec[i].tag;      error = try_load( face, tag );      if ( error == 0 )        validation_flags |= spec[i].validation_flag;    }    return validation_flags;  }  static FT_UInt  make_table_specs( FT_Face             face,                    const char*         request,                    const TableSpecRec  spec[],                    int                 spec_count )  {    if ( request == NULL || request[0] == '\0' )      return list_face_tables ( face, spec, spec_count );    else      return parse_table_specs ( request, spec, spec_count );  }  static int  print_tables( FILE*               stream,                FT_UInt             validation_flags,                const TableSpecRec  spec[],                int                 spec_count )  {    int i;    int n_print;        for ( i = 0, n_print = 0; i < spec_count; i++ )    {      if ( spec[i].validation_flag & validation_flags )      {        if ( n_print != 0 )          fprintf( stream, "%c", ':' );        print_tag( stream, spec[i].tag );        n_print++;      }    }        fprintf( stream, "\n" );    return !n_print;  }  static void  report_header( FT_UInt             validation_flags,                 const TableSpecRec  spec[],                 int                 spec_count )  {    printf( "[%s:%s] validation targets: ",            execname, validator_symbols[validator] );    print_tables( stdout, validation_flags, spec, spec_count );    printf( "-------------------------------------------------------------------\n" );  }  static void  report_result( FT_Bytes            data[],                 FT_UInt             validation_flags,                 const TableSpecRec  spec[],                 int                 spec_count )  {    int  i;    int  n_passes;        for ( i = 0, n_passes = 0; i < spec_count; i++ )    {      if ( ( spec[i].validation_flag & validation_flags ) &&             data[i] != NULL                              )      {        printf( "[%s:%s] ", execname, validator_symbols[validator] );        print_tag( stdout, spec[i].tag );        fprintf( stdout, "...pass\n" );        n_passes++;      }    }    if ( n_passes == 0 )    {      printf( "[%s:%s] layout tables are not invalid.\n",              execname, validator_symbols[validator] );      printf( "[%s:%s] set FT2_DEBUG environment variable to \n",              execname, validator_symbols[validator] );      printf( "[%s:%s] know the validation detail. \n",              execname, validator_symbols[validator] );    }  }  /*    * OpenType related funtions   */  static int  run_ot_validator( FT_Face      face,                    const char*  tables,                    int          validation_level )  {    FT_UInt       validation_flags;    FT_Error      error;    FT_Bytes      data[N_OT_TABLE_SPEC];    unsigned int  i;    FT_Memory     memory = FT_FACE_MEMORY( face );        validation_flags  = validation_level;    validation_flags |= make_table_specs( face, tables, ot_table_spec,                                          N_OT_TABLE_SPEC );    for ( i = 0; i < N_OT_TABLE_SPEC; i++ )      data[i] = NULL;    report_header( validation_flags, ot_table_spec, N_OT_TABLE_SPEC );    error = FT_OpenType_Validate(              face,               validation_flags,               &data[0], &data[1], &data[2], &data[3], &data[4] );          report_result( data, validation_flags, ot_table_spec, N_OT_TABLE_SPEC );    for ( i = 0; i < N_OT_TABLE_SPEC; i++ )      FT_FREE( data[i] );    return (int)error;  }  static int  list_ot_tables( FT_Face  face )  {    FT_UInt  validation_flags;    validation_flags = list_face_tables( face, ot_table_spec,                                         N_OT_TABLE_SPEC );    return print_tables( stdout, validation_flags, ot_table_spec,                         N_OT_TABLE_SPEC );  }  /*   * Main driver   */  int  main( int     argc,         char**  argv )  {    char*  fontfile;    int    option;    int    status;    char*  tables;    int    dump_table_list;    FT_ValidationLevel  validation_level;#if 0    int  trace_level;#endif  /* 0 */        execname = ft_basename( argv[0] );    /*     * Parsing options     */    validator        = OT_VALIDATE;    tables           = NULL;    dump_table_list  = 0;    validation_level = FT_VALIDATE_DEFAULT;#if 0    trace_level      = 0;#endif  /* 0 */    while ( 1 )    {      option = getopt( argc, argv, "t:T:Lv:l:" );      if ( option == -1 )        break;          switch ( option )      {      case 't':        if ( strcmp( optarg, OT_VALIDATOR_SYMBOL ) == 0 )          validator = OT_VALIDATE;        else        {          fprintf( stderr, "*** Unknown validator name: %s\n", optarg );          print_usage();        }        break;      case 'T':        tables = optarg;        break;      case 'L':        dump_table_list = 1;        break;      case 'v':        validation_level = (FT_ValidationLevel)atoi( optarg );        if ( validation_level > FT_VALIDATE_PARANOID )        {          fprintf( stderr, "*** Validation level is out of range: %d\n",                           validation_level );          print_usage();        }        break;      default:        print_usage();        break;      }    }    argc -= optind;    argv += optind;    if ( argc == 0 )    {      fprintf(stderr, "*** Font file is not specified.\n");      print_usage();    }    else if ( argc > 1 )    {      fprintf(stderr, "*** Too many font files.\n");      print_usage();    }    fontfile = argv[0];#if 0    printf( "fontfile: %s\n",            fontfile );    printf( "validator type: %s\n",            ( validator == OT_VALIDATE ) ? OT_VALIDATOR_SYMBOL : "unknown" );    printf( "tables: %s\n",            ( tables != NULL ) ? tables : "unspecified" );    printf( "action: %s\n",            ( dump_table_list == 1 ) ? "list" : "validate" );    printf( "validation level: %d\n",            validation_level );#if 0    printf( "trace level: %d\n", trace_level );#endif /* 0 */#endif /* 0 */    /*     * Run a validator     */    {      FT_Library  library;      FT_Face     face;      FT_Error    error;      status = 0;      error = FT_Init_FreeType( &library );      if ( error )        panic ( error, "Could not initialize FreeType library" );      /* TODO: Multiple faces in a font file? */      error = FT_New_Face( library, fontfile, 0, &face );      if ( error )        panic( error, "Could not open face." );            if ( validator == OT_VALIDATE )      {        if ( dump_table_list == 0 )          status = run_ot_validator( face, tables, validation_level );        else          status = list_ot_tables  ( face );      }      /* ...More validator here */            FT_Done_FreeType( library );    }    return status;  }/* End */

⌨️ 快捷键说明

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