diff --git a/src/font/font.c b/src/font/font.c index be5ed1d9..a2ce0986 100644 --- a/src/font/font.c +++ b/src/font/font.c @@ -245,6 +245,7 @@ F_Run F_RunFromString(Arena *arena, F_Font *font, String str) F_Run result = ZI; result.rects = PushDry(arena, F_RunRect); + f32 baseline_length = 0; for (CodepointIter it = InitCodepointIter(str); NextCodepoint(&it);) { u32 codepoint = it.codepoint; @@ -263,15 +264,16 @@ F_Run F_RunFromString(Arena *arena, F_Font *font, String str) rect->atlas_p1 = glyph.atlas_p1; Vec2I32 size = SubVec2I32(glyph.atlas_p1, glyph.atlas_p0); - rect->baseline_start_offset = glyph.baseline_offset; - rect->baseline_start_offset.x += result.baseline_length; + rect->pos = baseline_length; + rect->offset = glyph.baseline_offset; + rect->advance = glyph.advance; - result.p0.x = MinF32(result.p0.x, rect->baseline_start_offset.x); /* Left run bounds */ - result.p1.x = MaxF32(result.p1.x, rect->baseline_start_offset.x + size.x); /* Right run bounds */ - result.p0.y = MinF32(result.p0.y, rect->baseline_start_offset.y); /* Top run bounds */ - result.p1.y = MaxF32(result.p1.y, rect->baseline_start_offset.y + size.y); /* Bottom run bounds */ + result.p0.x = MinF32(result.p0.x, rect->offset.x + rect->pos); /* Left run bounds */ + result.p1.x = MaxF32(result.p1.x, rect->offset.x + rect->pos + size.x); /* Right run bounds */ + result.p0.y = MinF32(result.p0.y, rect->offset.y); /* Top run bounds */ + result.p1.y = MaxF32(result.p1.y, rect->offset.y + size.y); /* Bottom run bounds */ - result.baseline_length += glyph.advance; + baseline_length += rect->advance; } } diff --git a/src/font/font.h b/src/font/font.h index 11c8a800..262682cd 100644 --- a/src/font/font.h +++ b/src/font/font.h @@ -31,7 +31,9 @@ Struct(F_Font) Struct(F_RunRect) { - Vec2 baseline_start_offset; /* Vector from start of baseline to top left of rect */ + Vec2 offset; /* Vector from baseline offset to top left of glyph rect */ + f32 pos; /* Horizontal distance from start of baseline */ + f32 advance; Vec2I32 atlas_p0; Vec2I32 atlas_p1; }; @@ -40,7 +42,6 @@ Struct(F_Run) { Vec2 p0; /* Start of baseline to top-left-most rect */ Vec2 p1; /* Start of baseline to bottom-right-most rect corner */ - f32 baseline_length; u32 count; F_RunRect *rects; }; diff --git a/src/pp/pp.c b/src/pp/pp.c index 5e2144fa..b4b924c6 100644 --- a/src/pp/pp.c +++ b/src/pp/pp.c @@ -369,7 +369,7 @@ void DrawDebugConsole(b32 minimized) if (minimized) { UI_SetNext(BackgroundColor, 0); - UI_SetNext(Width, UI_PIX(500, 1)); + UI_SetNext(Width, UI_PIX(500, 0)); UI_SetNext(Height, UI_FIT(1)); } else @@ -443,7 +443,7 @@ void DrawDebugConsole(b32 minimized) u32 color = colors[log->level][log->color_index]; UI_SetNext(BackgroundColor, color); UI_SetNext(LayoutAxis, Axis_X); - UI_SetNext(Width, UI_FILL(1, 1)); + UI_SetNext(Width, UI_FILL(1, 0)); UI_SetNext(Height, UI_FIT(1)); UI_SetNext(BorderColor, Rgba32F(0.25, 0.25, 0.25, 1)); UI_SetNext(Rounding, 0); @@ -456,7 +456,7 @@ void DrawDebugConsole(b32 minimized) UI_SetNext(Border, 0); UI_SetNext(TextPadding, 6); UI_SetNext(Text, text); - UI_SetNext(Width, UI_FILL(1, 1)); + UI_SetNext(Width, UI_FILL(1, 0)); UI_SetNext(Height, UI_TXT(1)); UI_Box *log_textbox = UI_BuildBox(UI_BoxFlag_DrawText, UI_NilKey); } @@ -2116,7 +2116,7 @@ void UpdateUser(void) UI_SetNext(LayoutAxis, Axis_Y); UI_SetNext(BackgroundColor, 0); UI_SetNext(BorderColor, 0); - UI_SetNext(Width, UI_FIT(1)); + UI_SetNext(Width, UI_FIT(0)); UI_SetNext(Height, UI_FIT(1)); UI_SetNext(Tint, 0); UI_Box *dbg_box = UI_BuildBox(0, UI_NilKey); diff --git a/src/pp/pp_step.c b/src/pp/pp_step.c index 48ea285e..d9fdc31c 100644 --- a/src/pp/pp_step.c +++ b/src/pp/pp_step.c @@ -1096,8 +1096,7 @@ void StepSim(SimStepCtx *ctx) } if (flags & ControlFlag_SpawnTest1) { - // P_LogDebugF("Spawn test 1"); - P_LogDebugF("Spawn test 1 ****************************************************************************************************************************************************************"); + P_LogDebugF("Spawn test 1"); u32 count = 1; f32 spread = 0; for (u32 j = 0; j < count; ++j) diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index b2c2ecf1..8b5bfb8f 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -412,8 +412,12 @@ i64 UI_EndBuild(GPU_Resource *render_target) } if (axis == Axis_X) { - f32 baseline_length = box->glyph_run.baseline_length; - text_size = baseline_length; + if (box->glyph_run.count > 0) + { + F_RunRect rr = box->glyph_run.rects[box->glyph_run.count - 1]; + f32 baseline_length = rr.pos + rr.advance; + text_size = baseline_length; + } } else { @@ -507,8 +511,16 @@ i64 UI_EndBuild(GPU_Resource *render_target) f32 size = child->solved_dims[axis]; f32 strictness = child->pref_size[axis].strictness; f32 flex = size * (1.0 - strictness); - f32 chopoff = MinF32(flex, violation * (flex / flex_accum)); - f32 new_size = size - chopoff; + f32 new_size = size; + if (axis == box->layout_axis) + { + f32 chopoff = MinF32(flex, violation * (flex / flex_accum)); + new_size = size - chopoff; + } + else + { + new_size = MinF32(flex, box->solved_dims[axis]); + } child->solved_dims[axis] = new_size; } } @@ -555,7 +567,7 @@ i64 UI_EndBuild(GPU_Resource *render_target) is_visible = is_visible && (box->p1.y > box->p0.y); if (is_visible || UI_DEBUG) { - /* Push box rect */ + /* Box rect */ { UI_RectInstance *rect = PushStruct(g->draw_rects_arena, UI_RectInstance); rect->flags |= UI_RectFlag_DrawTexture * !!(box->background_texture != 0); @@ -575,14 +587,14 @@ i64 UI_EndBuild(GPU_Resource *render_target) rect->tex_uv1 = box->background_texture_uv1; } } - /* Push text rects */ + + /* Text rects */ if ((box->flags & UI_BoxFlag_DrawText) && box->glyph_run.count > 0 && box->font) { Texture2DRid tex_rid = GPU_Texture2DRidFromResource(box->font->texture); Vec2 inv_font_image_size = VEC2(1.0f / (f32)box->font->image_width, 1.0f / (f32)box->font->image_height); String text = box->display_text; - F_Run run = box->glyph_run; f32 ascent = box->font->ascent; f32 descent = box->font->descent; @@ -591,6 +603,49 @@ i64 UI_EndBuild(GPU_Resource *render_target) Vec2 baseline = box->p0; baseline = AddVec2(baseline, VEC2(padding, padding + ascent)); + F_Run run = box->glyph_run; + f32 max_baseline = box->p1.x - (padding * 2); + b32 should_truncate = run.count > 0 && (run.rects[run.count - 1].pos + run.rects[run.count - 1].advance) > max_baseline; + + /* Truncate run */ + if (should_truncate && !(box->flags & UI_BoxFlag_NoTextTruncation)) + { + /* Get elipses run */ + F_Run trunc_run = F_RunFromString(g->build_arena, box->font, Lit("...")); + if (trunc_run.count > 0) + { + max_baseline -= trunc_run.rects[trunc_run.count - 1].pos + trunc_run.rects[trunc_run.count - 1].advance; + } + + /* Subtract glyphs */ + while (run.count > 0) + { + F_RunRect rr = run.rects[run.count - 1]; + if (rr.pos + rr.advance <= max_baseline) + { + break; + } + --run.count; + } + + /* Merge trunc rects */ + F_RunRect *new_rects = 0; + { + new_rects = PushStructsNoZero(g->build_arena, F_RunRect, run.count + trunc_run.count); + CopyStructs(new_rects, run.rects, run.count); + f32 trunc_offset = run.count > 0 ? (run.rects[run.count - 1].pos + run.rects[run.count - 1].advance) : 0; + for (u32 i = 0; i < trunc_run.count; ++i) + { + F_RunRect *rr = &new_rects[i + run.count]; + *rr = trunc_run.rects[i]; + rr->pos += trunc_offset; + } + } + run.count += trunc_run.count; + run.rects = new_rects; + } + + /* Push text rects */ for (u64 i = 0; i < run.count; ++i) { F_RunRect rr = run.rects[i]; @@ -601,12 +656,12 @@ i64 UI_EndBuild(GPU_Resource *render_target) { UI_RectInstance *rect = PushStruct(g->draw_rects_arena, UI_RectInstance); rect->flags |= UI_RectFlag_DrawTexture; - rect->p0 = AddVec2(baseline, rr.baseline_start_offset); + rect->p0 = AddVec2(baseline, VEC2(rr.pos, 0)); + rect->p0 = AddVec2(rect->p0, rr.offset); rect->p1 = AddVec2(rect->p0, glyph_size); rect->tint_srgb = box->tint; rect->tex_uv0 = MulVec2Vec2(atlas_p0, inv_font_image_size); rect->tex_uv1 = MulVec2Vec2(atlas_p1, inv_font_image_size); - rect->tex = tex_rid; } } diff --git a/src/ui/ui_core.h b/src/ui/ui_core.h index f109347b..0fb104fc 100644 --- a/src/ui/ui_core.h +++ b/src/ui/ui_core.h @@ -87,6 +87,7 @@ Enum(UI_BoxFlag) { UI_BoxFlag_None = 0, UI_BoxFlag_DrawText = (1 << 0), + UI_BoxFlag_NoTextTruncation = (1 << 1), }; Struct(UI_Box)