From 616ade56d7af7cfb3e8b76f2ca98e07357d8285d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Madar=C3=A1sz?= Date: Sun, 10 Dec 2023 16:47:42 +0100 Subject: [PATCH] add font_metrics() method --- demos/01-font.c | 3 ++- engine/v4k.c | 31 +++++++++++++++++++++++++++++++ engine/v4k.h | 16 ++++++++++++---- 3 files changed, 45 insertions(+), 5 deletions(-) diff --git a/demos/01-font.c b/demos/01-font.c index 42511b1..fc73def 100644 --- a/demos/01-font.c +++ b/demos/01-font.c @@ -117,7 +117,8 @@ int main() { char *txt = "This is the first line.\nAnd now the second line.\nYou can do a third great line, too!\n"; font_goto(pos.x, pos.y); vec2 size=font_rect(txt); - ddraw_aabb(vec3(pos.x,pos.y,0), vec3(pos.x+size.x,pos.y+size.y,0)); + font_metrics_t m=font_metrics(txt); + ddraw_aabb(vec3(pos.x,pos.y,0), vec3(pos.x+size.x,pos.y+size.y-m.descent+m.linegap,0)); font_print(txt); ddraw_pop_2d(); } diff --git a/engine/v4k.c b/engine/v4k.c index d38b668..31fec2a 100644 --- a/engine/v4k.c +++ b/engine/v4k.c @@ -11050,6 +11050,37 @@ vec2 font_highlight(const char *text, const void *colors) { vec2 font_rect(const char *str) { return font_draw_ex(str, gotoxy, NULL, NULL); } + +font_metrics_t font_metrics(const char *text) { + font_metrics_t m={0}; + int S = 3; + font_t *f = &fonts[0]; + + // utf8 to utf32 + array(uint32_t) unicode = string32(text); + + // parse string + for( int i = 0, end = array_count(unicode); i < end; ++i ) { + uint32_t ch = unicode[i]; + if( ch >= 1 && ch <= 6 ) { + S = ch; + continue; + } + if( ch >= 0x1a && ch <= 0x1f ) { + if( fonts[ ch - 0x1a ].initialized) { + // change face + f = &fonts[ ch - 0x1a ]; + } + continue; + } + } + + m.ascent = f->ascent*f->factor*f->scale[S]; + m.descent = f->descent*f->factor*f->scale[S]; + m.linegap = f->linegap*f->factor*f->scale[S]; + m.linedist = f->linedist*f->factor*f->scale[S]; + return m; +} #line 0 #line 1 "v4k_gui.c" diff --git a/engine/v4k.h b/engine/v4k.h index 0ada3b9..b81c1f1 100644 --- a/engine/v4k.h +++ b/engine/v4k.h @@ -2182,6 +2182,13 @@ enum FONT_FLAGS { // FONT_DEFAULTS = FONT_512 | FONT_NO_OVERSAMPLE | FONT_ASCII, }; +typedef struct font_metrics_t { + float ascent; // max distance above baseline for all glyphs + float descent; // max distance below baseline for all glyphs + float linegap; // distance betwen ascent of next line and descent of current line + float linedist; // distance between the baseline of two lines (ascent - descent + linegap) +} font_metrics_t; + // configures API void font_face(const char *face_tag, const char *filename_ttf, float font_size, unsigned flags); API void font_face_from_mem(const char *tag, const void *ttf_buffer, unsigned ttf_len, float font_size, unsigned flags); @@ -2190,10 +2197,11 @@ API void font_color(const char *color_tag, uint32_t color); API void ui_font(); // commands -API vec2 font_xy(); -API void font_goto(float x, float y); -API vec2 font_print(const char *text); -API vec2 font_rect(const char *text); +API vec2 font_xy(); +API void font_goto(float x, float y); +API vec2 font_print(const char *text); +API vec2 font_rect(const char *text); +API font_metrics_t font_metrics(const char *text); // void font_clip(vec2 topleft, vec2 bottomright); // void font_wrap(vec2 topleft, vec2 bottomright);