Skip to content

Commit de53322

Browse files
replace glyph run API with text line API in UI widgets
1 parent f664682 commit de53322

File tree

5 files changed

+77
-65
lines changed

5 files changed

+77
-65
lines changed

src/graphics/graphics.h

Lines changed: 8 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -140,16 +140,6 @@ typedef enum
140140

141141
} oc_text_direction;
142142

143-
typedef struct oc_text_shape_settings
144-
{
145-
oc_str8 script; //TODO: replace with anonymous struct and have a helper to get it from string?
146-
oc_str8 lang;
147-
oc_text_direction direction;
148-
149-
} oc_text_shape_settings;
150-
151-
typedef struct oc_glyph_run oc_glyph_run;
152-
153143
typedef struct oc_text_attributes
154144
{
155145
oc_font font;
@@ -331,37 +321,20 @@ ORCA_API void oc_stroke(void);
331321
//------------------------------------------------------------------------------------------
332322
//SECTION: text
333323
//------------------------------------------------------------------------------------------
334-
// shaping
335-
ORCA_API oc_glyph_run* oc_text_shape(oc_arena* arena,
336-
oc_font font,
337-
oc_text_shape_settings* settings,
338-
oc_str32 codepoints,
339-
u64 begin,
340-
u64 end);
341324

342-
// measuring
343-
ORCA_API u64 oc_glyph_run_point_to_cursor(oc_glyph_run* run, f32 size, oc_vec2 point);
344-
ORCA_API oc_vec2 oc_glyph_run_cursor_to_point(oc_glyph_run* run, f32 size, u64 cursor);
325+
// text lines
326+
ORCA_API oc_text_line* oc_text_line_from_utf8(oc_arena* arena, oc_str8 string, oc_text_attributes* attributes);
327+
ORCA_API oc_text_line* oc_text_line_from_utf32(oc_arena* arena, oc_str32 string, oc_text_attributes* attributes);
345328

346-
ORCA_API oc_text_metrics oc_glyph_run_range_metrics(oc_glyph_run* run, f32 fontSize, u64 begin, u64 end);
329+
ORCA_API oc_text_metrics oc_text_line_get_metrics(oc_text_line* line);
330+
ORCA_API oc_text_metrics oc_text_line_get_metrics_for_range(oc_text_line* line, u64 start, u64 end);
331+
ORCA_API u64 oc_text_line_codepoint_index_for_position(oc_text_line* line, oc_vec2 position);
332+
ORCA_API oc_vec2 oc_text_line_position_for_codepoint_index(oc_text_line* line, u64 index);
347333

348-
// drawing
349-
ORCA_API void oc_text_draw_run(oc_glyph_run* run, f32 fontSize);
334+
ORCA_API void oc_text_line_draw(oc_text_line* line);
350335
ORCA_API void oc_text_draw_utf8(oc_str8 text, oc_font font, f32 fontSize);
351336
ORCA_API void oc_text_draw_utf32(oc_str32 codepoints, oc_font font, f32 fontSize);
352337

353-
// text lines
354-
oc_text_line* oc_text_line_from_utf8(oc_arena* arena, oc_str8 string, oc_text_attributes* attributes);
355-
oc_text_line* oc_text_line_from_utf32(oc_arena* arena, oc_str32 string, oc_text_attributes* attributes);
356-
357-
oc_text_metrics oc_text_line_get_metrics(oc_text_line* line);
358-
oc_text_metrics oc_text_line_get_metrics_for_range(oc_text_line* line, u64 start, u64 end);
359-
360-
u64 oc_text_line_codepoint_index_for_position(oc_text_line* line, oc_vec2 position);
361-
oc_vec2 oc_text_line_position_for_codepoint_index(oc_text_line* line, u64 index);
362-
363-
void oc_text_line_draw(oc_text_line* line);
364-
365338
//------------------------------------------------------------------------------------------
366339
//SECTION: shapes helpers
367340
//------------------------------------------------------------------------------------------

src/graphics/graphics_common.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1288,9 +1288,14 @@ void oc_text_draw_utf32(oc_str32 codepoints, oc_font font, f32 fontSize)
12881288
{
12891289
oc_arena_scope scratch = oc_scratch_begin();
12901290

1291-
oc_glyph_run* run = oc_text_shape(scratch.arena, font, 0, codepoints, 0, codepoints.len);
1292-
oc_text_draw_run(run, fontSize);
1293-
1291+
oc_text_line* line = oc_text_line_from_utf32(scratch.arena,
1292+
codepoints,
1293+
&(oc_text_attributes){
1294+
.font = font,
1295+
.fontSize = fontSize,
1296+
.color = oc_get_color(),
1297+
});
1298+
oc_text_line_draw(line);
12941299
oc_scratch_end(scratch);
12951300
}
12961301

@@ -1299,8 +1304,7 @@ void oc_text_draw_utf8(oc_str8 text, oc_font font, f32 fontSize)
12991304
oc_arena_scope scratch = oc_scratch_begin();
13001305

13011306
oc_str32 codepoints = oc_utf8_push_to_codepoints(scratch.arena, text);
1302-
oc_glyph_run* run = oc_text_shape(scratch.arena, font, 0, codepoints, 0, codepoints.len);
1303-
oc_text_draw_run(run, fontSize);
1307+
oc_text_draw_utf32(codepoints, font, fontSize);
13041308

13051309
oc_scratch_end(scratch);
13061310
}

