From 804168ec76f27f58ecbe8ffd6bd493807ee933fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89milie=20Feral?= Date: Wed, 25 Jan 2017 10:58:43 +0100 Subject: [PATCH] [kandinsky] Rasterize some non-ASCII glyphs Change-Id: I7e8ac19de72a35621a7101b3bf4686e5e7b6763e --- kandinsky/Makefile | 4 +- kandinsky/fonts/rasterizer.c | 71 +++++++++++++++++++++++++--- kandinsky/fonts/unicode_for_symbol.c | 6 +++ kandinsky/fonts/unicode_for_symbol.h | 10 ++++ kandinsky/src/context_text.cpp | 4 +- 5 files changed, 84 insertions(+), 11 deletions(-) create mode 100644 kandinsky/fonts/unicode_for_symbol.c create mode 100644 kandinsky/fonts/unicode_for_symbol.h diff --git a/kandinsky/Makefile b/kandinsky/Makefile index dbc0e7a02..caf708d15 100644 --- a/kandinsky/Makefile +++ b/kandinsky/Makefile @@ -53,9 +53,9 @@ kandinsky/src/large_font.c: kandinsky/fonts/rasterizer @echo "RASTER $(large_font_files)" @$< kandinsky/fonts/largePixelFont.ttf 16 16 LargeFont $(large_font_files) -kandinsky/fonts/rasterizer: kandinsky/fonts/rasterizer.c +kandinsky/fonts/rasterizer: kandinsky/fonts/rasterizer.c kandinsky/fonts/unicode_for_symbol.c @echo "HOSTCC $@" - @$(HOSTCC) -std=c99 $(RASTERIZER_CFLAGS) $< $(RASTERIZER_LDFLAGS) -o$@ + @$(HOSTCC) $(RASTERIZER_CFLAGS) $^ $(RASTERIZER_LDFLAGS) -o $@ products += $(small_font_files) $(large_font_files) kandinsky/fonts/rasterizer diff --git a/kandinsky/fonts/rasterizer.c b/kandinsky/fonts/rasterizer.c index 4730f5079..d6e2ce461 100644 --- a/kandinsky/fonts/rasterizer.c +++ b/kandinsky/fonts/rasterizer.c @@ -15,6 +15,8 @@ #include #include FT_FREETYPE_H +#include "unicode_for_symbol.h" + #define ENSURE(action, description...) { if (!(action)) { fprintf(stderr, "Error: "); fprintf(stderr, description); fprintf(stderr, "\n"); exit(-1);}} // Pixel format is RGB888 @@ -40,9 +42,9 @@ void writeImageToPNGFile(image_t * image, char * filename); #define CHARACTER_RANGE_END 0x7E #define GRID_WIDTH 19 -#define GRID_HEIGHT 5 +#define GRID_HEIGHT 8 -#if (GRID_WIDTH*GRID_HEIGHT < (CHARACTER_RANGE_END-CHARACTER_RANGE_START+1)) +#if (GRID_WIDTH*GRID_HEIGHT < (NUMBER_OF_SYMBOL+CHARACTER_RANGE_END-CHARACTER_RANGE_START+1)) #error Grid too small. Consider increasing GRID_WIDTH or GRID_HEIGHT #endif @@ -115,6 +117,22 @@ int main(int argc, char * argv[]) { maxBelowBaseline = belowBaseline; } } + for (int charIndex = 0; charIndex < NUMBER_OF_SYMBOL; charIndex++) { + wchar_t wideChar = codePointForSymbol[charIndex]; + ENSURE(!FT_Load_Char(face, wideChar, FT_LOAD_RENDER), "Loading character 0x%02x", wideChar); + int aboveBaseline = face->glyph->bitmap_top; + int belowBaseline = face->glyph->bitmap.rows - face->glyph->bitmap_top; + int width = face->glyph->bitmap_left + face->glyph->bitmap.width; + if (width > maxWidth) { + maxWidth = width; + } + if (aboveBaseline > maxAboveBaseline) { + maxAboveBaseline = aboveBaseline; + } + if (belowBaseline > maxBelowBaseline) { + maxBelowBaseline = belowBaseline; + } + } int glyph_width = maxWidth-1; int glyph_height = maxAboveBaseline+maxBelowBaseline; @@ -151,6 +169,20 @@ int main(int argc, char * argv[]) { y*(glyph_height+grid_size) + maxAboveBaseline - face->glyph->bitmap_top ); } + // We are now using unicode to access non-ASCII characters + for (int charIndex = 0; charIndex < NUMBER_OF_SYMBOL; charIndex++) { + wchar_t wideChar = codePointForSymbol[charIndex]; + int x = (charIndex+1+CHARACTER_RANGE_END-CHARACTER_RANGE_START)%(GRID_WIDTH); + int y = (charIndex+1+CHARACTER_RANGE_END-CHARACTER_RANGE_START)/(GRID_WIDTH); + // FT_LOAD_RENDER: Render the glyph upon load + ENSURE(!FT_Load_Char(face, wideChar, FT_LOAD_RENDER), "Loading character 0x%02x", wideChar); + //printf("Advances = %dx%d\n", face->glyph->bitmap_left, face->glyph->bitmap_top); + drawGlyphInImage(&face->glyph->bitmap, + &bitmap_image, + x*(glyph_width+grid_size) + face->glyph->bitmap_left, + y*(glyph_height+grid_size) + maxAboveBaseline - face->glyph->bitmap_top + ); + } #if GENERATE_PNG writeImageToPNGFile(&bitmap_image, output_png); @@ -158,16 +190,17 @@ int main(int argc, char * argv[]) { FILE * headerFile = fopen(output_header, "w"); fprintf(headerFile, "/* Auto-generated by rasterizer */\n\n"); - fprintf(headerFile, "#define BITMAP_%s_FIRST_CHARACTER 0x%2x\n", font_name, CHARACTER_RANGE_START); - fprintf(headerFile, "#define BITMAP_%s_LAST_CHARACTER 0x%2x\n\n", font_name, CHARACTER_RANGE_END); + fprintf(headerFile, "#define BITMAP_%s_FIRST_ASCII_CHARACTER 0x%2x\n", font_name, CHARACTER_RANGE_START); + fprintf(headerFile, "#define BITMAP_%s_LAST_ASCII_CHARACTER 0x%2x\n\n", font_name, CHARACTER_RANGE_END); + fprintf(headerFile, "#define BITMAP_%s_LAST_CHARACTER 0x%2x\n\n", font_name, CHARACTER_RANGE_END+NUMBER_OF_SYMBOL); fprintf(headerFile, "#define BITMAP_%s_CHARACTER_WIDTH %d\n", font_name, glyph_width); fprintf(headerFile, "#define BITMAP_%s_CHARACTER_HEIGHT %d\n\n", font_name, glyph_height); - fprintf(headerFile, "extern unsigned char bitmap%s[%d][%d][%d];\n", font_name, CHARACTER_RANGE_END-CHARACTER_RANGE_START+1, glyph_height, glyph_width); + fprintf(headerFile, "extern unsigned char bitmap%s[%d][%d][%d];\n", font_name, NUMBER_OF_SYMBOL+CHARACTER_RANGE_END-CHARACTER_RANGE_START+1, glyph_height, glyph_width); fclose(headerFile); FILE * sourceFile = fopen(output_implementation, "w"); fprintf(sourceFile, "/* Auto-generated by rasterizer */\n\n"); - fprintf(sourceFile, "unsigned char bitmap%s[%d][%d][%d] = {\n", font_name, CHARACTER_RANGE_END-CHARACTER_RANGE_START+1, glyph_height, glyph_width); + fprintf(sourceFile, "unsigned char bitmap%s[%d][%d][%d] = {\n", font_name, NUMBER_OF_SYMBOL+CHARACTER_RANGE_END-CHARACTER_RANGE_START+1, glyph_height, glyph_width); for (unsigned char character = CHARACTER_RANGE_START; character <= CHARACTER_RANGE_END; character++) { fprintf(sourceFile, " {\n"); int characterX = ((character-CHARACTER_RANGE_START)%GRID_WIDTH * (glyph_width+grid_size)); @@ -188,7 +221,31 @@ int main(int argc, char * argv[]) { fprintf(sourceFile, "\n"); } fprintf(sourceFile, " }"); - if (character+1 <= CHARACTER_RANGE_END) { + fprintf(sourceFile, ","); + fprintf(sourceFile, "\n"); + } + for (int charIndex = 0; charIndex < NUMBER_OF_SYMBOL; charIndex++) { + wchar_t wideChar = codePointForSymbol[charIndex]; + fprintf(sourceFile, " {\n"); + int characterX = ((charIndex+1+CHARACTER_RANGE_END-CHARACTER_RANGE_START)%GRID_WIDTH * (glyph_width+grid_size)); + int characterY = ((charIndex+1+CHARACTER_RANGE_END-CHARACTER_RANGE_START)/GRID_WIDTH * (glyph_height+grid_size)); + for (int y = 0; y < glyph_height; y++) { + fprintf(sourceFile, " {"); + for (int x = 0; x < glyph_width; x++) { + pixel_t * pixel = (bitmap_image.pixels + (y+characterY)*bitmap_image.width + (x+characterX)); + fprintf(sourceFile, "0x%02x", 0xFF - pixel->green); + if (x+1 < glyph_width) { + fprintf(sourceFile, ", "); + } + } + fprintf(sourceFile, "}"); + if (y+1 < glyph_height) { + fprintf(sourceFile, ","); + } + fprintf(sourceFile, "\n"); + } + fprintf(sourceFile, " }"); + if (charIndex < NUMBER_OF_SYMBOL - 1) { fprintf(sourceFile, ","); } fprintf(sourceFile, "\n"); diff --git a/kandinsky/fonts/unicode_for_symbol.c b/kandinsky/fonts/unicode_for_symbol.c new file mode 100644 index 000000000..c3e35ec63 --- /dev/null +++ b/kandinsky/fonts/unicode_for_symbol.c @@ -0,0 +1,6 @@ +#include "unicode_for_symbol.h" + +wchar_t codePointForSymbol[NUMBER_OF_SYMBOL] = {0x00c1, 0x00c9, 0x00cd, 0x00d1, 0x00d3, 0x00da, 0x00e0, + 0x00e1, 0x00e2, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ed, 0x00ee, 0x00ef, 0x00f1, 0x00f3, 0x00f9, 0x00fa, + 0x00fb, 0x00fc, 0x222b, 0x0078, 0x0305, 0x0079, 0x0305, 0x0393, 0x03a3, 0x03b8, 0x03b9, 0x03bb, + 0x03bc, 0x03c0, 0x03c3, 0x1D07, 0x2032, 0x2192, 0x221A, 0x2264, 0x2265}; diff --git a/kandinsky/fonts/unicode_for_symbol.h b/kandinsky/fonts/unicode_for_symbol.h new file mode 100644 index 000000000..c4dbedd1c --- /dev/null +++ b/kandinsky/fonts/unicode_for_symbol.h @@ -0,0 +1,10 @@ +#ifndef KANDINSKY_FONT_UNICODE_H +#define KANDINSKY_FONT_UNICODE_H + +#include + +#define NUMBER_OF_SYMBOL 41 + +extern wchar_t codePointForSymbol[NUMBER_OF_SYMBOL]; + +#endif \ No newline at end of file diff --git a/kandinsky/src/context_text.cpp b/kandinsky/src/context_text.cpp index 12e8819a2..cffeb2742 100644 --- a/kandinsky/src/context_text.cpp +++ b/kandinsky/src/context_text.cpp @@ -6,7 +6,7 @@ KDColor smallCharacterBuffer[BITMAP_SmallFont_CHARACTER_WIDTH*BITMAP_SmallFont_C KDColor largeCharacterBuffer[BITMAP_LargeFont_CHARACTER_WIDTH*BITMAP_LargeFont_CHARACTER_HEIGHT]; void KDContext::drawChar(char character, KDText::FontSize size, KDPoint p, KDColor textColor, KDColor backgroundColor) { - int firstCharacter = size == KDText::FontSize::Large ? BITMAP_LargeFont_FIRST_CHARACTER : BITMAP_SmallFont_FIRST_CHARACTER; + int firstCharacter = size == KDText::FontSize::Large ? BITMAP_LargeFont_FIRST_ASCII_CHARACTER : BITMAP_SmallFont_FIRST_ASCII_CHARACTER; int characterHeight = size == KDText::FontSize::Large ? BITMAP_LargeFont_CHARACTER_HEIGHT : BITMAP_SmallFont_CHARACTER_HEIGHT; int characterWidth = size == KDText::FontSize::Large ? BITMAP_LargeFont_CHARACTER_WIDTH : BITMAP_SmallFont_CHARACTER_WIDTH; KDColor * characterBuffer = size == KDText::FontSize::Large ? largeCharacterBuffer : smallCharacterBuffer; @@ -39,7 +39,7 @@ void KDContext::drawString(const char * text, KDText::FontSize size, KDPoint p, } void KDContext::blendChar(char character, KDText::FontSize size, KDPoint p, KDColor textColor) { - int firstCharacter = size == KDText::FontSize::Large ? BITMAP_LargeFont_FIRST_CHARACTER : BITMAP_SmallFont_FIRST_CHARACTER; + int firstCharacter = size == KDText::FontSize::Large ? BITMAP_LargeFont_FIRST_ASCII_CHARACTER : BITMAP_SmallFont_FIRST_ASCII_CHARACTER; int characterHeight = size == KDText::FontSize::Large ? BITMAP_LargeFont_CHARACTER_HEIGHT : BITMAP_SmallFont_CHARACTER_HEIGHT; int characterWidth = size == KDText::FontSize::Large ? BITMAP_LargeFont_CHARACTER_WIDTH : BITMAP_SmallFont_CHARACTER_WIDTH; KDColor * characterBuffer = size == KDText::FontSize::Large ? largeCharacterBuffer : smallCharacterBuffer;