From 4cd39aa6c528dc040c29385906ebf097843a3f14 Mon Sep 17 00:00:00 2001 From: "A.Olokhtonov" Date: Thu, 21 Jul 2022 23:31:29 +0300 Subject: [PATCH] Fix so that it compiles and runs --- main.c | 59 ++---------------------------- ttf.h | 53 +++++++++++++++++++++++++++ ttf-parse.c => ttf_parse.c | 22 +++++------ ttf-rasterize.c => ttf_rasterize.c | 49 +++++++++++++++++++------ 4 files changed, 103 insertions(+), 80 deletions(-) rename ttf-parse.c => ttf_parse.c (98%) rename ttf-rasterize.c => ttf_rasterize.c (87%) diff --git a/main.c b/main.c index 3079855..df305e4 100644 --- a/main.c +++ b/main.c @@ -2,15 +2,11 @@ #include #include #include -#include - -#include #include #include #include -#include #include #include @@ -20,17 +16,6 @@ #include #include -#define ASSERT(expr) if (!expr) { fprintf(stderr, "[ASSERT] Assertion fail %s:%d\n", __FILE__, __LINE__); abort(); } - -#define MIN(a, b) ((a) < (b) ? (a) : (b)) -#define MAX(a, b) ((a) > (b) ? (a) : (b)) - -#define MAX_INTERSECTIONS 16 -#define F32EPS 1e-5f -#define MAX_CONTOURS 256 - -#define TTF_ENGINE_STACK 4096 - typedef int64_t s64; typedef int32_t s32; typedef int16_t s16; @@ -44,49 +29,11 @@ typedef uint8_t u8; typedef float f32; typedef double f64; -static int -clamp_u32(u32 val, u32 cap) -{ - u32 result = val; - if (val > cap) result = cap; - return(result); -} - -static f32 -abs_f32(f32 v) -{ - f32 result = (v > 0 ? v : -v); - return(result); -} - -static int -round_f32(f32 v) -{ - int towards_zero = (int) v; - f32 diff = abs_f32(v - towards_zero); - - if (diff >= 0.5f) { - return(v > 0 ? towards_zero + 1 : towards_zero - 1); - } else { - return(towards_zero); - } -} - -static int -ceil_f32(f32 v) -{ - int trunc = v; - if (v - trunc < F32EPS) { - return(trunc); - } - return(trunc + 1); -} - #include "ttf.h" #include "ttf_engine.c" -#include "ttf-parse.c" -#include "ttf-rasterize.c" +#include "ttf_parse.c" +#include "ttf_rasterize.c" static Display *display; static Window window; @@ -148,7 +95,7 @@ main(int argc, char **argv) default_gc = DefaultGC(display, default_screen); - struct ttf_font font = parse_ttf_file(argv[1], "Inter"); + struct ttf_font font = parse_ttf_file(argv[1]); printf("Loaded font\n"); u32 *pixels = hc_vram; diff --git a/ttf.h b/ttf.h index cdd20c7..2699efe 100644 --- a/ttf.h +++ b/ttf.h @@ -1,3 +1,18 @@ +#include +#include // wchar_t, wcslen +#include + +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#define MAX(a, b) ((a) > (b) ? (a) : (b)) + +#define MAX_INTERSECTIONS 16 +#define F32EPS 1e-5f +#define MAX_CONTOURS 256 + +#define TTF_ENGINE_STACK 4096 + +#define ASSERT(expr) if (!(expr)) { fprintf(stderr, "[ASSERT] Assertion fail %s:%d\n", __FILE__, __LINE__); abort(); } + struct v2 { int x; int y; @@ -152,3 +167,41 @@ struct ttf_font { char *name; }; + +static int +clamp_u32(u32 val, u32 cap) +{ + u32 result = val; + if (val > cap) result = cap; + return(result); +} + +static f32 +abs_f32(f32 v) +{ + f32 result = (v > 0 ? v : -v); + return(result); +} + +static int +round_f32(f32 v) +{ + int towards_zero = (int) v; + f32 diff = abs_f32(v - towards_zero); + + if (diff >= 0.5f) { + return(v > 0 ? towards_zero + 1 : towards_zero - 1); + } else { + return(towards_zero); + } +} + +static int +ceil_f32(f32 v) +{ + int trunc = v; + if (v - trunc < F32EPS) { + return(trunc); + } + return(trunc + 1); +} diff --git a/ttf-parse.c b/ttf_parse.c similarity index 98% rename from ttf-parse.c rename to ttf_parse.c index 96059a5..c8c49b2 100644 --- a/ttf-parse.c +++ b/ttf_parse.c @@ -485,7 +485,7 @@ iterate_instructions(struct ttf_font *font, struct font_buffer *font_file, u32 o u32 value = pop(state); u32 location = pop(state); s16 cvt_value = value; - assert(location <= font->dir.cvt_size / sizeof(s16)); + ASSERT(location <= font->dir.cvt_size / sizeof(s16)); font->cvt[location] = cvt_value; break; } @@ -494,14 +494,14 @@ iterate_instructions(struct ttf_font *font, struct font_buffer *font_file, u32 o u32 value = pop(state); u32 location = pop(state); s16 cvt_value = funits_to_pixels(value); - assert(location <= font->dir.cvt_size / sizeof(s16)); + ASSERT(location <= font->dir.cvt_size / sizeof(s16)); font->cvt[location] = cvt_value; break; } case RCVT: { u32 location = pop(state); - assert(location <= font->dir.cvt_size / sizeof(s16)); + ASSERT(location <= font->dir.cvt_size / sizeof(s16)); s16 integer = font->cvt[location]; push(state, integer); break; @@ -793,7 +793,7 @@ iterate_instructions(struct ttf_font *font, struct font_buffer *font_file, u32 o // 1: round the distance and look at the control_value_cut_in int a = inst - MIAP; - assert(state->stack_head >= 2); + ASSERT(state->stack_head >= 2); u32 n = pop(state); // CVT entry number u32 p = pop(state); // point number @@ -918,7 +918,7 @@ iterate_instructions(struct ttf_font *font, struct font_buffer *font_file, u32 o } case SWAP: { - assert(state->stack_head >= 2); + ASSERT(state->stack_head >= 2); u32 last = state->stack[state->stack_head - 1]; u32 prelast = state->stack[state->stack_head - 2]; @@ -951,7 +951,7 @@ iterate_instructions(struct ttf_font *font, struct font_buffer *font_file, u32 o if_true = pop(state); if (!if_true) { - assert(pair.x != (u32) -1 || pair.y != (u32) -1); + ASSERT(pair.x != (u32) -1 || pair.y != (u32) -1); offset = MIN(pair.x, pair.y); } @@ -961,7 +961,7 @@ iterate_instructions(struct ttf_font *font, struct font_buffer *font_file, u32 o case ELSE: { if (if_true) { offset = skip_until(font_file, offset, size - (offset - base_offset), EIF); - assert(offset != (u32) -1); + ASSERT(offset != (u32) -1); } break; @@ -1171,7 +1171,7 @@ iterate_instructions(struct ttf_font *font, struct font_buffer *font_file, u32 o case CALL: { int f = state->stack[--state->stack_head]; - assert(f <= font->maxp.max_fdefs); + ASSERT(f <= font->maxp.max_fdefs); struct ttf_function proc = font->functions[f]; iterate_instructions(font, font_file, proc.from, proc.to - proc.from, state); break; @@ -1678,7 +1678,7 @@ read_post(struct font_directory font_dir, struct ttf_font *font) } static struct ttf_font -parse_ttf_file(char *filename, char *fontname) +parse_ttf_file(char *filename) { struct ttf_font result = { 0 }; struct font_buffer font_file = read_file(filename); @@ -1713,7 +1713,5 @@ parse_ttf_file(char *filename, char *fontname) //read_cvt(&result, &font_file, font_dir, &prep_state); // the cvt program //printf("------------- CVT END -------------\n"); - result.name = fontname; - return(result); -} \ No newline at end of file +} diff --git a/ttf-rasterize.c b/ttf_rasterize.c similarity index 87% rename from ttf-rasterize.c rename to ttf_rasterize.c index ccea2f2..9f16bdd 100644 --- a/ttf-rasterize.c +++ b/ttf_rasterize.c @@ -1,4 +1,3 @@ - static int scanline_intersects_line(f32 y, struct v2f p0, struct v2f p1, f32 lasty, f32 *vx) { @@ -74,7 +73,7 @@ sort_intersections(struct intersection *intersections, int size) static void render_glyph(struct glyph g, int px_size, struct line_contour *lines, - f32 scale, u32 *pixels, int width, int at_x, int at_y) + f32 scale, u32 *pixels, int width, int at_x, int at_y, u32 color) { int oversample_y = 4; if (px_size <= 12) { @@ -131,10 +130,15 @@ render_glyph(struct glyph g, int px_size, struct line_contour *lines, for (int x = 0; x < gwidth; ++x) { //printf(" %.2f", accumulator[y * gwidth + x]); u32 brightness = clamp_u32(accumulator[y * gwidth + x] * 255.99f, 255); - u32 white = 0xFF000000 | brightness << 16 | brightness << 8 | brightness; if (brightness > 0) { - pixels[(at_y + (gheight - 1 - y)) * width + (at_x + x)] = white; + f32 alpha = brightness / 256.0f; + u32 bg = pixels[(at_y + (gheight - 1 - y)) * width + (at_x + x)]; + u8 r = ((bg & 0xff0000) >> 16) * (1.0f - alpha) + alpha * ((color & 0xff0000) >> 16); + u8 g = ((bg & 0x00ff00) >> 8) * (1.0f - alpha) + alpha * ((color & 0x00ff00) >> 8); + u8 b = ((bg & 0x0000ff) >> 0) * (1.0f - alpha) + alpha * ((color & 0x0000ff) >> 0); + u32 value = 0xFF000000 | r << 16 | g << 8 | b; + pixels[(at_y + (gheight - 1 - y)) * width + (at_x + x)] = value; } else { //pixels[(at_y + (gheight - 1 - y)) * width + (at_x + x)] = 0xFFFF0000; } @@ -242,10 +246,11 @@ outline_to_lines(struct glyph g, f32 scale, int max_descent, struct line_contour static struct v2 -render_utf_string(struct ttf_font font, int px_size, u32 *pixels, u32 width, wchar_t *string, u32 fit_width, int at_x, int at_y) +render_utf_string(struct ttf_font font, int px_size, u32 *pixels, u32 width, wchar_t *string, int fit_width, int at_x, int at_y) { - u32 offset_x = at_x; - u32 offset_y = at_y; + u32 color = 0xffffffff; + s32 offset_x = at_x; + s32 offset_y = at_y; f32 scale = (f32) px_size / ((f32) (font.hhea.ascent - font.hhea.descent)); u32 len = wcslen(string); @@ -257,7 +262,25 @@ render_utf_string(struct ttf_font font, int px_size, u32 *pixels, u32 width, wch for (u32 i = 0; i < len; ++i) { u16 codepoint = string[i]; int advance; - if (codepoint != ' ') { + if (codepoint == ' ') { + if (offset_x > 0) { + advance = get_codepoint_width(&font, scale, codepoint); + } else { + advance = 0; + } + } else if (codepoint == '\t') { + advance = get_codepoint_width(&font, scale, codepoint); + advance *= 4; + } else if (codepoint == '\n') { + if (offset_x > box.x) { + box.x = offset_x; + } + + advance = 0; + offset_x = at_x; + offset_y += px_size; + box.y += px_size; + } else { struct glyph g = get_outline(&font, codepoint); //exit(0); @@ -268,23 +291,25 @@ render_utf_string(struct ttf_font font, int px_size, u32 *pixels, u32 width, wch lines.data = malloc(nlines * sizeof(struct line)); outline_to_lines(g, scale, font.hhea.descent, &lines, 0); - render_glyph(g, px_size, &lines, scale, pixels, width, offset_x, offset_y); + render_glyph(g, px_size, &lines, scale, pixels, width, offset_x, offset_y, color); advance = ceil_f32(scale * g.advance); free(lines.data); - } else { - advance = get_codepoint_width(&font, scale, codepoint); } offset_x += advance; - box.x += advance; if (offset_x - at_x >= fit_width) { offset_x = at_x; offset_y += px_size; box.y += px_size; + box.x = fit_width; } } + if (offset_x > box.x) { + box.x = offset_x - at_x; + } + return(box); }