Compare commits

...

75 Commits

Author SHA1 Message Date
Kushal K S V S dd8e130c72 Taking include files from parent folder itself 2018-04-17 11:29:18 +00:00
Kushal K S V S 6f79ed889f Generating files based on new file structure 2018-03-22 16:31:55 +05:30
Kushal K S V S 7d3fd3115d Using the functions added / changing the directory structure - pages are categorized into font type and then font name 2018-03-22 16:30:49 +05:30
Kushal K S V S 7b9c8e88ba Adding functions to differentiate Font Type 2018-03-22 16:25:26 +05:30
Kushal K S V S 9fdda1ad75 Editing README and Makefile to accomodate make clean 2018-03-22 16:21:49 +05:30
Kushal K S V S c535ed6d7c Moving Files 2018-03-18 20:50:33 +05:30
Kushal K S V S e55739740e Making a source file and modifying make clean 2018-03-18 20:40:45 +05:30
Kushal K S V S 3087c10f54 Some cosmetic changes 2018-03-18 20:40:45 +05:30
Kushal K S V S 4acdc51547 Pause|Play Button 2018-03-18 20:40:45 +05:30
Kushal K S V S 4775ffbe7a Remove unnecessary library linking 2018-03-18 20:40:45 +05:30
Kushal K S V S 92ba2ff330 jQuery not needed for now 2018-03-18 20:40:45 +05:30
Kushal K S V S db54493e20 Change TOP_DIR 2018-03-18 20:40:45 +05:30
Kushal K S V S 9c5a104ac1 Comments and README 2018-03-18 20:40:45 +05:30
Kushal K S V S 2e52ff0d14 Hold to pause 2018-03-18 20:40:45 +05:30
Kushal K S V S 2721a8129a Moving Files 2018-03-18 20:40:45 +05:30
Kushal K S V S 7a01001b39 size to point size (name change) 2018-03-18 20:40:45 +05:30
Kushal K S V S fbaf709510 Add Go to top button 2018-03-18 20:40:45 +05:30
Kushal K S V S 13d3b701f0 Adding 3 Sprite Animations and adding DLL locations 2018-03-18 20:40:45 +05:30
Kushal K S V S 8f99ece4ef Click to Display 2018-03-18 20:40:45 +05:30
Kushal K S V S a2f066f7a5 Script change and Render Mode calling 2018-03-18 20:40:45 +05:30
Kushal K S V S e7edf130be Update README 2018-03-18 20:40:45 +05:30
Kushal K S V S 02e6c8abea Using strings for render_modes 2018-03-18 20:40:45 +05:30
Kushal K S V S 828e89379d Some Bug Fixes 2018-03-18 20:40:45 +05:30
Kushal K S V S a2c76421c2 Resolving errors 2018-03-18 20:40:45 +05:30
Kushal K S V S 3a2869a929 Generating Pages and Sprite animation [Testing] 2018-03-18 20:40:45 +05:30
Kushal K S V S 637fb40ac9 Minor fix 2018-03-18 20:40:44 +05:30
Kushal K S V S 14c38dccd1 Updating Makefile and runme.sh 2018-03-18 20:40:44 +05:30
Kushal K S V S b80db811cf Comments in make_sprite.c 2018-03-18 20:40:44 +05:30
Kushal K S V S d8e07e8ad3 Some corrections 2018-03-18 20:40:44 +05:30
Kushal K S V S 46c66dcd32 Some corrections 2018-03-18 20:40:44 +05:30
Kushal K S V S a2e5fef55b Comments in bitmap.c 2018-03-18 20:40:44 +05:30
Kushal K S V S 0a920f8028 Changing image names and location 2018-03-18 20:40:44 +05:30
Kushal K S V S 2b001c149d Update README 2018-03-18 20:40:44 +05:30
Kushal K S V S 40c3ab9041 script to compile and run 2018-03-18 20:40:44 +05:30
Kushal K S V S d66639a95c Updating Difference Metric score calculation 2018-03-18 20:40:44 +05:30
Kushal K S V S 6277cc4600 MAking code compatible with C89 2018-03-18 20:40:44 +05:30
Kushal K S V S a5755f0842 Update README 2018-03-18 20:40:44 +05:30
Kushal K S V S 9a0220875a Removing files 2018-03-18 20:40:44 +05:30
Kushal K S V S 9d96aa93d4 Remove redundant files 2018-03-18 20:40:44 +05:30
Kushal K S V S efa97eeb89 makefile to Makefile 2018-03-18 20:40:44 +05:30
Kushal K S V S 785ce40aa6 Aligning glyphs and adding white rows/columns 2018-03-18 20:40:44 +05:30
Kushal K S V S 2241dc7b81 Aligning the glyphs 2018-03-18 20:40:44 +05:30
Kushal K S V S ab5bfe79e2 Typo 2018-03-18 20:40:44 +05:30
Kushal K S V S aa15682fd8 To display Hashes 2018-03-18 20:40:44 +05:30
Kushal K S V S c638d9a522 Updating README 2018-03-18 20:40:44 +05:30
Kushal K S V S 98839c0811 Code for List-View HTML page generation 2018-03-18 20:40:44 +05:30
Kushal K S V S f5a2bc2e60 Fixing error in hash comparison 2018-03-18 20:40:44 +05:30
Kushal K S V S f03d33e195 Fixed Monochrome PNG rendering 2018-03-18 20:40:44 +05:30
Kushal K S V S be682f2885 change TODO 2018-03-18 20:40:44 +05:30
Kushal K S V S 13468509d4 Apply effects and stitch 4 sub-images together 2018-03-18 20:40:44 +05:30
Kushal K S V S 78c8ff3247 Adding requred headers 2018-03-18 20:40:44 +05:30
Kushal K S V S 43002bb592 Adding functions to Remove and Adjust the Height and Width differences between glyphs 2018-03-18 20:40:44 +05:30
Kushal K S V S 4de40800f5 Generate images for only the glyphs having differences 2018-03-18 20:40:44 +05:30
Kushal K S V S 2f39d67911 Using the Add-effect functions (to be implemented) 2018-03-18 20:40:44 +05:30
Kushal K S V S a30badf3a9 Removing sudo 2018-03-18 20:40:44 +05:30
Kushal K S V S 526ca6aa33 Add make_sprite.c (under Development) - Look at README 2018-03-18 20:40:44 +05:30
Kushal K S V S 97bee81339 Add another Effect and put both effects in one function 2018-03-18 20:40:44 +05:30
Kushal K S V S 1d4fbc5e29 Remove dependency between Make_PNG and Generate_PNG 2018-03-18 20:40:44 +05:30
Kushal K S V S fd3ff32ecc Adding code to stitch 2 PNG files 2018-03-18 20:40:44 +05:30
Kushal K S V S 417f5e3c59 Add PNG effect 1 (Gray + Red) 2018-03-18 20:40:44 +05:30
Kushal K S V S efd9510850 minor changes 2018-03-18 20:40:44 +05:30
Kushal K S V S 9082ff89ef Remove test print loop 2018-03-18 20:40:44 +05:30
Kushal K S V S 51347b348b Read PNG function 2018-03-18 20:40:44 +05:30
Kushal K S V S 6bf7bcd378 Changes to makefile to use compiled version of freetype 2018-03-18 20:40:44 +05:30
Kushal K S V S 4d3200b4db cleaning 2018-03-18 20:40:44 +05:30
Kushal K S V S 838c65dce2 fixed warning 2018-03-18 20:40:44 +05:30
Kushal K S V S c84c32d576 fixed mono rendering 2018-03-18 20:40:44 +05:30
Kushal K S V S 48d9bb4345 Loop across all glyphs 2018-03-18 20:40:44 +05:30
Kushal K S V S 54cfe58d76 Apply LCD filter 2018-03-18 20:40:44 +05:30
Kushal K S V S 68f7652dbb Indentation change 2018-03-18 20:40:44 +05:30
Kushal K S V S d73dc59e0f code for generating PNG 2018-03-18 20:40:44 +05:30
Kushal K S V S 2c4571ffa4 new code for generating hashes 2018-03-18 20:40:44 +05:30
Kushal K S V S 4caeea2cd6 Modified LCD_V rendering 2018-03-18 20:40:44 +05:30
Kushal K S V S ef6231e5bf Removed unnecessary loops and variables 2018-03-18 20:40:44 +05:30
Kushal K S V S 797e74abd6 First commit 2018-03-18 20:40:44 +05:30
17 changed files with 2271 additions and 1 deletions

BIN
.DS_Store vendored Normal file

Binary file not shown.

View File

@ -118,7 +118,7 @@ FT_BEGIN_HEADER
/* rendering technology that produces excellent output without LCD */
/* filtering. */
/* */
/* #define FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
#define FT_CONFIG_OPTION_SUBPIXEL_RENDERING
/*************************************************************************/

BIN
tests/.DS_Store vendored Normal file

Binary file not shown.

20
tests/Makefile Normal file
View File

@ -0,0 +1,20 @@
TOP_DIR := ..
BUILD_DIR := $(TOP_DIR)/builds/unix
include $(TOP_DIR)/builds/unix/unix-def.mk
SRC_SPRITE = make_sprite.c bitmap.c murmur3.c
CFLAGS = -Wall -g
CC = gcc
INCLUDE = -I $(includedir)/freetype2
LIBS = -lpng -ldl
all: tests
tests: $(SRC_SPRITE)
$(CC) $(CFLAGS) $(INCLUDE) -o $@ $^ $(LIBS)
.PHONY: clean
clean:
-rm -rf *.o html/top.html html/pages tests

109
tests/README Normal file
View File

@ -0,0 +1,109 @@
Test-Framework for FreeType's Rendering output.
INSTRUCTIONS
NOTE: One version of FreeType is referred as "base" version and the
other as the "test" version.
1. Get the two versions ready
-------------------------------------
Download an older version of FreeType (For example : 2.6.5)
( This being the "base" version of the two)
Go to 'include/freetype/ftoption.h' and uncomment this line
#define FT_CONFIG_OPTION_SUBPIXEL_RENDERING
2. Compile the two versions
-------------------------------------
Go to the "base" version's folder and compile the library.
./configure --enable-shared --disable-static
make
Repeat step 2. for the "test" version as well.
3. Compile the code
-------------------------------------
Return to this folder and make the binary
make tests
4. Run the executable
-------------------------------------
=> Set resolution in DPI by passing argument to variable FT_TEST_DPI.
=> Set the Rendering mode by passing FT_TEST_RENDER_MODE.
FT_TEST_RENDER_MODE can take values 1. MONO
2. AA
3. RGB
4. BGR
5. VRGB
6. VBGR
=> Set the variables FT_TEST_BASE_DLL and FT_TEST_TEST_DLL to
point to the libfreetype.so file of the base and the test
versions respectively.
By default, the folders '$(HOME)/base/' and '$(HOME)/test/'
folders are set for FT_TEST_BASE_DIR and FT_TEST_TEST_DIR
respectively. If FT_TEST_XXX_DLL isn't defined, these values
are taken to search for DLL files.
=> Set FT_TEST_FONT_FILE to the path to font files needed.
=> set FT_TEST_PT_SIZE as a number to denote the font size.
EXAMPLE: FT_TEST_BASE_DIR=$(HOME)/base \
FT_TEST_TEST_DIR=$(HOME)/test \
FT_TEST_DPI="72 96" \
FT_TEST_FONT_FILE="test.ttf" \
FT_TEST_RENDER_MODE="AA RGB" \
FT_TEST_PT_SIZE="16 20" \
./runme.sh
( The values in the above example denote the default values
for the variables. )
Open ./html/top.html for the web interface.
5. Run the executable
-------------------------------------
To clean the html folder / to remove all the generated files,
make clean
---------------------------------------------------------------------
FEATURES
An interactive web interface to visualize glyphs.(html/top.html)
View lists of glyphs in tables in the left iFrame accessed by
selecting values from the drop-box.
( The list consists of all the glyphs whose images rendered on
the two versions of the FreeType library are different. )
NOTE: If there is no visual difference in the two images, this
means that the dimensions of the images rendered aren't
the same for both the versions.
This is because the smaller images are aligned and padded
and then compared.
Subimages in the sprite sheet.
1. 'Base' version's rendering of the glyph.
2. 'Test' version's rendering of the glyph.
3. 'Base' version glyph as Gray
By clicking on the Headers of the respective columns,they can be
arranged (in increasing/decreasing order) based on
-> Glyph-Index
-> Name
-> Difference Metric
When clicked on any image in the table, a detailed visualization
page for the glyph is shown in the right iFrame.
Click on the Buttons below the iframe for the animations.
To pause the animation, click and hold on the image.

756
tests/bitmap.c Normal file
View File

