summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKushal K S V S <kkushal32@gmail.com>2017-06-29 01:59:00 +0530
committerKushal K S V S <kkushal32@gmail.com>2017-06-29 01:59:00 +0530
commit7a751accb0b85ba41b25f534e36fec4053c9e976 (patch)
tree991600964dac7e74c9152e7c99e1b513a123828b
parent1297c0ddc511527936e1400593023746e4203fd7 (diff)
downloadfreetype2-7a751accb0b85ba41b25f534e36fec4053c9e976.tar.gz
code for generating PNG
-rw-r--r--new/README25
-rw-r--r--new/bitmap.c195
-rw-r--r--new/bitmap.h40
-rw-r--r--new/make_png.c167
-rw-r--r--new/makefile14
5 files changed, 433 insertions, 8 deletions
diff --git a/new/README b/new/README
index a01ac2d77..e3ebb412b 100644
--- a/new/README
+++ b/new/README
@@ -1,6 +1,6 @@
-To generate hashes and store it in the same folder,
+To generate hashes and store it in the ./hashes folder,
- 1) sudo make
+ 1) sudo make hash
(set resoluton in DPI by passing argument
example: sudo make DPI=100, if not specified,default is 72)
@@ -12,5 +12,24 @@ To generate hashes and store it in the same folder,
Values for render_mode 0 - monochrome
1 - anti-aliased
+ 2 - lcd horizontal
+ 3 - lcd vertical
+
+To generate 32-bit RGBA PNG(s) of all glyphs in a font\n
+
+ 1) sudo make png
+ (set resoluton in DPI by passing argument
+ example: sudo make DPI=100, if not specified,default is 72)
+
+ 2.Usage ./<exe> <font_file> <pt_size> <render_mode>
+
+ 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
+
+ Values for render_mode 0 - monochrome
+ 1 - anti-aliased
2 - lcd horizontal-RGB
- 3 - lcd vertical-RGB \ No newline at end of file
+ 3 - lcd horizontal-BGR
+ 4 - lcd vertical-RGB
+ 5 - lcd vertical-BGR \ No newline at end of file
diff --git a/new/bitmap.c b/new/bitmap.c
index 923d072f3..2813ff1b4 100644
--- a/new/bitmap.c
+++ b/new/bitmap.c
@@ -27,3 +27,198 @@ HASH_32 * Generate_Hash_x86_32(FT_Bitmap * bitmap, HASH_32 * murmur)
return murmur;
}
+PIXEL * Pixel_At (IMAGE * bitmap, int x, int y)
+{
+ return bitmap->pixels + bitmap->width * y + x;
+}
+
+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;
+ int depth = 8;
+
+ 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)
+ {
+ *row++ = pixel->blue;
+ *row++ = pixel->green;
+ *row++ = pixel->red;
+ *row++ = pixel->alpha;
+ continue;
+ }
+ *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;
+
+ for (y = 0; y < bitmap->height; y++) {
+ png_free (png_ptr, row_pointers[y]);
+ }
+ png_free (png_ptr, row_pointers);
+
+ 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;
+}
+
+void Make_PNG(FT_Bitmap* bitmap,char* name,int i,int render_mode){
+
+ IMAGE fruit;
+ int x;
+ int y;
+
+ unsigned char value;
+ int p;
+
+ switch(render_mode){
+
+ case 0 :
+ case 1 : fruit.width = bitmap->width; // MONO and 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;
+
+ value = bitmap->buffer[p];
+
+ pixel->red = 255- value;
+ pixel->green = 255- value;
+ pixel->blue = 255- value;
+ pixel->alpha = 255;
+ }
+ }
+ break;
+
+ 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;
+
+ 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;
+ }
+
+ char * file_name = ( char * )calloc(150,sizeof(char));
+
+ sprintf(file_name, "%s_%d",name,i);
+
+ Generate_PNG (& fruit, file_name,render_mode);
+
+ free (fruit.pixels);
+} \ No newline at end of file
diff --git a/new/bitmap.h b/new/bitmap.h
index fb7ab12e5..8a3a4f58e 100644
--- a/new/bitmap.h
+++ b/new/bitmap.h
@@ -1,7 +1,17 @@
#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <unistd.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
#include <ft2build.h>
+
#include "murmur3.h" // MurmurHash3_x64_128 header file
-#include <unistd.h>
+
+#include <png.h>
+
#include FT_FREETYPE_H
#include FT_MODULE_H
@@ -18,6 +28,28 @@ typedef struct { // To store 128bit Hash
FT_UInt32 hash[4];
}HASH_128;
+typedef struct {
+ unsigned char red;
+ unsigned char green;
+ unsigned char blue;
+ unsigned char alpha;
+} PIXEL;
+
+typedef struct {
+ unsigned char red;
+ unsigned char green;
+ unsigned char blue;
+ unsigned char alpha;
+} PIXEL_BGRA;
+
+/* A picture. */
+
+typedef struct {
+ PIXEL *pixels;
+ size_t width;
+ size_t height;
+} IMAGE;
+
//-------------------------------------------------------------------------------
HASH_32 * Generate_Hash_x86_32(FT_Bitmap * bitmap, HASH_32 * murmur);
@@ -25,3 +57,9 @@ HASH_128 * Generate_Hash_x86_128(FT_Bitmap * bitmap, HASH_128 * murmur);
HASH_128 * Generate_Hash_x64_128(FT_Bitmap * bitmap, HASH_128 * murmur);
//-------------------------------------------------------------------------------
+
+PIXEL * Pixel_At (IMAGE * bitmap, int x, int y);
+
+void Make_PNG(FT_Bitmap* bitmap,char* name,int i,int render_mode);
+int Generate_PNG (IMAGE *bitmap, const char *path,int render_mode);
+
diff --git a/new/make_png.c b/new/make_png.c
new file mode 100644
index 000000000..4d3312561
--- /dev/null
+++ b/new/make_png.c
@@ -0,0 +1,167 @@
+#include "bitmap.h"
+
+int main (int argc, char const *argv[])
+{
+ FT_Library library;
+ FT_Face face;
+ FT_GlyphSlot slot;
+
+ FT_Bitmap* bitmap;
+
+ FT_Error error;
+
+ const char* font_file;
+ int size;
+ int render_mode; // argument
+
+ int load_flag; // FT_LOAD_XXX
+ int render_flag; // FT_RENDER_MODE_XXX
+ int target_flag; // FT_LOAD_TARGET_XXX
+ char* render_type; // for file_name
+
+ char name[100]; // hashes file name
+ int i; // for loop
+
+ if (argc != 4)
+ {
+ printf("\nTo generate 32-bit RGBA PNG(s) of all glyphs in a font\n");
+ printf("Images will be saved in a file named \n\
+ $(font)_$(pt_size)_$(render_mode)_$(glyph_index).png \n\n");
+
+ printf("By default, hashes of 256-level gray bitmaps will be generated\n\n");
+
+ printf("Usage ./<exe> <font_file> <pt_size> <render_mode>\n\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 1;
+ }
+
+ font_file = argv[1];
+ size = atof(argv[2]);
+ render_mode = atoi(argv[3]);
+
+ error = FT_Init_FreeType( &library );
+ if(error){
+ printf("Error while initialising library\n");
+ }
+
+ error = FT_New_Face( library,
+ font_file,
+ 0,
+ &face );
+ if(error){
+ printf("Error loading new face\n");
+ }
+
+ error = FT_Set_Char_Size( face,
+ size * 64,
+ 0,
+ DPI,
+ 0 );
+ if(error){
+ printf("Error setting character size\n");
+ }
+
+ switch ( render_mode ) {
+ case 0: render_flag = FT_RENDER_MODE_MONO;
+ load_flag = FT_LOAD_MONOCHROME;
+ target_flag = FT_LOAD_TARGET_MONO;
+ render_type = "mono";
+ break;
+
+ case 1: render_flag = FT_RENDER_MODE_NORMAL;
+ load_flag = FT_LOAD_DEFAULT;
+ target_flag = FT_LOAD_TARGET_NORMAL;
+ render_type = "gray";
+ break;
+
+ case 2: render_flag = FT_RENDER_MODE_LCD;
+ load_flag = FT_LOAD_DEFAULT;
+ target_flag = FT_LOAD_TARGET_LCD;
+ render_type = "lcd_rgb";
+ break;
+
+ case 3: render_flag = FT_RENDER_MODE_LCD;
+ load_flag = FT_LOAD_DEFAULT;
+ target_flag = FT_LOAD_TARGET_LCD;
+ render_type = "lcd_bgr";
+ break;
+
+ case 4: render_flag = FT_RENDER_MODE_LCD_V;
+ load_flag = FT_LOAD_DEFAULT;
+ target_flag = FT_LOAD_TARGET_LCD_V;
+ render_type = "lcd_ver_rgb";
+ break;
+
+ case 5: render_flag = FT_RENDER_MODE_LCD_V;
+ load_flag = FT_LOAD_DEFAULT;
+ target_flag = FT_LOAD_TARGET_LCD_V;
+ render_type = "lcd_ver_bgr";
+ break;
+
+ default:render_flag = FT_RENDER_MODE_NORMAL;
+ load_flag = FT_LOAD_DEFAULT;
+ target_flag = FT_LOAD_TARGET_NORMAL;
+ render_type = "gray";
+ }
+
+ slot = face->glyph;
+
+ sprintf(name,"./images/%s_%d_%s",font_file,
+ size,
+ render_type);
+
+ for (i = 0; i <50; ++i)
+ {
+ error = FT_Load_Glyph( face,
+ i,
+ load_flag | target_flag);
+ if(error){
+ printf("Error loading glyph\n");
+ }
+
+ FT_Render_Glyph( slot,
+ render_flag);
+ if(error){
+ printf("Error rendering the glyph\n");
+ }
+
+ bitmap = &slot->bitmap;
+
+ if (bitmap->width == 0 || bitmap->rows == 0)
+ {
+ continue;
+ }
+
+ FT_Bitmap target;
+ FT_Bitmap_Init( &target );
+
+ if (bitmap->pixel_mode == 1)
+ {
+ int alignment = 4;
+ error = FT_Bitmap_Convert( library,
+ bitmap,
+ &target,
+ alignment);
+ if(error){
+ printf("Error converting the bitmap\n");
+ }
+ Make_PNG(&target,name,i,render_mode);
+ }else{
+
+ Make_PNG(bitmap,name,i,render_mode);
+ }
+ }
+
+ FT_Done_Face ( face );
+ FT_Done_FreeType( library );
+
+ return 0;
+
+}
diff --git a/new/makefile b/new/makefile
index d60a6d685..691a6fd1b 100644
--- a/new/makefile
+++ b/new/makefile
@@ -2,18 +2,24 @@
SHELL = /bin/sh
-SRC = hash_to_file.c bitmap.c murmur3.c
+SRC_HASH = hash_to_file.c bitmap.c murmur3.c
+SRC_PNG = make_png.c bitmap.c murmur3.c
OBJS = $(src:.c=.o)
CFLAGS = -Wall -g
CC = gcc
INCLUDE = -I /usr/local/include/freetype2/
-LIBS = -lfreetype
+LIBS = -lfreetype -lpng
DPI = 72
-hash:$(SRC)
- $(CC) $(CFLAGS) $(INCLUDE) -DDPI=$(DPI) -o $@ $(SRC) $(OBJS) $(LIBS)
+all: png hash
+
+png:$(SRC_PNG)
+ $(CC) $(CFLAGS) $(INCLUDE) -DDPI=$(DPI) -o $@ $(SRC_PNG) $(OBJS) $(LIBS)
+
+hash:$(SRC_HASH)
+ $(CC) $(CFLAGS) $(INCLUDE) -DDPI=$(DPI) -o $@ $(SRC_HASH) $(OBJS) $(LIBS)
.PHONY: clean
clean: