From 3a853d09d7f84c06ca2de1e1370b04c9875e9e75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Madar=C3=A1sz?= Date: Sat, 10 Feb 2024 17:05:45 +0100 Subject: [PATCH] font: font_print_rect -> font_clip + scissor test --- bind/v4k.lua | 2 +- demos/01-font.c | 24 +++++++++++++++++++++--- engine/joint/v4k.h | 37 ++++++++++++++++++++++--------------- engine/split/v4k_font.c | 34 +++++++++++++++++++++------------- engine/split/v4k_font.h | 3 +-- engine/v4k.c | 34 +++++++++++++++++++++------------- engine/v4k.h | 3 +-- 7 files changed, 88 insertions(+), 49 deletions(-) diff --git a/bind/v4k.lua b/bind/v4k.lua index ddd0dd4..80ff0f5 100644 --- a/bind/v4k.lua +++ b/bind/v4k.lua @@ -680,7 +680,7 @@ typedef struct font_metrics_t { vec2 font_xy(); void font_goto(float x, float y); vec2 font_print(const char *text); - vec2 font_print_rect(const char *text, vec4 rect); + vec2 font_clip(const char *text, vec4 rect); vec2 font_rect(const char *text); font_metrics_t font_metrics(const char *text); void* font_colorize(const char *text, const char *comma_types, const char *comma_keywords); diff --git a/demos/01-font.c b/demos/01-font.c index daaaf3f..745f6ef 100644 --- a/demos/01-font.c +++ b/demos/01-font.c @@ -133,19 +133,37 @@ int main() { vec2 size=font_rect(txt); 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+100,0)); - font_print_rect(txt, vec4(pos.x, pos.y, size.x, size.y+100)); + font_clip(txt, vec4(pos.x, pos.y, size.x, size.y+100)); + ddraw_pop_2d(); + } + + { + vec2 pos = vec2(1490,240); + ddraw_push_2d(); + char *txt = "This is the first line.\nAnd now the second line.\nYou can do a third great line, too!\nNow this is a very long line aaaaaaaaaa!\n"; + font_goto(pos.x, pos.y); + vec2 size=font_rect(txt); + size.y -= 20; // artifically shrink textbox to test clipping + 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_clip(txt, vec4(pos.x, pos.y, size.x, size.y)); ddraw_pop_2d(); } { vec2 pos = vec2(1990,820); ddraw_push_2d(); - char *txt = FONT_RIGHT FONT_BOTTOM FONT_WHITE "This is the first line.\n" FONT_LIME "And now the second line.\n" FONT_WHITE "You can do a third" FONT_ORANGE " great" FONT_WHITE " line, too!\n"; + char *txt = FONT_RIGHT FONT_BOTTOM + FONT_WHITE "This is the first line.\n" + FONT_LIME "And now the second line.\n" + FONT_WHITE "You can do a third" + FONT_ORANGE " great" + FONT_WHITE " line, too!\n"; font_goto(pos.x, pos.y); vec2 size=font_rect(txt); 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+100,0)); - font_print_rect(txt, vec4(pos.x, pos.y, size.x, size.y+100)); + font_clip(txt, vec4(pos.x, pos.y, size.x, size.y+100)); ddraw_pop_2d(); } diff --git a/engine/joint/v4k.h b/engine/joint/v4k.h index 77da590..7e32988 100644 --- a/engine/joint/v4k.h +++ b/engine/joint/v4k.h @@ -16146,10 +16146,9 @@ API void font_color(const char *color_tag, uint32_t color); API vec2 font_xy(); API void font_goto(float x, float y); API vec2 font_print(const char *text); -API vec2 font_print_rect(const char *text, vec4 rect); +API vec2 font_clip(const char *text, vec4 rect); 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); // syntax highlighting @@ -363522,7 +363521,7 @@ void font_face(const char *tag, const char *filename_ttf, float font_size, unsig } static -void font_draw_cmd(font_t *f, const float *glyph_data, int glyph_idx, float factor, vec2 offset) { +void font_draw_cmd(font_t *f, const float *glyph_data, int glyph_idx, float factor, vec2 offset, vec4 rect) { // Backup GL state GLint last_program, last_vertex_array; GLint last_texture0, last_texture1, last_texture2; @@ -363546,12 +363545,17 @@ void font_draw_cmd(font_t *f, const float *glyph_data, int glyph_idx, float fact GLboolean last_enable_blend = glIsEnabled(GL_BLEND); GLboolean last_enable_depth_test = glIsEnabled(GL_DEPTH_TEST); + GLboolean last_scissor_test = glIsEnabled(GL_SCISSOR_TEST); - // Setup render state: alpha-blending enabled, no depth testing and bind textures + // Setup render state: alpha-blending enabled, no depth testing, enable clipping and bind textures glEnable(GL_BLEND); glBlendEquation(GL_FUNC_ADD); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + // @fixme: store existing scissor test setup + glEnable(GL_SCISSOR_TEST); + glScissor(rect.x, window_height() - (rect.y+rect.w), rect.z, rect.w); + glDisable(GL_DEPTH_TEST); glActiveTexture(GL_TEXTURE0); @@ -363597,13 +363601,14 @@ void font_draw_cmd(font_t *f, const float *glyph_data, int glyph_idx, float fact (last_enable_depth_test ? glEnable(GL_DEPTH_TEST) : glDisable(GL_DEPTH_TEST)); (last_enable_blend ? glEnable(GL_BLEND) : glDisable(GL_BLEND)); + (last_scissor_test ? glEnable(GL_SCISSOR_TEST) : glDisable(GL_SCISSOR_TEST)); } // 1. call font_face() if it's the first time it's called. // 1. parse the string and update the instance vbo, then upload it // 1. draw the string static -vec2 font_draw_ex(const char *text, vec2 offset, const char *col, void (*draw_cmd)(font_t *,const float *,int,float,vec2)) { +vec2 font_draw_ex(const char *text, vec2 offset, vec4 rect, const char *col, void (*draw_cmd)(font_t *,const float *,int,float,vec2,vec4)) { font_init(); // sanity checks @@ -363643,7 +363648,7 @@ vec2 font_draw_ex(const char *text, vec2 offset, const char *col, void (*draw_cm } if( ch >= 1 && ch <= 6 ) { // flush previous state - if(draw_cmd) draw_cmd(f, text_glyph_data, (t - text_glyph_data)/4, f->scale[S], offset); + if(draw_cmd) draw_cmd(f, text_glyph_data, (t - text_glyph_data)/4, f->scale[S], offset, rect); t = text_glyph_data; // reposition offset to align new baseline @@ -363664,7 +363669,7 @@ vec2 font_draw_ex(const char *text, vec2 offset, const char *col, void (*draw_cm if( ch >= 0x10 && ch <= 0x19 ) { if( fonts[ ch - 0x10 ].initialized) { // flush previous state - if(draw_cmd) draw_cmd(f, text_glyph_data, (t - text_glyph_data)/4, f->scale[S], offset); + if(draw_cmd) draw_cmd(f, text_glyph_data, (t - text_glyph_data)/4, f->scale[S], offset, rect); t = text_glyph_data; // change face @@ -363691,7 +363696,7 @@ vec2 font_draw_ex(const char *text, vec2 offset, const char *col, void (*draw_cm X += f->cdata[cp].xadvance*f->scale[S]; } - if(draw_cmd) draw_cmd(f, text_glyph_data, (t - text_glyph_data)/4, f->scale[S], offset); + if(draw_cmd) draw_cmd(f, text_glyph_data, (t - text_glyph_data)/4, f->scale[S], offset, rect); //if(strstr(text, "fps")) printf("(%f,%f) (%f) L:%f LINEDIST:%f\n", X, Y, W, L, f->linedist); return abs2(vec2(W*W > X*X ? W : X, Y*Y > LL*LL ? Y : LL)); @@ -363932,7 +363937,7 @@ void font_goto(float x, float y) { } // Print and linefeed. Text may include markup code -vec2 font_print_rect(const char *text, vec4 rect) { +vec2 font_clip(const char *text, vec4 rect) { int l=0,c=0,r=0,j=0,t=0,b=0,m=0,B=0; while ( text[0] == FONT_LEFT[0] ) { @@ -363998,14 +364003,14 @@ vec2 font_print_rect(const char *text, vec4 rect) { int gaps = array_count(words) - 1; float space_offset = gaps > 0 ? extra_space / (float)gaps : 0; for (int k = 0; k < array_count(words); ++k) { - vec2 dims = font_draw_ex(va("%s%s", tags, words[k]), gotoxy, NULL, font_draw_cmd); + vec2 dims = font_draw_ex(va("%s%s", tags, words[k]), gotoxy, rect, NULL, font_draw_cmd); gotoxy.x += dims.x + space_offset; } gotoxy.x = rect.x; } if (!j) { - font_draw_ex(line, gotoxy, NULL, font_draw_cmd); + font_draw_ex(line, gotoxy, rect, NULL, font_draw_cmd); } gotoxy.y += text_rect.y; @@ -364020,7 +364025,7 @@ vec2 font_print_rect(const char *text, vec4 rect) { vec2 text_rect = font_rect(text); gotoxy.y = t ? rect.y : b ? ((rect.y+rect.w) - text_rect.y) : m ? rect.y+rect.w/2.-text_rect.y/2. : rect.y+rect.w/2.-text_rect.y/1; } - vec2 dims = font_draw_ex(text, gotoxy, NULL, font_draw_cmd); + vec2 dims = font_draw_ex(text, gotoxy, rect, NULL, font_draw_cmd); gotoxy.y += strchr(text, '\n') ? dims.y : 0; gotoxy.x = strchr(text, '\n') ? rect.x : gotoxy.x + dims.x; return dims; @@ -364029,12 +364034,13 @@ vec2 font_print_rect(const char *text, vec4 rect) { vec2 font_print(const char *text) { vec4 dims = {0, 0, window_width(), window_height()}; - return font_print_rect(text, dims); + return font_clip(text, dims); } // Print a code snippet with syntax highlighting vec2 font_highlight(const char *text, const void *colors) { - vec2 dims = font_draw_ex(text, gotoxy, (const char *)colors, font_draw_cmd); + vec4 screen_dim = {0, 0, window_width(), window_height()}; + vec2 dims = font_draw_ex(text, gotoxy, screen_dim, (const char *)colors, font_draw_cmd); gotoxy.y += strchr(text, '\n') ? dims.y : 0; gotoxy.x = strchr(text, '\n') ? 0 : gotoxy.x + dims.x; return dims; @@ -364042,7 +364048,8 @@ vec2 font_highlight(const char *text, const void *colors) { // Calculate the size of a string, in the pixel size specified. Count stray newlines too. vec2 font_rect(const char *str) { - return font_draw_ex(str, gotoxy, NULL, NULL); + vec4 dims = {0, 0, window_width(), window_height()}; + return font_draw_ex(str, gotoxy, dims, NULL, NULL); } font_metrics_t font_metrics(const char *text) { diff --git a/engine/split/v4k_font.c b/engine/split/v4k_font.c index c7ade24..6f85f8e 100644 --- a/engine/split/v4k_font.c +++ b/engine/split/v4k_font.c @@ -1964,7 +1964,7 @@ void font_face(const char *tag, const char *filename_ttf, float font_size, unsig } static -void font_draw_cmd(font_t *f, const float *glyph_data, int glyph_idx, float factor, vec2 offset) { +void font_draw_cmd(font_t *f, const float *glyph_data, int glyph_idx, float factor, vec2 offset, vec4 rect) { // Backup GL state GLint last_program, last_vertex_array; GLint last_texture0, last_texture1, last_texture2; @@ -1988,12 +1988,17 @@ void font_draw_cmd(font_t *f, const float *glyph_data, int glyph_idx, float fact GLboolean last_enable_blend = glIsEnabled(GL_BLEND); GLboolean last_enable_depth_test = glIsEnabled(GL_DEPTH_TEST); + GLboolean last_scissor_test = glIsEnabled(GL_SCISSOR_TEST); - // Setup render state: alpha-blending enabled, no depth testing and bind textures + // Setup render state: alpha-blending enabled, no depth testing, enable clipping and bind textures glEnable(GL_BLEND); glBlendEquation(GL_FUNC_ADD); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + // @fixme: store existing scissor test setup + glEnable(GL_SCISSOR_TEST); + glScissor(rect.x, window_height() - (rect.y+rect.w), rect.z, rect.w); + glDisable(GL_DEPTH_TEST); glActiveTexture(GL_TEXTURE0); @@ -2039,13 +2044,14 @@ void font_draw_cmd(font_t *f, const float *glyph_data, int glyph_idx, float fact (last_enable_depth_test ? glEnable(GL_DEPTH_TEST) : glDisable(GL_DEPTH_TEST)); (last_enable_blend ? glEnable(GL_BLEND) : glDisable(GL_BLEND)); + (last_scissor_test ? glEnable(GL_SCISSOR_TEST) : glDisable(GL_SCISSOR_TEST)); } // 1. call font_face() if it's the first time it's called. // 1. parse the string and update the instance vbo, then upload it // 1. draw the string static -vec2 font_draw_ex(const char *text, vec2 offset, const char *col, void (*draw_cmd)(font_t *,const float *,int,float,vec2)) { +vec2 font_draw_ex(const char *text, vec2 offset, vec4 rect, const char *col, void (*draw_cmd)(font_t *,const float *,int,float,vec2,vec4)) { font_init(); // sanity checks @@ -2085,7 +2091,7 @@ vec2 font_draw_ex(const char *text, vec2 offset, const char *col, void (*draw_cm } if( ch >= 1 && ch <= 6 ) { // flush previous state - if(draw_cmd) draw_cmd(f, text_glyph_data, (t - text_glyph_data)/4, f->scale[S], offset); + if(draw_cmd) draw_cmd(f, text_glyph_data, (t - text_glyph_data)/4, f->scale[S], offset, rect); t = text_glyph_data; // reposition offset to align new baseline @@ -2106,7 +2112,7 @@ vec2 font_draw_ex(const char *text, vec2 offset, const char *col, void (*draw_cm if( ch >= 0x10 && ch <= 0x19 ) { if( fonts[ ch - 0x10 ].initialized) { // flush previous state - if(draw_cmd) draw_cmd(f, text_glyph_data, (t - text_glyph_data)/4, f->scale[S], offset); + if(draw_cmd) draw_cmd(f, text_glyph_data, (t - text_glyph_data)/4, f->scale[S], offset, rect); t = text_glyph_data; // change face @@ -2133,7 +2139,7 @@ vec2 font_draw_ex(const char *text, vec2 offset, const char *col, void (*draw_cm X += f->cdata[cp].xadvance*f->scale[S]; } - if(draw_cmd) draw_cmd(f, text_glyph_data, (t - text_glyph_data)/4, f->scale[S], offset); + if(draw_cmd) draw_cmd(f, text_glyph_data, (t - text_glyph_data)/4, f->scale[S], offset, rect); //if(strstr(text, "fps")) printf("(%f,%f) (%f) L:%f LINEDIST:%f\n", X, Y, W, L, f->linedist); return abs2(vec2(W*W > X*X ? W : X, Y*Y > LL*LL ? Y : LL)); @@ -2374,7 +2380,7 @@ void font_goto(float x, float y) { } // Print and linefeed. Text may include markup code -vec2 font_print_rect(const char *text, vec4 rect) { +vec2 font_clip(const char *text, vec4 rect) { int l=0,c=0,r=0,j=0,t=0,b=0,m=0,B=0; while ( text[0] == FONT_LEFT[0] ) { @@ -2440,14 +2446,14 @@ vec2 font_print_rect(const char *text, vec4 rect) { int gaps = array_count(words) - 1; float space_offset = gaps > 0 ? extra_space / (float)gaps : 0; for (int k = 0; k < array_count(words); ++k) { - vec2 dims = font_draw_ex(va("%s%s", tags, words[k]), gotoxy, NULL, font_draw_cmd); + vec2 dims = font_draw_ex(va("%s%s", tags, words[k]), gotoxy, rect, NULL, font_draw_cmd); gotoxy.x += dims.x + space_offset; } gotoxy.x = rect.x; } if (!j) { - font_draw_ex(line, gotoxy, NULL, font_draw_cmd); + font_draw_ex(line, gotoxy, rect, NULL, font_draw_cmd); } gotoxy.y += text_rect.y; @@ -2462,7 +2468,7 @@ vec2 font_print_rect(const char *text, vec4 rect) { vec2 text_rect = font_rect(text); gotoxy.y = t ? rect.y : b ? ((rect.y+rect.w) - text_rect.y) : m ? rect.y+rect.w/2.-text_rect.y/2. : rect.y+rect.w/2.-text_rect.y/1; } - vec2 dims = font_draw_ex(text, gotoxy, NULL, font_draw_cmd); + vec2 dims = font_draw_ex(text, gotoxy, rect, NULL, font_draw_cmd); gotoxy.y += strchr(text, '\n') ? dims.y : 0; gotoxy.x = strchr(text, '\n') ? rect.x : gotoxy.x + dims.x; return dims; @@ -2471,12 +2477,13 @@ vec2 font_print_rect(const char *text, vec4 rect) { vec2 font_print(const char *text) { vec4 dims = {0, 0, window_width(), window_height()}; - return font_print_rect(text, dims); + return font_clip(text, dims); } // Print a code snippet with syntax highlighting vec2 font_highlight(const char *text, const void *colors) { - vec2 dims = font_draw_ex(text, gotoxy, (const char *)colors, font_draw_cmd); + vec4 screen_dim = {0, 0, window_width(), window_height()}; + vec2 dims = font_draw_ex(text, gotoxy, screen_dim, (const char *)colors, font_draw_cmd); gotoxy.y += strchr(text, '\n') ? dims.y : 0; gotoxy.x = strchr(text, '\n') ? 0 : gotoxy.x + dims.x; return dims; @@ -2484,7 +2491,8 @@ vec2 font_highlight(const char *text, const void *colors) { // Calculate the size of a string, in the pixel size specified. Count stray newlines too. vec2 font_rect(const char *str) { - return font_draw_ex(str, gotoxy, NULL, NULL); + vec4 dims = {0, 0, window_width(), window_height()}; + return font_draw_ex(str, gotoxy, dims, NULL, NULL); } font_metrics_t font_metrics(const char *text) { diff --git a/engine/split/v4k_font.h b/engine/split/v4k_font.h index df9a694..f360cbd 100644 --- a/engine/split/v4k_font.h +++ b/engine/split/v4k_font.h @@ -89,10 +89,9 @@ API void font_color(const char *color_tag, uint32_t color); API vec2 font_xy(); API void font_goto(float x, float y); API vec2 font_print(const char *text); -API vec2 font_print_rect(const char *text, vec4 rect); +API vec2 font_clip(const char *text, vec4 rect); 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); // syntax highlighting diff --git a/engine/v4k.c b/engine/v4k.c index 420dca3..53f5524 100644 --- a/engine/v4k.c +++ b/engine/v4k.c @@ -10662,7 +10662,7 @@ void font_face(const char *tag, const char *filename_ttf, float font_size, unsig } static -void font_draw_cmd(font_t *f, const float *glyph_data, int glyph_idx, float factor, vec2 offset) { +void font_draw_cmd(font_t *f, const float *glyph_data, int glyph_idx, float factor, vec2 offset, vec4 rect) { // Backup GL state GLint last_program, last_vertex_array; GLint last_texture0, last_texture1, last_texture2; @@ -10686,12 +10686,17 @@ void font_draw_cmd(font_t *f, const float *glyph_data, int glyph_idx, float fact GLboolean last_enable_blend = glIsEnabled(GL_BLEND); GLboolean last_enable_depth_test = glIsEnabled(GL_DEPTH_TEST); + GLboolean last_scissor_test = glIsEnabled(GL_SCISSOR_TEST); - // Setup render state: alpha-blending enabled, no depth testing and bind textures + // Setup render state: alpha-blending enabled, no depth testing, enable clipping and bind textures glEnable(GL_BLEND); glBlendEquation(GL_FUNC_ADD); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + // @fixme: store existing scissor test setup + glEnable(GL_SCISSOR_TEST); + glScissor(rect.x, window_height() - (rect.y+rect.w), rect.z, rect.w); + glDisable(GL_DEPTH_TEST); glActiveTexture(GL_TEXTURE0); @@ -10737,13 +10742,14 @@ void font_draw_cmd(font_t *f, const float *glyph_data, int glyph_idx, float fact (last_enable_depth_test ? glEnable(GL_DEPTH_TEST) : glDisable(GL_DEPTH_TEST)); (last_enable_blend ? glEnable(GL_BLEND) : glDisable(GL_BLEND)); + (last_scissor_test ? glEnable(GL_SCISSOR_TEST) : glDisable(GL_SCISSOR_TEST)); } // 1. call font_face() if it's the first time it's called. // 1. parse the string and update the instance vbo, then upload it // 1. draw the string static -vec2 font_draw_ex(const char *text, vec2 offset, const char *col, void (*draw_cmd)(font_t *,const float *,int,float,vec2)) { +vec2 font_draw_ex(const char *text, vec2 offset, vec4 rect, const char *col, void (*draw_cmd)(font_t *,const float *,int,float,vec2,vec4)) { font_init(); // sanity checks @@ -10783,7 +10789,7 @@ vec2 font_draw_ex(const char *text, vec2 offset, const char *col, void (*draw_cm } if( ch >= 1 && ch <= 6 ) { // flush previous state - if(draw_cmd) draw_cmd(f, text_glyph_data, (t - text_glyph_data)/4, f->scale[S], offset); + if(draw_cmd) draw_cmd(f, text_glyph_data, (t - text_glyph_data)/4, f->scale[S], offset, rect); t = text_glyph_data; // reposition offset to align new baseline @@ -10804,7 +10810,7 @@ vec2 font_draw_ex(const char *text, vec2 offset, const char *col, void (*draw_cm if( ch >= 0x10 && ch <= 0x19 ) { if( fonts[ ch - 0x10 ].initialized) { // flush previous state - if(draw_cmd) draw_cmd(f, text_glyph_data, (t - text_glyph_data)/4, f->scale[S], offset); + if(draw_cmd) draw_cmd(f, text_glyph_data, (t - text_glyph_data)/4, f->scale[S], offset, rect); t = text_glyph_data; // change face @@ -10831,7 +10837,7 @@ vec2 font_draw_ex(const char *text, vec2 offset, const char *col, void (*draw_cm X += f->cdata[cp].xadvance*f->scale[S]; } - if(draw_cmd) draw_cmd(f, text_glyph_data, (t - text_glyph_data)/4, f->scale[S], offset); + if(draw_cmd) draw_cmd(f, text_glyph_data, (t - text_glyph_data)/4, f->scale[S], offset, rect); //if(strstr(text, "fps")) printf("(%f,%f) (%f) L:%f LINEDIST:%f\n", X, Y, W, L, f->linedist); return abs2(vec2(W*W > X*X ? W : X, Y*Y > LL*LL ? Y : LL)); @@ -11072,7 +11078,7 @@ void font_goto(float x, float y) { } // Print and linefeed. Text may include markup code -vec2 font_print_rect(const char *text, vec4 rect) { +vec2 font_clip(const char *text, vec4 rect) { int l=0,c=0,r=0,j=0,t=0,b=0,m=0,B=0; while ( text[0] == FONT_LEFT[0] ) { @@ -11138,14 +11144,14 @@ vec2 font_print_rect(const char *text, vec4 rect) { int gaps = array_count(words) - 1; float space_offset = gaps > 0 ? extra_space / (float)gaps : 0; for (int k = 0; k < array_count(words); ++k) { - vec2 dims = font_draw_ex(va("%s%s", tags, words[k]), gotoxy, NULL, font_draw_cmd); + vec2 dims = font_draw_ex(va("%s%s", tags, words[k]), gotoxy, rect, NULL, font_draw_cmd); gotoxy.x += dims.x + space_offset; } gotoxy.x = rect.x; } if (!j) { - font_draw_ex(line, gotoxy, NULL, font_draw_cmd); + font_draw_ex(line, gotoxy, rect, NULL, font_draw_cmd); } gotoxy.y += text_rect.y; @@ -11160,7 +11166,7 @@ vec2 font_print_rect(const char *text, vec4 rect) { vec2 text_rect = font_rect(text); gotoxy.y = t ? rect.y : b ? ((rect.y+rect.w) - text_rect.y) : m ? rect.y+rect.w/2.-text_rect.y/2. : rect.y+rect.w/2.-text_rect.y/1; } - vec2 dims = font_draw_ex(text, gotoxy, NULL, font_draw_cmd); + vec2 dims = font_draw_ex(text, gotoxy, rect, NULL, font_draw_cmd); gotoxy.y += strchr(text, '\n') ? dims.y : 0; gotoxy.x = strchr(text, '\n') ? rect.x : gotoxy.x + dims.x; return dims; @@ -11169,12 +11175,13 @@ vec2 font_print_rect(const char *text, vec4 rect) { vec2 font_print(const char *text) { vec4 dims = {0, 0, window_width(), window_height()}; - return font_print_rect(text, dims); + return font_clip(text, dims); } // Print a code snippet with syntax highlighting vec2 font_highlight(const char *text, const void *colors) { - vec2 dims = font_draw_ex(text, gotoxy, (const char *)colors, font_draw_cmd); + vec4 screen_dim = {0, 0, window_width(), window_height()}; + vec2 dims = font_draw_ex(text, gotoxy, screen_dim, (const char *)colors, font_draw_cmd); gotoxy.y += strchr(text, '\n') ? dims.y : 0; gotoxy.x = strchr(text, '\n') ? 0 : gotoxy.x + dims.x; return dims; @@ -11182,7 +11189,8 @@ vec2 font_highlight(const char *text, const void *colors) { // Calculate the size of a string, in the pixel size specified. Count stray newlines too. vec2 font_rect(const char *str) { - return font_draw_ex(str, gotoxy, NULL, NULL); + vec4 dims = {0, 0, window_width(), window_height()}; + return font_draw_ex(str, gotoxy, dims, NULL, NULL); } font_metrics_t font_metrics(const char *text) { diff --git a/engine/v4k.h b/engine/v4k.h index 71c8fb8..b87155a 100644 --- a/engine/v4k.h +++ b/engine/v4k.h @@ -2213,10 +2213,9 @@ API void font_color(const char *color_tag, uint32_t color); API vec2 font_xy(); API void font_goto(float x, float y); API vec2 font_print(const char *text); -API vec2 font_print_rect(const char *text, vec4 rect); +API vec2 font_clip(const char *text, vec4 rect); 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); // syntax highlighting