@ -0,0 +1,756 @@
#include "bitmap.h"
/* Functions to generate MurmurHash3 values of the bitmap image */
/*data with a constant as the seed */
HASH_128 * Generate_Hash_x64_128( FT_Bitmap * bitmap,
HASH_128 * murmur)
{
int seed = 99; /* Dont change */
MurmurHash3_x64_128(bitmap->buffer,
(bitmap->pitch * bitmap->rows),
seed,
murmur->hash);
return murmur;
}
/*Not used*/
HASH_128 * Generate_Hash_x86_128( FT_Bitmap * bitmap,
HASH_128 * murmur)
{
int seed = 99; /* Dont change */
MurmurHash3_x86_128(bitmap->buffer,
(bitmap->pitch * bitmap->rows),
seed,
murmur->hash);
return murmur;
}
/*Not used*/
HASH_32 * Generate_Hash_x86_32( FT_Bitmap * bitmap,
HASH_32 * murmur)
{
int seed = 99; /* Dont change */
MurmurHash3_x86_32( bitmap->buffer,
(bitmap->pitch * bitmap->rows),
seed,
&murmur->hash);
return murmur;
}
/* This function takes the render mode argument and */
/* returns the corresponding render_mode code */
int Get_Render_Mode(const char* mode){
/* Using -1 as the error code */
int render_mode = -1;
if ( strcmp(mode,"MONO") == 0 )
{
render_mode = 0;
}else if ( strcmp(mode,"AA") == 0 )
{
render_mode = 1;
}else if ( strcmp(mode,"RGB") == 0 )
{
render_mode = 2;
}else if ( strcmp(mode,"BGR") == 0 )
{
render_mode = 3;
}else if ( strcmp(mode,"VRGB") == 0 )
{
render_mode = 4;
}else if ( strcmp(mode,"VBGR") == 0 )
{
render_mode = 5;
}
return render_mode;
}
/* This function takes in the IMAGE data and returns the pointer */
/* to the pixel at co-ordinates (x,y). This is used to access the */
/* pixel data */
PIXEL * Pixel_At (IMAGE * bitmap, int x, int y)
{
return bitmap->pixels + bitmap->width * y + x;
}
/* Here we take the FT_Bitmap structure and make an IMAGE structure */
/* with pixel data from the FT_Bitmap buffer */
void Make_PNG(FT_Bitmap* bitmap,IMAGE* fruit,int i,int render_mode){
int x;
int y;
unsigned char value;
int p;
switch(render_mode){
case 0 : fruit->width = bitmap->width; /* MONO */
fruit->height = bitmap->rows;
/* Allocate Memory to the IMAGE structure as per the */
/* dimensions of the FT_Bitmap image*/
fruit->pixels = calloc ( fruit->width * fruit->height,
sizeof (PIXEL));
for (y = 0; y < fruit->height; y++) {
for (x = 0; x < fruit->width; x++) {
/* Access pixel by co-ordinates */
PIXEL * pixel = Pixel_At ( fruit, x, y);
p = (y * bitmap->pitch ) + x;
value = bitmap->buffer[p];
/* If there is some colour, make it white */
/* else, make it black */
if ( value != 0x00 ){
value = 0xff;
}else{
value = 0x00;
}
/* Invert the colours to make the background white*/
/* and the character black */
pixel->red = 255- value;
pixel->green = 255- value;
pixel->blue = 255- value;
pixel->alpha = 255;
}
}
break;
case 1 : fruit->width = bitmap->width; /* GRAY */
fruit->height = bitmap->rows;
fruit->pixels = calloc ( fruit->width * fruit->height,
sizeof (PIXEL));
for (y = 0; y < fruit->height; y++) {
for (x = 0; x < fruit->width; x++) {
PIXEL * pixel = Pixel_At ( fruit, x, y);
p = (y * bitmap->pitch ) + x;
/* Access the image data from the buffer */
value = bitmap->buffer[p];
/* R=G=B for Grayscale images */
pixel->red = 255- value;
pixel->green = 255- value;
pixel->blue = 255- value;
pixel->alpha = 255;
}
}
break;
/********************************************************************/
/* FT_Bitmap has 'width' three times the size of glyph in case of */
/* LCD rendering i.e. three adjacent values in bitmap buffer row */
/* correspond to one RGB triplet. Accessing the buffer accordingly */
/* and filling the RGB values of the IMAGE structure */
/********************************************************************/
case 2 :
case 3 : fruit->width = bitmap->width / 3; /* LCD */
fruit->height = bitmap->rows;
fruit->pixels = calloc ( fruit->width * fruit->height,
sizeof (PIXEL));
for (y = 0; y < fruit->height; y++) {
for (x = 0; x < fruit->width; x++) {
PIXEL * pixel = Pixel_At ( fruit, x, y);
p = (y * bitmap->pitch ) + (x)*3;
value = bitmap->buffer[p];
pixel->red = 255- value;
p++;
value = bitmap->buffer[p];
pixel->green = 255- value;
p++;
value = bitmap->buffer[p];
pixel->blue = 255- value;
pixel->alpha = 255;
}
}
break;
/********************************************************************/
/* FT_Bitmap has 'height' three times the size of glyph in case of */
/* LCD_v rendering i.e. three adjacent values in bitmap buffer */
/* column correspond to one RGB triplet. Accessing the buffer */
/* accordingly and filling the RGB values of the IMAGE structure */
/********************************************************************/
case 4 :
case 5 : fruit->width = bitmap->width; /* LCD_V */
fruit->height = bitmap->rows / 3;
fruit->pixels = calloc ( fruit->width * fruit->height,
sizeof (PIXEL));
for (y = 0; y < fruit->height; y++) {
for (x = 0; x < fruit->width; x++) {
PIXEL * pixel = Pixel_At ( fruit, x, y);
p = ((y*3) * bitmap->pitch ) + x;
value = bitmap->buffer[p];
pixel->red = 255- value;
p += bitmap->pitch;
value = bitmap->buffer[p];
pixel->green = 255- value;
p += bitmap->pitch;
value = bitmap->buffer[p];
pixel->blue = 255- value;
pixel->alpha = 255;
}
}
break;
default : fruit->width = bitmap->width;
fruit->height = bitmap->rows;
break;
}
}
/********************************************************************/
/* This function generates the PNG file taking the IMAGE structure */
/* , path to the file and the render_mode. ( Using libpng ) */
/* 32-bit RGBA images are generated. Each channel is 8-bit with */
/* alpha channel set to 255. Transparency can be set accordingly */
/********************************************************************/
int Generate_PNG (IMAGE *bitmap,
const char *path,
int render_mode)
{
FILE * fp;
png_structp png_ptr = NULL;
png_infop info_ptr = NULL;
size_t x, y;
png_byte ** row_pointers = NULL;
int status = -1;
int pixel_size = 4; /* Each pixel is 4-byte */
int depth = 8; /* Each colour is 8-bit*/
fp = fopen (path, "wb");
if (! fp) {
goto fopen_failed;
}
png_ptr = png_create_write_struct ( PNG_LIBPNG_VER_STRING,
NULL,
NULL,
NULL);
if (png_ptr == NULL) {
goto png_create_write_struct_failed;
}
info_ptr = png_create_info_struct (png_ptr);
if (info_ptr == NULL) {
goto png_create_info_struct_failed;
}
if (setjmp (png_jmpbuf (png_ptr))) {
goto png_failure;
}
png_set_IHDR (png_ptr,
info_ptr,
bitmap->width,
bitmap->height,
depth,
PNG_COLOR_TYPE_RGBA,
PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_DEFAULT,
PNG_FILTER_TYPE_DEFAULT);
row_pointers = png_malloc ( png_ptr,
bitmap->height * sizeof (png_byte *));
for (y = 0; y < bitmap->height; y++) {
png_byte *row =
png_malloc(png_ptr, sizeof(uint8_t) * bitmap->width * pixel_size);
row_pointers[y] = row;
for (x = 0; x < bitmap->width; x++) {
PIXEL * pixel = Pixel_At (bitmap, x, y);
if (render_mode == 3 || render_mode == 5)
{ /* For BGRA images */
*row++ = pixel->blue;
*row++ = pixel->green;
*row++ = pixel->red;
*row++ = pixel->alpha;
continue;
}
/* For RGBA images */
*row++ = pixel->red;
*row++ = pixel->green;
*row++ = pixel->blue;
*row++ = pixel->alpha;
}
}
png_init_io ( png_ptr,
fp);
png_set_rows (png_ptr,
info_ptr,
row_pointers);
png_write_png ( png_ptr,
info_ptr,
PNG_TRANSFORM_IDENTITY,
NULL);
status = 0;
printf("%s\n", path );
for (y = 0; y < bitmap->height; y++) {
png_free (png_ptr, row_pointers[y]);
}
png_free (png_ptr, row_pointers);
free (bitmap->pixels);
png_failure:
png_create_info_struct_failed:
png_destroy_write_struct (&png_ptr, &info_ptr);
png_create_write_struct_failed:
fclose (fp);
fopen_failed:
return status;
}
/********************************************************************/
/* Compare the MurmurHash3 values ( x64_128 bit implemented ) */
/* Returns 1 if they are different and 0 if identical. */
/********************************************************************/
int Compare_Hash(HASH_128* hash_b, HASH_128* hash_t){
if (hash_b->hash[0] != hash_t->hash[0] ||
hash_b->hash[1] != hash_t->hash[1] ||
hash_b->hash[2] != hash_t->hash[2] ||
hash_b->hash[3] != hash_t->hash[3] )
{
return 1;
}
return 0;
}
/********************************************************************/
/* Returns the index of the first-column to have a coloured pixel. */
/* 'Coloured' means the pixel isn't in the background */
/* Background Colour RGB = ( 255,255,255 ) */
/********************************************************************/
int First_Column(IMAGE* input){
int x, y;
for ( x = 0; x < input->width; ++x)
{
for ( y = 0; y < input->height; ++y)
{
PIXEL * pixel_result = Pixel_At ( input, x, y);
if ( pixel_result->red == 255 &&
pixel_result->green == 255 &&
pixel_result->blue == 255 &&
pixel_result->alpha == 255 )
{
continue;
}else{
return x;
}
}
}
return input->width;
}
/* Returns the index of the first-row to have a coloured pixel. */
int First_Row(IMAGE* input){
int x, y;
for ( y = 0; y < input->height; ++y)
{
for ( x = 0; x < input->width; ++x)
{
PIXEL * pixel_result = Pixel_At ( input, x, y);
if ( pixel_result->red == 255 &&
pixel_result->green == 255 &&
pixel_result->blue == 255 &&
pixel_result->alpha == 255 )
{
continue;
}else{
return y;
}
}
}
return input->height;
}
/********************************************************************/
/* The following two functions takes two IMAGES with different */
/* dimensions and aligns the two images based on the first pixel */
/* that isn't in the background i.e. RGB != ( 255,255,255 ). */
/* The first argument is the one which has smaller height/width. */
/* Columns/Rows are appended to the smaller image to match the */
/* dimensions. */
/********************************************************************/
IMAGE* Append_Columns(IMAGE* small, IMAGE* big){
/* small->width < big->width */
int x, y;
IMAGE* result = (IMAGE*)malloc(sizeof(IMAGE));
result->height = small->height;
result->width = big->width;
result->pixels =
(PIXEL*) malloc(result->width * result->height * sizeof(PIXEL));
int first_col = First_Column(big);
for ( x = 0; x < first_col; ++x) /* Filling White columns */
{
for ( y = 0; y < result->height; ++y)
{
PIXEL * pixel_result = Pixel_At ( result, x, y);
/* Filling White columns */
pixel_result->red = 255;
pixel_result->green = 255;
pixel_result->blue = 255;
pixel_result->alpha = 255;
}
}
for ( y = 0; y < result->height; ++y)
{
for ( x = first_col; x < first_col + small->width; ++x)
{
PIXEL * pixel_small = Pixel_At ( small, (x - first_col), y);
PIXEL * pixel_result = Pixel_At ( result, x, y);
/* Putting the original IMAGE data */
pixel_result->red = pixel_small->red;
pixel_result->green = pixel_small->green;
pixel_result->blue = pixel_small->blue;
pixel_result->alpha = pixel_small->alpha;
}
}
for ( x = first_col + small->width; x < result->width; ++x)
{
for ( y = 0; y < result->height; ++y)
{
PIXEL * pixel_result = Pixel_At ( result, x, y);
/* Filling White columns */
pixel_result->red = 255;
pixel_result->green = 255;
pixel_result->blue = 255;
pixel_result->alpha = 255;
}
}
return result;
}
IMAGE* Append_Rows(IMAGE* small, IMAGE* big){
/* small->height < big->height */
int x, y;
IMAGE* result = (IMAGE*)malloc(sizeof(IMAGE));
result->height = big->height;
result->width = small->width;
result->pixels =
(PIXEL*) malloc(result->width * result->height * sizeof(PIXEL));
int first_row = First_Row(big);
for ( y = 0; y < first_row; ++y)
{
for ( x = 0; x < result->width; ++x)
{
PIXEL * pixel_result = Pixel_At ( result, x, y);
/* Filling White rows */
pixel_result->red = 255;
pixel_result->green = 255;
pixel_result->blue = 255;
pixel_result->alpha = 255;
}
}
for ( y = first_row; y < first_row + small->height; ++y)
{
for ( x = 0; x < result->width; ++x)
{
PIXEL * pixel_small = Pixel_At ( small, x, y - first_row);
PIXEL * pixel_result = Pixel_At ( result, x, y);
/* Putting the original IMAGE data */
pixel_result->red = pixel_small->red;
pixel_result->green = pixel_small->green;
pixel_result->blue = pixel_small->blue;
pixel_result->alpha = pixel_small->alpha;
}
}
for ( y = first_row + small->height; y < result->height; ++y)
{
for ( x = 0; x < result->width; ++x)
{
PIXEL * pixel_result = Pixel_At ( result, x, y);
/* Filling White rows */
pixel_result->red = 255;
pixel_result->green = 255;
pixel_result->blue = 255;
pixel_result->alpha = 255;
}
}
return result;
}
/********************************************************************/
/* This fuction visually highlights the differences between the two */
/* images generated for the same glyph. There are two effects each */
/* given an Effect_ID. */
/* This function generates a new IMAGE structure after comparing and*/
/* adding the desired effect. */
/* */
/* Effect_ID =1 means that the differences in pixels are highlighted*/
/* and the pixels that are same are in GRAY (RGB = (128,128,128)) */
/* */
/* Effect_ID =2 means that the differences in pixels are highlighted*/
/* over the 'base' version's rendered image */
/* */
/* Highlighting is done in RED colour i.e. RGB=( 255, 0, 0) for */
/* mono, grayscale and RGB-LCD displays and for BGR-LCD displays */
/* is is done in BLUE colour i.e. RGB = ( 0, 0, 255). */
/********************************************************************/
int Add_effect(IMAGE* base, IMAGE* test, IMAGE* out, int Effect_ID)
{
int pixel_diff = 0;
int x,y;
/* new IMAGE */
out->width = base->width;
out->height = base->height;
out->pixels =
(PIXEL*)malloc(base->width * base->height * sizeof(PIXEL));
for( y = 0; y < base->height; y++) {
for( x = 0; x < base->width; x++ ) {
PIXEL * pixel_base = Pixel_At ( base, x, y);
PIXEL * pixel_test = Pixel_At ( test, x, y);
PIXEL * pixel_out = Pixel_At ( out, x, y);
if (Effect_ID == 1)
{ /* If colour is white */
if (pixel_base->red == 255 &&
pixel_base->green == 255 &&
pixel_base->blue == 255 &&
pixel_base->alpha == 255 )
{
pixel_out->red = 255; /* White*/
pixel_out->green = 255;
pixel_out->blue = 255;
pixel_out->alpha = 255;
}else{
pixel_out->red = 127; /* Gray */
pixel_out->green = 127;
pixel_out->blue = 127;
pixel_out->alpha = 255;
}
}
/* if colour is different*/
if (pixel_base->red != pixel_test->red ||
pixel_base->green != pixel_test->green ||
pixel_base->blue != pixel_test->blue ||
pixel_base->alpha != pixel_test->alpha )
{ /* Highlighting pixels */
pixel_out->red = 255;
pixel_out->green = 0;
pixel_out->blue = 0;
pixel_out->alpha = 255;
pixel_diff++;
}else{
if (Effect_ID == 2)
{
pixel_out->red = pixel_base->red;
pixel_out->green = pixel_base->green;
pixel_out->blue = pixel_base->blue;
pixel_out->alpha = pixel_base->alpha;
}
}
}
}
return pixel_diff;
}
/********************************************************************/
/* This function takes two IMAGE structures and stitches the images */
/* horizontally to make one IMAGE. */
/* i.e. ( result->width = left->width + right->width ) */
/* The first argument forms the left part of the image and the */
/* second forms the right part. */
/* This returns the pointer to the stitched image */
/********************************************************************/
void Stitch(IMAGE* left, IMAGE* right, IMAGE* result){
int x, y;
result->width = left->width + right->width;
result->height = MAX(left->height, right->height);
result->pixels =
(PIXEL*)calloc(result->width * result->height, sizeof(PIXEL));
for ( y = 0; y < left->height; ++y)
{
for ( x = 0; x < left->width; ++x)
{
PIXEL * pixel_left = Pixel_At ( left, x, y);
PIXEL * pixel_result = Pixel_At ( result, x, y);
/* Filling Left part of the image*/
pixel_result->red = pixel_left->red;
pixel_result->green = pixel_left->green;
pixel_result->blue = pixel_left->blue;
pixel_result->alpha = pixel_left->alpha;
}
}
for ( y = 0; y < right->height; ++y)
{
for ( x = left->width; x < result->width; ++x)
{
PIXEL * pixel_right = Pixel_At ( right, x - left->width, y);
PIXEL * pixel_result = Pixel_At ( result, x, y);
/* Filling right part of the image*/
pixel_result->red = pixel_right->red;
pixel_result->green = pixel_right->green;
pixel_result->blue = pixel_right->blue;
pixel_result->alpha = pixel_right->alpha;
}
}
}
/* This prints table-headers to a HTML file for the list-view page */
void Print_Head( FILE* fp ){
printf(" *** Generating Images *** \n");
fprintf(fp,
"<html>\n\
<head>\n\
<title>\n\
Glyph_Diff\n\
</title>\n\
<script src=\"../../../../../../source/scripts/top.js\" type=\"text/javascript\"></script>\n\
<link href=\"../../../../../../source/styles/top.css\" rel=\"stylesheet\" type=\"text/css\" >\n\
</head>\n\
<body>\n\
<button onclick=\"topFunction()\" id=\"myBtn\" title=\"Go to top\">Top</button>\n\
<table>\n\
<colgroup>\n\
<col span=\"3\" style=\"background-color:white\">\n\
<col style=\"width:50%%\">\n\
</colgroup>\n\
<thead>\n\
<tr>\n\
<th onclick=\"sort_t(data,0,asc1);asc1*=-1;asc2=1;asc3=1;\">\n\
<a href=\"#\">Index</a>\n\
</th>\n\
<th onclick=\"sort_t(data,1,asc2);asc2*=-1;asc3=1;asc1=1;\">\n\
<a href=\"#\">Name</a>\n\
</th>\n\
<th onclick=\"sort_t(data,2,asc3);asc3*=-1;asc1=1;asc2=1;\">\n\
<a href=\"#\">Diff</a>\n\
</th>\n\
<th>\n\
Images\n\
</th>\n\
</tr>\n\
</thead>\n\
<tbody id=\"data\">\n" );
}
/* This prints a row to the HTML file for the list-view page. */
void Print_Row( FILE* fp, int index, char* name, int diff )
{
fprintf(fp,
"<tr>\n\
<td>%04d</td>\n\
<td>%s</td>\n\
<td>%04d</td>\n\
<td id=\"image_row\">\
<img id=\"sprite\" src=\"images/%s.png\" onclick=\"frame_2_source(this)\">\
</td>\n\
</tr>\n", index, name, diff, name);
}
/* To calculate the Difference-Metric used in the list-view page */
int Image_Diff(IMAGE* base, IMAGE* test){
int diff = 0;
int max_width = MAX(base->width, test->width);
int min_width = MIN(base->width, test->width);
int max_height = MAX(base->height, test->height);
int min_height = MIN(base->height, test->height);
diff = (max_width - min_width) * max_height;
diff += (max_height - min_height) * min_width;
return diff;
}
/* This function takes font file name and returns the font name */
/* Returns a string */
char* Get_Font_File_Name(const char* font_file_full_name){
int file_name_length = strlen(font_file_full_name);
char* name = (char*)malloc(file_name_length*sizeof(char));
int count = 0;
while(font_file_full_name[count] != '.'){
name[count] = font_file_full_name[count];
count++;
}
name[count] = '\0'; /* Ending the String */
return name;
}
/* This function takes font file name and returns the file extension*/
/* Returns a string */
char* Get_Font_File_Type(const char* font_file_full_name){
int file_name_length = strlen(font_file_full_name);
char* extension = (char*)malloc(file_name_length*sizeof(char));
int count = 0;
while(font_file_full_name[count++] != '.'){}
int i = 0;
while(count < file_name_length){
extension[i++] = font_file_full_name[count++];
}
extension[i] = '\0'; /* Ending the String */
return extension;
}
/* For more information on the list-view page, go to README */

