text truncation
This commit is contained in:
parent
04d8039f5c
commit
658527738a
@ -245,6 +245,7 @@ F_Run F_RunFromString(Arena *arena, F_Font *font, String str)
|
|||||||
F_Run result = ZI;
|
F_Run result = ZI;
|
||||||
result.rects = PushDry(arena, F_RunRect);
|
result.rects = PushDry(arena, F_RunRect);
|
||||||
|
|
||||||
|
f32 baseline_length = 0;
|
||||||
for (CodepointIter it = InitCodepointIter(str); NextCodepoint(&it);)
|
for (CodepointIter it = InitCodepointIter(str); NextCodepoint(&it);)
|
||||||
{
|
{
|
||||||
u32 codepoint = it.codepoint;
|
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;
|
rect->atlas_p1 = glyph.atlas_p1;
|
||||||
Vec2I32 size = SubVec2I32(glyph.atlas_p1, glyph.atlas_p0);
|
Vec2I32 size = SubVec2I32(glyph.atlas_p1, glyph.atlas_p0);
|
||||||
|
|
||||||
rect->baseline_start_offset = glyph.baseline_offset;
|
rect->pos = baseline_length;
|
||||||
rect->baseline_start_offset.x += result.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.p0.x = MinF32(result.p0.x, rect->offset.x + rect->pos); /* Left run bounds */
|
||||||
result.p1.x = MaxF32(result.p1.x, rect->baseline_start_offset.x + size.x); /* Right 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->baseline_start_offset.y); /* Top run bounds */
|
result.p0.y = MinF32(result.p0.y, rect->offset.y); /* Top run bounds */
|
||||||
result.p1.y = MaxF32(result.p1.y, rect->baseline_start_offset.y + size.y); /* Bottom 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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -31,7 +31,9 @@ Struct(F_Font)
|
|||||||
|
|
||||||
Struct(F_RunRect)
|
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_p0;
|
||||||
Vec2I32 atlas_p1;
|
Vec2I32 atlas_p1;
|
||||||
};
|
};
|
||||||
@ -40,7 +42,6 @@ Struct(F_Run)
|
|||||||
{
|
{
|
||||||
Vec2 p0; /* Start of baseline to top-left-most rect */
|
Vec2 p0; /* Start of baseline to top-left-most rect */
|
||||||
Vec2 p1; /* Start of baseline to bottom-right-most rect corner */
|
Vec2 p1; /* Start of baseline to bottom-right-most rect corner */
|
||||||
f32 baseline_length;
|
|
||||||
u32 count;
|
u32 count;
|
||||||
F_RunRect *rects;
|
F_RunRect *rects;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -369,7 +369,7 @@ void DrawDebugConsole(b32 minimized)
|
|||||||
if (minimized)
|
if (minimized)
|
||||||
{
|
{
|
||||||
UI_SetNext(BackgroundColor, 0);
|
UI_SetNext(BackgroundColor, 0);
|
||||||
UI_SetNext(Width, UI_PIX(500, 1));
|
UI_SetNext(Width, UI_PIX(500, 0));
|
||||||
UI_SetNext(Height, UI_FIT(1));
|
UI_SetNext(Height, UI_FIT(1));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -443,7 +443,7 @@ void DrawDebugConsole(b32 minimized)
|
|||||||
u32 color = colors[log->level][log->color_index];
|
u32 color = colors[log->level][log->color_index];
|
||||||
UI_SetNext(BackgroundColor, color);
|
UI_SetNext(BackgroundColor, color);
|
||||||
UI_SetNext(LayoutAxis, Axis_X);
|
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(Height, UI_FIT(1));
|
||||||
UI_SetNext(BorderColor, Rgba32F(0.25, 0.25, 0.25, 1));
|
UI_SetNext(BorderColor, Rgba32F(0.25, 0.25, 0.25, 1));
|
||||||
UI_SetNext(Rounding, 0);
|
UI_SetNext(Rounding, 0);
|
||||||
@ -456,7 +456,7 @@ void DrawDebugConsole(b32 minimized)
|
|||||||
UI_SetNext(Border, 0);
|
UI_SetNext(Border, 0);
|
||||||
UI_SetNext(TextPadding, 6);
|
UI_SetNext(TextPadding, 6);
|
||||||
UI_SetNext(Text, text);
|
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_SetNext(Height, UI_TXT(1));
|
||||||
UI_Box *log_textbox = UI_BuildBox(UI_BoxFlag_DrawText, UI_NilKey);
|
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(LayoutAxis, Axis_Y);
|
||||||
UI_SetNext(BackgroundColor, 0);
|
UI_SetNext(BackgroundColor, 0);
|
||||||
UI_SetNext(BorderColor, 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(Height, UI_FIT(1));
|
||||||
UI_SetNext(Tint, 0);
|
UI_SetNext(Tint, 0);
|
||||||
UI_Box *dbg_box = UI_BuildBox(0, UI_NilKey);
|
UI_Box *dbg_box = UI_BuildBox(0, UI_NilKey);
|
||||||
|
|||||||
@ -1096,8 +1096,7 @@ void StepSim(SimStepCtx *ctx)
|
|||||||
}
|
}
|
||||||
if (flags & ControlFlag_SpawnTest1)
|
if (flags & ControlFlag_SpawnTest1)
|
||||||
{
|
{
|
||||||
// P_LogDebugF("Spawn test 1");
|
P_LogDebugF("Spawn test 1");
|
||||||
P_LogDebugF("Spawn test 1 ****************************************************************************************************************************************************************");
|
|
||||||
u32 count = 1;
|
u32 count = 1;
|
||||||
f32 spread = 0;
|
f32 spread = 0;
|
||||||
for (u32 j = 0; j < count; ++j)
|
for (u32 j = 0; j < count; ++j)
|
||||||
|
|||||||
@ -412,8 +412,12 @@ i64 UI_EndBuild(GPU_Resource *render_target)
|
|||||||
}
|
}
|
||||||
if (axis == Axis_X)
|
if (axis == Axis_X)
|
||||||
{
|
{
|
||||||
f32 baseline_length = box->glyph_run.baseline_length;
|
if (box->glyph_run.count > 0)
|
||||||
text_size = baseline_length;
|
{
|
||||||
|
F_RunRect rr = box->glyph_run.rects[box->glyph_run.count - 1];
|
||||||
|
f32 baseline_length = rr.pos + rr.advance;
|
||||||
|
text_size = baseline_length;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -507,8 +511,16 @@ i64 UI_EndBuild(GPU_Resource *render_target)
|
|||||||
f32 size = child->solved_dims[axis];
|
f32 size = child->solved_dims[axis];
|
||||||
f32 strictness = child->pref_size[axis].strictness;
|
f32 strictness = child->pref_size[axis].strictness;
|
||||||
f32 flex = size * (1.0 - strictness);
|
f32 flex = size * (1.0 - strictness);
|
||||||
f32 chopoff = MinF32(flex, violation * (flex / flex_accum));
|
f32 new_size = size;
|
||||||
f32 new_size = size - chopoff;
|
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;
|
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);
|
is_visible = is_visible && (box->p1.y > box->p0.y);
|
||||||
if (is_visible || UI_DEBUG)
|
if (is_visible || UI_DEBUG)
|
||||||
{
|
{
|
||||||
/* Push box rect */
|
/* Box rect */
|
||||||
{
|
{
|
||||||
UI_RectInstance *rect = PushStruct(g->draw_rects_arena, UI_RectInstance);
|
UI_RectInstance *rect = PushStruct(g->draw_rects_arena, UI_RectInstance);
|
||||||
rect->flags |= UI_RectFlag_DrawTexture * !!(box->background_texture != 0);
|
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;
|
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)
|
if ((box->flags & UI_BoxFlag_DrawText) && box->glyph_run.count > 0 && box->font)
|
||||||
{
|
{
|
||||||
Texture2DRid tex_rid = GPU_Texture2DRidFromResource(box->font->texture);
|
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);
|
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;
|
String text = box->display_text;
|
||||||
F_Run run = box->glyph_run;
|
|
||||||
|
|
||||||
f32 ascent = box->font->ascent;
|
f32 ascent = box->font->ascent;
|
||||||
f32 descent = box->font->descent;
|
f32 descent = box->font->descent;
|
||||||
@ -591,6 +603,49 @@ i64 UI_EndBuild(GPU_Resource *render_target)
|
|||||||
Vec2 baseline = box->p0;
|
Vec2 baseline = box->p0;
|
||||||
baseline = AddVec2(baseline, VEC2(padding, padding + ascent));
|
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)
|
for (u64 i = 0; i < run.count; ++i)
|
||||||
{
|
{
|
||||||
F_RunRect rr = run.rects[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);
|
UI_RectInstance *rect = PushStruct(g->draw_rects_arena, UI_RectInstance);
|
||||||
rect->flags |= UI_RectFlag_DrawTexture;
|
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->p1 = AddVec2(rect->p0, glyph_size);
|
||||||
rect->tint_srgb = box->tint;
|
rect->tint_srgb = box->tint;
|
||||||
rect->tex_uv0 = MulVec2Vec2(atlas_p0, inv_font_image_size);
|
rect->tex_uv0 = MulVec2Vec2(atlas_p0, inv_font_image_size);
|
||||||
rect->tex_uv1 = MulVec2Vec2(atlas_p1, inv_font_image_size);
|
rect->tex_uv1 = MulVec2Vec2(atlas_p1, inv_font_image_size);
|
||||||
|
|
||||||
rect->tex = tex_rid;
|
rect->tex = tex_rid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -87,6 +87,7 @@ Enum(UI_BoxFlag)
|
|||||||
{
|
{
|
||||||
UI_BoxFlag_None = 0,
|
UI_BoxFlag_None = 0,
|
||||||
UI_BoxFlag_DrawText = (1 << 0),
|
UI_BoxFlag_DrawText = (1 << 0),
|
||||||
|
UI_BoxFlag_NoTextTruncation = (1 << 1),
|
||||||
};
|
};
|
||||||
|
|
||||||
Struct(UI_Box)
|
Struct(UI_Box)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user