From 57e8b41330853e1346b1fad23b17d616d5c45490 Mon Sep 17 00:00:00 2001 From: "A.Olokhtonov" Date: Sat, 14 Aug 2021 19:29:37 +0300 Subject: [PATCH] Read 'post' table to determine if font is monospaced. Fix string width computation. Fix overflow glyph.baseline --- main.c | 24 +++++++++++------------- ttf2.c | 29 +++++++++++++++++++++++------ 2 files changed, 34 insertions(+), 19 deletions(-) diff --git a/main.c b/main.c index 71db615..05b692d 100644 --- a/main.c +++ b/main.c @@ -98,6 +98,7 @@ struct font_directory { u32 glyf_offset; u32 hmtx_offset; u32 maxp_offset; + u32 post_offset; u32 cvt_offset; u32 cvt_size; @@ -191,6 +192,7 @@ struct ttf_font { s16 *cvt; int cmap_format; + int is_monospace; struct font_directory dir; struct ttf_function *functions; @@ -646,11 +648,7 @@ render_utf_string(struct ttf_font font, int px_size, u32 *pixels, u32 width, wch render_glyph(g, px_size, &lines, scale, pixels, width, offset_x + g.lsb * scale, offset_y); -#if 1 - offset_x += round_f32(scale * g.advance); -#else - offset_x += px_size * 2; -#endif + offset_x += ceil_f32(scale * g.advance); free(lines.data); } else { @@ -732,23 +730,23 @@ main(int argc, char **argv) //render_utf_string(font, 18, pixels, width, L"The quick brown fox jumps over the lazy dog", 100, 150); //render_utf_string(font, 12, pixels, width, L"This text is seriously small", 100, at); at += 12; //render_utf_string(font, 13, pixels, width, L"This text is seriously small", 100, at); at += 13; - //render_utf_string(font, 14, pixels, width, L"This text is seriously small", 100, at); at += 14; + render_utf_string(font, 14, pixels, width, L"This text is seriously small", 100, at); at += 14; //render_utf_string(font, 15, pixels, width, L"This text is seriously small", 100, at); at += 14; - render_utf_string(font, 20, pixels, width, L"result = XCreateImage(display, visinfo.visual, visinfo.depth, ZPixmap, 0, hc_vram, width, height, pixel_bits, 0);", 100, at); at += 20; - render_utf_string(font, 24, pixels, width, L"The quick brown fox jumps over the lazy dog", 100, at); at += 24; + render_utf_string(font, 26, pixels, width, L"memset(pixels, 0x00, width * height * 4);", 10, at); at += 24; + render_utf_string(font, 24, pixels, width, L"The quick brown fox jumps over the lazy dog", 10, at); at += 24; - wchar_t *string1 = L"iiiiiiiiil"; + wchar_t *string1 = L"iiiiiiiiiiiiiiiiiii"; wchar_t *string2 = L"something-some"; wchar_t *string3 = L"MORE MORE"; int w1 = get_string_width(&font, 32, string1, wcslen(string1)); int w2 = get_string_width(&font, 32, string2, wcslen(string2)); - render_utf_string(font, 32, pixels, width, string1, 100, at); - render_utf_string(font, 32, pixels, width, string2, 100 + w1, at); - render_utf_string(font, 32, pixels, width, string3, 100 + w1 + w2, at); + render_utf_string(font, 32, pixels, width, string1, 10, at); + render_utf_string(font, 32, pixels, width, string2, 10 + w1, at); + render_utf_string(font, 32, pixels, width, string3, 10 + w1 + w2, at); at += 80; - render_utf_string(font, 80, pixels, width, L"~!@#$%^&*()_+;:,./\\|", 100, at); + render_utf_string(font, 80, pixels, width, L"~!@#$%^&*()_+;:,./\\||||", 10, at); XPutImage(display, window, default_gc, xwindow_buffer, 0, 0, 0, 0, width, height); diff --git a/ttf2.c b/ttf2.c index 3d674d6..615ee26 100644 --- a/ttf2.c +++ b/ttf2.c @@ -1453,9 +1453,11 @@ get_hmtx(struct ttf_font *font, u32 glyph_index, struct glyph *dest) { struct font_buffer font_file = font->file; - // TODO: monospaced font only has one record - - font_file.offset = font->dir.hmtx_offset + glyph_index * 4; + if (font->is_monospace) { + font_file.offset = font->dir.hmtx_offset; + } else { + font_file.offset = font->dir.hmtx_offset + glyph_index * 4; + } dest->advance = read_be16(&font_file); dest->lsb = read_be16s(&font_file); @@ -1472,11 +1474,9 @@ get_string_width(struct ttf_font *font, int px_size, wchar_t *string, int length u16 codepoint = string[i]; u32 glyph_index = get_glyph_index(font, codepoint); get_hmtx(font, glyph_index, &g); - result += g.advance; + result += ceil_f32(scale * g.advance); // NOTE(aolo2): ceil each time because that's what the rasterizing code does } - result = ceil_f32(result * scale); - return(result); } @@ -1588,6 +1588,11 @@ read_font_directory(struct font_buffer *file) result.hhea_offset = offset; break; } + + case 0x706f7374: { + /* post */ + result.post_offset = offset; + } } } @@ -1652,6 +1657,17 @@ read_cvt(struct ttf_font *font, struct font_buffer *font_file, struct font_direc iterate_instructions(font, font_file, font_dir.prep_offset, font_dir.prep_size, state); } +static void +read_post(struct font_directory font_dir, struct ttf_font *font) +{ + if (font_dir.post_offset) { + font->is_monospace = be32(font->file.data + font_dir.post_offset + 12); + } else { + printf("Warning: font file doesn't have a 'post' table. Assuming font is proportional\n"); + font->is_monospace = 0; + } +} + static struct ttf_font parse_ttf_file(char *filename, char *fontname) { @@ -1667,6 +1683,7 @@ parse_ttf_file(char *filename, char *fontname) result.cvt = (s16 *) (font_file.data + font_dir.cvt_offset); read_head(font_dir, &result); + read_post(font_dir, &result); read_maxp(font_dir, &result); read_cmap(font_dir, &result); read_hhea(font_dir, &result);