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

📄 ftbench.c

📁 Demo for Free type 2.2.1
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************/
/*                                                                          */
/*  The FreeType project -- a free and portable quality TrueType renderer.  */
/*                                                                          */
/*  Copyright 2002, 2003, 2004, 2005, 2006 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>
#endif

#include "common.h"


typedef struct {
  double  t0;
  double  total;
} btimer_t;

typedef int
(*bcall_t)( btimer_t*  timer,
            FT_Face    face,
            void*      user_data );

typedef struct {
  const char*  title;
  bcall_t      bench;
  int          cache_first;
  void*        user_data;
} btest_t;

typedef struct
{
  FT_Int     size;
  FT_ULong*  code;
} bcharset_t;

FT_Error
get_face( FT_Face*     face );


/*
 * Globals
 */

#define CACHE_SIZE 1024
#define BENCH_TIME 2.0f
#define FACE_SIZE  10

FT_Library        lib;
FTC_Manager       cache_man;
FTC_CMapCache     cmap_cache;
FTC_ImageCache    image_cache;
FTC_SBitCache     sbit_cache;
FTC_ImageTypeRec  font_type;

enum {
  FT_BENCH_LOAD_GLYPH,
  FT_BENCH_RENDER,
  FT_BENCH_GET_GLYPH,
  FT_BENCH_GET_CBOX,
  FT_BENCH_CMAP,
  FT_BENCH_CMAP_ITER,
  FT_BENCH_NEW_FACE,
  N_FT_BENCH
};

const char* bench_desc[] = {
  "Load a glyph",
  "Render a glyph",
  "Get FT_Glyph",
  "Get glyph cbox",
  "Get glyph index",
  "Iterate CMap",
  "Open a new face",
  NULL
};

int             preload;
char*           filename;

FT_Render_Mode  render_mode = FT_RENDER_MODE_NORMAL;
FT_Int32        load_flags  = FT_LOAD_DEFAULT;


/*
 * Dummy face requester (the face object is already loaded)
 */

FT_Error
face_requester( FTC_FaceID  face_id,
                FT_Library  library,
                FT_Pointer  request_data,
                FT_Face*    aface )
{
  FT_UNUSED( face_id );
  FT_UNUSED( library );

  *aface = (FT_Face)request_data;

  return 0;
}


/*
 * timer
 */

double
get_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
}

#define TIMER_START( timer )   ( timer )->t0 = get_time()
#define TIMER_STOP( timer )    ( timer )->total += get_time() - ( timer )->t0
#define TIMER_GET( timer )     ( timer )->total
#define TIMER_RESET( timer )   ( timer )->total = 0


/*
 * Bench code
 */

void
benchmark( FT_Face   face,
           btest_t*  test,
           int       max_iter,
           double    max_time )
{
  int       n, done;
  btimer_t  timer, elapsed;


  if ( test->cache_first )
  {
    if ( !cache_man )
    {
      printf( "%-25s : no cache manager\n", test->title );

      return;
    }

    TIMER_RESET( &timer );
    test->bench( &timer, face, test->user_data );
  }

  printf( "%-25s : ", test->title );
  fflush( stdout );

  n = done = 0;
  TIMER_RESET( &timer );
  TIMER_RESET( &elapsed );

  for ( n = 0; !max_iter || n < max_iter; n++ )
  {
    TIMER_START( &elapsed );

    done += test->bench( &timer, face, test->user_data );

    TIMER_STOP( &elapsed );

    if ( TIMER_GET( &elapsed ) > max_time )
      break;
  }

  printf("%5.3f us/op\n", TIMER_GET( &timer ) * 1E6 / (double)done);
}


/*
 * Various tests
 */

int
test_load( btimer_t*  timer,
           FT_Face    face,
           void*      user_data )
{
  int  i, done = 0;


  FT_UNUSED( user_data );

  TIMER_START( timer );

  for ( i = 0; i < face->num_glyphs; i++ )
  {
    if ( !FT_Load_Glyph( face, i, load_flags ) )
      done++;
  }

  TIMER_STOP( timer );

  return done;
}


int
test_render( btimer_t*  timer,
             FT_Face    face,
             void*      user_data )
{
  int  i, done = 0;


  FT_UNUSED( user_data );

  for ( i = 0; i < face->num_glyphs; i++ )
  {
    if ( FT_Load_Glyph( face, i, load_flags ) )
      continue;

    TIMER_START( timer );
    if ( !FT_Render_Glyph( face->glyph, render_mode ) )
      done++;
    TIMER_STOP( timer );
  }

  return done;
}


int
test_get_glyph( btimer_t*  timer,
                FT_Face    face,
                void*      user_data )
{
  FT_Glyph  glyph;
  int       i, done = 0;


  FT_UNUSED( user_data );

  for ( i = 0; i < face->num_glyphs; i++ )
  {
    if ( FT_Load_Glyph( face, i, load_flags ) )
      continue;

    TIMER_START( timer );
    if ( !FT_Get_Glyph( face->glyph, &glyph ) )
    {
      FT_Done_Glyph( glyph );
      done++;
    }
    TIMER_STOP( timer );
  }

  return done;
}


int
test_get_cbox( btimer_t*  timer,
               FT_Face    face,
               void*      user_data )
{
  FT_Glyph  glyph;
  FT_BBox   bbox;
  int       i, done = 0;


  FT_UNUSED( user_data );

  for ( i = 0; i < face->num_glyphs; i++ )
  {
    if ( FT_Load_Glyph( face, i, load_flags ) )
      continue;

    if ( FT_Get_Glyph( face->glyph, &glyph ) )
      continue;

    TIMER_START( timer );
    FT_Glyph_Get_CBox( glyph, FT_GLYPH_BBOX_PIXELS, &bbox );
    TIMER_STOP( timer );

    FT_Done_Glyph( glyph );
    done++;
  }

  return done;
}


int
test_get_char_index( btimer_t*  timer,
                     FT_Face    face,
                     void*      user_data )
{
  bcharset_t*  charset = (bcharset_t*)user_data;
  int          i, done = 0;


  TIMER_START( timer );

  for ( i = 0; i < charset->size; i++ )
  {
    if ( FT_Get_Char_Index(face, charset->code[i]) )
      done++;
  }

  TIMER_STOP( timer );

  return done;
}


int
test_cmap_cache( btimer_t*  timer,
                 FT_Face    face,
                 void*      user_data )
{
  bcharset_t*  charset = (bcharset_t*)user_data;
  int          i, done = 0;


  FT_UNUSED( face );

  if ( !cmap_cache )
  {
    if ( FTC_CMapCache_New(cache_man, &cmap_cache) )
      return 0;
  }

  TIMER_START( timer );

  for ( i = 0; i < charset->size; i++ )
  {
    if ( FTC_CMapCache_Lookup( cmap_cache, font_type.face_id, 0, charset->code[i] ) )
      done++;
  }

  TIMER_STOP( timer );

  return done;
}


int
test_image_cache( btimer_t*  timer,
                  FT_Face    face,
                  void*      user_data )
{
  FT_Glyph  glyph;
  int       i, done = 0;


  FT_UNUSED( user_data );

  if ( !image_cache )
  {
    if ( FTC_ImageCache_New(cache_man, &image_cache) )
      return 0;
  }

  TIMER_START( timer );

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

  TIMER_STOP( timer );

  return done;
}


int
test_sbit_cache( btimer_t*  timer,
                 FT_Face    face,
                 void*      user_data )
{
  FTC_SBit  glyph;
  int       i, done = 0;


  FT_UNUSED( user_data );

  if ( !sbit_cache )

⌨️ 快捷键说明

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