Browse Source

Improvements to SDF impl., and support in terminal

K. Lange 4 years ago
parent
commit
db4337f17b

+ 9 - 1
apps/sh.c

@@ -792,7 +792,7 @@ void sort_commands() {
 }
 
 void show_version(void) {
-	printf("esh 0.11.0 - experimental shell\n");
+	printf("esh 1.3.0\n");
 }
 
 void show_usage(int argc, char * argv[]) {
@@ -944,6 +944,14 @@ uint32_t shell_cmd_set(int argc, char * argv[]) {
 		printf("\033[1555;%sz", argv[2]);
 		fflush(stdout);
 		return 0;
+	} else if (!strcmp(argv[1], "gamma")) {
+		if (argc < 3) {
+			fprintf(stderr, "%s %s [floating point gamma, 1.7 = normal]\n", argv[0], argv[1]);
+			return 1;
+		}
+		printf("\033[1556;%sz", argv[2]);
+		fflush(stdout);
+		return 0;
 	} else if (!strcmp(argv[1], "size")) {
 		if (argc < 4) {
 			fprintf(stderr, "%s %s [width] [height]\n", argv[0], argv[1]);

+ 1 - 0
apps/terminal-vga.c

@@ -741,6 +741,7 @@ term_callbacks_t term_callbacks = {
 	unsupported_int,
 	unsupported_int,
 	term_set_csr_show,
+	set_term_font_size,
 };
 
 void reinit(int send_sig) {

+ 38 - 185
apps/terminal.c

@@ -44,6 +44,7 @@
 #include <toaru/spinlock.h>
 #include <toaru/list.h>
 #include <toaru/menu.h>
+#include <toaru/sdf.h>
 
 #include "terminal-palette.h"
 #include "terminal-font.h"
@@ -57,9 +58,10 @@ static FILE * terminal;
 
 int      scale_fonts    = 0;    /* Whether fonts should be scaled */
 float    font_scaling   = 1.0;  /* How much they should be scaled by */
+float    font_gamma     = 1.7;  /* Gamma to use for SDF library */
 uint16_t term_width     = 0;    /* Width of the terminal (in cells) */
 uint16_t term_height    = 0;    /* Height of the terminal (in cells) */
-uint16_t font_size      = 13;   /* Font size according to Freetype */
+uint16_t font_size      = 13;   /* Font size according to SDF library */
 uint16_t char_width     = 9;    /* Width of a cell in pixels */
 uint16_t char_height    = 20;   /* Height of a cell in pixels */
 uint16_t char_offset    = 0;    /* Offset of the font within the cell */
@@ -72,7 +74,7 @@ uint8_t  cursor_on      = 1;    /* Whether or not the cursor should be rendered
 uint8_t  _fullscreen    = 0;    /* Whether or not we are running in fullscreen mode (GUI only) */
 uint8_t  _no_frame      = 0;    /* Whether to disable decorations or not */
 uint8_t  _login_shell   = 0;    /* Whether we're going to display a login shell or not */
-uint8_t  _use_freetype  = 0;    /* Whether we should use freetype or not XXX seriously, how about some flags */
+uint8_t  _use_sdf       = 1;    /* Whether or not to use SDF text rendering */
 uint8_t  _force_kernel  = 0;
 uint8_t  _hold_out      = 0;    /* state indicator on last cell ignore \n */
 uint8_t  _free_size     = 1;    /* Disable rounding when resized */
@@ -136,6 +138,11 @@ static void set_term_font_size(float s) {
 	reinit(1);
 }
 
+static void set_term_font_gamma(float s) {
+	font_gamma = s;
+	reinit(1);
+}
+
 /* Returns the lower of two shorts */
 int32_t min(int32_t a, int32_t b) {
 	return (a < b) ? a : b;
@@ -185,35 +192,6 @@ static inline void term_set_point(uint16_t x, uint16_t y, uint32_t color ) {
 	}
 }
 
-/* FreeType text rendering */
-#if 0
-FT_Library   library;
-FT_Face      face;
-FT_Face      face_bold;
-FT_Face      face_italic;
-FT_Face      face_bold_italic;
-FT_Face      face_extra;
-FT_Face      face_symbol;
-FT_Face      face_variable;
-
-FT_Face * fallbacks[] = {&face_variable, &face_symbol, &face_extra, &face_symbol, NULL};
-
-
-void drawChar(FT_Bitmap * bitmap, int x, int y, uint32_t fg, uint32_t bg) {
-	int i, j, p, q;
-	int x_max = x + bitmap->width;
-	int y_max = y + bitmap->rows;
-	for (j = y, q = 0; j < y_max; j++, q++) {
-		for ( i = x, p = 0; i < x_max; i++, p++) {
-			uint32_t a = _ALP(fg);
-			a = (a * bitmap->buffer[q * bitmap->width + p]) / 255;
-			uint32_t tmp = rgba(_RED(fg),_GRE(fg),_BLU(fg),a);
-			term_set_point(i,j, alpha_blend_rgba(premultiply(bg), premultiply(tmp)));
-		}
-	}
-}
-#endif
-
 void draw_semi_block(int c, int x, int y, uint32_t fg, uint32_t bg) {
 	int height;
 	bg = premultiply(bg);
@@ -432,87 +410,31 @@ term_write_char(
 	} else {
 		_bg = bg;
 	}
-	if (_use_freetype) {
-#if 0
-		if (val == 0xFFFF) { return; } /* Unicode, do not redraw here */
+	if (val >= 0x2580 && val <= 0x2588) {
 		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));
 			}
 		}
-		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));
-				}
+		draw_semi_block(val, x, y, _fg, _bg);
+		goto _extra_stuff;
+	}
+	if (val > 128) {
+		val = ununicode(val);
+	}
+	if (_use_sdf) {
+		char tmp[2] = {val,0};
+		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));
 			}
 		}
