mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-29 19:49:58 +02:00
[kandinsky] Rasterize some non-ASCII glyphs
Change-Id: I7e8ac19de72a35621a7101b3bf4686e5e7b6763e
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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");
|
||||
|
||||
6
kandinsky/fonts/unicode_for_symbol.c
Normal file
6
kandinsky/fonts/unicode_for_symbol.c
Normal 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};
|
||||
10
kandinsky/fonts/unicode_for_symbol.h
Normal file
10
kandinsky/fonts/unicode_for_symbol.h
Normal 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
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user