[kandinsky] Rasterize some non-ASCII glyphs

Change-Id: I7e8ac19de72a35621a7101b3bf4686e5e7b6763e
This commit is contained in:
Émilie Feral
2017-01-25 10:58:43 +01:00
parent bfb1ee24ec
commit 804168ec76
5 changed files with 84 additions and 11 deletions

View File

@@ -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

View File

@@ -15,6 +15,8 @@
#include <ft2build.h>
#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");

View File

@@ -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};

View File

@@ -0,0 +1,10 @@
#ifndef KANDINSKY_FONT_UNICODE_H
#define KANDINSKY_FONT_UNICODE_H
#include <stddef.h>
#define NUMBER_OF_SYMBOL 41
extern wchar_t codePointForSymbol[NUMBER_OF_SYMBOL];
#endif

View File

@@ -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;