-		if (val < 32 || val == ' ') {
-			goto _extra_stuff;
-		}
-		if (val >= 0x2580 && val <= 0x2588) {
-			draw_semi_block(val, x, y, _fg, _bg);
-			goto _extra_stuff;
-		}
-
-		int pen_x = x;
-		int pen_y = y + char_offset;
-		int error;
-
-		FT_Face * _font = NULL;
-		FT_GlyphSlot slot;
-		FT_UInt      glyph_index;
-
-		if (flags & ANSI_ALTFONT) {
-			_font = &face_extra;
-		} else if (flags & ANSI_BOLD && flags & ANSI_ITALIC) {
-			_font = &face_bold_italic;
-		} else if (flags & ANSI_ITALIC) {
-			_font = &face_italic;
-		} else if (flags & ANSI_BOLD) {
-			_font = &face_bold;
+		if (_no_frame) {
+			draw_sdf_string_gamma(ctx, x, y, tmp, font_size, _fg, SDF_FONT_MONO, font_gamma);
 		} else {
-			_font = &face;
-		}
-		glyph_index = FT_Get_Char_Index(*_font, val);
-
-		if (!glyph_index) {
-			int i = 0;
-			while (!glyph_index && fallbacks[i]) {
-				_font = fallbacks[i];
-				glyph_index = FT_Get_Char_Index(*_font, val);
-				i++;
-			}
-		}
-		error = FT_Load_Glyph(*_font, glyph_index,  FT_LOAD_DEFAULT);
-		if (error) {
-			fprintf(terminal, "Error loading glyph: %d\n", val);
-			fprintf(stderr, "Error loading glyph: %d\n", val);
-		};
-		slot = (*_font)->glyph;
-		if (slot->format == FT_GLYPH_FORMAT_OUTLINE) {
-			error = FT_Render_Glyph((*_font)->glyph, FT_RENDER_MODE_NORMAL);
-			if (error) {
-				fprintf(stderr, "Error rendering glyph: %d\n", val);
-				goto _extra_stuff;
-			}
+			draw_sdf_string_gamma(ctx, x+decor_left_width, y+decor_top_height, tmp, font_size, _fg, SDF_FONT_MONO, font_gamma);
 		}
-		drawChar(&slot->bitmap, pen_x + slot->bitmap_left, pen_y - slot->bitmap_top, _fg, _bg);
-
-#endif
 	} else {
-		if (val >= 0x2580 && val <= 0x2588) {
-			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));
-				}
-			}
-			draw_semi_block(val, x, y, _fg, _bg);
-			goto _extra_stuff;
-		}
-		if (val > 128) {
-			val = ununicode(val);
-		}
 #ifdef number_font
 		uint8_t * c = number_font[val];
 		for (uint8_t i = 0; i < char_height; ++i) {
@@ -538,27 +460,14 @@ term_write_char(
 #endif
 	}
 _extra_stuff:
-	if (_use_freetype) {
-		if (flags & ANSI_UNDERLINE) {
-			for (uint8_t i = 0; i < char_width; ++i) {
-				term_set_point(x + i, y + char_offset + 2, _fg);
-			}
+	if (flags & ANSI_UNDERLINE) {
+		for (uint8_t i = 0; i < char_width; ++i) {
+			term_set_point(x + i, y + char_height - 1, _fg);
 		}
-		if (flags & ANSI_CROSS) {
-			for (uint8_t i = 0; i < char_width; ++i) {
-				term_set_point(x + i, y + char_offset - 5, _fg);
-			}
-		}
-	} else {
-		if (flags & ANSI_UNDERLINE) {
-			for (uint8_t i = 0; i < char_width; ++i) {
-				term_set_point(x + i, y + char_height - 1, _fg);
-			}
-		}
-		if (flags & ANSI_CROSS) {
-			for (uint8_t i = 0; i < char_width; ++i) {
-				term_set_point(x + i, y + char_height - 7, _fg);
-			}
+	}
+	if (flags & ANSI_CROSS) {
+		for (uint8_t i = 0; i < char_width; ++i) {
+			term_set_point(x + i, y + char_height - 7, _fg);
 		}
 	}
 	if (flags & ANSI_BORDER) {
@@ -1305,10 +1214,8 @@ void usage(char * argv[]) {
 			"usage: %s [-b] [-F] [-h]\n"
 			"\n"
 			" -F --fullscreen \033[3mRun in fullscreen (background) mode.\033[0m\n"
-#if 0
 			" -b --bitmap     \033[3mUse the integrated bitmap font.\033[0m\n"
-			" -s --scale      \033[3mScale the font in FreeType mode by a given amount.\033[0m\n"
-#endif
+			" -s --scale      \033[3mScale the font in SDF mode by a given amount.\033[0m\n"
 			" -h --help       \033[3mShow this help message.\033[0m\n"
 			" -x --grid       \033[3mMake resizes round to nearest match for character cell size.\033[0m\n"
 			" -n --no-frame   \033[3mDisable decorations.\033[0m\n"
@@ -1335,35 +1242,19 @@ term_callbacks_t term_callbacks = {
 	term_get_cell_width,
 	term_get_cell_height,
 	term_set_csr_show,
+	set_term_font_gamma,
 };
 
 void reinit(int send_sig) {
-	if (_use_freetype) {
-#if 0
-		/* Reset font sizes */
-
-		font_size   = 13;
-		char_height = 17;
-		char_width  = 8;
-		char_offset = 13;
-
+	if (_use_sdf) {
+		char_width = 10;
+		char_height = 18;
+		font_size = 18;
 		if (scale_fonts) {
-			/* Recalculate scaling */
 			font_size   *= font_scaling;
 			char_height *= font_scaling;
 			char_width  *= font_scaling;
-			char_offset *= font_scaling;
 		}
-
-		/* Initialize the freetype font pixel sizes */
-		FT_Set_Pixel_Sizes(face, font_size, font_size);
-		FT_Set_Pixel_Sizes(face_bold, font_size, font_size);
-		FT_Set_Pixel_Sizes(face_italic, font_size, font_size);
-		FT_Set_Pixel_Sizes(face_bold_italic, font_size, font_size);
-		FT_Set_Pixel_Sizes(face_extra, font_size, font_size);
-		FT_Set_Pixel_Sizes(face_symbol, font_size, font_size);
-		FT_Set_Pixel_Sizes(face_variable, font_size, font_size);
-#endif
 	}
 
 	int old_width  = term_width;
@@ -1605,7 +1496,6 @@ void maybe_flip_cursor(void) {
 
 int main(int argc, char ** argv) {
 
-	_use_freetype = 0;
 	_login_shell = 0;
 	_fullscreen = 0;
 	_no_frame = 0;
@@ -1615,10 +1505,8 @@ int main(int argc, char ** argv) {
 
 	static struct option long_opts[] = {
 		{"fullscreen", no_argument,       0, 'F'},
-#if 0
 		{"bitmap",     no_argument,       0, 'b'},
 		{"scale",      required_argument, 0, 's'},
-#endif
 		{"login",      no_argument,       0, 'l'},
 		{"help",       no_argument,       0, 'h'},
 		{"kernel",     no_argument,       0, 'k'},
@@ -1654,18 +1542,16 @@ int main(int argc, char ** argv) {
 				_no_frame = 1;
 				break;
 			case 'b':
-				_use_freetype = 0;
+				_use_sdf = 0;
 				break;
 			case 'h':
 				usage(argv);
 				return 0;
 				break;
-#if 0
 			case 's':
 				scale_fonts = 1;
 				font_scaling = atof(optarg);
 				break;
-#endif
 			case 'g':
 				{
 					char * c = strstr(optarg, "x");
@@ -1717,39 +1603,6 @@ int main(int argc, char ** argv) {
 
 	yutani_window_move(yctx, window, yctx->display_width / 2 - window->width / 2, yctx->display_height / 2 - window->height / 2);
 
-	if (_use_freetype) {
-#if 0
-		int error;
-		error = FT_Init_FreeType(&library);
-		if (error) return 1;
-
-		char * font = NULL;
-		size_t s;
-
-		/* XXX Use shmemfont library */
-
-		font = loadMemFont("/usr/share/fonts/DejaVuSansMono.ttf",  "monospace", &s);
-		error = FT_New_Memory_Face(library, font, s, 0, &face); if (error) return 1;
-
-		font = loadMemFont("/usr/share/fonts/DejaVuSansMono-Bold.ttf",  "monospace.bold", &s);
-		error = FT_New_Memory_Face(library, font, s, 0, &face_bold); if (error) return 1;
-
-		font = loadMemFont("/usr/share/fonts/DejaVuSansMono-Oblique.ttf",  "monospace.italic", &s);
-		error = FT_New_Memory_Face(library, font, s, 0, &face_italic); if (error) return 1;
-
-		font = loadMemFont("/usr/share/fonts/DejaVuSansMono-BoldOblique.ttf",  "monospace.bolditalic", &s);
-		error = FT_New_Memory_Face(library, font, s, 0, &face_bold_italic); if (error) return 1;
-
-		error = FT_New_Face(library, "/usr/share/fonts/VLGothic.ttf", 0, &face_extra);
-
-		error = FT_New_Face(library, "/usr/share/fonts/Symbola.ttf", 0, &face_symbol);
-
-		font = loadMemFont("/usr/share/fonts/DejaVuSans.ttf",  "sans-serif", &s);
-		error = FT_New_Memory_Face(library, font, s, 0, &face_variable); if (error) return 1;
-
-#endif
-	}
-
 	syscall_openpty(&fd_master, &fd_slave, NULL, NULL, NULL);
 
 	terminal = fdopen(fd_slave, "w");

+ 2 - 0
base/usr/include/toaru/sdf.h

@@ -3,7 +3,9 @@
 enum sdf_font {
     SDF_FONT_THIN,
     SDF_FONT_BOLD,
+    SDF_FONT_MONO,
 };
 
 extern int draw_sdf_string(gfx_context_t * ctx, int32_t x, int32_t y, const char * str, int size, uint32_t color, int font);
 extern int draw_sdf_string_width(const char * str, int size, int font);
+extern int draw_sdf_string_gamma(gfx_context_t * ctx, int32_t x, int32_t y, const char * str, int size, uint32_t color, int font, double _gamma);

+ 1 - 0
base/usr/include/toaru/termemu.h

@@ -33,6 +33,7 @@ typedef struct {
 	int  (*get_cell_width)(void);
 	int  (*get_cell_height)(void);
 	void (*set_csr_on)(int);
+	void (*set_font_gamma)(float);
 } term_callbacks_t;
 
 typedef struct {

BIN
base/usr/share/sdf_bold.bmp


BIN
base/usr/share/sdf_mono.bmp


BIN
base/usr/share/sdf_thin.bmp


+ 29 - 132
lib/sdf.c

@@ -13,128 +13,28 @@
 
 #define BASE_WIDTH 50
 #define BASE_HEIGHT 50
-#define GAMMA 1.7
 
 static sprite_t _font_data_thin;
 static sprite_t _font_data_bold;
+static sprite_t _font_data_mono;
 
 static hashmap_t * _font_cache;
 
 static volatile int _sdf_lock = 0;
+static double gamma = 1.7;
 
 struct CharData{
 	char code;
 	size_t width_bold;
 	size_t width_thin;
-} _char_data[] = {
-	{'!',  20, 20},
-	{'"',  35, 20},
-	{'#',  40, 20},
-	{'$',  35, 20},
-	{'%',  35, 20},
-	{'&',  35, 20},
-	{'\'', 35, 20},
-	{'(',  22, 20},
-	{')',  22, 20},
-	{'*',  35, 20},
-	{'+',  35, 20},
-	{',',  35, 20},
-	{'-',  30, 20},
-	{'.',  18, 20},
-	{'/',  24, 20},
-	{'0',  32, 20},
-	{'1',  32, 20},
-	{'2',  32, 20},
-	{'3',  32, 20},
-	{'4',  32, 20},
-	{'5',  32, 20},
-	{'6',  32, 20},
-	{'7',  32, 20},
-	{'8',  32, 20},
-	{'9',  32, 20},
-	{':',  22, 20},
-	{';',  22, 20},
-	{'<',  35, 20},
-	{'=',  35, 20},
-	{'>',  35, 20},
-	{'?',  35, 20},
-	{'@',  50, 20},
-	{'A',  35, 20},
-	{'B',  35, 20},
-	{'C',  34, 20},
-	{'D',  36, 20},
-	{'E',  34, 20},
-	{'F',  34, 20},
-	{'G',  35, 20},
-	{'H',  35, 20},
-	{'I',  22, 20},
-	{'J',  24, 20},
-	{'K',  35, 20},
-	{'L',  32, 20},
-	{'M',  45, 20},
-	{'N',  36, 20},
-	{'O',  38, 20},
-	{'P',  35, 20},
-	{'Q',  38, 20},
-	{'R',  36, 20},
-	{'S',  35, 20},
-	{'T',  35, 20},
-	{'U',  35, 20},
-	{'V',  37, 20},
-	{'W',  50, 20},
-	{'X',  35, 20},
-	{'Y',  32, 20},
-	{'Z',  35, 20},
-	{'[',  35, 20},
-	{'\\', 35, 20},
-	{']',  35, 20},
-	{'^',  35, 20},
-	{'_',  35, 20},
-	{'`',  35, 20},
-	{'a',  32, 20},
-	{'b',  32, 20},
-	{'c',  29, 20},
-	{'d',  32, 20},
-	{'e',  32, 20},
-	{'f',  25, 20},
-	{'g',  32, 20},
-	{'h',  32, 20},
-	{'i',  16, 20},
-	{'j',  16, 20},
-	{'k',  30, 20},
-	{'l',  16, 20},
-	{'m',  47, 20},
-	{'n',  33, 20},
-	{'o',  32, 20},
-	{'p',  32, 20},
-	{'q',  32, 20},
-	{'r',  25, 20},
-	{'s',  31, 20},
-	{'t',  26, 20},
-	{'u',  32, 20},
-	{'v',  32, 20},
-	{'w',  42, 20},
-	{'x',  32, 20},
-	{'y',  32, 20},
-	{'z',  32, 20},
-	{'{',  32, 20},
-	{'|',  32, 20},
-	{'}',  32, 20},
-	{'~',  32, 20},
-	{' ',  20, 20},
-	{0,0,0},
-};
+	size_t width_mono;
+} _char_data[256];
 
 static int loaded = 0;
 
 static int offset(int ch) {
 	/* Calculate offset into table above */
-	if (ch == ' ') {
-		return '~' + 1 - '!';
-	} else {
-		return ch - '!';
-	}
-
+	return ch;
 }
 
 __attribute__((constructor))
@@ -143,9 +43,16 @@ static void _init_sdf(void) {
 	_font_cache = hashmap_create_int(10);
 	load_sprite(&_font_data_thin, "/usr/share/sdf_thin.bmp");
 	load_sprite(&_font_data_bold, "/usr/share/sdf_bold.bmp");
+	load_sprite(&_font_data_mono, "/usr/share/sdf_mono.bmp");
 	FILE * fi = fopen("/etc/sdf.conf", "r");
 	char tmp[1024];
 	char * s = tmp;
+	for (int i = 0; i < 256; ++i) {
+		_char_data[i].code = i;
+		_char_data[i].width_bold = 25;
+		_char_data[i].width_thin = 20;
+		_char_data[i].width_mono = 25;
+	}
 	while ((s = fgets(tmp, 1024, fi))) {
 		if (strlen(s) < 1) continue;
 		int i = offset(*s);
@@ -157,6 +64,8 @@ static void _init_sdf(void) {
 			_char_data[i].width_bold = o;
 		} else if (t == 't') {
 			_char_data[i].width_thin = o;
+		} else if (t == 'm') {
+			_char_data[i].width_mono = o;
 		}
 	}
 	fclose(fi);
@@ -167,6 +76,8 @@ static sprite_t * _select_font(int font) {
 	switch (font) {
 		case SDF_FONT_BOLD:
 			return &_font_data_bold;
+		case SDF_FONT_MONO:
+			return &_font_data_mono;
 		case SDF_FONT_THIN:
 		default:
 			return &_font_data_thin;
@@ -177,6 +88,8 @@ static int _select_width(char ch, int font) {
 	switch (font) {
 		case SDF_FONT_BOLD:
 			return _char_data[(int)ch].width_bold;
+		case SDF_FONT_MONO:
+			return _char_data[(int)ch].width_mono;
 		case SDF_FONT_THIN:
 		default:
 			return _char_data[(int)ch].width_thin;
@@ -184,17 +97,7 @@ static int _select_width(char ch, int font) {
 }
 
 static int draw_sdf_character(gfx_context_t * ctx, int32_t x, int32_t y, int ch, int size, uint32_t color, sprite_t * tmp, int font, sprite_t * _font_data) {
-	if (ch != ' ' && (ch < '!' || ch > '~')) {
-		/* TODO: Draw missing symbol? */
-		return 0;
-	}
-
-	/* Calculate offset into table above */
-	if (ch == ' ') {
-		ch = '~' + 1 - '!';
-	} else {
-		ch -= '!';
-	}
+	if (ch < 0 || ch > 255) return 0;
 
 	double scale = (double)size / 50.0;
 	int width = _select_width(ch, font) * scale;
@@ -212,8 +115,8 @@ static int draw_sdf_character(gfx_context_t * ctx, int32_t x, int32_t y, int ch,
 			if (fy+j > tmp->height) continue;
 			uint32_t c = SPRITE((tmp), fx+i, fy+j);
 			double dist = (double)_RED(c) / 255.0;
-			double edge0 = 0.75 - GAMMA * 1.4142 / (double)size;
-			double edge1 = 0.75 + GAMMA * 1.4142 / (double)size;
+			double edge0 = 0.75 - gamma * 1.4142 / (double)size;
+			double edge1 = 0.75 + gamma * 1.4142 / (double)size;
 			double a = (dist - edge0) / (edge1 - edge0);
 			if (a < 0.0) a = 0.0;
 			if (a > 1.0) a = 1.0;
@@ -226,7 +129,7 @@ static int draw_sdf_character(gfx_context_t * ctx, int32_t x, int32_t y, int ch,
 
 }
 
-int draw_sdf_string(gfx_context_t * ctx, int32_t x, int32_t y, const char * str, int size, uint32_t color, int font) {
+int draw_sdf_string_gamma(gfx_context_t * ctx, int32_t x, int32_t y, const char * str, int size, uint32_t color, int font, double _gamma) {
 
 	sprite_t * _font_data = _select_font(font);
 
@@ -246,32 +149,26 @@ int draw_sdf_string(gfx_context_t * ctx, int32_t x, int32_t y, const char * str,
 	} else {
 		tmp = hashmap_get(_font_cache, (void *)(scale_height | (font << 16)));
 	}
-	spin_unlock(&_sdf_lock);
 
 	int32_t out_width = 0;
+	gamma = _gamma;
 	while (*str) {
-		int w = draw_sdf_character(ctx,x,y,*str,size,color,tmp,font,_font_data);
+		int w = draw_sdf_character(ctx,x,y,*((uint8_t *)str),size,color,tmp,font,_font_data);
 		out_width += w;
 		x += w;
 		str++;
 	}
+	spin_unlock(&_sdf_lock);
 
 	return out_width;
 }
 
-static int char_width(char ch, int font) {
-	if (ch != ' ' && (ch < '!' || ch > '~')) {
-		/* TODO: Draw missing symbol? */
-		return 0;
-	}
 
-	/* Calculate offset into table above */
-	if (ch == ' ') {
-		ch = '~' + 1 - '!';
-	} else {
-		ch -= '!';
-	}
+int draw_sdf_string(gfx_context_t * ctx, int32_t x, int32_t y, const char * str, int size, uint32_t color, int font) {
+	return draw_sdf_string_gamma(ctx,x,y,str,size,color,font,1.7);
+}
 
+static int char_width(char ch, int font) {
 	return _select_width(ch, font);
 }
 

+ 5 - 2
lib/termemu.c

@@ -180,13 +180,16 @@ static void _ansi_put(term_state_t * s, char c) {
 									case 1:
 										callbacks->redraw_cursor();
 										break;
-#if 0
 									case 1555:
 										if (argc > 1) {
 											callbacks->set_font_size(atof(argv[1]));
 										}
 										break;
-#endif
+									case 1556:
+										if (argc > 1) {
+											callbacks->set_font_gamma(atof(argv[1]));
+										}
+										break;
 									default:
 										break;
 								}