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

📄 ftbench.c

📁 Demo for Free type 2.2.1
💻 C
📖 第 1 页 / 共 2 页
字号:
  {
    if ( FTC_SBitCache_New(cache_man, &sbit_cache) )
      return 0;
  }

  TIMER_START( timer );

  for ( i = 0; i < face->num_glyphs; i++ )
  {
    if ( !FTC_SBitCache_Lookup(sbit_cache, &font_type, i, &glyph, NULL) )
      done++;
  }

  TIMER_STOP( timer );

  return done;
}


int
test_cmap_iter( btimer_t*  timer,
                FT_Face    face,
                void*      user_data )
{
  FT_UInt   idx;
  FT_ULong  charcode;


  FT_UNUSED( user_data );

  TIMER_START( timer );

  charcode = FT_Get_First_Char( face, &idx );
  while ( idx != 0 )
    charcode = FT_Get_Next_Char( face, charcode, &idx );

  TIMER_STOP( timer );

  return 1;
}


int
test_new_face( btimer_t*  timer,
               FT_Face    face,
               void*      user_data )
{
  FT_Face  bench_face;


  FT_UNUSED( face );
  FT_UNUSED( user_data );

  TIMER_START( timer );

  if ( !get_face( &bench_face ) )
    FT_Done_Face( bench_face );

  TIMER_STOP( timer );

  return 1;
}


/*
 * main
 */

void
get_charset( FT_Face      face,
             bcharset_t*  charset )
{
  FT_ULong  charcode;
  FT_UInt   gindex;
  int i;


  charset->code = (FT_ULong*)calloc( face->num_glyphs, sizeof( FT_ULong ) );
  if ( !charset->code )
    return;

  if ( face->charmap )
  {
    i = 0;
    charcode = FT_Get_First_Char(face, &gindex);

    /* certain fonts contain a broken charmap that will map character codes */
    /* to out-of-bounds glyph indices. Take care of that here !!            */
    /*                                                                      */
    while ( gindex && i < face->num_glyphs )
    {
      charset->code[i++] = charcode;
      charcode = FT_Get_Next_Char(face, charcode, &gindex);
    }

  }
  else
  {
    /* no charmap, do an identity mapping */
    for ( i = 0; i < face->num_glyphs; i++ )
      charset->code[i] = i;
  }

  charset->size = i;
}


FT_Error
get_face( FT_Face*     face )
{
  static unsigned char*  memory_file = NULL;
  static size_t          memory_size;
  int                    face_index = 0;
  FT_Error               error;


  if ( preload )
  {
    if ( !memory_file )
    {
      FILE*  file = fopen( filename, "rb" );


      if ( file == NULL )
      {
        fprintf( stderr, "couldn't find or open `%s'\n", filename );

        return 1;
      }

      fseek( file, 0, SEEK_END );
      memory_size = ftell( file );
      fseek( file, 0, SEEK_SET );

      memory_file = (FT_Byte*)malloc( memory_size );
      if ( memory_file == NULL )
      {
        fprintf( stderr, "couldn't allocate memory to pre-load font file\n" );

        return 1;
      }

      if ( fread( memory_file, 1, memory_size, file ) != memory_size )
      {
        fprintf( stderr, "read error\n" );
        free( memory_file );
        memory_file = NULL;

        return 1;
      }
    }

    error = FT_New_Memory_Face( lib, memory_file, memory_size, face_index, face );
  }
  else
    error = FT_New_Face(lib, filename, face_index, face);

  if ( error )
    fprintf( stderr, "couldn't load font resource\n");

  return error;
}


void usage(void)
{
  int  i;


  fprintf( stderr,
    "ftbench: bench some common FreeType paths\n"
    "-----------------------------------------\n\n"
    "Usage: ftbench [options] fontname\n\n"
    "options:\n"
    "   -C : compare with cached version if available\n"
    "   -c : max iteration count for each test (0 means time limited)\n"
    "   -f : load flags (hexadecimal)\n"
    "   -m : max cache size in KByte (default is %d)\n"
    "   -p : preload font file in memory\n"
    "   -r : render mode (default is FT_RENDER_MODE_NORMAL)\n"
    "   -s : face size (default is %d)\n"
    "   -t : max time per bench in seconds (default is %.0f)\n"
    "   -b tests : perform chosen tests (default is all)\n",
    CACHE_SIZE, FACE_SIZE, BENCH_TIME );

  for ( i = 0; i < N_FT_BENCH; i++ )
  {
    if ( !bench_desc[i] )
      break;

    fprintf( stderr, "      %c : %s\n", 'a' + i, bench_desc[i] );
  }

  exit( 1 );
}


#define TEST(x) (!test_string || strchr(test_string, (x)))

