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

📄 ftbench.c

📁 freetype库的应用demo,里面包含freetype的很多实例
💻 C
字号:
/****************************************************************************//*                                                                          *//*  The FreeType project -- a free and portable quality TrueType renderer.  *//*                                                                          *//*  Copyright 2002, 2003, 2004 by                                           *//*  D. Turner, R.Wilhelm, and W. Lemberg                                    *//*                                                                          *//*  ftbench: bench some common FreeType call paths                          *//*                                                                          *//****************************************************************************/#include <stdlib.h>#include <stdio.h>#include <string.h>#include <time.h>#include <ft2build.h>#include FT_FREETYPE_H#include FT_GLYPH_H#include FT_CACHE_H#include FT_CACHE_CHARMAP_H#include FT_CACHE_IMAGE_H#include FT_CACHE_SMALL_BITMAPS_H#ifdef UNIX#include <sys/time.h>#endiftypedef int(*bench_t)(FT_UInt idx,           FT_UInt charcode);typedef struct charmap_t_{  FT_UInt charcode;  FT_UInt index;} charmap_t;/* * Globals */#define CACHE_SIZE 1024#define BENCH_TIME 2.0fFT_Library        lib;FT_Face           face;FTC_Manager       cache_man;FTC_CMapCache     cmap_cache;FTC_ImageCache    image_cache;FTC_SBitCache     sbit_cache;FTC_ImageTypeRec  font_type;charmap_t*        cmap = NULL;double            bench_time = BENCH_TIME;int               preload = 0;FT_Byte*          memory_file = NULL;long              memory_size;/* * Dummy face requester (the face object is already loaded) */FT_Errorface_requester (FTC_FaceID face_id,                FT_Library library,                FT_Pointer request_data,\                FT_Face* aface){  FT_UNUSED( face_id );  FT_UNUSED( library );  FT_UNUSED( request_data );  *aface = face;  return 0;}/* * Bench code */doubleget_time(void){#ifdef UNIX  struct timeval tv;  gettimeofday(&tv, NULL);  return (double)tv.tv_sec + (double)tv.tv_usec / 1E6;#else  /* clock() has an awful precision (~10ms) under Linux 2.4 + glibc 2.2 */  return (double)clock() / (double)CLOCKS_PER_SEC;#endif}voidget_cmap(void){  FT_ULong charcode;  FT_UInt  gindex;  int i;  if (cmap)    return; /* Already available */  cmap = (charmap_t*)calloc(face->num_glyphs, sizeof(charmap_t));  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 )    {      cmap[i].index    = gindex;      cmap[i].charcode = charcode;      i++;      charcode = FT_Get_Next_Char(face, charcode, &gindex);    }  }  else    /* no charmap, do an identity mapping */    for (i = 0; i < face->num_glyphs; i++)    {      cmap[i].index = i;      cmap[i].charcode = i;      i++;    }}voidbench(bench_t bench_func,      const char* title,      int max){  int      i, n, done;  double   t0, delta;  printf("%-30s : ", title);  fflush(stdout);  get_cmap();  n = 0;  done = 0;  t0 = get_time();  do  {    for (i = 0; i < face->num_glyphs; i++)      if (!(*bench_func)(cmap[i].index, cmap[i].charcode))        done++;    n++;    delta = get_time() - t0;  }  while ((!max || n < max) && delta < bench_time);  printf("%5.3f us/op\n", delta * 1E6 / (double)done);}/* * Various tests */intload_test(FT_UInt idx,          FT_UInt charcode){  FT_UNUSED( charcode );  return FT_Load_Glyph(face, idx, FT_LOAD_DEFAULT);}intfetch_test(FT_UInt idx,           FT_UInt charcode){  FT_Glyph  glyph;  FT_Error  error;  FT_UNUSED( charcode );  error = FT_Load_Glyph( face, idx, FT_LOAD_DEFAULT );  if ( !error )  {    error = FT_Get_Glyph( face->glyph, &glyph );    if ( !error )      FT_Done_Glyph( glyph );  }  return error;}intcbox_test(FT_UInt idx,          FT_UInt charcode){  FT_BBox  bbox;  FT_Glyph glyph;  FT_Error error;  FT_UNUSED( charcode );  error = FT_Load_Glyph( face, idx, FT_LOAD_DEFAULT );  if ( !error )  {    error = FT_Get_Glyph( face->glyph, &glyph );    if ( !error )    {      FT_Glyph_Get_CBox( glyph, FT_GLYPH_BBOX_PIXELS, &bbox );      FT_Done_Glyph( glyph );    }  }  return error;}intcmap_test(FT_UInt idx,          FT_UInt charcode){  FT_UNUSED( idx );  return !FT_Get_Char_Index(face, charcode);}intcmap_cache_test(FT_UInt idx,                FT_UInt charcode){  FT_UNUSED( idx );  return !FTC_CMapCache_Lookup( cmap_cache, (FTC_FaceID)1, 0, charcode );}intimage_cache_test(FT_UInt idx,                 FT_UInt charcode){  FT_Glyph glyph;  FT_UNUSED( charcode );  return FTC_ImageCache_Lookup(image_cache, &font_type, idx, &glyph, NULL);}intsbit_cache_test(FT_UInt idx,                FT_UInt charcode){  FTC_SBit glyph;  FT_UNUSED( charcode );  return FTC_SBitCache_Lookup(sbit_cache, &font_type, idx, &glyph, NULL);}voidbench_open_close( const char*  filename,                  const char* title,                  int max){  int     n, done;  double  t0, delta;  printf("%-30s : ", title);  fflush(stdout);  n = 0;  done = 0;  t0 = get_time();  do  {    FT_Face   bench_face;    FT_Error  error;    if ( preload )      error = FT_New_Memory_Face( lib, memory_file, memory_size, 0, &bench_face );    else      error = FT_New_Face( lib, filename, 0, &bench_face );    if ( !error )    {      FT_Done_Face( bench_face );    }    done++;    n++;    delta = get_time() - t0;  }  while ((!max || n < max) && delta < bench_time);  printf("%5.3f us/op\n", delta * 1E6 / (double)done);}voidbench_cmap_parse( const char* title,                  int         max ){  int     n, done;  double  t0, delta;  printf("%-30s : ", title);  fflush(stdout);  n = 0;  done = 0;  t0 = get_time();  do  {    FT_UInt   gindex;    FT_ULong  charcode;    charcode = FT_Get_First_Char( face, &gindex );    while ( gindex != 0 )      charcode = FT_Get_Next_Char( face, charcode, &gindex );    done++;    n++;    delta = get_time() - t0;  }  while ((!max || n < max) && delta < bench_time);  printf("%5.3f us/op\n", delta * 1E6 / (double)done);}/* * main */void usage(void){  fprintf( stderr,    "ftbench: bench some common FreeType paths\n"    "-----------------------------------------\n\n"    "Usage: ftbench [options] fontname\n\n"    "options:\n" );  fprintf( stderr,  "   -m : max cache size in KByte (default is %d)\n", CACHE_SIZE );  fprintf( stderr,  "   -t : max time per bench in seconds (default is %.0f)\n", BENCH_TIME );  fprintf( stderr,  "   -p : preload font file in memory\n"  "   -b tests : perform chosen tests (default is all)\n"  "      a : Load\n"  "      b : Load + Get_Glyph\n"  "      c : Load + Get_Glyph + Get_CBox\n"  "      d : Get_Char_Index\n"  "      e : CMap cache\n"  "      f : Outline cache\n"  "      g : Bitmap cache\n"  "      h : SBit cache\n"  "      i : Open/Close\n"  "      j : Charmap iteration\n" );  exit( 1 );}#define TEST(x) (!tests || strchr(tests, x))intmain(int argc,     char** argv){  long max_bytes = CACHE_SIZE * 1024;  char* tests = NULL;  int size;  while (argc > 1 && argv[1][0] == '-')  {    switch (argv[1][1])    {    case 'm':      argc--;      argv++;      if (argc < 2 ||          sscanf(argv[1], "%ld", &max_bytes) != 1)        usage();      max_bytes *= 1024;      break;    case 'p':      preload = 1;      break;    case 't':      argc--;      argv++;      if (argc < 2 ||          sscanf(argv[1], "%lf", &bench_time) != 1)        usage();      break;    case 'b':      argc--;      argv++;      if (argc < 2)        usage();      tests = argv[1];      break;    default:      fprintf(stderr, "Unknown argument `%s'\n\n", argv[1]);      usage();      break;    }    argc--;    argv++;  }  if ( argc != 2 )    usage();  if (FT_Init_FreeType(&lib))  {    fprintf( stderr, "could not initialize font library\n" );    return 1;  }  if ( preload )  {    FILE*  file = fopen( argv[1], "rb" );    if ( file == NULL )    {      fprintf( stderr, "couldn't find or open `%s'\n", argv[1] );      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;    }    fread( memory_file, 1, memory_size, file );    if ( FT_New_Memory_Face( lib, memory_file, memory_size, 0, &face ) )    {      fprintf( stderr, "couldn't load font resource\n" );      return 1;    }  }  else if ( FT_New_Face(lib, argv[1], 0, &face) )  {    fprintf( stderr, "couldn't load font resource\n");    return 1;  }  if (FT_IS_SCALABLE(face))  {    /* We're not benchmarking the scanline renderer, pick any size */    size = 10;    FT_Set_Pixel_Sizes(face, size, size);  }  else    size = face->available_sizes[0].width;  if (TEST('a')) bench( load_test,  "Load", 0);  if (TEST('b')) bench( fetch_test, "Load + Get_Glyph", 0);  if (TEST('c')) bench( cbox_test,  "Load + Get_Glyph + Get_CBox", 0);#if 0  cmap_desc.face_id    = (void*)1;  cmap_desc.type       = FTC_CMAP_BY_INDEX;  cmap_desc.u.encoding = FT_ENCODING_NONE;#endif  if (TEST('d') &&      face->charmap) /* some fonts (eg. windings) don't have a charmap */  {    bench( cmap_test,  "Get_Char_Index", 0);  }  if (!FTC_Manager_New(lib, 0, 0, max_bytes, face_requester, NULL, &cache_man))  {    if (TEST('e') &&        face->charmap && !FTC_CMapCache_New(cache_man, &cmap_cache))    {      bench( cmap_cache_test,  "CMap cache (1st run)", 1);      bench( cmap_cache_test,  "CMap cache", 0);    }    font_type.face_id = (FTC_FaceID)1;    font_type.width   = (short) size;    font_type.height  = (short) size;    if (!FTC_ImageCache_New(cache_man, &image_cache))    {      if (TEST('f'))      {        font_type.flags = FT_LOAD_NO_BITMAP;        bench( image_cache_test,  "Outline cache (1st run)", 1);        bench( image_cache_test,  "Outline cache", 0);      }      if (TEST('g'))      {        font_type.flags = FT_LOAD_RENDER;        bench( image_cache_test,  "Bitmap cache (1st run)", 1);        bench( image_cache_test,  "Bitmap cache", 0);      }    }    if (TEST('h') &&        !FTC_SBitCache_New(cache_man, &sbit_cache))    {      font_type.flags = FT_LOAD_DEFAULT;      bench( sbit_cache_test,  "SBit cache (1st run)", 1);      bench( sbit_cache_test,  "SBit cache", 0);    }  }  if (TEST('i') )    bench_open_close( argv[1], "Open/Close file", 0 );  if (TEST('j'))    bench_cmap_parse( "Charmap iteration", 0 );  if (cmap)    free (cmap);  if (cache_man)    FTC_Manager_Done(cache_man);  FT_Done_FreeType(lib);  return 0;}/* End */

⌨️ 快捷键说明

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