From 994c84ae5c909a8d1991edbeb0bd0c8951ada4b5 Mon Sep 17 00:00:00 2001 From: jacob Date: Wed, 12 Nov 2025 11:38:35 -0600 Subject: [PATCH] use cap height to center text --- src/font/font.c | 1 + src/font/font.h | 1 + src/proto/pp_game.c | 9 +------ src/proto/pp_game.h | 2 +- src/proto/pp_widgets.c | 7 +++--- src/ttf/ttf.h | 1 + src/ttf/ttf_dwrite/ttf_dwrite.c | 3 +++ src/ui/ui_core.c | 43 ++++++++++++++++++++++++++++++++- 8 files changed, 54 insertions(+), 13 deletions(-) diff --git a/src/font/font.c b/src/font/font.c index 0f4736da..25023f5f 100644 --- a/src/font/font.c +++ b/src/font/font.c @@ -133,6 +133,7 @@ JobDef(F_Load, sig, _) font->size = font_size; font->ascent = decoded.ascent; font->descent = decoded.descent; + font->cap = decoded.cap; /* FIXME: Load baked font instead of panicking */ if (font->glyphs_count <= 0) diff --git a/src/font/font.h b/src/font/font.h index e2bf2b7f..e2922940 100644 --- a/src/font/font.h +++ b/src/font/font.h @@ -24,6 +24,7 @@ Struct(F_Font) f32 size; f32 ascent; f32 descent; + f32 cap; }; //////////////////////////////////////////////////////////// diff --git a/src/proto/pp_game.c b/src/proto/pp_game.c index 1f1bb538..5f36e987 100644 --- a/src/proto/pp_game.c +++ b/src/proto/pp_game.c @@ -147,13 +147,6 @@ JobDef(PP_VisWorker, sig, job_id) } } } - // #define X(name, display, hotkey) \ - // do { - // // PP_Shortcut *shortcut = PushStruct( - // u64 hash = HashFnv64(Fnv64Basis, StringFromStruct(&hotkey)); - // } while (0) - // PP_VisCmdsTableXMacro(X) - // #undef X } ////////////////////////////// @@ -270,7 +263,7 @@ JobDef(PP_VisWorker, sig, job_id) { PP_CommandsWidgetItemDesc item_desc = ZI; item_desc.display_name = desc.display_name; - /* FIXME: Search active shortcuts instead of default hotkeys */ + /* FIXME: Attach active shortcuts instead of default hotkeys */ CopyStructs(item_desc.hotkeys, desc.default_hotkeys, MinU32(countof(item_desc.hotkeys), countof(desc.default_hotkeys))); if (PP_PushCommandsWidgetItem(&persist.commands_widget, item_desc).pressed > 0) { diff --git a/src/proto/pp_game.h b/src/proto/pp_game.h index 9a35645e..f672a818 100644 --- a/src/proto/pp_game.h +++ b/src/proto/pp_game.h @@ -24,7 +24,7 @@ Struct(PP_SimCmd) X(toggle_console, Toggle Developer Console, PP_VisCmdDescFlag_None, PP_HOTKEY( Button_GraveAccent ), ) \ X(toggle_fullscreen, Toggle Fullscreen Mode, PP_VisCmdDescFlag_None, PP_HOTKEY( Button_Enter, .alt = 1 ), PP_HOTKEY( Button_F11 ) ) \ X(toggle_window_topmost, Toggle Window Topmost, PP_VisCmdDescFlag_None, PP_HOTKEY( Button_F4 ), ) \ - X(spawn, Spawn, PP_VisCmdDescFlag_None, PP_HOTKEY( Button_S, .ctrl = 1 ), ) \ + X(spawn, Ctrl, PP_VisCmdDescFlag_None, PP_HOTKEY( Button_S, .ctrl = 1 ), ) \ /* -------------------------------------------------------------------------------------------------------------------- */ //////////////////////////////////////////////////////////// diff --git a/src/proto/pp_widgets.c b/src/proto/pp_widgets.c index decb1b11..bb74c5fb 100644 --- a/src/proto/pp_widgets.c +++ b/src/proto/pp_widgets.c @@ -201,6 +201,7 @@ void PP_EndCommandsWidget(PP_CommandsWidget *widget) UI_BuildSpacer(UI_PIX(20, 1), Axis_X); /* Command label */ + UI_SetNext(ChildAlignment, UI_Alignment_Center); UI_BuildLabel(item->desc.display_name); /* Middle spacer */ @@ -233,16 +234,16 @@ void PP_EndCommandsWidget(PP_CommandsWidget *widget) } else { + UI_BuildSpacer(UI_PIX(10, 1), Axis_X); + String hotkey_name = PP_StringFromHotkey(UI_FrameArena(), hotkey); UI_SetNext(BackgroundColor, hotkey_color); UI_SetNext(BorderColor, hotkey_border_color); UI_SetNext(Text, hotkey_name); - UI_SetNext(Width, UI_SHRINK(theme.text_padding_x + 5, 1)); - // UI_SetNext(Width, UI_SHRINK(0, 1)); + UI_SetNext(Width, UI_SHRINK(theme.text_padding_x, 1)); UI_SetNext(Height, UI_GROW(1, 0)); UI_SetNext(Rounding, UI_RPIX(5)); UI_SetNext(Border, 1); - // UI_SetNext(BackgroundColor, Color_Cyan); UI_SetNext(ChildAlignment, UI_Alignment_Center); UI_SetNext(Flags, UI_BoxFlag_DrawText | UI_BoxFlag_Interactable); UI_PushCP(UI_BuildRowEx(hotkey_key)); diff --git a/src/ttf/ttf.h b/src/ttf/ttf.h index ee0d4506..ca2675f9 100644 --- a/src/ttf/ttf.h +++ b/src/ttf/ttf.h @@ -18,6 +18,7 @@ Struct(TTF_Decoded) /* Metrics */ f32 ascent; f32 descent; + f32 cap; }; diff --git a/src/ttf/ttf_dwrite/ttf_dwrite.c b/src/ttf/ttf_dwrite/ttf_dwrite.c index 2327d89c..20516c3f 100644 --- a/src/ttf/ttf_dwrite/ttf_dwrite.c +++ b/src/ttf/ttf_dwrite/ttf_dwrite.c @@ -137,6 +137,7 @@ TTF_Decoded TTF_Decode(Arena *arena, String encoded, f32 em_size, u32 *cache_cod i32 ascent = 0; i32 descent = 0; + i32 cap = 0; //- Fill atlas & metric data u32 out_offset_x = 0; @@ -178,6 +179,7 @@ TTF_Decoded TTF_Decode(Arena *arena, String encoded, f32 em_size, u32 *cache_cod error = IDWriteFontFace_GetDesignGlyphMetrics(font_face, &i, 1, &glyph_metrics, 0); ascent = metrics.ascent * pixel_per_design_unit; descent = metrics.descent * pixel_per_design_unit; + cap = metrics.capHeight * pixel_per_design_unit; f32 off_x = (f32)bounding_box.left - raster_target_x; f32 off_y = (f32)bounding_box.top - raster_target_y; @@ -282,5 +284,6 @@ TTF_Decoded TTF_Decode(Arena *arena, String encoded, f32 em_size, u32 *cache_cod result.image_pixels = (u32 *)atlas_memory; result.ascent = ascent; result.descent = descent; + result.cap = cap; return result; } diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index 52a53d00..7afab8e0 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -313,6 +313,46 @@ UI_Style UI_PopStyle(UI_StyleDesc desc) result = UI_PopStyle(desc); } }; + + case UI_StyleKind_ChildAlignment: + { + UI_StyleDesc x_desc = desc; + UI_StyleDesc y_desc = desc; + x_desc.style.kind = UI_StyleKind_ChildAlignmentX; + y_desc.style.kind = UI_StyleKind_ChildAlignmentY; + UI_AxisAlignment x_alignment = UI_PopStyle(x_desc).ChildAlignmentX; + UI_AxisAlignment y_alignment = UI_PopStyle(y_desc).ChildAlignmentY; + switch(y_alignment) + { + case UI_AxisAlignment_Start: + { + switch(x_alignment) + { + case UI_AxisAlignment_Start: { result.ChildAlignment = UI_Alignment_TopLeft; } break; + case UI_AxisAlignment_Center: { result.ChildAlignment = UI_Alignment_Top; } break; + case UI_AxisAlignment_End: { result.ChildAlignment = UI_Alignment_TopRight; } break; + } + } break; + case UI_AxisAlignment_Center: + { + switch(x_alignment) + { + case UI_AxisAlignment_Start: { result.ChildAlignment = UI_Alignment_Left; } break; + case UI_AxisAlignment_Center: { result.ChildAlignment = UI_Alignment_Center; } break; + case UI_AxisAlignment_End: { result.ChildAlignment = UI_Alignment_Right; } break; + } + } break; + case UI_AxisAlignment_End: + { + switch(x_alignment) + { + case UI_AxisAlignment_Start: { result.ChildAlignment = UI_Alignment_BottomLeft; } break; + case UI_AxisAlignment_Center: { result.ChildAlignment = UI_Alignment_Bottom; } break; + case UI_AxisAlignment_End: { result.ChildAlignment = UI_Alignment_BottomRight; } break; + } + } break; + } + } break; } } else @@ -1275,6 +1315,7 @@ i64 UI_EndFrame(UI_Frame frame) /* Calculate baseline */ f32 ascent = box->font->ascent; f32 descent = box->font->descent; + f32 cap = box->font->cap; f32 baseline_width = run.count > 0 ? (run.rects[run.count - 1].pos + run.rects[run.count - 1].advance) : 0; f32 baseline_height = ascent + descent; f32 box_width = box->p1.x - box->p0.x; @@ -1313,7 +1354,7 @@ i64 UI_EndFrame(UI_Frame frame) { baseline.y = box->p0.y; baseline.y += box_height / 2; - baseline.y += baseline_height / 4; + baseline.y += cap / 2; } break; } baseline = CeilVec2(baseline);