home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: SysTools / SysTools.zip / ft-beta.zip / freetype / test / timer.c < prev    next >
C/C++ Source or Header  |  1997-10-06  |  15KB  |  524 lines

  1. /****************************************************************************/
  2. /*                                                                          */
  3. /*  The FreeType project - a Free and Portable Quality TrueType Renderer.   */
  4. /*                                                                          */
  5. /*  Copyright 1996, 1997 by                                                 */
  6. /*  D. Turner, R.Wilhelm, and W. Lemberg                                    */
  7. /*                                                                          */
  8. /*  timer : A simple performance benchmark. Now with graylevel rendering    */
  9. /*          with the '-g' option.                                           */
  10. /*                                                                          */
  11. /*          Be aware that the timer program benchmarks different things     */
  12. /*          in each release of the FreeType library. Thus, performance      */
  13. /*          should only be compared between similar release numbers.        */
  14. /*                                                                          */
  15. /*                                                                          */
  16. /*  NOTE : This is just a test program that is used to show off and         */
  17. /*         debug the current engine; which is still in alpha. In no         */
  18. /*         way does it shows the final high-level interface that            */
  19. /*         client applications will use. Wait for at least a beta for       */
  20. /*         this.                                                            */
  21. /*                                                                          */
  22. /****************************************************************************/
  23.  
  24. #include "freetype.h"
  25. #include "ttraster.h"
  26. #include "tterror.h"  /* for Panic */
  27. #include "ttengine.h"
  28.  
  29. #include "gmain.h"
  30. #include "gdriver.h"
  31. #include "gevents.h"
  32.  
  33. #include <stdio.h>
  34. #include <stdlib.h>
  35. #include <string.h>
  36. #include <time.h>    /* for 'clock' */
  37.  
  38. /* SunOS 4.1.* does not define CLOCKS_PER_SEC, so include <sys/param.h> */
  39. /* to get the HZ macro which is the equivalent.                         */
  40. #if defined(__sun__) && !defined(SVR4) && !defined(__SVR4)
  41. #include <sys/param.h>
  42. #define CLOCKS_PER_SEC HZ
  43. #endif
  44.  
  45.   #ifdef TT_STATIC_RASTER
  46.  
  47.     #define  RAS_OPS   /* void */
  48.     #define  RAS_OP    /* void */
  49.  
  50.   #else
  51.  
  52.     #define  RAS_OPS   ((TRaster_Instance*)engine.raster_component),
  53.     #define  RAS_OP    ((TRaster_Instance*)engine.raster_component)
  54.  
  55.   #endif /* TT_STATIC_RASTER */
  56.   
  57.   #define RENDER_Glyph(glyph,target) \
  58.             Render_Glyph( RAS_OPS  glyph, target )
  59.  
  60.   #define RENDER_Gray_Glyph(glyph,target,palette) \
  61.             Render_Gray_Glyph( RAS_OPS  glyph, target, palette )
  62.  
  63.   #define SET_High_Precision( high ) \
  64.             Set_High_Precision( RAS_OPS  high )
  65.  
  66.   #define SET_Second_Pass( pass )  \
  67.             Set_Second_Pass( RAS_OPS  pass )
  68.  
  69. #define MAX_GLYPHS  512   /* Maximum number of glyphs rendered at one time */
  70.  
  71.   char              Header[128];
  72.  
  73.   TT_Error     error;
  74.  
  75.   TT_Face      face;
  76.   TT_Instance  instance;
  77.   TT_Glyph     glyph;
  78.  
  79.   TT_Glyph_Outline  outline;
  80.   TT_Glyph_Metrics  metrics;
  81.  
  82.   TT_Face_Properties  properties;
  83.  
  84.   TT_F26Dot6*   cur_x;
  85.   TT_F26Dot6*   cur_y;
  86.  
  87.   unsigned short*           cur_endContour;
  88.   unsigned char*             cur_touch;
  89.  
  90.   int  max_points;
  91.   int  max_contours;
  92.  
  93.   int  start_point[MAX_GLYPHS];
  94.   int  num_points [MAX_GLYPHS];
  95.  
  96.   unsigned short  start_contour[MAX_GLYPHS];
  97.   int     num_contours [MAX_GLYPHS];
  98.  
  99.   int     num_glyphs;
  100.   int     tab_glyphs;
  101.   int     cur_glyph;
  102.   int     cur_point;
  103.   unsigned short  cur_contour;
  104.  
  105.   TT_Raster_Map  Bit;
  106.  
  107.   int  Fail;
  108.   int  Num;
  109.  
  110.   short  visual;      /* display glyphs while rendering */
  111.   short  gray_render; /* smooth fonts with gray levels  */
  112.  
  113.   static void Clear_Buffer();
  114.  
  115.  
  116. /*******************************************************************/
  117. /*                                                                 */
  118. /*  Get_Time:                                                      */
  119. /*                                                                 */
  120. /*    returns the current time in milliseconds.                    */
  121. /*                                                                 */
  122. /*******************************************************************/
  123.  
  124.   long  Get_Time()
  125.   {
  126.     return clock() * 1000 / CLOCKS_PER_SEC;
  127.   }
  128.  
  129.  
  130. /*******************************************************************/
  131. /*                                                                 */
  132. /*  Init_Engine :                                                  */
  133. /*                                                                 */
  134. /*    Allocate bitmap, render pool and other structs...            */
  135. /*                                                                 */
  136. /*******************************************************************/
  137.  
  138.   void  Init_Engine()
  139.   {
  140.     Bit.rows  = vio_Height;   /* The whole window */
  141.     Bit.width = vio_Width;
  142.  
  143.     if ( gray_render )
  144.     {
  145.       Bit.cols = Bit.width;
  146.       Bit.flow = TT_Flow_Up;
  147.       Bit.size = Bit.rows * Bit.width;
  148.     }
  149.     else
  150.     {
  151.       Bit.cols = (Bit.width + 7) / 8;       /* convert to # of bytes */
  152.       Bit.flow = TT_Flow_Up;
  153.       Bit.size = Bit.rows * Bit.cols;       /* number of bytes in buffer */
  154.     }
  155.  
  156.     Bit.bitmap = (void*)malloc( Bit.size );
  157.     if ( !Bit.bitmap )
  158.       Panic( "ERROR: not enough memory to allocate bitmap!\n" );
  159.  
  160.     SET_High_Precision( 0 );
  161.     /* set low precision */
  162.  
  163.     SET_Second_Pass( 0 );
  164.     /* Disable horizontal drop-out control */
  165.  
  166.     Clear_Buffer();
  167.   }
  168.  
  169.  
  170. /*******************************************************************/
  171. /*                                                                 */
  172. /*  Clear_Buffer                                                   */
  173. /*                                                                 */
  174. /*    Clear current bitmap                                         */
  175. /*                                                                 */
  176. /*******************************************************************/
  177.  
  178.   static void  Clear_Buffer()
  179.   {
  180.     if ( gray_render )
  181.       memset( Bit.bitmap, gray_palette[0], Bit.size );
  182.     else
  183.       memset( Bit.bitmap, 0, Bit.size );
  184.   }
  185.  
  186.  
  187. /*******************************************************************/
  188. /*                                                                 */
  189. /*  LoadTrueTypeChar                                               */
  190. /*                                                                 */
  191. /*    Load a glyph into memory.                                    */
  192. /*                                                                 */
  193. /*******************************************************************/
  194.  
  195.   TT_Error  LoadTrueTypeChar( int  idx )
  196.   {
  197.     short            numP, numC;
  198.  
  199.     TT_F26Dot6 *cx, *cy;   /* current x and y arrays */
  200.  
  201.     unsigned short*  ccontour; /* current contour array */
  202.     unsigned char*   ctouch;   /* current touch array */
  203.  
  204.     int  j;
  205.  
  206.     error = TT_Load_Glyph( instance, glyph, idx, TTLOAD_DEFAULT );
  207.     if (error)
  208.       return error;
  209.  
  210.     TT_Get_Glyph_Outline( glyph, &outline );
  211.  
  212.     /* debugging */
  213. /*
  214.     if ( idx == 0 && !visual )
  215.     {
  216.       Message( "points = %d\n", outline.points );
  217.       for ( j = 0; j < outline.points; j++ )
  218.         Message( "%02x  (%01hx,%01hx)\n",
  219.                  j, outline.xCoord[j], outline.yCoord[j] );
  220.       Message( "\n" );
  221.     }
  222. */
  223.     numP = outline.points;
  224.     numC = outline.contours;
  225.  
  226.     numP -= 2;  /* get rid of phantom points */
  227.  
  228.     start_point[cur_glyph] = cur_point;
  229.     num_points [cur_glyph] = numP;
  230.  
  231.     start_contour[cur_glyph] = cur_contour;
  232.     num_contours [cur_glyph] = numC;
  233.  
  234.     cx = cur_x + cur_point;
  235.     cy = cur_y + cur_point;
  236.  
  237.     ctouch = cur_touch + cur_point;
  238.  
  239.     ccontour = cur_endContour + cur_contour;
  240.  
  241.     for ( j = 0; j < numP; j++ )
  242.     {
  243.       cx[j] = outline.xCoord[j] + vio_Width * 16 - 32;
  244.       cy[j] = outline.yCoord[j] + vio_Height * 16 - 32;
  245.  
  246.       ctouch[j] = outline.flag[j];
  247.     }
  248.  
  249.     for ( j = 0; j < numC; j++ )
  250.     {
  251.       ccontour[j] = outline.conStarts[j];
  252.     }
  253.  
  254.     cur_point   += numP;
  255.     cur_contour += numC;
  256.     cur_glyph++;
  257.  
  258.     return TT_Err_Ok;
  259.   }
  260.  
  261.  
  262. /*******************************************************************/
  263. /*                                                                 */
  264. /*  ConvertRaster                                                  */
  265. /*                                                                 */
  266. /*    Perform scan conversion                                      */
  267. /*                                                                 */
  268. /*******************************************************************/
  269.  
  270.   TT_Error  ConvertRaster( int  index )
  271.   {
  272.     outline.xCoord = cur_x + start_point[index];
  273.     outline.yCoord = cur_y + start_point[index];
  274.  
  275.     outline.flag      = cur_touch + start_point[index];
  276.     outline.points    = num_points[index];
  277.     outline.contours  = num_contours[index];
  278.     outline.conStarts = cur_endContour + start_contour[index];
  279.  
  280.     outline.dropout_mode = 2;
  281.  
  282.     /* Note : for gray-levels, we use the default palette. */
  283.     /*        Make up your own if necessary.               */
  284.  
  285.     if ( gray_render )
  286.       return RENDER_Gray_Glyph( &outline, &Bit, gray_palette );
  287.     else
  288.       return RENDER_Glyph( &outline, &Bit );
  289.   }
  290.  
  291.  
  292.   int  main( int  argc, char**  argv )
  293.   {
  294.     int    i, total, mode, base, rendered_glyphs;
  295.     char   filename[128 + 4];
  296.     char   alt_filename[128 + 4];
  297.     char*  execname;
  298.  
  299.     /*    TEvent  event; */
  300.  
  301.     long   t, t0, tz0;
  302.  
  303.     execname    = argv[0];
  304.  
  305.     gray_render = 0;
  306.     visual      = 0;
  307.  
  308.     while ( argc > 1 && argv[1][0] == '-' )
  309.     {
  310.       switch (argv[1][1])
  311.       {
  312.         case 'g':
  313.           gray_render = 1;
  314.           break;
  315.  
  316.         case 'v':
  317.           visual = 1;
  318.           break;
  319.  
  320.         default:
  321.           Panic( "ERROR: unknown argument '%s'!\n", argv[1] );
  322.       }
  323.       argc--;
  324.       argv++;
  325.     }
  326.  
  327.     if ( argc != 2 )
  328.     {
  329.       Message( "Time: simple performance timer - part of the FreeType project\n" );
  330.       Message( "-------------------------------------------------------------\n\n" );
  331.       Message( "Usage: %s [-g] [-v] fontname[.ttf|.ttc]\n\n", execname );
  332.       Message( "  where '-g' asks for gray-levels rendering\n" );
  333.       Message( "        '-v' displays while rendering (slower)\n" );
  334.       exit( 1 );
  335.     }
  336.  
  337.     i = strlen( argv[1] );
  338.     while ( i > 0 && argv[1][i] != '\\' )
  339.     {
  340.       if ( argv[1][i] == '.' )
  341.         i = 0;
  342.       i--;
  343.     }
  344.  
  345.     filename[128] = '\0';
  346.     alt_filename[128] = '\0';
  347.  
  348.     strncpy( filename, argv[1], 128 );
  349.     strncpy( alt_filename, argv[1], 128 );
  350.  
  351.     if ( i >= 0 )
  352.     {
  353.       strncpy( filename + strlen( filename ), ".ttf", 4 );
  354.       strncpy( alt_filename + strlen( alt_filename ), ".ttc", 4 );
  355.     }
  356.  
  357.     /* Initialize engine */
  358.  
  359.     if ( (error = TT_Init_FreeType()) )
  360.       Panic( "ERROR : While initializing engine, code = %d\n", error );
  361.  
  362.     /* Load face */
  363.  
  364.     error = TT_Open_Face( filename, &face );
  365.  
  366.     if (error == TT_Err_Could_Not_Open_File)
  367.     {
  368.       strcpy( filename, alt_filename );
  369.       error = TT_Open_Face( alt_filename, &face );
  370.     }
  371.  
  372.     if (error)
  373.       Panic( "ERROR: could not find/open %s\n", filename );
  374.  
  375.     /* get face properties and allocate preload arrays */
  376.  
  377.     TT_Get_Face_Properties( face, &properties );
  378.  
  379.     num_glyphs = properties.num_Glyphs;
  380.         
  381.     tab_glyphs = MAX_GLYPHS;
  382.     if ( tab_glyphs > num_glyphs ) tab_glyphs = num_glyphs;
  383.  
  384.     max_points = properties.max_Points * tab_glyphs;
  385.  
  386.     cur_x = malloc( max_points * sizeof ( TT_F26Dot6 ) );
  387.     cur_y = malloc( max_points * sizeof ( TT_F26Dot6 ) );
  388.  
  389.     cur_touch = malloc( max_points );
  390.  
  391.     max_contours = properties.max_Contours * tab_glyphs;
  392.  
  393.     cur_endContour = (unsigned short*)malloc( max_contours * sizeof ( unsigned short ) );
  394.  
  395.     if ( !cur_x || !cur_y || !cur_touch || !cur_endContour )
  396.       Panic( "Error: not enough memory for preload array\n" );
  397.  
  398.     /* create glyph */
  399.  
  400.     error = TT_New_Glyph( face, &glyph );
  401.     if (error)
  402.       Panic( "ERROR : could not create glyph container\n" );
  403.  
  404.     /* create instance */
  405.  
  406.     error = TT_New_Instance( face, &instance );
  407.     if (error)
  408.       Panic( "ERROR : could not create instance for %s\n", filename );
  409.  
  410.     error = TT_Set_Instance_PointSize( instance, 400 );
  411.     if (error)
  412.       Panic( "ERROR : could not reset instance for %s\n", filename );
  413.  
  414.     if ( gray_render )
  415.       mode = Graphics_Mode_Gray;
  416.     else
  417.       mode = Graphics_Mode_Mono;
  418.  
  419.     if ( visual )
  420.     {
  421.       if ( !SetGraphScreen( mode ) )
  422.         Panic( "ERROR: could not set graphics mode\n" );
  423.     }
  424.     else
  425.     {
  426.       /* This is the default bitmap size used */
  427.       vio_Width  = 640;
  428.       vio_Height = 450;
  429.     }
  430.  
  431.     Init_Engine();
  432.  
  433.     Num  = 0;
  434.     Fail = 0;
  435.  
  436.     total = num_glyphs;
  437.     base  = 0;
  438.  
  439.     rendered_glyphs = 0;
  440.  
  441.     t0 = 0;  /* Initial time */
  442.  
  443.     tz0 = Get_Time();
  444.  
  445.     while ( total > 0 )
  446.     {
  447.       /* First, preload 'tab_glyphs' in memory */
  448.  
  449.       cur_glyph   = 0;
  450.       cur_point   = 0;
  451.       cur_contour = 0;
  452.   
  453.       Message( "loading %d glyphs", tab_glyphs );
  454.  
  455.       for ( Num = 0; Num < tab_glyphs; Num++ )
  456.       {
  457.         error = LoadTrueTypeChar( base + Num );
  458.         if (error)
  459.           Fail++;
  460.  
  461.         total--;
  462.       }
  463.  
  464.       base += tab_glyphs;
  465.  
  466.       if ( tab_glyphs > total ) 
  467.         tab_glyphs = total;
  468.  
  469.       Message( ", rendering... " );
  470.  
  471.       /* Now, render the loaded glyphs */
  472.  
  473.       t = Get_Time();
  474.  
  475.       for ( Num = 0; Num < cur_glyph; Num++ )
  476.       {
  477.         if ( (error = ConvertRaster( Num )) )
  478.           Fail++;
  479.         else
  480.         {
  481.           rendered_glyphs ++;
  482.  
  483.           if ( visual )
  484.           {
  485.             sprintf( Header, "Glyph : %5d", Num );
  486.             Display_Bitmap_On_Screen( Bit.bitmap, Bit.rows, Bit.cols );
  487.  
  488. /*            Get_Event( &event ); */
  489.  
  490.             Clear_Buffer();
  491.           }
  492.         }
  493.       }
  494.  
  495.       t = Get_Time() - t;
  496.       if ( t < 0 ) t += 100 * 60 * 60;
  497.  
  498.       Message( " = %f s\n", (double)t / 1000 );
  499.       t0 += t;
  500.     }
  501.  
  502.     tz0 = Get_Time() - tz0;
  503.  
  504.     if ( visual ) RestoreScreen();
  505.  
  506.     TT_Close_Face( face );
  507.  
  508.     Message( "\n" );
  509.     Message( "rendered glyphs  = %d\n", rendered_glyphs );
  510.     Message( "render time      = %f s\n", (double)t0 / 1000 );
  511.     Message( "fails            = %d\n", Fail );
  512.     Message( "average glyphs/s = %f\n", 
  513.              (double)rendered_glyphs / t0 * 1000 );
  514.  
  515.     Message( "total timing     = %f s\n", (double)tz0 / 1000 );
  516.     Message( "Fails = %d\n", Fail );
  517.  
  518.     TT_Done_FreeType();
  519.  
  520.     return 0; 
  521.   }
  522.  
  523. /* End */
  524.