94
tests/bitmap.h Normal file
View File

@ -0,0 +1,94 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "../include/ft2build.h"
#include "murmur3.h" /* MurmurHash3_x64_128 header file */
#include <png.h>
#include <dlfcn.h>
#include <math.h>
#include FT_FREETYPE_H
#include FT_MODULE_H
#include FT_LCD_FILTER_H
#include FT_BITMAP_H
#define BITS_PER_PIXEL_RGBA 32
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define MIN(a, b) ((a) < (b) ? (a) : (b))
typedef struct { /* To store 32bit Hash */
FT_UInt32 hash;
}HASH_32;
typedef struct { /* To store 128bit Hash */
FT_UInt32 hash[4];
}HASH_128;
/* A 32-bit pixel */
typedef struct {
unsigned char red;
unsigned char green;
unsigned char blue;
unsigned char alpha;
} PIXEL;
/* A picture. */
typedef struct {
PIXEL* pixels;
size_t width;
size_t height;
} IMAGE;
/* Render modes */
enum render_modes
{ MONO, AA, RGB, BGR, VRGB, VBGR };
/*-----------------------------------------------------------------*/
HASH_32* Generate_Hash_x86_32(FT_Bitmap* bitmap, HASH_32* murmur);
HASH_128* Generate_Hash_x86_128(FT_Bitmap* bitmap, HASH_128* murmur);
HASH_128* Generate_Hash_x64_128(FT_Bitmap* bitmap, HASH_128* murmur);
int Compare_Hash(HASH_128* hash_b, HASH_128* hash_t);
/*-----------------------------------------------------------------*/
/* Returns the render_mode */
int Get_Render_Mode(const char* mode);
/* Returns a pointer to pixel */
/* at (x,y) co-ordinate */
PIXEL* Pixel_At (IMAGE * bitmap, int x, int y);
/*Render mode string to render_mode code */
void Make_PNG (FT_Bitmap* bitmap,IMAGE* fruit, int i,int render_mode);
/* Image to file */
int Generate_PNG (IMAGE *bitmap, const char *path,int render_mode);
/* Read PNG */
void Read_PNG(char *filename, IMAGE * after_effect);
/* Add effects using two PNG images and generate an image*/
int Add_effect(IMAGE* base, IMAGE* test, IMAGE* out, int Effect_ID);
/* Stitch 2 PNG files */
void Stitch(IMAGE* left, IMAGE* right, IMAGE* result);
/* Finding the first non-empty (non-white) column */
int First_Column(IMAGE* input);
/* Finding the first non-empty (non-white) row */
int First_Row(IMAGE* input);
/* Appening white columns with image alignment */
IMAGE* Append_Columns(IMAGE* small, IMAGE* big);
/* Appening white columns with image alignment */
IMAGE* Append_Rows(IMAGE* small, IMAGE* big);
/* calculating the Pixel Differences */
int Image_Diff( IMAGE* base, IMAGE* test);
/* Print the row in list-view webpage */
void Print_Row( FILE* fp, int index, char* name, int diff );
/* Print the table-headers in list-view webpage */
void Print_Head( FILE* fp );
/* Returns the name of the font file without the extension */
char* Get_Font_File_Name(const char* font_file_full_name);
/* Returns the file extension of the font file */
char* Get_Font_File_Type(const char* font_file_full_name);

BIN
tests/html/.DS_Store vendored Normal file

Binary file not shown.

BIN
tests/html/source/.DS_Store vendored Normal file

Binary file not shown.

View File

@ -0,0 +1,12 @@
<!DOCTYPE html>
<html id="body">
<head>
<title>Detailed Comparison</title>
<script type="text/javascript" src ="scripts/top.js" ></script>
<link rel="stylesheet" type="text/css" href="styles/top.css">
</head>
<!-- Division used for animation -->
<div id="animation" class="animation"></div><br>
</body>
</html>

View File

@ -0,0 +1,120 @@
// If any value in the 'select' list(s) changes, the corresponding
// HTML document is loaded in frame_1.
function change() {
var dpi = document.getElementById('dpi').value;
var font = document.getElementById('font').value;
var mode = document.getElementById('mode').value;
var size = document.getElementById('size').value;
var frame = document.getElementById('frame_1');
var font_type = font.substring(font.indexOf('.')+1) // Font file extension
var font_name = font.split('.')[0] // Font name without extension
var string = "pages/"+dpi+"/"+font_type+"/"+font_name+"/"+mode+"/"+size+"/index.html";
frame.src = string;
}
// Function to sort the columns of the table when you click on the header
var people, asc1 = 1,asc2 = 1,asc3 = 1;
function sort_t(tbody, col, asc){
var rows = tbody.rows, rlen = rows.length, arr = new Array(), i, j, cells, clen;
// fill the array with values from the table
for(i = 0; i < rlen; i++){
cells = rows[i].cells;
clen = cells.length;
arr[i] = new Array();
for(j = 0; j < clen; j++){
arr[i][j] = cells[j].innerHTML;
}
}
// sort the array by the specified column number (col) and order (asc)
arr.sort(function(a, b){
return (a[col] == b[col]) ? 0 : ((a[col] > b[col]) ? asc : -1*asc);
});
for(i = 0; i < rlen; i++){
arr[i] = "<td>"+arr[i].join("</td><td>")+"</timaged>";
}
tbody.innerHTML = "<tr>"+arr.join("</tr><tr>")+"</tr>";
}
// Function to change the source of the background image in the iframe
// (frame_2). This function also fits the division according to the
// size of the iframe such that the background image fits in the frame.
function frame_2_source(image){
var path = "url("+image.src+")";
var fr_2 = parent.frame_2.document;
// Division whose background image is the sprite
var div = fr_2.getElementById('animation');
div.style.backgroundImage=path;
// To get the dimensions of the image file
var new_image = new Image();
new_image.src = image.src;
var src_w = new_image.width;
var src_h = new_image.height;
//Using dimensions of the iFrame
var win_w = window.innerWidth;
var win_h = window.innerHeight-40;
// r_w and r_j represent the maximum times that the width or the
// height can be multiplied so that we get the maximum image size
// possible without exceeding the iFrame dimensions and maintaining
// aspect ratio.
var r_w = (win_w/(src_w/4)).toString();
r_w = parseInt(r_w);
var r_h = (win_h/src_h).toString();
r_h = parseInt(r_h);
var div_w = 0;
var div_h = 0;
if (r_w > r_h)
{
div_w = src_w * r_h;
div_h = src_h * r_h;
} else {
div_w = src_w * r_w;
div_h = src_h * r_w;
}
// Setting the division width and height.
div.style.width= div_w/4 + "px";
div.style.height= div_h + "px";
}
// Functions to trigger the corresponding animations.
function class_one_two(){
var div = frame_2.document.getElementById('animation');
div.className = 'animation one_two';
}
function class_one_three(){
var div = frame_2.document.getElementById('animation');
div.className = 'animation one_three';
}
function class_one_four(){
var div = frame_2.document.getElementById('animation');
div.className = 'animation one_four';
}
// Functions for the 'Go to Top button'
// When the user scrolls down 20px from the top of the document, show the button
window.onscroll = function() {scrollFunction()};
function scrollFunction() {
if (document.body.scrollTop > 20 || document.documentElement.scrollTop > 20) {
document.getElementById("myBtn").style.display = "block";
} else {
document.getElementById("myBtn").style.display = "none";
}
}
// When the user clicks on the button, scroll to the top of the document
function topFunction() {
document.body.scrollTop = 0;
document.documentElement.scrollTop = 0;
}
// Function to pause/play the animation
function pause_play() {
var div = frame_2.document.getElementById('animation');
div.classList.toggle('pause');
}

View File

@ -0,0 +1,192 @@
/* Font for the whole document */
* {
font-family: "Courier New", Courier, monospace;
}
/* Sprite image in the table */
#sprite {
image-rendering: optimizeSpeed; /* STOP SMOOTHING, GIVE ME SPEED */
image-rendering: -moz-crisp-edges; /* Firefox */
image-rendering: -o-crisp-edges; /* Opera */
image-rendering: -webkit-optimize-contrast; /* Chrome (and eventually Safari) */
image-rendering: pixelated; /* Chrome */
image-rendering: optimize-contrast; /* CSS3 Proposed */
-ms-interpolation-mode: nearest-neighbor; /* IE8+ */
width: 100%;
height: auto;
}
/* Table style for the list view */
table {
border-collapse: collapse;
border: none;
position: relative;
width: 100%;
}
th,
td {
border: 1px solid black;
padding: 4px 16px;
font-family: "Courier New", Courier, monospace;
font-size: 16px;
text-align: left;
}
th {
background-color: #C8C8C8;
cursor: pointer;
}
/* Image column in a row */
#image_row{
width: 50%;
height: auto;
}
/* Go to top button */
#myBtn {
display: none;
position: fixed;
bottom: 10px;
right: 10px;
z-index: 99;
cursor: pointer;
padding: 15px;
border-radius: 10px;
background-color: #555;
color: white;
}
/* Top Page styling begins */
#frame_1{
width:49%;
height:500px;
align-self: right;
}
#frame_2{
width:49%;
height:500px;
align-self: left;
}
/* Animation select buttons*/
#select_animation{
margin-left: 50%;
}
.select {
font-size: 16px;
text-align: left;
}
/* Pause/Play Button */
#pause_btn{
float: right;
}
/* Animation div on the right iframe */
.animation {
image-rendering: optimizeSpeed;
image-rendering: -moz-crisp-edges;
image-rendering: -o-crisp-edges;
image-rendering: -webkit-optimize-contrast;
image-rendering: pixelated;
image-rendering: optimize-contrast;
-ms-interpolation-mode: nearest-neighbor;
margin: auto;
display: block;
background: url("");
background-repeat: no-repeat;
background-size: cover;
/* Nominal Width on load */
width: 120px;
height: 130px;
}
/*Animations*/
/* Transition between 1st and the 2nd sub-image */
.one_two {
-webkit-animation: one_two 2s steps(2) infinite;
-moz-animation: one_two 2s steps(2) infinite;
-ms-animation: one_two 2s steps(2) infinite;
-o-animation: one_two 2s steps(2) infinite;
animation: one_two 2s steps(2) infinite;
}
/* Transition between 1st and the 2nd sub-image */
.one_three {
-webkit-animation: one_three 2s steps(2) infinite;
-moz-animation: one_three 2s steps(2) infinite;
-ms-animation: one_three 2s steps(2) infinite;
-o-animation: one_three 2s steps(2) infinite;
animation: one_three 2s steps(2) infinite;
}
/* Transition between 1st and the 2nd sub-image */
.one_four {
-webkit-animation: one_four 2s steps(2) infinite;
-moz-animation: one_four 2s steps(2) infinite;
-ms-animation: one_four 2s steps(2) infinite;
-o-animation: one_four 2s steps(2) infinite;
animation: one_four 2s steps(2) infinite;
}
/* Pause/Play the animation */
.pause {
animation-play-state: paused;
-o-animation-play-state: paused;
-moz-animation-play-state: paused;
-webkit-animation-play-state: paused;
}
@-webkit-keyframes one_two {
from { background-position: 0px; }
to { background-position: 66.66%; } /* Goes to 2nd sub-image */
}
@-webkit-keyframes one_three {
from { background-position: 0px; }
to { background-position: 133.33%; } /* Goes to 3rd sub-image */
}
@-webkit-keyframes one_four {
from { background-position: 0px; }
to { background-position: 200%; } /* Goes to 4rd sub-image */
}
@-moz-keyframes one_two {
from { background-position: 0px; }
to { background-position: 66.66%; }
}
@-moz-keyframes one_three {
from { background-position: 0px; }
to { background-position: 133.33%; }
}@-moz-keyframes one_four {
from { background-position: 0px; }
to { background-position: 200%; }
}
@-ms-keyframes one_two {
from { background-position: 0px; }
to { background-position: 66.66%; }
}
@-ms-keyframes one_three {
from { background-position: 0px; }
to { background-position: 133.33%; }
}
@-ms-keyframes one_four {
from { background-position: 0px; }
to { background-position: 200%; }
}
@-o-keyframes one_two {
from { background-position: 0px; }
to { background-position: 66.66%; }
}
@-o-keyframes one_three {
from { background-position: 0px; }
to { background-position: 133.33%; }
}
@-o-keyframes one_four {
from { background-position: 0px; }
to { background-position: 200%; }
}
@keyframes one_two {
from { background-position: 0px; }
to { background-position: 66.66%; }
}
@keyframes one_three {
from { background-position: 0px; }
to { background-position: 133.33%; }
}
@keyframes one_four {
from { background-position: 0px; }
to { background-position: 200%; }
}

532
tests/make_sprite.c Normal file
View File

