diff -r a501f5ec7b34 -r 0f5961910e27 misc/libfreetype/src/tools/ftrandom/ftrandom.c --- a/misc/libfreetype/src/tools/ftrandom/ftrandom.c Tue Jul 16 11:14:27 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,659 +0,0 @@ -/* Copyright (C) 2005, 2007, 2008 by George Williams */ -/* - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - - * The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO - * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* modified by Werner Lemberg */ -/* This file is now part of the FreeType library */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include FT_FREETYPE_H -#include FT_OUTLINE_H - -#define true 1 -#define false 0 -#define forever for (;;) - - - static int check_outlines = false; - static int nohints = false; - static int rasterize = false; - static char* results_dir = "results"; - -#define GOOD_FONTS_DIR "/home/wl/freetype-testfonts" - - static char* default_dir_list[] = - { - GOOD_FONTS_DIR, - NULL - }; - - static char* default_ext_list[] = - { - "ttf", - "otf", - "ttc", - "cid", - "pfb", - "pfa", - "bdf", - "pcf", - "pfr", - "fon", - "otb", - "cff", - NULL - }; - - static int error_count = 1; - static int error_fraction = 0; - - static FT_F26Dot6 font_size = 12 * 64; - - static struct fontlist - { - char* name; - int len; - unsigned int isbinary: 1; - unsigned int isascii: 1; - unsigned int ishex: 1; - - } *fontlist; - - static int fcnt; - - - static int - FT_MoveTo( const FT_Vector *to, - void *user ) - { - return 0; - } - - - static int - FT_LineTo( const FT_Vector *to, - void *user ) - { - return 0; - } - - - static int - FT_ConicTo( const FT_Vector *_cp, - const FT_Vector *to, - void *user ) - { - return 0; - } - - - static int - FT_CubicTo( const FT_Vector *cp1, - const FT_Vector *cp2, - const FT_Vector *to, - void *user ) - { - return 0; - } - - - static FT_Outline_Funcs outlinefuncs = - { - FT_MoveTo, - FT_LineTo, - FT_ConicTo, - FT_CubicTo, - 0, 0 /* No shift, no delta */ - }; - - - static void - TestFace( FT_Face face ) - { - int gid; - int load_flags = FT_LOAD_DEFAULT; - - - if ( check_outlines && - FT_IS_SCALABLE( face ) ) - load_flags = FT_LOAD_NO_BITMAP; - - if ( nohints ) - load_flags |= FT_LOAD_NO_HINTING; - - FT_Set_Char_Size( face, 0, font_size, 72, 72 ); - - for ( gid = 0; gid < face->num_glyphs; ++gid ) - { - if ( check_outlines && - FT_IS_SCALABLE( face ) ) - { - if ( !FT_Load_Glyph( face, gid, load_flags ) ) - FT_Outline_Decompose( &face->glyph->outline, &outlinefuncs, NULL ); - } - else - FT_Load_Glyph( face, gid, load_flags ); - - if ( rasterize ) - FT_Render_Glyph( face->glyph, ft_render_mode_normal ); - } - - FT_Done_Face( face ); - } - - - static void - ExecuteTest( char* testfont ) - { - FT_Library context; - FT_Face face; - int i, num; - - - if ( FT_Init_FreeType( &context ) ) - { - fprintf( stderr, "Can't initialize FreeType.\n" ); - exit( 1 ); - } - - if ( FT_New_Face( context, testfont, 0, &face ) ) - { - /* The font is erroneous, so if this fails that's ok. */ - exit( 0 ); - } - - if ( face->num_faces == 1 ) - TestFace( face ); - else - { - num = face->num_faces; - FT_Done_Face( face ); - - for ( i = 0; i < num; ++i ) - { - if ( !FT_New_Face( context, testfont, i, &face ) ) - TestFace( face ); - } - } - - exit( 0 ); - } - - - static int - extmatch( char* filename, - char** extensions ) - { - int i; - char* pt; - - - if ( extensions == NULL ) - return true; - - pt = strrchr( filename, '.' ); - if ( pt == NULL ) - return false; - if ( pt < strrchr( filename, '/' ) ) - return false; - - for ( i = 0; extensions[i] != NULL; ++i ) - if ( strcasecmp( pt + 1, extensions[i] ) == 0 || - strcasecmp( pt, extensions[i] ) == 0 ) - return true; - - return false; - } - - - static void - figurefiletype( struct fontlist* item ) - { - FILE* foo; - - - item->isbinary = item->isascii = item->ishex = false; - - foo = fopen( item->name, "rb" ); - if ( foo != NULL ) - { - /* Try to guess the file type from the first few characters... */ - int ch1 = getc( foo ); - int ch2 = getc( foo ); - int ch3 = getc( foo ); - int ch4 = getc( foo ); - - - fclose( foo ); - - if ( ( ch1 == 0 && ch2 == 1 && ch3 == 0 && ch4 == 0 ) || - ( ch1 == 'O' && ch2 == 'T' && ch3 == 'T' && ch4 == 'O' ) || - ( ch1 == 't' && ch2 == 'r' && ch3 == 'u' && ch4 == 'e' ) || - ( ch1 == 't' && ch2 == 't' && ch3 == 'c' && ch4 == 'f' ) ) - { - /* ttf, otf, ttc files */ - item->isbinary = true; - } - else if ( ch1 == 0x80 && ch2 == '\01' ) - { - /* PFB header */ - item->isbinary = true; - } - else if ( ch1 == '%' && ch2 == '!' ) - { - /* Random PostScript */ - if ( strstr( item->name, ".pfa" ) != NULL || - strstr( item->name, ".PFA" ) != NULL ) - item->ishex = true; - else - item->isascii = true; - } - else if ( ch1 == 1 && ch2 == 0 && ch3 == 4 ) - { - /* Bare CFF */ - item->isbinary = true; - } - else if ( ch1 == 'S' && ch2 == 'T' && ch3 == 'A' && ch4 == 'R' ) - { - /* BDF */ - item->ishex = true; - } - else if ( ch1 == 'P' && ch2 == 'F' && ch3 == 'R' && ch4 == '0' ) - { - /* PFR */ - item->isbinary = true; - } - else if ( ( ch1 == '\1' && ch2 == 'f' && ch3 == 'c' && ch4 == 'p' ) || - ( ch1 == 'M' && ch2 == 'Z' ) ) - { - /* Windows FON */ - item->isbinary = true; - } - else - { - fprintf( stderr, - "Can't recognize file type of `%s', assuming binary\n", - item->name ); - item->isbinary = true; - } - } - else - { - fprintf( stderr, "Can't open `%s' for typing the file.\n", - item->name ); - item->isbinary = true; - } - } - - - static void - FindFonts( char** fontdirs, - char** extensions ) - { - DIR* examples; - struct dirent* ent; - - int i, max; - char buffer[1025]; - struct stat statb; - - - max = 0; - fcnt = 0; - - for ( i = 0; fontdirs[i] != NULL; ++i ) - { - examples = opendir( fontdirs[i] ); - if ( examples == NULL ) - { - fprintf( stderr, - "Can't open example font directory `%s'\n", - fontdirs[i] ); - exit( 1 ); - } - - while ( ( ent = readdir( examples ) ) != NULL ) - { - snprintf( buffer, sizeof ( buffer ), - "%s/%s", fontdirs[i], ent->d_name ); - if ( stat( buffer, &statb ) == -1 || S_ISDIR( statb.st_mode ) ) - continue; - if ( extensions == NULL || extmatch( buffer, extensions ) ) - { - if ( fcnt >= max ) - { - max += 100; - fontlist = realloc( fontlist, max * sizeof ( struct fontlist ) ); - if ( fontlist == NULL ) - { - fprintf( stderr, "Can't allocate memory\n" ); - exit( 1 ); - } - } - - fontlist[fcnt].name = strdup( buffer ); - fontlist[fcnt].len = statb.st_size; - - figurefiletype( &fontlist[fcnt] ); - ++fcnt; - } - } - - closedir( examples ); - } - - if ( fcnt == 0 ) - { - fprintf( stderr, "Can't find matching font files.\n" ); - exit( 1 ); - } - - fontlist[fcnt].name = NULL; - } - - - static int - getErrorCnt( struct fontlist* item ) - { - if ( error_count == 0 && error_fraction == 0 ) - return 0; - - return error_count + ceil( error_fraction * item->len ); - } - - - static int - getRandom( int low, - int high ) - { - if ( low - high < 0x10000L ) - return low + ( ( random() >> 8 ) % ( high + 1 - low ) ); - - return low + ( random() % ( high + 1 - low ) ); - } - - - static int - copyfont( struct fontlist* item, - char* newfont ) - { - static char buffer[8096]; - FILE *good, *new; - int len; - int i, err_cnt; - - - good = fopen( item->name, "r" ); - if ( good == NULL ) - { - fprintf( stderr, "Can't open `%s'\n", item->name ); - return false; - } - - new = fopen( newfont, "w+" ); - if ( new == NULL ) - { - fprintf( stderr, "Can't create temporary output file `%s'\n", - newfont ); - exit( 1 ); - } - - while ( ( len = fread( buffer, 1, sizeof ( buffer ), good ) ) > 0 ) - fwrite( buffer, 1, len, new ); - - fclose( good ); - - err_cnt = getErrorCnt( item ); - for ( i = 0; i < err_cnt; ++i ) - { - fseek( new, getRandom( 0, item->len - 1 ), SEEK_SET ); - - if ( item->isbinary ) - putc( getRandom( 0, 0xff ), new ); - else if ( item->isascii ) - putc( getRandom( 0x20, 0x7e ), new ); - else - { - int hex = getRandom( 0, 15 ); - - - if ( hex < 10 ) - hex += '0'; - else - hex += 'A' - 10; - - putc( hex, new ); - } - } - - if ( ferror( new ) ) - { - fclose( new ); - unlink( newfont ); - return false; - } - - fclose( new ); - - return true; - } - - - static int child_pid; - - static void - abort_test( int sig ) - { - /* If a time-out happens, then kill the child */ - kill( child_pid, SIGFPE ); - write( 2, "Timeout... ", 11 ); - } - - - static void - do_test( void ) - { - int i = getRandom( 0, fcnt - 1 ); - static int test_num = 0; - char buffer[1024]; - - - sprintf( buffer, "%s/test%d", results_dir, test_num++ ); - - if ( copyfont ( &fontlist[i], buffer ) ) - { - signal( SIGALRM, abort_test ); - /* Anything that takes more than 20 seconds */ - /* to parse and/or rasterize is an error. */ - alarm( 20 ); - if ( ( child_pid = fork() ) == 0 ) - ExecuteTest( buffer ); - else if ( child_pid != -1 ) - { - int status; - - - waitpid( child_pid, &status, 0 ); - alarm( 0 ); - if ( WIFSIGNALED ( status ) ) - printf( "Error found in file `%s'\n", buffer ); - else - unlink( buffer ); - } - else - { - fprintf( stderr, "Can't fork test case.\n" ); - exit( 1 ); - } - alarm( 0 ); - } - } - - - static void - usage( FILE* out, - char* name ) - { - fprintf( out, "%s [options] -- Generate random erroneous fonts\n" - " and attempt to parse them with FreeType.\n\n", name ); - - fprintf( out, " --all All non-directory files are assumed to be fonts.\n" ); - fprintf( out, " --check-outlines Make sure we can parse the outlines of each glyph.\n" ); - fprintf( out, " --dir Append to list of font search directories.\n" ); - fprintf( out, " --error-count Introduce single byte errors into each font.\n" ); - fprintf( out, " --error-fraction Introduce *filesize single byte errors\n" - " into each font.\n" ); - fprintf( out, " --ext Add to list of extensions indicating fonts.\n" ); - fprintf( out, " --help Print this.\n" ); - fprintf( out, " --nohints Turn off hinting.\n" ); - fprintf( out, " --rasterize Attempt to rasterize each glyph.\n" ); - fprintf( out, " --results Directory in which to place the test fonts.\n" ); - fprintf( out, " --size Use the given font size for the tests.\n" ); - fprintf( out, " --test Run a single test on an already existing file.\n" ); - } - - - int - main( int argc, - char** argv ) - { - char **dirs, **exts; - char *pt, *end; - int dcnt = 0, ecnt = 0, rset = false, allexts = false; - int i; - time_t now; - char* testfile = NULL; - - - dirs = calloc( argc + 1, sizeof ( char ** ) ); - exts = calloc( argc + 1, sizeof ( char ** ) ); - - for ( i = 1; i < argc; ++i ) - { - pt = argv[i]; - if ( pt[0] == '-' && pt[1] == '-' ) - ++pt; - - if ( strcmp( pt, "-all" ) == 0 ) - allexts = true; - else if ( strcmp( pt, "-check-outlines" ) == 0 ) - check_outlines = true; - else if ( strcmp( pt, "-dir" ) == 0 ) - dirs[dcnt++] = argv[++i]; - else if ( strcmp( pt, "-error-count" ) == 0 ) - { - if ( !rset ) - error_fraction = 0; - rset = true; - error_count = strtol( argv[++i], &end, 10 ); - if ( *end != '\0' ) - { - fprintf( stderr, "Bad value for error-count: %s\n", argv[i] ); - exit( 1 ); - } - } - else if ( strcmp( pt, "-error-fraction" ) == 0 ) - { - if ( !rset ) - error_count = 0; - rset = true; - error_fraction = strtod( argv[++i], &end ); - if ( *end != '\0' ) - { - fprintf( stderr, "Bad value for error-fraction: %s\n", argv[i] ); - exit( 1 ); - } - } - else if ( strcmp( pt, "-ext" ) == 0 ) - exts[ecnt++] = argv[++i]; - else if ( strcmp( pt, "-help" ) == 0 ) - { - usage( stdout, argv[0] ); - exit( 0 ); - } - else if ( strcmp( pt, "-nohints" ) == 0 ) - nohints = true; - else if ( strcmp( pt, "-rasterize" ) == 0 ) - rasterize = true; - else if ( strcmp( pt, "-results" ) == 0 ) - results_dir = argv[++i]; - else if ( strcmp( pt, "-size" ) == 0 ) - { - font_size = (FT_F26Dot6)( strtod( argv[++i], &end ) * 64 ); - if ( *end != '\0' || font_size < 64 ) - { - fprintf( stderr, "Bad value for size: %s\n", argv[i] ); - exit( 1 ); - } - } - else if ( strcmp( pt, "-test" ) == 0 ) - testfile = argv[++i]; - else - { - usage( stderr, argv[0] ); - exit( 1 ); - } - } - - if ( allexts ) - exts = NULL; - else if ( ecnt == 0 ) - exts = default_ext_list; - - if ( dcnt == 0 ) - dirs = default_dir_list; - - if ( testfile != NULL ) - ExecuteTest( testfile ); /* This should never return */ - - time( &now ); - srandom( now ); - - FindFonts( dirs, exts ); - mkdir( results_dir, 0755 ); - - forever - do_test(); - - return 0; - } - - -/* EOF */