diff --git a/tests/web_interface/main.c b/tests/web_interface/main.c index 84eefbd65..a535378fd 100644 --- a/tests/web_interface/main.c +++ b/tests/web_interface/main.c @@ -11,7 +11,6 @@ // a row in the generated html table struct entry { - int code; // charcode char base_img[256]; // filename of base png char test_img[256]; // filename of test png char base_hash[33]; // base mm3 hash @@ -21,26 +20,23 @@ struct entry double difference; // difference holding the distance between glyphs }; -void render(const char*, const char*, FT_UInt32, int, struct entry (*entries)[], int*, int*); +void render(const char*, const char*, FT_UInt32, int, struct entry**, int*); int compare(const void* e1, const void* e2); -void make_html(struct entry (*entries)[], int* num, const char*); +void make_html(struct entry**, int* , const char*); int main(int argc, char const *argv[]) { - const char* base_ft; - const char* test_ft; - FT_UInt32 size; - const char* font; - int num = 0; - int max = 0; + const char* base_ft; // path of base ft + const char* test_ft; // path of test ft + FT_UInt32 size; // char size + const char* font; // path of font int mode; - struct entry entries[2000]; - for (int i = 0; i < 2000; ++i) - { - entries[i].difference = 0.0; - } + + // create array of structs with size 1 + struct entry* entries = malloc(1 * sizeof(struct entry)); + int entries_len = 1; if(argc != 5) { @@ -54,22 +50,30 @@ int main(int argc, char const *argv[]) font = argv[4]; mode = 0; // base hashes - render(base_ft, font, size, mode, &entries, &num, &max); + render(base_ft, font, size, mode, &entries, &entries_len); mode = 1; // test hashes - render(test_ft, font, size, mode, &entries, &num, &max); + render(test_ft, font, size, mode, &entries, &entries_len); mode = 2; // base images for differing glyphs - render(test_ft, font, size, mode, &entries, &num, &max); + render(test_ft, font, size, mode, &entries, &entries_len); mode = 3; // test images for differing glyphs - render(test_ft, font, size, mode, &entries, &num, &max); + render(test_ft, font, size, mode, &entries, &entries_len); + + // quicksort array by decreasing difference + qsort(entries, entries_len, sizeof(struct entry), compare); + + // generate HTML output + make_html(&entries, &entries_len, font); + + // free array + free(entries); - qsort(entries, 2000, sizeof(struct entry), compare); - make_html(&entries, &num, font); } -void make_html(struct entry (*entries)[], int* num, const char* font) +// generate HTML output +void make_html(struct entry** entries, int* num, const char* font) { FILE *fp = fopen("index.html", "w"); if (fp == NULL) @@ -77,31 +81,33 @@ void make_html(struct entry (*entries)[], int* num, const char* font) printf("Error opening file.\n"); exit(1); } + + // TODO: refactor fprintf(fp, "\n\n\n\n\n\n\n"); fprintf(fp, "

%s

\n", font); fprintf(fp, "\n"); for (int i = 0; i < *num; ++i) { - fprintf(fp, "\n", (*entries)[i].code, (*entries)[i].difference, (*entries)[i].base_img, (*entries)[i].test_img); + if ((*entries)[i].difference > 0){ + fprintf(fp, "\n", i, (*entries)[i].difference, (*entries)[i].base_img, (*entries)[i].test_img); + } } fprintf(fp, "
IDDifferenceBase glyph | Test glyph
%d%.2f
%d%.2f
\n\n"); fclose(fp); } +// comparison function for quick sort int compare (const void* e1, const void* e2) { struct entry *s1 = (struct entry *)e1; struct entry *s2 = (struct entry *)e2; - int comp = (int)(s1->difference) - (int)(s2->difference); - return -comp; + int comp = (int)(s2->difference) - (int)(s1->difference); + return comp; } -// mode 0: hash base -// mode 1: hash test -// mode 2: image base -// mode 3: image test -void render(const char* ft_dir, const char* font, FT_UInt32 size, int mode, struct entry (*entries)[], int* num, int* max) +// multifunctional render function +void render(const char* ft_dir, const char* font, FT_UInt32 size, int mode, struct entry** entries, int* entries_len) { FT_Library library; FT_Face face; @@ -110,6 +116,7 @@ void render(const char* ft_dir, const char* font, FT_UInt32 size, int mode, stru FT_Error error; int i; + // declare dynamically loaded functions FT_Error (*ft_init_fun)(FT_Library*); FT_Error (*ft_newface_fun)(FT_Library, const char*, FT_Long, FT_Face*); FT_Error (*ft_setcharsize_fun)(FT_Face, FT_F26Dot6, FT_F26Dot6, FT_UInt, @@ -122,14 +129,17 @@ void render(const char* ft_dir, const char* font, FT_UInt32 size, int mode, stru FT_Error (*ft_bitmapconvert_fun)(FT_Library, const FT_Bitmap*, FT_Bitmap, FT_Int); + // dynamically load ft version specified by ft_dir void* handle = dlopen(ft_dir, RTLD_LAZY | RTLD_LOCAL | RTLD_DEEPBIND); if (!handle) { fputs(dlerror(), stderr); exit(1); } + // error checking dlerror(); + // initialize dynamically loaded functions *(void**)(&ft_init_fun) = dlsym(handle,"FT_Init_FreeType"); *(void**)(&ft_newface_fun) = dlsym(handle,"FT_New_Face"); *(void**)(&ft_setcharsize_fun) = dlsym(handle,"FT_Set_Char_Size"); @@ -140,6 +150,7 @@ void render(const char* ft_dir, const char* font, FT_UInt32 size, int mode, stru *(void**)(&ft_bitmapinit_fun) = dlsym(handle,"FT_Bitmap_Init"); *(void**)(&ft_bitmapconvert_fun) = dlsym(handle,"FT_Bitmap_Convert"); + // error checking dlerror(); error = ft_init_fun(&library); @@ -162,15 +173,27 @@ void render(const char* ft_dir, const char* font, FT_UInt32 size, int mode, stru slot = face->glyph; + // if 'images' folder doesn't exist, create it struct stat st = {0}; if (stat("./images/", &st) == -1) { mkdir("./images/", 0777); } + // iterate over all glyphs in the font for (i = 0; i < face->num_glyphs; ++i) { - (*entries)[i].code = i; + // if we've reached capacity of array, double array size + if (i == *entries_len) + { + *entries = realloc(*entries, (*entries_len * 2) * sizeof (struct entry)); + entries = &(*entries); + *entries_len = *entries_len * 2; + } + + (*entries)[i].difference = 0.0; // initially assume no difference between glyphs + + // if hashes are the same, move to the next glyph if (((mode == 2) || (mode == 3)) && (strcmp((*entries)[i].base_hash, (*entries)[i].test_hash) == 0)) { @@ -191,31 +214,34 @@ void render(const char* ft_dir, const char* font, FT_UInt32 size, int mode, stru bitmap = &slot->bitmap; + // calculates and stores hash for a glyph if ((mode == 0) || (mode == 1)) { HASH_128 * murmur = (HASH_128 *)malloc(sizeof(HASH_128)); murmur = Generate_Hash_x64_128(bitmap, murmur); if (mode == 0) { - sprintf((*entries)[i].base_hash, "%08x%08x%08x%08x", murmur->hash[0], murmur->hash[1], - murmur->hash[2], murmur->hash[3]); + sprintf((*entries)[i].base_hash, "%08x%08x%08x%08x", + murmur->hash[0], murmur->hash[1], murmur->hash[2], murmur->hash[3]); } else { - sprintf((*entries)[i].test_hash, "%08x%08x%08x%08x", murmur->hash[0], murmur->hash[1], - murmur->hash[2], murmur->hash[3]); + sprintf((*entries)[i].test_hash, "%08x%08x%08x%08x", + murmur->hash[0], murmur->hash[1], murmur->hash[2], murmur->hash[3]); } - } else { - *max = i; + } else { // if we're done hashing + // if glyph is empty, move to the next glyph if (bitmap->width == 0 || bitmap->rows == 0) { continue; } + + // the glyphs have a different hash and are not empty so we generate a + // PNG for the glyph and calculate the difference between them if (mode == 2) { - *num = *num + 1; Make_PNG(bitmap, "./images/base", i, 1); sprintf((*entries)[i].base_img, "images/base_%d.png", i); (*entries)[i].base_value = (double)(rand() % 1000); @@ -223,7 +249,7 @@ void render(const char* ft_dir, const char* font, FT_UInt32 size, int mode, stru Make_PNG(bitmap, "./images/test", i, 1); sprintf((*entries)[i].test_img, "images/test_%d.png", i); (*entries)[i].test_value = (double)(rand() % 1000); - (*entries)[i].difference = fabs((*entries)[i].base_value- (*entries)[i].test_value); + (*entries)[i].difference = fabs((*entries)[i].base_value - (*entries)[i].test_value); } } }