/*
 * Glyph Keeper text mode benchmark
 *
 * Copyright (c) 2003-2007 Kirill Kryukov
 *
 * This file is part of Glyph Keeper library, and may only be used,
 * modified, and distributed under the terms of the Glyph Keeper
 * license, located in the file 'license.txt' within this package.
 */


/*
 * This program tests Glyph Keeper speed in text mode, with or without
 * cache. Rendered glyphs are not printed anywhere. Without cache it will
 * mostly benchmark FreeType speed, with cache it will benchmark Glyph
 * Keeper caching. Try both modes to see why you always should use glyph
 * cache for text rendering.
 *
 * Running:
 *     bench_text <fontfile> [-time <seconds>] [-cache] [-hint]
 * It will run for 10 seconds if you don't specify time.
 * By default glyph cache is not used, add "-cache" to enable it.
 * By default no hinting is applied, but you can enable it with "-hint"
 * to see how much it affects speed.
 *
 * This program can also be used to benchmark your computer, OS and
 * compiler. But be aware that there are many factors affecting
 * performance, including your hardware, OS, compiler options, GK version,
 * FreeType version and settings, font file you use, and programs you are
 * running in background.
 */

/* Standard includes. */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <limits.h>
#include <ctype.h>

/* Glyph Keeper header. */
#ifndef GK_NO_LEGACY
#define GK_NO_LEGACY
#endif
#include "glyph.h"


char usage[] = "Usage:  bench_text <fontfile> [options] [-cache] [-hint]\n"
               "where:\n"
               "   <font file> - font to use. If the file contains several font faces,\n"
               "      only first one will be used. Any scalable font format supported\n"
               "      by your FreeType version will be fine.\n"
               "Available options are:\n"
               "   -time <N>  - Time to run, in seconds (default: 10 sec)\n"
               "   -cache     - Use glyph cache\n"
               "   -hint      - Use FreeType hinting\n";

int main(int argc,char **argv)
{
    int char_min_range = 32;   /* Unicode characters in this range will be rendered. */
    int char_max_range = 255;  /*                                                    */
    int cache_on = 0;
    int hinting_on = 0;
    int seconds_to_run = 10;
    char *fontfile = 0;

    GLYPH_FACE *fc1 = 0;
    GLYPH_KEEP *keep = 0;
    GLYPH_REND *rend = 0;
    time_t start_time,end_time,now_time;
    int count = 0;
    int now_char;
    unsigned str[2] = {0,0};
    int tx,ty,i;

    setbuf(stdout,0);
    printf("Glyph Keeper text-mode benchmark v.1.0\n");
    gk_set_font_path("C:\\prg\\fonts\\;C:\\windows\\fonts\\");

    for (i=1; i<argc; i++)
    {
        if (!strcmp(argv[i],"-cache")) { cache_on = 1; continue; }
        if (!strcmp(argv[i],"-hint")) { hinting_on = 1; continue; }
        if (i<argc-1)
        {
            if (!strcmp(argv[i],"-time")) { seconds_to_run = atoi(argv[++i]); continue; }
        }
        if (!fontfile) { fontfile = argv[i]; continue; }
        printf("Unrecognised option: \"%s\"\n",argv[i]);
        printf(usage);
        exit(1);
    }

    if (!fontfile)
    {
        fontfile = "Vera.ttf";
        printf("Font is not specified => using default font \"%s\"\n",fontfile);
    }


    /* Loading a font face from file. */
    fc1 = gk_load_face_from_file(fontfile,0);
    if (!fc1) { printf("can't read font from file \"%s\"\n",fontfile); exit(1); }
    printf("font %s (%s) is loaded from file \"%s\"\n",gk_face_family(fc1),gk_face_style(fc1),fontfile);

    if (cache_on) keep = gk_create_keeper(char_max_range-char_min_range+1,0);

    /* Setting up a renderer object. */
    rend = gk_create_renderer(fc1,keep);
    if (!rend) { printf("Error: can't create renderer\n"); exit(1); }
    gk_rend_set_size_pixels(rend,35,35);
    if (hinting_on) { gk_rend_set_hinting_force_autohint(rend); }
    else { gk_rend_set_hinting_off(rend); }

    printf("Running for %d seconds ",seconds_to_run);

    /* Checking time */
    { time_t zero = time(0); do time(&start_time); while (start_time==zero); }
    end_time = start_time + seconds_to_run;

    now_char = char_min_range;
    now_time = start_time;
    while (now_time<end_time)
    {
        time_t t;
        for (i=0; i<10; i++)
        {
            str[0] = now_char;
            gk_text_size_utf32(rend,str,&tx,&ty);
            count++;
            now_char++;
            if (now_char>=char_max_range) now_char = char_min_range;
        }
        time(&t);
        if (now_time < t) { printf("."); now_time = t; }
    }
    printf("\n%.2f characters / second\n",(double)(count)/seconds_to_run);

    return 0;
}