src/graphics/graphics_common.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,23 @@ typedef struct oc_glyph_run
4444

4545
} oc_glyph_run;
4646

47+
typedef struct oc_text_shape_settings
48+
{
49+
oc_str8 script; //TODO: replace with anonymous struct and have a helper to get it from string?
50+
oc_str8 lang;
51+
oc_text_direction direction;
52+
53+
} oc_text_shape_settings;
54+
55+
oc_glyph_run* oc_text_shape(oc_arena* arena,
56+
oc_font font,
57+
oc_text_shape_settings* settings,
58+
oc_str32 codepoints,
59+
u64 begin,
60+
u64 end);
61+
62+
void oc_text_draw_run(oc_glyph_run* run, f32 fontSize);
63+
4764
typedef struct oc_harfbuzz_handle
4865
{
4966
u64 h;

src/ui/ui.c

Lines changed: 42 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,7 @@ oc_ui_box* oc_ui_box_make_str8(oc_str8 string, oc_ui_flags flags)
398398

399399
box->flags = flags;
400400
box->string = oc_str8_push_copy(&ui->frameArena, string);
401-
box->glyphRun = 0;
401+
box->textLine = 0;
402402

403403
//NOTE: setup hierarchy
404404
if(box->frameCounter != ui->frameCounter)
@@ -975,8 +975,14 @@ void oc_ui_styling_prepass(oc_ui_context* ui, oc_ui_box* box, oc_list* before, o
975975
|| desiredSize[OC_UI_AXIS_Y].kind == OC_UI_SIZE_TEXT)
976976
{
977977
oc_str32 codepoints = oc_utf8_push_to_codepoints(&ui->frameArena, box->string);
978-
box->glyphRun = oc_text_shape(&ui->frameArena, style->font, 0, codepoints, 0, codepoints.len);
979-
textBox = oc_glyph_run_range_metrics(box->glyphRun, style->fontSize, 0, codepoints.len).logical;
978+
box->textLine = oc_text_line_from_utf32(&ui->frameArena,
979+
codepoints,
980+
&(oc_text_attributes){
981+
.font = style->font,
982+
.fontSize = style->fontSize,
983+
.color = style->color,
984+
});
985+
textBox = oc_text_line_get_metrics_for_range(box->textLine, 0, codepoints.len).logical;
980986
}
981987

982988
for(int i = 0; i < OC_UI_AXIS_COUNT; i++)
@@ -1549,11 +1555,17 @@ void oc_ui_draw_box(oc_ui_box* box)
15491555
//TODO: might not want to recompute codepoints each time?
15501556
oc_ui_context* ui = oc_ui_get_context();
15511557
oc_str32 codepoints = oc_utf8_push_to_codepoints(&ui->frameArena, box->string);
1552-
if(!box->glyphRun)
1558+
if(!box->textLine)
15531559
{
1554-
box->glyphRun = oc_text_shape(&ui->frameArena, style->font, 0, codepoints, 0, codepoints.len);
1560+
box->textLine = oc_text_line_from_utf32(&ui->frameArena,
1561+
codepoints,
1562+
&(oc_text_attributes){
1563+
.font = style->font,
1564+
.fontSize = style->fontSize,
1565+
.color = style->color,
1566+
});
15551567
}
1556-
oc_rect textBox = oc_glyph_run_range_metrics(box->glyphRun, style->fontSize, 0, codepoints.len).logical;
1568+
oc_rect textBox = oc_text_line_get_metrics_for_range(box->textLine, 0, codepoints.len).logical;
15571569

15581570
f32 x = 0;
15591571
f32 y = 0;
@@ -1590,7 +1602,7 @@ void oc_ui_draw_box(oc_ui_box* box)
15901602
oc_set_color(style->color);
15911603

15921604
oc_move_to(x, y);
1593-
oc_text_draw_run(box->glyphRun, style->fontSize);
1605+
oc_text_line_draw(box->textLine);
15941606
}
15951607

15961608
if(box->flags & OC_UI_FLAG_CLIP)
@@ -3786,7 +3798,7 @@ i32 oc_ui_edit_find_word_end(oc_ui_context* ui, oc_str32 codepoints, i32 startCh
37863798
typedef struct oc_ui_text_box_render_info
37873799
{
37883800
oc_str32 codepoints;
3789-
oc_glyph_run* glyphRun;
3801+
oc_text_line* textLine;
37903802

37913803
} oc_ui_text_box_render_info;
37923804

@@ -3807,7 +3819,7 @@ void oc_ui_text_box_render(oc_ui_box* box, void* data)
38073819
oc_font_metrics extents = oc_font_get_metrics(style->font, style->fontSize);
38083820
f32 lineHeight = extents.ascent + extents.descent;
38093821

3810-
oc_rect beforeBox = oc_glyph_run_range_metrics(info->glyphRun, style->fontSize, 0, firstDisplayedChar).logical;
3822+
oc_rect beforeBox = oc_text_line_get_metrics_for_range(info->textLine, 0, firstDisplayedChar).logical;
38113823

38123824
f32 textX = box->rect.x - beforeBox.w;
38133825
f32 textTop = box->rect.y + 0.5 * (box->rect.h - lineHeight);
@@ -3818,15 +3830,15 @@ void oc_ui_text_box_render(oc_ui_box* box, void* data)
38183830
u32 selectStart = oc_min(ui->editCursor, ui->editMark);
38193831
u32 selectEnd = oc_max(ui->editCursor, ui->editMark);
38203832

3821-
oc_rect beforeSelectBox = oc_glyph_run_range_metrics(info->glyphRun, style->fontSize, 0, selectStart).logical;
3833+
oc_rect beforeSelectBox = oc_text_line_get_metrics_for_range(info->textLine, 0, selectStart).logical;
38223834

38233835
beforeSelectBox.x += textX;
38243836
beforeSelectBox.y += textY;
38253837

38263838
if(selectStart != selectEnd)
38273839
{
3828-
oc_rect selectBox = oc_glyph_run_range_metrics(info->glyphRun, style->fontSize, selectStart, selectEnd).logical;
3829-
oc_rect afterSelectBox = oc_glyph_run_range_metrics(info->glyphRun, style->fontSize, selectEnd, codepoints.len).logical;
3840+
oc_rect selectBox = oc_text_line_get_metrics_for_range(info->textLine, selectStart, selectEnd).logical;
3841+
oc_rect afterSelectBox = oc_text_line_get_metrics_for_range(info->textLine, selectEnd, codepoints.len).logical;
38303842

38313843
selectBox.x += textX;
38323844
selectBox.y += textY;
@@ -3837,7 +3849,7 @@ void oc_ui_text_box_render(oc_ui_box* box, void* data)
38373849
oc_set_color(style->color);
38383850

38393851
oc_move_to(textX, textY);
3840-
oc_text_draw_run(info->glyphRun, style->fontSize);
3852+
oc_text_line_draw(info->textLine);
38413853
}
38423854
else
38433855
{
@@ -3850,14 +3862,14 @@ void oc_ui_text_box_render(oc_ui_box* box, void* data)
38503862
}
38513863
oc_set_color(style->color);
38523864
oc_move_to(textX, textY);
3853-
oc_text_draw_run(info->glyphRun, style->fontSize);
3865+
oc_text_line_draw(info->textLine);
38543866
}
38553867
}
38563868
else
38573869
{
38583870
oc_set_color(style->color);
38593871
oc_move_to(textX, textY);
3860-
oc_text_draw_run(info->glyphRun, style->fontSize);
3872+
oc_text_line_draw(info->textLine);
38613873
}
38623874
}
38633875

@@ -3912,7 +3924,13 @@ oc_ui_text_box_result oc_ui_text_box_str8(oc_str8 name, oc_arena* arena, oc_str8
39123924
oc_font_metrics extents = oc_font_get_metrics(font, fontSize);
39133925

39143926
oc_str32 codepoints = oc_utf8_push_to_codepoints(&ui->frameArena, text);
3915-
oc_glyph_run* run = oc_text_shape(&ui->frameArena, font, 0, codepoints, 0, codepoints.len);
3927+
oc_text_line* line = oc_text_line_from_utf32(&ui->frameArena,
3928+
codepoints,
3929+
&(oc_text_attributes){
3930+
.font = font,
3931+
.fontSize = fontSize,
3932+
.color = textBox->style.color,
3933+
});
39163934

39173935
oc_ui_sig sig = oc_ui_box_sig(frame);
39183936

@@ -3945,7 +3963,7 @@ oc_ui_text_box_result oc_ui_text_box_str8(oc_str8 name, oc_arena* arena, oc_str8
39453963
//TODO: update text API: use point to cursor on shaped text?
39463964
for(int i = ui->editFirstDisplayedChar; i < codepoints.len; i++)
39473965
{
3948-
oc_rect bbox = oc_glyph_run_range_metrics(run, fontSize, i, i + 1).logical;
3966+
oc_rect bbox = oc_text_line_get_metrics_for_range(line, i, i + 1).logical;
39493967
if(x < cursorX)
39503968
{
39513969
hoveredChar = i;
@@ -4001,7 +4019,7 @@ oc_ui_text_box_result oc_ui_text_box_str8(oc_str8 name, oc_arena* arena, oc_str8
40014019
}
40024020
else if(ui->editSelectionMode == OC_UI_EDIT_MOVE_LINE)
40034021
{
4004-
oc_rect bbox = oc_glyph_run_range_metrics(run, fontSize, 0, codepoints.len).logical;
4022+
oc_rect bbox = oc_text_line_get_metrics_for_range(line, 0, codepoints.len).logical;
40054023
if(fabsf(bbox.w - cursorX) < fabsf(cursorX))
40064024
{
40074025
ui->editCursor = codepoints.len;
@@ -4018,8 +4036,8 @@ oc_ui_text_box_result oc_ui_text_box_str8(oc_str8 name, oc_arena* arena, oc_str8
40184036
if(oc_min(ui->editCursor, ui->editMark) == oc_min(ui->editWordSelectionInitialCursor, ui->editWordSelectionInitialMark)
40194037
&& oc_max(ui->editCursor, ui->editMark) == oc_max(ui->editWordSelectionInitialCursor, ui->editWordSelectionInitialMark))
40204038
{
4021-
oc_rect editCursorPrefixBbox = oc_glyph_run_range_metrics(run, fontSize, 0, ui->editCursor).logical;
4022-
oc_rect editMarkPrefixBbox = oc_glyph_run_range_metrics(run, fontSize, 0, ui->editMark).logical;
4039+
oc_rect editCursorPrefixBbox = oc_text_line_get_metrics_for_range(line, 0, ui->editCursor).logical;
4040+
oc_rect editMarkPrefixBbox = oc_text_line_get_metrics_for_range(line, 0, ui->editMark).logical;
40234041

40244042
f32 editCursorX = editCursorPrefixBbox.w;
40254043
f32 editMarkX = editMarkPrefixBbox.w;
@@ -4154,12 +4172,12 @@ oc_ui_text_box_result oc_ui_text_box_str8(oc_str8 name, oc_arena* arena, oc_str8
41544172
else
41554173
{
41564174
i32 firstDisplayedChar = ui->editFirstDisplayedChar;
4157-
oc_rect firstToCursorBox = oc_glyph_run_range_metrics(run, fontSize, firstDisplayedChar, ui->editCursor).logical;
4175+
oc_rect firstToCursorBox = oc_text_line_get_metrics_for_range(line, firstDisplayedChar, ui->editCursor).logical;
41584176

41594177
while(firstToCursorBox.w > textBox->rect.w)
41604178
{
41614179
firstDisplayedChar++;
4162-
firstToCursorBox = oc_glyph_run_range_metrics(run, fontSize, firstDisplayedChar, ui->editCursor).logical;
4180+
firstToCursorBox = oc_text_line_get_metrics_for_range(line, firstDisplayedChar, ui->editCursor).logical;
41634181
}
41644182

41654183
ui->editFirstDisplayedChar = firstDisplayedChar;
@@ -4169,7 +4187,7 @@ oc_ui_text_box_result oc_ui_text_box_str8(oc_str8 name, oc_arena* arena, oc_str8
41694187
//NOTE: set renderer
41704188
oc_ui_text_box_render_info* info = oc_arena_push_type(&ui->frameArena, oc_ui_text_box_render_info);
41714189
info->codepoints = codepoints;
4172-
info->glyphRun = run;
4190+
info->textLine = line;
41734191

41744192
oc_ui_box_set_draw_proc(textBox, oc_ui_text_box_render, info);
41754193
}
@@ -4178,7 +4196,7 @@ oc_ui_text_box_result oc_ui_text_box_str8(oc_str8 name, oc_arena* arena, oc_str8
41784196
//NOTE: set renderer
41794197
oc_ui_text_box_render_info* info = oc_arena_push_type(&ui->frameArena, oc_ui_text_box_render_info);
41804198
info->codepoints = codepoints;
4181-
info->glyphRun = run;
4199+
info->textLine = line;
41824200

41834201
oc_ui_box_set_draw_proc(textBox, oc_ui_text_box_render, info);
41844202
}

src/ui/ui.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -515,7 +515,7 @@ struct oc_ui_box
515515
void* drawData;
516516

517517
// text shaping
518-
oc_glyph_run* glyphRun;
518+
oc_text_line* textLine;
519519

520520
// styling
521521
oc_list beforeRules;

0 commit comments

Comments
 (0)