int
main(int argc,
     char** argv)
{
  FT_Face     face;
  long        max_bytes = CACHE_SIZE * 1024;
  char*       test_string = NULL;
  int         size = FACE_SIZE;
  int         max_iter = 0;
  double      max_time = BENCH_TIME;
  int         compare_cached = 0;
  int         i;

  while ( 1 )
  {
    int  opt;


    opt = getopt( argc, argv, "Cc:f:m:pr:s:t:b:" );

    if ( opt == -1 )
      break;

    switch ( opt )
    {
    case 'C':
      compare_cached = 1;
      break;
    case 'c':
      max_iter = atoi( optarg );
      break;
    case 'f':
      load_flags = strtol( optarg, NULL, 16 );
      break;
    case 'm':
      max_bytes = atoi( optarg );
      max_bytes *= 1024;
      break;
    case 'p':
      preload = 1;
      break;
    case 'r':
      render_mode = (FT_Render_Mode)atoi( optarg );
      if ( render_mode >= FT_RENDER_MODE_MAX )
        render_mode = FT_RENDER_MODE_NORMAL;
      break;
    case 's':
      size = atoi( optarg );
      if ( size <= 0 )
        size = 1;
      else if ( size > 500 )
        size = 500;
      break;
    case 't':
      max_time = atof( optarg );
      break;
    case 'b':
      test_string = optarg;
      break;
    default:
      usage();
      break;
    }
  }

  argc -= optind;
  argv += optind;

  if ( argc != 1 )
    usage();

  if ( FT_Init_FreeType( &lib ) )
  {
    fprintf( stderr, "could not initialize font library\n" );

    return 1;
  }

  filename = *argv;

  if ( get_face( &face ) )
    return 1;

  if ( FT_IS_SCALABLE( face ) )
  {

    if ( FT_Set_Pixel_Sizes( face, size, size ) )
    {
      fprintf( stderr, "failed to set pixel size to %d\n", size );

      return 1;
    }
  }
  else
    size = face->available_sizes[0].width;

  FTC_Manager_New( lib, 0, 0, max_bytes, face_requester, face, &cache_man );

  font_type.face_id = (FTC_FaceID) 1;
  font_type.width   = (short) size;
  font_type.height  = (short) size;
  font_type.flags   = load_flags;

  for ( i = 0; i < N_FT_BENCH; i++ )
  {
    btest_t  test;


    if ( !TEST( 'a' + i ) )
      continue;

    test.title       = NULL;
    test.bench       = NULL;
    test.cache_first = 0;
    test.user_data   = NULL;

    switch ( i )
    {
    case FT_BENCH_LOAD_GLYPH:
      test.title = "Load";
      test.bench = test_load;
      benchmark( face, &test, max_iter, max_time );

      if ( compare_cached )
      {
        test.cache_first = 1;

        test.title = "Load (image cached)";
        test.bench = test_image_cache;
        benchmark( face, &test, max_iter, max_time );

        test.title = "Load (sbit cached)";
        test.bench = test_sbit_cache;
        benchmark( face, &test, max_iter, max_time );
      }
      break;
    case FT_BENCH_RENDER:
      test.title = "Render";
      test.bench = test_render;
      benchmark( face, &test, max_iter, max_time );
      break;
    case FT_BENCH_GET_GLYPH:
      test.title = "Get_Glyph";
      test.bench = test_get_glyph;
      benchmark( face, &test, max_iter, max_time );
      break;
    case FT_BENCH_GET_CBOX:
      test.title = "Get_CBox";
      test.bench = test_get_cbox;
      benchmark( face, &test, max_iter, max_time );
      break;
    case FT_BENCH_CMAP:
      {
        bcharset_t  charset;


        get_charset( face, &charset );
        if ( charset.code )
        {
          test.user_data = (void*)&charset;


          test.title = "Get_Char_Index";
          test.bench = test_get_char_index;

          benchmark( face, &test, max_iter, max_time );

          if ( compare_cached )
          {
            test.cache_first = 1;

            test.title = "Get_Char_Index (cached)";
            test.bench = test_cmap_cache;
            benchmark( face, &test, max_iter, max_time );
          }

          free( charset.code );
        }
      }
      break;
    case FT_BENCH_CMAP_ITER:
      test.title = "Iterate CMap";
      test.bench = test_cmap_iter;
      benchmark( face, &test, max_iter, max_time );
      break;
    case FT_BENCH_NEW_FACE:
      test.title = "New_Face";
      test.bench = test_new_face;
      benchmark( face, &test, max_iter, max_time );
      break;
    }
  }

  if ( cache_man )
    FTC_Manager_Done( cache_man );

  FT_Done_Face( face );

  FT_Done_FreeType( lib );

  return 0;
}


/* End */

⌨️ 快捷键说明

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