Last active
August 18, 2025 14:18
-
-
Save ogam/0ebe3773c835a795c9f3357a1ec477d2 to your computer and use it in GitHub Desktop.
cute font debug view
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <cute.h> | |
| #include "cimgui.h" | |
| #include "build/_deps/cute-src/src/internal/cute_font_internal.h" | |
| #ifdef USE_PROGGY | |
| #define FONT_NAME "ProggyClean" | |
| #include "proggy.h" | |
| #else | |
| #define FONT_NAME "Calibri" | |
| #endif | |
| enum | |
| { | |
| font_state_text_aabb = 1 << 0, | |
| font_state_glyph = 1 << 1, | |
| }; | |
| int main(int argc, char *argv[]) | |
| { | |
| int options = CF_APP_OPTIONS_WINDOW_POS_CENTERED_BIT | CF_APP_OPTIONS_RESIZABLE_BIT; | |
| int display_index = 0; | |
| int x = 0; | |
| int y = 0; | |
| int w = 640; | |
| int h = 480; | |
| CF_Result result = cf_make_app("cute text test", display_index, x, y, w, h, options, argv[0]); | |
| if (cf_is_error(result)) return -1; | |
| cf_app_init_imgui(); | |
| #ifdef USE_PROGGY | |
| cf_make_font_from_memory(proggy_data, proggy_sz, FONT_NAME); | |
| #endif | |
| const char *text = "Some not so lOng Text"; | |
| int font_state = 0; | |
| float font_size = 26.0f; | |
| float font_size_min = font_size * 0.5f; | |
| float font_size_max = font_size * 4.0f; | |
| int glyph_index = 0; | |
| int text_glyph_length = 0; | |
| { | |
| const char *s = text; | |
| while (true) | |
| { | |
| int codepoint = 0; | |
| s = cf_decode_UTF8(s, &codepoint); | |
| if (codepoint == 0) | |
| { | |
| break; | |
| } | |
| text_glyph_length++; | |
| } | |
| } | |
| while (cf_app_is_running()) | |
| { | |
| cf_app_update(nullptr); | |
| cf_push_font(FONT_NAME); | |
| cf_push_font_size(font_size); | |
| CF_V2 text_size = cf_text_size(text, -1); | |
| CF_V2 text_position = cf_v2(0, 0); | |
| text_position.x -= text_size.x * 0.5f; | |
| CF_Aabb text_aabb = cf_make_aabb_from_top_left(text_position, text_size.x, text_size.y); | |
| cf_draw_push_color(cf_color_white()); | |
| cf_draw_text(text, text_position, -1); | |
| cf_draw_pop_color(); | |
| if (font_state & font_state_text_aabb) | |
| { | |
| cf_draw_push_color(cf_color_grey()); | |
| cf_draw_box(text_aabb, 0.0f, 1.0f); | |
| cf_draw_pop_color(); | |
| } | |
| if (font_state & font_state_glyph) | |
| { | |
| CF_Font* font = cf_font_get(FONT_NAME); | |
| float x_offset = 0; | |
| int prev_codepoint = 0; | |
| int codepoint = 0; | |
| int current_glyph_index = 0; | |
| { | |
| const char *s = text; | |
| while (true) | |
| { | |
| prev_codepoint = codepoint; | |
| s = cf_decode_UTF8(s, &codepoint); | |
| if (current_glyph_index == glyph_index) | |
| { | |
| break; | |
| } | |
| if (codepoint == 0) | |
| { | |
| break; | |
| } | |
| CF_Glyph* glyph = cf_font_get_glyph(font, codepoint, font_size, 0); | |
| x_offset += glyph->xadvance; | |
| current_glyph_index ++; | |
| } | |
| } | |
| if (codepoint) | |
| { | |
| CF_Font* font = cf_font_get(FONT_NAME); | |
| CF_Glyph* glyph = cf_font_get_glyph(font, codepoint, font_size, 0); | |
| float scale = stbtt_ScaleForPixelHeight(&font->info, font_size); | |
| float ascent = font->ascent * scale; | |
| float descent = font->descent * scale; | |
| float line_gap = font->line_gap * scale; | |
| float line_height = font->line_height * scale; | |
| float kerning = cf_font_get_kern(font, font_size, prev_codepoint, codepoint); | |
| CF_V2 glyph_position = text_position; | |
| glyph_position.y -= line_height - ascent - descent; | |
| glyph_position.x += x_offset; | |
| CF_V2 glyph_min = glyph_position; | |
| CF_V2 glyph_max = glyph_position; | |
| glyph_min = cf_add_v2(glyph_min, glyph->q0); | |
| glyph_max = cf_add_v2(glyph_max, glyph->q1); | |
| CF_Aabb glyph_aabb = cf_make_aabb(glyph_min, glyph_max); | |
| // origin | |
| { | |
| CF_V2 p0 = cf_v2(glyph_min.x, glyph_position.y); | |
| CF_V2 p1 = cf_v2(glyph_max.x, glyph_position.y); | |
| cf_draw_push_color(cf_color_red()); | |
| cf_draw_line(p0, p1, 1.0f); | |
| cf_draw_pop_color(); | |
| } | |
| // ascent | |
| { | |
| CF_V2 p0 = cf_v2(glyph_min.x, glyph_position.y + ascent); | |
| CF_V2 p1 = cf_v2(glyph_max.x, glyph_position.y + ascent); | |
| cf_draw_push_color(cf_color_cyan()); | |
| cf_draw_line(p0, p1, 1.0f); | |
| cf_draw_pop_color(); | |
| } | |
| // ascent | |
| { | |
| CF_V2 p0 = cf_v2(glyph_min.x, glyph_position.y + descent); | |
| CF_V2 p1 = cf_v2(glyph_max.x, glyph_position.y + descent); | |
| cf_draw_push_color(cf_color_orange()); | |
| cf_draw_line(p0, p1, 1.0f); | |
| cf_draw_pop_color(); | |
| } | |
| // xadvance | |
| { | |
| // offset y a bit so it doesn't overlap with origin line | |
| CF_V2 p0 = cf_v2(glyph_min.x , glyph_position.y - descent); | |
| CF_V2 p1 = cf_v2(glyph_min.x + glyph->xadvance, glyph_position.y - descent); | |
| cf_draw_push_color(cf_color_yellow()); | |
| cf_draw_line(p0, p1, 1.0f); | |
| cf_draw_pop_color(); | |
| } | |
| cf_draw_push_color(cf_color_grey()); | |
| cf_draw_box(glyph_aabb, 0.0f, 1.0f); | |
| cf_draw_pop_color(); | |
| } | |
| } | |
| cf_pop_font_size(); | |
| cf_pop_font(); | |
| igBegin("Font", 0, ImGuiWindowFlags_None); | |
| { | |
| igCheckboxFlags_IntPtr("Text Aabb", &font_state, font_state_text_aabb); | |
| igCheckboxFlags_IntPtr("Glyph", &font_state, font_state_glyph); | |
| igSliderInt("Glyph Index", &glyph_index, 0, text_glyph_length - 1, "%d", ImGuiSliderFlags_ClampOnInput); | |
| igSliderFloat("Font Size", &font_size, font_size_min, font_size_max, "%.0f", ImGuiSliderFlags_ClampOnInput); | |
| } | |
| igEnd(); | |
| cf_app_draw_onto_screen(true); | |
| } | |
| cf_destroy_app(); | |
| return 0; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment