diff --git a/src/pp/pp_vis/pp_vis_core.c b/src/pp/pp_vis/pp_vis_core.c index c6822193..68b1d095 100644 --- a/src/pp/pp_vis/pp_vis_core.c +++ b/src/pp/pp_vis/pp_vis_core.c @@ -82,11 +82,16 @@ V_WidgetTheme V_GetWidgetTheme(void) // theme.font = GC_FontKeyFromResource(ResourceKeyFromStore(&V_Resources, Lit("font/fixedsys.ttf"))); // theme.font_size = 16; - // theme.font = GC_FontKeyFromResource(ResourceKeyFromStore(&V_Resources, Lit("font/seguisb.ttf"))); - // theme.font_size = 16; - theme.font = GC_FontKeyFromResource(ResourceKeyFromStore(&V_Resources, Lit("font/seguisb.ttf"))); - theme.font_size = 12; + theme.font_size = 16; + + // theme.font = GC_FontKeyFromResource(ResourceKeyFromStore(&V_Resources, Lit("font/seguisb.ttf"))); + // theme.font_size = 12; + + + // theme.font = GC_FontKeyFromResource(ResourceKeyFromStore(&V_Resources, Lit("font/seguisb.ttf"))); + // theme.font_size = 30; + theme.window_background_color = Rgb32(0xff1a1d1e); theme.window_border_color = Rgb32(0xff343a3b); @@ -1301,8 +1306,8 @@ void V_TickForever(WaveLaneCtx *lane) } window_border_color = LerpSrgb(window_border_color, Rgb32(0x0078a6), titlebar_rep.hot); - UI_Push(Scale, LerpF32(0.75, 1, palette->show)); UI_Push(Tint, VEC4(1, 1, 1, palette->show)); + UI_SetNext(Scale, LerpF32(0.75, 1, palette->show)); UI_Push(BackgroundColor, window_background_color); UI_Push(BorderColor, window_border_color); diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index e0afe735..64b47c61 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -873,6 +873,36 @@ Vec2 UI_CursorPos(void) return UI_CurrentFrame()->cursor_pos; } +//////////////////////////////////////////////////////////// +//~ Text layout helpers + +GC_Run UI_ScaleRun(Arena *arena, GC_Run unscaled_run, f32 scale) +{ + GC_Run result = Zi; + result = unscaled_run; + + result.font_size *= scale; + result.font_ascent *= scale; + result.font_descent *= scale; + result.font_cap *= scale; + result.baseline_length *= scale; + + result.rects_count = unscaled_run.rects_count; + result.rects = PushStructsNoZero(arena, GC_RunRect, result.rects_count); + for (u64 rect_idx = 0; rect_idx < result.rects_count; ++rect_idx) + { + GC_RunRect *src = &unscaled_run.rects[rect_idx]; + GC_RunRect *dst = &result.rects[rect_idx]; + + *dst = *src; + dst->bounds = MulRng2Vec2(dst->bounds, VEC2(scale, scale)); + dst->advance *= scale; + dst->baseline_pos *= scale; + } + + return result; +} + //////////////////////////////////////////////////////////// //~ End frame @@ -1103,7 +1133,7 @@ void UI_EndFrame(UI_Frame *frame) UI_Size sem_dims = box->desc.pref_semantic_dims[axis]; if (sem_dims.kind == UI_SizeKind_Pixel) { - box->solved_dims.v[axis] = RoundF32(sem_dims.v * box->desc.scale); + box->solved_dims.v[axis] = sem_dims.v; } else if (sem_dims.kind == UI_SizeKind_Shrink && AnyBit(box->desc.flags, UI_BoxFlag_DrawText)) { @@ -1117,7 +1147,7 @@ void UI_EndFrame(UI_Frame *frame) { text_size = box->glyph_run.font_ascent + box->glyph_run.font_descent; } - box->solved_dims.v[axis] = RoundF32(text_size + (sem_dims.v * 2)); + box->solved_dims.v[axis] = text_size + (sem_dims.v * 2); } } } @@ -1144,7 +1174,7 @@ void UI_EndFrame(UI_Frame *frame) found_match = 1; } } - box->solved_dims.v[axis] = RoundF32(match_size * sem_dims.v); + box->solved_dims.v[axis] = match_size * sem_dims.v; } } } @@ -1173,7 +1203,7 @@ void UI_EndFrame(UI_Frame *frame) } } } - box->solved_dims.v[axis] = CeilF32(accum + (sem_dims.v * 2)); + box->solved_dims.v[axis] = accum + (sem_dims.v * 2); } } } @@ -1188,7 +1218,7 @@ void UI_EndFrame(UI_Frame *frame) UI_Size sem_dims = box->desc.pref_semantic_dims[axis]; if (sem_dims.kind == UI_SizeKind_Grow) { - box->solved_dims.v[axis] = RoundF32(box->parent->solved_dims.v[axis] * sem_dims.v); + box->solved_dims.v[axis] = box->parent->solved_dims.v[axis] * sem_dims.v; } } } @@ -1248,7 +1278,7 @@ void UI_EndFrame(UI_Frame *frame) } } adjusted_size_accum += new_size; - child->solved_dims.v[axis] = RoundF32(new_size); + child->solved_dims.v[axis] = new_size; } } size_accum = adjusted_size_accum; @@ -1265,13 +1295,42 @@ void UI_EndFrame(UI_Frame *frame) { f32 strictness = child->desc.pref_semantic_dims[axis].strictness; f32 flex = size * (1.0 - strictness); - child->solved_dims.v[axis] = RoundF32(MaxF32(size - flex, box_size)); + child->solved_dims.v[axis] = MaxF32(size - flex, box_size); } } } } } + // Apply scale + for (u64 pre_index = 0; pre_index < boxes_count; ++pre_index) + { + UI_Box *box = boxes_pre[pre_index]; + UI_Box *parent = box->parent; + + box->solved_scale = box->desc.scale; + if (parent) + { + box->solved_scale *= parent->solved_scale; + } + + for (Axis axis = 0; axis < Axis_COUNTXY; ++axis) + { + UI_Size sem_dims = box->desc.pref_semantic_dims[axis]; + f32 unscaled_size = box->solved_dims.v[axis]; + f32 scaled_size = unscaled_size * box->solved_scale; + // if (AbsF32(1.0 - box->solved_scale) < 0.001) + // { + // scaled_size = unscaled_size; + // } + if (unscaled_size >= 1) + { + scaled_size = MaxF32(scaled_size, 1); + } + box->solved_dims.v[axis] = scaled_size; + } + } + // Compute final positions for (u64 pre_index = 0; pre_index < boxes_count; ++pre_index) { @@ -1336,7 +1395,9 @@ void UI_EndFrame(UI_Frame *frame) } break; } } + offset = SubVec2(box->desc.floating_pos, anchor_offset); + offset = FloorVec2(offset); final_pos = AddVec2(parent->screen_rect.p0, offset); if (!AnyBit(box->desc.flags, UI_BoxFlag_NoFloatingClamp)) @@ -1381,13 +1442,14 @@ void UI_EndFrame(UI_Frame *frame) } break; } } + offset = RoundVec2(offset); final_pos.x = parent->screen_rect.p0.x + offset.x; final_pos.y = parent->screen_rect.p0.y + offset.y; parent->cursor += box->solved_dims.v[parent->desc.child_layout_axis]; } // Submit position - Vec2 rounded_final_pos = FloorVec2(final_pos); + Vec2 rounded_final_pos = final_pos; box->screen_rect.p0 = rounded_final_pos; box->screen_rect.p1 = AddVec2(rounded_final_pos, box->solved_dims); @@ -1485,10 +1547,11 @@ void UI_EndFrame(UI_Frame *frame) } // Text rects - GC_Run raw_run = box->glyph_run; + GC_Run raw_run_unscaled = box->glyph_run; + GC_Run raw_run = UI_ScaleRun(frame->arena, raw_run_unscaled, box->solved_scale); if (AnyBit(box->desc.flags, UI_BoxFlag_DrawText) && raw_run.ready) { - f32 max_baseline = DimsFromRng2(box->screen_rect).x; + f32 max_baseline = CeilF32(DimsFromRng2(box->screen_rect).x); b32 should_truncate = raw_run.baseline_length > max_baseline && !AnyBit(box->desc.flags, UI_BoxFlag_NoTextTruncation); // Truncate run @@ -1498,7 +1561,8 @@ void UI_EndFrame(UI_Frame *frame) if (should_truncate) { // Get elipses run - GC_Run elipses_run = GC_RunFromString(scratch.arena, Lit("..."), box->desc.font, box->desc.font_size); + GC_Run elipses_run_unscaled = GC_RunFromString(scratch.arena, Lit("..."), box->desc.font, box->desc.font_size); + GC_Run elipses_run = UI_ScaleRun(frame->arena, elipses_run_unscaled, box->solved_scale); f32 truncation_offset = max_baseline - elipses_run.baseline_length; // Append non-overflowed rects diff --git a/src/ui/ui_core.h b/src/ui/ui_core.h index cd2f1a06..9d0caee7 100644 --- a/src/ui/ui_core.h +++ b/src/ui/ui_core.h @@ -309,6 +309,7 @@ Struct(UI_Box) //- Layout data f32 cursor; f32 final_children_size_accum[Axis_COUNTXY]; + f32 solved_scale; Vec2 solved_dims; //- Layout results @@ -529,6 +530,11 @@ UI_Frame *UI_LastFrame(void); Arena *UI_FrameArena(void); Vec2 UI_CursorPos(void); +//////////////////////////////////////////////////////////// +//~ Text layout helpers + +GC_Run UI_ScaleRun(Arena *arena, GC_Run unscaled_run, f32 scale); + //////////////////////////////////////////////////////////// //~ End frame