@ -0,0 +1,532 @@
#include "bitmap.h"
int main(int argc, char const *argv[])
{
if(argc != 7)
{
/* Not needed coz it is automated using runme.sh */
printf("Not enough arguments. Refer README\n");
return 0;
}
/*******************************************************************/
/* variables declaration */
const char* base_version;
const char* test_version;
const char* font_file;
const char* mode;
int pt_size;
int dpi;
int load_flag; /* FT_LOAD_XXX */
int render_flag; /* FT_RENDER_MODE_XXX */
int target_flag; /* FT_LOAD_TARGET_XXX */
base_version = argv[1];
test_version = argv[2];
font_file = argv[3];
pt_size = atoi(argv[4]);
mode = argv[5];
dpi = atoi(argv[6]);
FT_Library base_library;
FT_Face base_face;
FT_GlyphSlot base_slot;
FT_Bitmap* base_bitmap;
FT_Bitmap base_target;
FT_Library test_library;
FT_Face test_face;
FT_GlyphSlot test_slot;
FT_Bitmap* test_bitmap;
FT_Bitmap test_target;
FT_Error error;
int render_mode;
int alignment = 4;
int output_file_size = 100 + strlen(argv[3]);
char * output_file_name = (char *)calloc( output_file_size,
sizeof(char));
IMAGE* base_png = (IMAGE*)malloc(sizeof(IMAGE));
IMAGE* test_png = (IMAGE*)malloc(sizeof(IMAGE));
IMAGE* after_effect_1 = (IMAGE*)malloc(sizeof(IMAGE));
IMAGE* after_effect_2 = (IMAGE*)malloc(sizeof(IMAGE));
IMAGE* combi_effect_1 = (IMAGE*)malloc(sizeof(IMAGE));
IMAGE* combi_effect_2 = (IMAGE*)malloc(sizeof(IMAGE));
IMAGE* output = (IMAGE*)malloc(sizeof(IMAGE));
HASH_128 * base_murmur = (HASH_128 *) malloc(sizeof(HASH_128)) ;
HASH_128 * test_murmur = (HASH_128 *) malloc(sizeof(HASH_128)) ;
int Is_Different, total_count = 0;
int pixel_diff, i;
char glyph_name[50] = ".not-def";
char* font_file_name = Get_Font_File_Name(font_file);
char* font_file_type = Get_Font_File_Type(font_file);
/*******************************************************************/
FT_Error ( *Base_Init_FreeType )( FT_Library* );
FT_Error ( *Base_Library_SetLcdFilter )( FT_Library ,
FT_LcdFilter );
FT_Error ( *Base_New_Face )( FT_Library,
const char*,
FT_Long,
FT_Face* );
FT_Error ( *Base_Set_Char_Size )( FT_Face,
FT_F26Dot6,
FT_F26Dot6,
FT_UInt,
FT_UInt );
FT_Error ( *Base_Load_Glyph )( FT_Face,
FT_UInt,
FT_Int32 );
FT_Error ( *Base_Render_Glyph )( FT_GlyphSlot,
FT_Render_Mode );
void ( *Base_Bitmap_Init )( FT_Bitmap* );
FT_Error ( *Base_Bitmap_Convert )( FT_Library,
const FT_Bitmap*,
FT_Bitmap*,
FT_Int);
FT_Error ( *Base_Get_Glyph_Name )( FT_Face,
FT_UInt,
FT_Pointer,
FT_UInt );
FT_Error ( *Base_Done_Face )( FT_Face );
FT_Error ( *Base_Done_FreeType )( FT_Library );
/*******************************************************************/
FT_Error ( *Test_Init_FreeType )( FT_Library* );
FT_Error ( *Test_Library_SetLcdFilter )( FT_Library ,
FT_LcdFilter );
FT_Error ( *Test_New_Face )( FT_Library,
const char*,
FT_Long,
FT_Face* );
FT_Error ( *Test_Set_Char_Size )( FT_Face,
FT_F26Dot6,
FT_F26Dot6,
FT_UInt,
FT_UInt );
FT_Error ( *Test_Load_Glyph )( FT_Face,
FT_UInt,
FT_Int32 );
FT_Error ( *Test_Render_Glyph )( FT_GlyphSlot,
FT_Render_Mode );
void ( *Test_Bitmap_Init )( FT_Bitmap* );
FT_Error ( *Test_Bitmap_Convert )( FT_Library,
const FT_Bitmap*,
FT_Bitmap*,
FT_Int);
FT_Error ( *Test_Get_Glyph_Name )( FT_Face,
FT_UInt,
FT_Pointer,
FT_UInt );
FT_Error ( *Test_Done_Face )( FT_Face );
FT_Error ( *Test_Done_FreeType )( FT_Library );
/*******************************************************************/
void* base_handle = dlopen( base_version, RTLD_LAZY );
if (!base_handle) {
fputs(dlerror(), stderr);
exit(1);
}
void* test_handle = dlopen( test_version, RTLD_LAZY );
if (!test_handle) {
fputs(dlerror(), stderr);
exit(1);
}
dlerror();
/*******************************************************************/
*(void**)( & Base_Library_SetLcdFilter ) = dlsym(base_handle,
"FT_Library_SetLcdFilter");
*(void**)( & Base_Init_FreeType ) = dlsym(base_handle,
"FT_Init_FreeType");
*(void**)( & Base_New_Face ) = dlsym(base_handle,
"FT_New_Face");
*(void**)( & Base_Set_Char_Size ) = dlsym(base_handle,
"FT_Set_Char_Size");
*(void**)( & Base_Load_Glyph ) = dlsym(base_handle,
"FT_Load_Glyph");
*(void**)( & Base_Render_Glyph ) = dlsym(base_handle,
"FT_Render_Glyph");
*(void**)( & Base_Bitmap_Init ) = dlsym(base_handle,
"FT_Bitmap_Init");
*(void**)( & Base_Bitmap_Convert ) = dlsym(base_handle,
"FT_Bitmap_Convert");
*(void**)( & Base_Get_Glyph_Name ) = dlsym(base_handle,
"FT_Get_Glyph_Name");
*(void**)( & Base_Done_Face ) = dlsym(base_handle,
"FT_Done_Face");
*(void**)( & Base_Done_FreeType ) = dlsym(base_handle,
"FT_Done_FreeType");
/*******************************************************************/
*(void**)( & Test_Library_SetLcdFilter ) = dlsym(test_handle,
"FT_Library_SetLcdFilter");
*(void**)( & Test_Init_FreeType ) = dlsym(test_handle,
"FT_Init_FreeType");
*(void**)( & Test_New_Face ) = dlsym(test_handle,
"FT_New_Face");
*(void**)( & Test_Set_Char_Size ) = dlsym(test_handle,
"FT_Set_Char_Size");
*(void**)( & Test_Load_Glyph ) = dlsym(test_handle,
"FT_Load_Glyph");
*(void**)( & Test_Render_Glyph ) = dlsym(test_handle,
"FT_Render_Glyph");
*(void**)( & Test_Bitmap_Init ) = dlsym(test_handle,
"FT_Bitmap_Init");
*(void**)( & Test_Bitmap_Convert ) = dlsym(test_handle,
"FT_Bitmap_Convert");
*(void**)( & Test_Get_Glyph_Name ) = dlsym(base_handle,
"FT_Get_Glyph_Name");
*(void**)( & Test_Done_Face ) = dlsym(test_handle,
"FT_Done_Face");
*(void**)( & Test_Done_FreeType ) = dlsym(test_handle,
"FT_Done_FreeType");
/*******************************************************************/
render_mode = Get_Render_Mode(mode);
if (render_mode < 0)
{
printf("Enter valid Render Mode.\n");
exit(1);
}
switch ( render_mode ) {
case 0: render_flag = FT_RENDER_MODE_MONO;
load_flag = FT_LOAD_MONOCHROME;
target_flag = FT_LOAD_TARGET_MONO;
break;
case 1: render_flag = FT_RENDER_MODE_NORMAL;
load_flag = FT_LOAD_DEFAULT;
target_flag = FT_LOAD_TARGET_NORMAL;
break;
case 2: render_flag = FT_RENDER_MODE_LCD;
load_flag = FT_LOAD_DEFAULT;
target_flag = FT_LOAD_TARGET_LCD;
break;
case 3: render_flag = FT_RENDER_MODE_LCD;
load_flag = FT_LOAD_DEFAULT;
target_flag = FT_LOAD_TARGET_LCD;
break;
case 4: render_flag = FT_RENDER_MODE_LCD_V;
load_flag = FT_LOAD_DEFAULT;
target_flag = FT_LOAD_TARGET_LCD_V;
break;
case 5: render_flag = FT_RENDER_MODE_LCD_V;
load_flag = FT_LOAD_DEFAULT;
target_flag = FT_LOAD_TARGET_LCD_V;
break;
default:render_flag = FT_RENDER_MODE_NORMAL;
load_flag = FT_LOAD_DEFAULT;
target_flag = FT_LOAD_TARGET_NORMAL;
}
error = Base_Init_FreeType( &base_library );
if(error){
printf("Error while initialising library\n");
exit(1);
}
error = Test_Init_FreeType( &test_library );
if(error){
printf("Error while initialising library\n");
exit(1);
}
if (render_mode > 1 )
{
error = Base_Library_SetLcdFilter( base_library,
FT_LCD_FILTER_DEFAULT );
if(error){
printf("Error while setting LCD filter\n");
exit(1);
}
error = Test_Library_SetLcdFilter( test_library,
FT_LCD_FILTER_DEFAULT );
if(error){
printf("Error while setting LCD filter\n");
exit(1);
}
}
error = Base_New_Face( base_library,
font_file,
0,
&base_face );
if(error){
printf("Error loading new face\n");
exit(1);
}
error = Test_New_Face( test_library,
font_file,
0,
&test_face );
if(error){
printf("Error loading new face\n");
exit(1);
}
error = Base_Set_Char_Size( base_face,
pt_size * 64,
0,
dpi,
0 );
if(error){
printf("Error setting character size\n");
exit(1);
}
error = Test_Set_Char_Size( test_face,
pt_size * 64,
0,
dpi,
0 );
if(error){
printf("Error setting character size\n");
exit(1);
}
base_slot = base_face->glyph;
test_slot = test_face->glyph;
/* Initialising file pointer for the list-view*/
if (snprintf( output_file_name,
output_file_size,
"./html/pages/%d/%s/%s/%s/%d/index.html",
dpi,
font_file_type,
font_file_name,
mode,
pt_size )
> output_file_size )
{
printf("Buffer overflow. Increase output_file_size\n");
exit(1);
}
FILE* fp = fopen(output_file_name,"w");
if (fp == NULL)
{
printf("Error opening file\n");
exit(1);
}
Print_Head( fp );
/* Need to write code to check the values in FT_Face and compare */
for ( i = 0; i < base_face->num_glyphs; ++i)
{
error = Base_Load_Glyph( base_face,
i,
load_flag | target_flag);
if(error){
printf("Error loading glyph\n");
exit(1);
}
error = Test_Load_Glyph( test_face,
i,
load_flag | target_flag);
if(error){
printf("Error loading glyph\n");
exit(1);
}
error = Base_Render_Glyph( base_slot,
render_flag);
if(error){
printf("Error rendering the glyph\n");
exit(1);
}
error = Test_Render_Glyph( test_slot,
render_flag);
if(error){
printf("Error rendering the glyph\n");
exit(1);
}
base_bitmap = &base_slot->bitmap;
test_bitmap = &test_slot->bitmap;
if (base_bitmap->width == 0 || base_bitmap->rows == 0)
{
printf("Empty Glyph in glyph-index %d\n", i);
continue;
}
/* Generating Hashes */
base_murmur = Generate_Hash_x64_128(base_bitmap,base_murmur);
test_murmur = Generate_Hash_x64_128(test_bitmap,test_murmur);
Is_Different = Compare_Hash(base_murmur, test_murmur);
/* To convert 1-bit monochrome to 8-bit bitmap */
/* because we need 8-bit colour to generate images */
Base_Bitmap_Init( &base_target );
Test_Bitmap_Init( &test_target );
error = Base_Bitmap_Convert( base_library,
base_bitmap,
&base_target,
alignment);
if(error){
printf("Error converting the bitmap\n");
exit(1);
}
error = Test_Bitmap_Convert( test_library,
test_bitmap,
&test_target,
alignment);
if(error){
printf("Error converting the bitmap\n");
exit(1);
}
if (Is_Different != 0)
{
total_count++;
pixel_diff = 0; /* Difference metric*/
if (render_mode == 0)
{ /* If monochrome, take the converted image*/
Make_PNG( &base_target, base_png, i, render_mode );
Make_PNG( &test_target, test_png, i, render_mode );
}else{
Make_PNG( base_bitmap, base_png, i, render_mode );
Make_PNG( test_bitmap, test_png, i, render_mode );
}
/* Aligning images and appending rows */
if (base_png->height < test_png->height)
{
base_png = Append_Rows(base_png, test_png);
}else if (base_png->height > test_png->height)
{
test_png = Append_Rows(test_png, base_png);
}
/* Aligning images and appending columns */
if (base_png->width < test_png->width)
{
base_png = Append_Columns(base_png, test_png);
}else if (base_png->width > test_png->width)
{
test_png = Append_Columns(test_png, base_png);
}
/* Updating Difference metric */
pixel_diff += Image_Diff( base_png, test_png);
Add_effect( base_png, test_png, after_effect_1, 1);
pixel_diff = Add_effect( base_png, test_png, after_effect_2,2);
Stitch( base_png, test_png, combi_effect_1);
Stitch( after_effect_1, after_effect_2, combi_effect_2);
Stitch( combi_effect_1, combi_effect_2, output);
if (FT_HAS_GLYPH_NAMES(base_face))
{
error = Base_Get_Glyph_Name( base_face,
i,
glyph_name,
50 );
if (error)
{
printf("Error setting glyph name\n");
}
}
if (snprintf( output_file_name,
output_file_size,
"./html/pages/%d/%s/%s/%s/%d/images/%s.png",
dpi,
font_file_type,
font_file_name,
mode,
pt_size,
glyph_name )
> output_file_size)
{
printf("Buffer Overflow. Increase size of glyph_name\n");
exit(1);
}
Generate_PNG ( output, output_file_name, render_mode );
/* To print table row to HTML file */
Print_Row(fp,i,glyph_name,pixel_diff );
}
}
printf("Total : %ld\nFaulty : %d\n\n",base_face->num_glyphs,
total_count );
/* HTML footer */
fprintf(fp,
"</tbody>\n\
</table>\n\
</body>\n\
</html>\n" );
fclose(fp);
error = Base_Done_Face(base_face);
if(error){
printf("Error freeing the face object");
exit(1);
}
error = Test_Done_Face(test_face);
if(error){
printf("Error freeing the face object");
exit(1);
}
error = Base_Done_FreeType(base_library);
if(error){
printf("Error freeing library");
exit(1);
}
error = Test_Done_FreeType(test_library);
if(error){
printf("Error freeing library");
exit(1);
}
dlclose(base_handle);
dlclose(test_handle);
return 0;
}

