From a283bf0b7e6676547c2aa66258012347ab7ad5d0 Mon Sep 17 00:00:00 2001 From: Kushal K S V S Date: Fri, 14 Jul 2017 07:55:51 +0530 Subject: Add make_sprite.c (under Development) - Look at README --- tests/make_png/README | 50 ++++-- tests/make_png/bitmap.h | 2 +- tests/make_png/make_sprite.c | 414 +++++++++++++++++++++++++++++++++++++++++++ tests/make_png/makefile | 9 +- 4 files changed, 458 insertions(+), 17 deletions(-) create mode 100644 tests/make_png/make_sprite.c diff --git a/tests/make_png/README b/tests/make_png/README index d30e35918..6bb3a68d7 100644 --- a/tests/make_png/README +++ b/tests/make_png/README @@ -2,14 +2,18 @@ NOTE: First make freetype library (in the ../../ directory) make devel make +NOTE: Right now, the sprite sheets are generated stitching the base and test glyph + together. +TODO: Monochrome sprite sheets. + Sprite sheets with more sub-images (visual effects). To generate hashes and store it in the ./hashes folder, 1) make hash - (set resoluton in DPI by passing argument - example: sudo make DPI=100, if not specified,default is 72) + (set resoluton in DPI by passing argument + example: sudo make DPI=100, if not specified,default is 72) -2) Usage ./hash +2) Usage ./hash Hashes will be saved in a file named $(font)_$(pt_size)_$(render_mode).hash @@ -24,19 +28,37 @@ To generate hashes and store it in the ./hashes folder, To generate 32-bit RGBA PNG(s) of all glyphs in a font\n 1) make png - (set resoluton in DPI by passing argument + (set resoluton in DPI by passing argument example: sudo make DPI=100, if not specified,default is 72) -2) Usage ./ +2) Usage ./ - Images will be saved in a file named - $(font)_$(pt_size)_$(render_mode)_$(glyph_index).png + Images will be saved in a file named + $(font)_$(pt_size)_$(render_mode)_$(glyph_index).png - By default, hashes of 256-level gray bitmaps will be generated + By default, hashes of 256-level gray bitmaps will be generated + + Values for render_mode 0 - monochrome + 1 - anti-aliased + 2 - lcd horizontal-RGB + 3 - lcd horizontal-BGR + 4 - lcd vertical-RGB + 5 - lcd vertical-BGR + +To generate sprite sheets, +First compile and install two versions of the FreeType libray in different folders +(with SUBPIXEL_RENDERING enabled in ftoption.h) + + +1) make sprite + (set resoluton in DPI by passing argument + example: sudo make DPI=100, if not specified,default is 72) + +2) Usage ./sprite + + The path to the "shared library files" in usage should be absolute. + + Sprite Sheets will be saved as sprite_$(glyph_index).png + + Render modes similar to generating PNG(s). - Values for render_mode 0 - monochrome - 1 - anti-aliased - 2 - lcd horizontal-RGB - 3 - lcd horizontal-BGR - 4 - lcd vertical-RGB - 5 - lcd vertical-BGR \ No newline at end of file diff --git a/tests/make_png/bitmap.h b/tests/make_png/bitmap.h index 51b949c25..be23460e6 100644 --- a/tests/make_png/bitmap.h +++ b/tests/make_png/bitmap.h @@ -11,7 +11,7 @@ #include "murmur3.h" // MurmurHash3_x64_128 header file #include - +#include #include FT_FREETYPE_H #include FT_MODULE_H diff --git a/tests/make_png/make_sprite.c b/tests/make_png/make_sprite.c new file mode 100644 index 000000000..2c68e8e8d --- /dev/null +++ b/tests/make_png/make_sprite.c @@ -0,0 +1,414 @@ +#include "bitmap.h" + +int main(int argc, char const *argv[]) +{ + const char* base_version; + const char* test_version; + const char* font_file; + int size; + int render_mode; + + int load_flag; // FT_LOAD_XXX + int render_flag; // FT_RENDER_MODE_XXX + int target_flag; // FT_LOAD_TARGET_XXX + + if(argc != 6) + { + printf("Usage: ./sprite \ + \n"); + + printf("Values for render_mode 0 - monochrome\n"); + printf(" 1 - anti-aliased\n"); + printf(" 2 - lcd horizontal-RGB\n"); + printf(" 3 - lcd horizontal-BGR\n"); + printf(" 4 - lcd vertical-RGB\n"); + printf(" 5 - lcd vertical-BGR\n"); + + return 0; + } + + base_version = argv[1]; + test_version = argv[2]; + + font_file = argv[3]; + size = atoi(argv[4]); + render_mode = atoi(argv[5]); + + 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 alignment = 4; + char * output_file_name = ( char * )calloc(20,sizeof(char)); + + IMAGE base_png; + IMAGE test_png; + IMAGE after_effect_1; + IMAGE after_effect_2; + IMAGE output; + +/*******************************************************************/ + + 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_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_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_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_Done_Face ) = dlsym(test_handle, + "FT_Done_Face"); + *(void**)( & Test_Done_FreeType ) = dlsym(test_handle, + "FT_Done_FreeType"); + +/*******************************************************************/ + + 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, + size * 64, + 0, + DPI, + 0 ); + if(error){ + printf("Error setting character size\n"); + exit(1); + } + error = Test_Set_Char_Size( test_face, + 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; + + struct stat st = {0}; + if (stat("./images/", &st) == -1) { + mkdir("./images/", 0777); + } +// Need to write code to check the values in FT_Face and compare + for (int 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; +// Need to write code to check the values in FT_Bitmap and compare + if (base_bitmap->width == 0 || base_bitmap->rows == 0) + { + continue; + } +// Mono rendering not working right now, will put it today + // 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); + // } + + sprintf( output_file_name, "./images/sprite_%d", i ); + + if (render_mode == 0) + { + Make_PNG( &base_target, &base_png, i, render_mode ); + Make_PNG( &test_target, &test_png, i, render_mode ); +// Will be added + // Add_effect( &base_png, &test_png, &after_effect_1, 1); + // Add_effect( &base_png, &test_png, &after_effect_2, 2); + + Stitch( &base_png, &test_png, &output); + + Generate_PNG ( &output, output_file_name, render_mode ); + }else{ + + Make_PNG( base_bitmap, &base_png, i, render_mode ); + Make_PNG( test_bitmap, &test_png, i, render_mode ); +// Will be added + // Add_effect( &base_png, &test_png, &after_effect_1, 1); + // Add_effect( &base_png, &test_png, &after_effect_2, 2); + + Stitch( &base_png, &test_png, &output); + + Generate_PNG ( &output, output_file_name, render_mode ); + } + } + + 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; +} \ No newline at end of file diff --git a/tests/make_png/makefile b/tests/make_png/makefile index 506ebfb62..30946f512 100644 --- a/tests/make_png/makefile +++ b/tests/make_png/makefile @@ -4,21 +4,26 @@ SHELL = /bin/sh SRC_HASH = hash_to_file.c bitmap.c murmur3.c SRC_PNG = make_png.c bitmap.c murmur3.c +SRC_SPRITE = make_sprite.c bitmap.c murmur3.c + SRC_LIB = ../../objs/libfreetype.a OBJS = $(src:.c=.o) CFLAGS = -Wall -g CC = gcc INCLUDE = -I ../../include/ -LIBS = -lpng -lharfbuzz -lbz2 +LIBS = -lpng -lharfbuzz -lbz2 -ldl DPI = 72 -all: png hash +all: png hash sprite png:$(SRC_PNG) $(CC) $(CFLAGS) $(INCLUDE) -DDPI=$(DPI) -o $@ $(SRC_PNG) $(SRC_LIB) $(OBJS) $(LIBS) +sprite:$(SRC_PNG) + $(CC) $(CFLAGS) $(INCLUDE) -DDPI=$(DPI) -o $@ $(SRC_SPRITE) $(SRC_LIB) $(OBJS) $(LIBS) + hash:$(SRC_HASH) $(CC) $(CFLAGS) $(INCLUDE) -DDPI=$(DPI) -o $@ $(SRC_HASH) $(SRC_LIB) $(OBJS) $(LIBS) -- cgit v1.2.1