Browse Source

Fixup terminal freetype backend

K. Lange 3 years ago
parent
commit
b929f78baf
2 changed files with 62 additions and 13 deletions
  1. 8 10
      apps/terminal.c
  2. 54 3
      ext/ext_freetype_fonts.c

+ 8 - 10
apps/terminal.c

@@ -115,7 +115,7 @@ static bool _free_size     = 1;    /* Disable rounding when resized */
 /** Freetype extension renderer functions */
 static void (*freetype_set_font_face)(int face) = NULL;
 static void (*freetype_set_font_size)(int size) = NULL;
-static void (*freetype_draw_string)(gfx_context_t * ctx, int x, int y, uint32_t fg, char * string) = NULL;
+static void (*freetype_draw_char)(gfx_context_t * ctx, int x, int y, uint32_t fg, uint32_t codepoint) = NULL;
 
 static list_t * images_list = NULL;
 
@@ -779,13 +779,13 @@ static void term_write_char(uint32_t val, uint16_t x, uint16_t y, uint32_t fg, u
 		if (val == 0xFFFF) { return; } /* Unicode, do not redraw here */
 		for (uint8_t i = 0; i < char_height; ++i) {
 			for (uint8_t j = 0; j < char_width; ++j) {
-				term_set_point(x+j,y+i,premultiply(_bg));
+				term_set_point(x+j,y+i,_bg);
 			}
 		}
 		if (flags & ANSI_WIDE) {
 			for (uint8_t i = 0; i < char_height; ++i) {
 				for (uint8_t j = char_width; j < 2 * char_width; ++j) {
-					term_set_point(x+j,y+i,premultiply(_bg));
+					term_set_point(x+j,y+i,_bg);
 				}
 			}
 		}
@@ -807,12 +807,10 @@ static void term_write_char(uint32_t val, uint16_t x, uint16_t y, uint32_t fg, u
 		}
 		freetype_set_font_face(_font);
 		freetype_set_font_size(font_size);
-		char tmp[8];
-		to_eight(val, tmp);
 		if (_no_frame) {
-			freetype_draw_string(ctx, x, y + char_offset, _fg, tmp);
+			freetype_draw_char(ctx, x, y + char_offset, _fg, val);
 		} else {
-			freetype_draw_string(ctx, x + decor_left_width, y + char_offset + decor_top_height + menu_bar_height, _fg, tmp);
+			freetype_draw_char(ctx, x + decor_left_width, y + char_offset + decor_top_height + menu_bar_height, _fg, val);
 		}
 	} else {
 		/* Convert other unicode characters. */
@@ -2235,9 +2233,9 @@ int main(int argc, char ** argv) {
 		void * freetype = dlopen("libtoaru_ext_freetype_fonts.so", 0);
 		if (freetype) {
 			_have_freetype = 1;
-			freetype_set_font_face = dlsym(freetype, "set_font_face");
-			freetype_set_font_size = dlsym(freetype, "set_font_size");
-			freetype_draw_string   = dlsym(freetype, "draw_string");
+			freetype_set_font_face = dlsym(freetype, "freetype_set_font_face");
+			freetype_set_font_size = dlsym(freetype, "freetype_set_font_size");
+			freetype_draw_char   = dlsym(freetype, "freetype_draw_char");
 		}
 	}
 

+ 54 - 3
ext/ext_freetype_fonts.c

@@ -81,11 +81,15 @@ static void _load_fonts() {
 	_load_font_f(FONT_SYMBOLA, "/usr/share/fonts/Symbola.ttf");
 }
 
-void set_font_face(int font) {
+void freetype_set_font_face(int font) {
 	selected_face = font;
 }
 
-void set_font_size(int size) {
+static int _old_size = -1;
+
+void freetype_set_font_size(int size) {
+	if (size == _old_size) return;
+	_old_size = size;
 	for (int i = 0; i < FONTS_TOTAL; ++i) {
 		FT_Set_Pixel_Sizes(faces[i], size, size);
 	}
@@ -107,7 +111,54 @@ static void draw_char(FT_Bitmap * bitmap, int x, int y, uint32_t fg, gfx_context
 	}
 }
 
-void draw_string(gfx_context_t * ctx, int x, int y, uint32_t fg, char * string) {
+void freetype_draw_char(gfx_context_t * ctx, int x, int y, uint32_t fg, uint32_t o) {
+	int pen_x = x, pen_y = y;
+	int error;
+	slot = faces[selected_face]->glyph;
+	FT_UInt glyph_index;
+
+	glyph_index = FT_Get_Char_Index( faces[selected_face], o);
+	if (glyph_index) {
+		error = FT_Load_Glyph(faces[selected_face], glyph_index, FT_LOAD_DEFAULT);
+		if (error) {
+			fprintf(stderr, "Error loading glyph for '%lu'\n", o);
+			return;
+		}
+		slot = (faces[selected_face])->glyph;
+		if (slot->format == FT_GLYPH_FORMAT_OUTLINE) {
+			error = FT_Render_Glyph((faces[selected_face])->glyph, FT_RENDER_MODE_NORMAL);
+			if (error) {
+				fprintf(stderr, "Error rendering glyph for '%lu'\n", o);
+				return;
+			}
+		}
+	} else {
+		int i = 0;
+		while (!glyph_index && fallbacks[i] != -1) {
+			int fallback = fallbacks[i++];
+			glyph_index = FT_Get_Char_Index( faces[fallback], o);
+			error = FT_Load_Glyph(faces[fallback], glyph_index, FT_LOAD_DEFAULT);
+			if (error) {
+				fprintf(stderr, "Error loading glyph for '%lu'\n", o);
+				return;
+			}
+			slot = (faces[fallback])->glyph;
+			if (slot->format == FT_GLYPH_FORMAT_OUTLINE) {
+				error = FT_Render_Glyph((faces[fallback])->glyph, FT_RENDER_MODE_NORMAL);
+				if (error) {
+					fprintf(stderr, "Error rendering glyph for '%lu'\n", o);
+					return;
+				}
+			}
+		}
+
+	}
+
+	draw_char(&slot->bitmap, pen_x + slot->bitmap_left, pen_y - slot->bitmap_top, fg, ctx);
+
+}
+
+void freetype_draw_string(gfx_context_t * ctx, int x, int y, uint32_t fg, char * string) {
 	slot = faces[selected_face]->glyph;
 	int pen_x = x, pen_y = y;
 	int error;