306
tests/murmur3.c Normal file
View File

@ -0,0 +1,306 @@
/*------------------------------------------------------------------*/
/* Note - The x86 and x64 versions do _not_ produce the same */
/* results, as the algorithms are optimized for their respective */
/* platforms. You can still compile and run any of them on any */
/* platform, but your performance with the non-native version */
/* will be less than optimal. */
#include "murmur3.h"
/*------------------------------------------------------------------*/
/* Platform-specific functions and macros */
static uint32_t rotl32 ( uint32_t x, int8_t r )
{
return (x << r) | (x >> (32 - r));
}
static uint64_t rotl64 ( uint64_t x, int8_t r )
{
return (x << r) | (x >> (64 - r));
}
#define ROTL32(x,y) rotl32(x,y)
#define ROTL64(x,y) rotl64(x,y)
#define BIG_CONSTANT(x) (x##LLU)
/*------------------------------------------------------------------*/
/* Block read - if your platform needs to do endian-swapping or can */
/* only handle aligned reads, do the conversion here */
#define getblock(p, i) (p[i])
/*------------------------------------------------------------------*/
/* Finalization mix - force all bits of a hash block to avalanche */
static uint32_t fmix32 ( uint32_t h )
{
h ^= h >> 16;
h *= 0x85ebca6b;
h ^= h >> 13;
h *= 0xc2b2ae35;
h ^= h >> 16;
return h;
}
/*----------*/
static uint64_t fmix64 ( uint64_t k )
{
k ^= k >> 33;
k *= BIG_CONSTANT(0xff51afd7ed558ccd);
k ^= k >> 33;
k *= BIG_CONSTANT(0xc4ceb9fe1a85ec53);
k ^= k >> 33;
return k;
}
/*------------------------------------------------------------------*/
void MurmurHash3_x86_32 ( const void * key, int len,
uint32_t seed, void * out )
{
const uint8_t * data = (const uint8_t*)key;
const int nblocks = len / 4;
int i;
uint32_t h1 = seed;
uint32_t c1 = 0xcc9e2d51;
uint32_t c2 = 0x1b873593;
/*----------*/
/* body */
const uint32_t * blocks = (const uint32_t *)(data + nblocks*4);
for(i = -nblocks; i; i++)
{
uint32_t k1 = getblock(blocks,i);
k1 *= c1;
k1 = ROTL32(k1,15);
k1 *= c2;
h1 ^= k1;
h1 = ROTL32(h1,13);
h1 = h1*5+0xe6546b64;
}
/*----------*/
/* tail */
const uint8_t * tail = (const uint8_t*)(data + nblocks*4);
uint32_t k1 = 0;
switch(len & 3)
{
case 3: k1 ^= tail[2] << 16;
case 2: k1 ^= tail[1] << 8;
case 1: k1 ^= tail[0];
k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1;
};
/*----------*/
/* finalization */
h1 ^= len;
h1 = fmix32(h1);
*(uint32_t*)out = h1;
}
/*------------------------------------------------------------------*/
void MurmurHash3_x86_128 ( const void * key, const int len,
uint32_t seed, void * out )
{
const uint8_t * data = (const uint8_t*)key;
const int nblocks = len / 16;
int i;
uint32_t h1 = seed;
uint32_t h2 = seed;
uint32_t h3 = seed;
uint32_t h4 = seed;
uint32_t c1 = 0x239b961b;
uint32_t c2 = 0xab0e9789;
uint32_t c3 = 0x38b34ae5;
uint32_t c4 = 0xa1e38b93;
/*----------*/
/* body */
const uint32_t * blocks = (const uint32_t *)(data + nblocks*16);
for(i = -nblocks; i; i++)
{
uint32_t k1 = getblock(blocks,i*4+0);
uint32_t k2 = getblock(blocks,i*4+1);
uint32_t k3 = getblock(blocks,i*4+2);
uint32_t k4 = getblock(blocks,i*4+3);
k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1;
h1 = ROTL32(h1,19); h1 += h2; h1 = h1*5+0x561ccd1b;
k2 *= c2; k2 = ROTL32(k2,16); k2 *= c3; h2 ^= k2;
h2 = ROTL32(h2,17); h2 += h3; h2 = h2*5+0x0bcaa747;
k3 *= c3; k3 = ROTL32(k3,17); k3 *= c4; h3 ^= k3;
h3 = ROTL32(h3,15); h3 += h4; h3 = h3*5+0x96cd1c35;
k4 *= c4; k4 = ROTL32(k4,18); k4 *= c1; h4 ^= k4;
h4 = ROTL32(h4,13); h4 += h1; h4 = h4*5+0x32ac3b17;
}
/*----------*/
/* tail */
const uint8_t * tail = (const uint8_t*)(data + nblocks*16);
uint32_t k1 = 0;
uint32_t k2 = 0;
uint32_t k3 = 0;
uint32_t k4 = 0;
switch(len & 15)
{
case 15: k4 ^= tail[14] << 16;
case 14: k4 ^= tail[13] << 8;
case 13: k4 ^= tail[12] << 0;
k4 *= c4; k4 = ROTL32(k4,18); k4 *= c1; h4 ^= k4;
case 12: k3 ^= tail[11] << 24;
case 11: k3 ^= tail[10] << 16;
case 10: k3 ^= tail[ 9] << 8;
case 9: k3 ^= tail[ 8] << 0;
k3 *= c3; k3 = ROTL32(k3,17); k3 *= c4; h3 ^= k3;
case 8: k2 ^= tail[ 7] << 24;
case 7: k2 ^= tail[ 6] << 16;
case 6: k2 ^= tail[ 5] << 8;
case 5: k2 ^= tail[ 4] << 0;
k2 *= c2; k2 = ROTL32(k2,16); k2 *= c3; h2 ^= k2;
case 4: k1 ^= tail[ 3] << 24;
case 3: k1 ^= tail[ 2] << 16;
case 2: k1 ^= tail[ 1] << 8;
case 1: k1 ^= tail[ 0] << 0;
k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1;
};
/*----------*/
/* finalization */
h1 ^= len; h2 ^= len; h3 ^= len; h4 ^= len;
h1 += h2; h1 += h3; h1 += h4;
h2 += h1; h3 += h1; h4 += h1;
h1 = fmix32(h1);
h2 = fmix32(h2);
h3 = fmix32(h3);
h4 = fmix32(h4);
h1 += h2; h1 += h3; h1 += h4;
h2 += h1; h3 += h1; h4 += h1;
((uint32_t*)out)[0] = h1;
((uint32_t*)out)[1] = h2;
((uint32_t*)out)[2] = h3;
((uint32_t*)out)[3] = h4;
}
/*------------------------------------------------------------------*/
void MurmurHash3_x64_128 ( const void * key, const int len,
const uint32_t seed, void * out )
{
const uint8_t * data = (const uint8_t*)key;
const int nblocks = len / 16;
int i;
uint64_t h1 = seed;
uint64_t h2 = seed;
uint64_t c1 = BIG_CONSTANT(0x87c37b91114253d5);
uint64_t c2 = BIG_CONSTANT(0x4cf5ad432745937f);
/*----------*/
/* body */
const uint64_t * blocks = (const uint64_t *)(data);
for(i = 0; i < nblocks; i++)
{
uint64_t k1 = getblock(blocks,i*2+0);
uint64_t k2 = getblock(blocks,i*2+1);
k1 *= c1; k1 = ROTL64(k1,31); k1 *= c2; h1 ^= k1;
h1 = ROTL64(h1,27); h1 += h2; h1 = h1*5+0x52dce729;
k2 *= c2; k2 = ROTL64(k2,33); k2 *= c1; h2 ^= k2;
h2 = ROTL64(h2,31); h2 += h1; h2 = h2*5+0x38495ab5;
}
/*----------*/
/* tail */
const uint8_t * tail = (const uint8_t*)(data + nblocks*16);
uint64_t k1 = 0;
uint64_t k2 = 0;
switch(len & 15)
{
case 15: k2 ^= (uint64_t)(tail[14]) << 48;
case 14: k2 ^= (uint64_t)(tail[13]) << 40;
case 13: k2 ^= (uint64_t)(tail[12]) << 32;
case 12: k2 ^= (uint64_t)(tail[11]) << 24;
case 11: k2 ^= (uint64_t)(tail[10]) << 16;
case 10: k2 ^= (uint64_t)(tail[ 9]) << 8;
case 9: k2 ^= (uint64_t)(tail[ 8]) << 0;
k2 *= c2; k2 = ROTL64(k2,33); k2 *= c1; h2 ^= k2;
case 8: k1 ^= (uint64_t)(tail[ 7]) << 56;
case 7: k1 ^= (uint64_t)(tail[ 6]) << 48;
case 6: k1 ^= (uint64_t)(tail[ 5]) << 40;
case 5: k1 ^= (uint64_t)(tail[ 4]) << 32;
case 4: k1 ^= (uint64_t)(tail[ 3]) << 24;
case 3: k1 ^= (uint64_t)(tail[ 2]) << 16;
case 2: k1 ^= (uint64_t)(tail[ 1]) << 8;
case 1: k1 ^= (uint64_t)(tail[ 0]) << 0;
k1 *= c1; k1 = ROTL64(k1,31); k1 *= c2; h1 ^= k1;
};
/*----------*/
/* finalization*/
h1 ^= len; h2 ^= len;
h1 += h2;
h2 += h1;
h1 = fmix64(h1);
h2 = fmix64(h2);
h1 += h2;
h2 += h1;
((uint64_t*)out)[0] = h1;
((uint64_t*)out)[1] = h2;
}
/*------------------------------------------------------------------*/

24
tests/murmur3.h Normal file
View File

@ -0,0 +1,24 @@
#ifndef _MURMURHASH3_H_
#define _MURMURHASH3_H_
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/*-----------------------------------------------------------------*/
void MurmurHash3_x86_32 (const void *key, int len, uint32_t seed, void *out);
void MurmurHash3_x86_128(const void *key, int len, uint32_t seed, void *out);
void MurmurHash3_x64_128(const void *key, int len, uint32_t seed, void *out);
/*-----------------------------------------------------------------*/
#ifdef __cplusplus
}
#endif
#endif /* _MURMURHASH3_H_ */

105
tests/runme.sh Executable file
View File

@ -0,0 +1,105 @@
#! /bin/bash
# Remove all the previous files.
rm -rf ./html/pages
rm -f ./html/top.html
#####################################################################
# Setting Default values for the variables if not defined.
FT_TEST_DPI=${FT_TEST_DPI:-72 96}
FT_TEST_FONT_FILE=${FT_TEST_FONT_FILE:-test.ttf}
FT_TEST_RENDER_MODE=${FT_TEST_RENDER_MODE:-AA RGB}
FT_TEST_PT_SIZE=${FT_TEST_PT_SIZE:-16 20}
FT_TEST_BASE_DIR=${FT_TEST_BASE_DIR:-$HOME/base}
FT_TEST_TEST_DIR=${FT_TEST_TEST_DIR:-..}
FT_TEST_BASE_DLL=${FT_TEST_BASE_DLL:-$FT_TEST_BASE_DIR/objs/.libs/libfreetype.so}
FT_TEST_TEST_DLL=${FT_TEST_TEST_DLL:-$FT_TEST_TEST_DIR/objs/.libs/libfreetype.so}
#####################################################################
mkdir ./html/pages
touch ./html/top.html
#####################################################################
# Generating top.html file
echo "
<!DOCTYPE html>
<head>
<title> FreeType Test Framework </title>
<script type=\"text/javascript\" src =\"source/scripts/top.js\" ></script>
<link rel=\"stylesheet\" type=\"text/css\" href=\"source/styles/top.css\">
</head>
<html>
<body onload=\"change()\">
<div id=\"top_info\">
<p><b>Base Version:</b> $FT_TEST_BASE_DLL<br>
<b>Test Version:</b> $FT_TEST_TEST_DLL
</p>
</div>
<iframe id=\"frame_1\" name=\"frame_1\" src=\"\" ></iframe>
<iframe id=\"frame_2\" name=\"frame_2\" src=\"source/diff.html\" ></iframe>">./html/top.html
#####################################################################
# Filling html/top.html file with links to all the index.html files.
x="";
y="";
for i in $FT_TEST_DPI; do
mkdir ./html/pages/$i
for j in $FT_TEST_FONT_FILE; do
eval x="$( cut -d '.' -f 2- <<< "$j" )"; #Font file type / extension
eval y="$( cut -d '.' -f 1 <<< "$j" )"; #Font file name
mkdir ./html/pages/$i/$x
mkdir ./html/pages/$i/$x/$y
for k in $FT_TEST_RENDER_MODE; do
mkdir ./html/pages/$i/$x/$y/$k
for l in $FT_TEST_PT_SIZE; do
mkdir ./html/pages/$i/$x/$y/$k/$l
mkdir ./html/pages/$i/$x/$y/$k/$l/images
./tests $FT_TEST_BASE_DLL $FT_TEST_TEST_DLL $j $l $k $i
done
done
done
done
#####################################################################
# Buttons for animation selection
echo '<div id="select_animation">
<button onclick="class_one_two()">One-Two</button>
<button onclick="class_one_three()">One-Three</button>
<button onclick="class_one_four()">One-Four</button>&nbsp&nbsp
<button onclick="pause_play()" id="pause_btn"> Pause|Play </button>
</div>
<div class="select">'>>./html/top.html
#####################################################################
# Populating the selection lists with options
echo '<label>DPI&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp:<select name="dpi" id="dpi" onchange="change()">'>>./html/top.html
for i in $FT_TEST_DPI; do
echo " <option value= $i > $i </option>">>./html/top.html
done
echo '</select>
</label><br>'>>./html/top.html
#####################################################################
echo '<label>Font&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp:<select name="font" id="font" onchange="change()">'>>./html/top.html
for i in $FT_TEST_FONT_FILE; do
echo " <option value= $i > $i </option>">>./html/top.html
done
echo '</select>
</label><br>'>>./html/top.html
#####################################################################
echo '<label>Render Mode:<select name="mode" id="mode" onchange="change()">'>>./html/top.html
for i in $FT_TEST_RENDER_MODE; do
echo " <option value= $i > $i </option>">>./html/top.html
done
echo '</select>
</label><br>'>>./html/top.html
#####################################################################
echo '<label>Point Size&nbsp:<select name="size" id="size" onchange="change()">'>>./html/top.html
for i in $FT_TEST_PT_SIZE; do
echo " <option value= $i > $i </option>">>./html/top.html
done
echo '</select>
</label><br>'>>./html/top.html
#####################################################################
echo '</div>
</body>
</html>'>>./html/top.html
#####################################################################
echo "Font : " $FT_TEST_FONT_FILE
echo "Point Size : " $FT_TEST_PT_SIZE
echo "Render_Mode: " $FT_TEST_RENDER_MODE
echo "DPI : " $FT_TEST_DPI

BIN
tests/test.ttf Executable file

Binary file not shown.