Skip to content

Commit 4ae8883

Browse files
author
Allen Webster
committed
Arbitrary text rotation in immediate mode text draw
1 parent d23135d commit 4ae8883

8 files changed

+106
-32
lines changed

4ed_render_target.cpp

+33-4
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ draw_rectangle(Render_Target *target, Rect_f32 rect, f32 roundness, u32 color){
163163

164164
internal void
165165
draw_font_glyph(Render_Target *target, Face *face, u32 codepoint, Vec2_f32 p,
166-
ARGB_Color color, u32 flags){
166+
ARGB_Color color, Glyph_Flag flags, Vec2_f32 x_axis){
167167
draw__set_face_id(target, face->id);
168168

169169
u16 glyph_index = 0;
@@ -174,9 +174,37 @@ draw_font_glyph(Render_Target *target, Face *face, u32 codepoint, Vec2_f32 p,
174174
Glyph_Bounds bounds = face->bounds[glyph_index];
175175
Vec3_f32 texture_dim = face->texture_dim;
176176

177+
Render_Vertex vertices[6] = {};
178+
177179
Rect_f32 uv = bounds.uv;
180+
vertices[0].uvw = V3f32(uv.x0, uv.y0, bounds.w);
181+
vertices[1].uvw = V3f32(uv.x1, uv.y0, bounds.w);
182+
vertices[2].uvw = V3f32(uv.x0, uv.y1, bounds.w);
183+
vertices[5].uvw = V3f32(uv.x1, uv.y1, bounds.w);
178184

179-
Render_Vertex vertices[6] = {};
185+
Vec2_f32 y_axis = V2f32(-x_axis.y, x_axis.x);
186+
Vec2_f32 x_min = bounds.xy_off.x0*x_axis;
187+
Vec2_f32 x_max = bounds.xy_off.x1*x_axis;
188+
Vec2_f32 y_min = bounds.xy_off.y0*y_axis;
189+
Vec2_f32 y_max = bounds.xy_off.y1*y_axis;
190+
Vec2_f32 p_x_min = p + x_min;
191+
Vec2_f32 p_x_max = p + x_max;
192+
vertices[0].xy = p_x_min + y_min;
193+
vertices[1].xy = p_x_max + y_min;
194+
vertices[2].xy = p_x_min + y_max;
195+
vertices[5].xy = p_x_max + y_max;
196+
197+
#if 0
198+
Vec2_f32 xy_min = p + bounds.xy_off.x0*x_axis + bounds.xy_off.y0*y_axis;
199+
Vec2_f32 xy_max = p + bounds.xy_off.x1*x_axis + bounds.xy_off.y1*y_axis;
200+
201+
vertices[0].xy = V2f32(xy_min.x, xy_min.y);
202+
vertices[1].xy = V2f32(xy_max.x, xy_min.y);
203+
vertices[2].xy = V2f32(xy_min.x, xy_max.y);
204+
vertices[5].xy = V2f32(xy_max.x, xy_max.y);
205+
#endif
206+
207+
#if 0
180208
if (!HasFlag(flags, GlyphFlag_Rotate90)){
181209
Rect_f32 xy = Rf32(p + bounds.xy_off.p0, p + bounds.xy_off.p1);
182210

@@ -202,6 +230,7 @@ draw_font_glyph(Render_Target *target, Face *face, u32 codepoint, Vec2_f32 p,
202230
vertices[5].xy = V2f32(xy.x1, xy.y0);
203231
vertices[5].uvw = V3f32(uv.x0, uv.y0, bounds.w);
204232
}
233+
#endif
205234

206235
vertices[3] = vertices[1];
207236
vertices[4] = vertices[2];
@@ -252,7 +281,7 @@ draw_string(Render_Target *target, Face *face, String_Const_u8 string, Vec2_f32
252281
if (draw_codepoint == '\t'){
253282
draw_codepoint = ' ';
254283
}
255-
draw_font_glyph(target, face, draw_codepoint, point, color, flags);
284+
draw_font_glyph(target, face, draw_codepoint, point, color, flags, delta);
256285
}
257286
local_const f32 internal_tab_width = 4.f;
258287
f32 d = font_get_glyph_advance(&face->advance_map, &face->metrics, codepoint, internal_tab_width);
@@ -279,7 +308,7 @@ draw_string(Render_Target *target, Face *face, String_Const_u8 string, Vec2_f32
279308

280309
Vec2_f32 pp = point;
281310
for (u32 j = 0; j < 3; ++j){
282-
draw_font_glyph(target, face, cs[j], pp, color, flags);
311+
draw_font_glyph(target, face, cs[j], pp, color, flags, delta);
283312
pp += delta*byte_sub_advances[j];
284313
}
285314
}

4ed_text_layout.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ text_layout_render(Thread_Context *tctx, Models *models, Text_Layout *layout,
9292
Face *face = file_get_face(models, file);
9393
f32 width = rect_width(layout->rect);
9494

95+
Vec2_f32 delta = V2f32(1.f, 0.f);
96+
9597
Vec2_f32 shift_p = layout->rect.p0 - layout->point.pixel_shift;
9698
i64 first_index = layout->visible_range.first;
9799
i64 line_number = layout->visible_line_number_range.min;
@@ -120,7 +122,7 @@ text_layout_render(Thread_Context *tctx, Models *models, Text_Layout *layout,
120122
color = item_colors[item->index - first_index];
121123
}
122124
Vec2_f32 p = item->rect.p0 + shift_p;
123-
draw_font_glyph(target, face, item->codepoint, p, color, GlyphFlag_None);
125+
draw_font_glyph(target, face, item->codepoint, p, color, GlyphFlag_None, delta);
124126
}
125127
}
126128
}

custom/4coder_default_hooks.cpp

+11-2
Original file line numberDiff line numberDiff line change
@@ -483,8 +483,17 @@ default_whole_screen_render_caller(Application_Links *app, Frame_Info frame_info
483483
Face_ID face_id = get_face_id(app, 0);
484484
Scratch_Block scratch(app);
485485
draw_string_oriented(app, face_id, finalize_color(defcolor_text_default, 0),
486-
SCu8("Hello, World!"), center,
487-
GlyphFlag_Rotate90, V2f32(0.f, 1.f));
486+
SCu8("Hello, World!"), center - V2f32(200.f, 300.f),
487+
0, V2f32(0.f, -1.f));
488+
draw_string_oriented(app, face_id, finalize_color(defcolor_text_default, 0),
489+
SCu8("Hello, World!"), center - V2f32(240.f, 300.f),
490+
0, V2f32(0.f, 1.f));
491+
draw_string_oriented(app, face_id, finalize_color(defcolor_text_default, 0),
492+
SCu8("Hello, World!"), center - V2f32(400.f, 400.f),
493+
0, V2f32(-1.f, 0.f));
494+
draw_string_oriented(app, face_id, finalize_color(defcolor_text_default, 0),
495+
SCu8("Hello, World!"), center - V2f32(400.f, -100.f),
496+
0, V2f32(cos_f32(pi_f32*.333f), sin_f32(pi_f32*.333f)));
488497
#endif
489498
}
490499

custom/4coder_search.cpp

+55-22
Original file line numberDiff line numberDiff line change
@@ -301,37 +301,66 @@ word_complete_list_extend_from_raw(Application_Links *app, Arena *arena, String_
301301
}
302302
}
303303

304+
function void
305+
word_complete_iter_init__inner(Buffer_ID buffer, String_Const_u8 needle, Range_i64 range, Word_Complete_Iterator *iter){
306+
Application_Links *app = iter->app;
307+
Arena *arena = iter->arena;
308+
309+
Base_Allocator *allocator = get_base_allocator_system();
310+
if (iter->already_used_table.allocator != 0){
311+
end_temp(iter->arena_restore);
312+
table_clear(&iter->already_used_table);
313+
}
314+
315+
block_zero_struct(iter);
316+
iter->app = app;
317+
iter->arena = arena;
318+
319+
Scratch_Block scratch(app);
320+
String_Match_List list = get_complete_list_raw(app, scratch, buffer, range, needle);
321+
322+
iter->arena_restore = begin_temp(arena);
323+
iter->first_buffer = buffer;
324+
iter->current_buffer = buffer;
325+
iter->needle = needle;
326+
327+
iter->already_used_table = make_table_Data_u64(allocator, 100);
328+
word_complete_list_extend_from_raw(app, arena, &list, &iter->list, &iter->already_used_table);
329+
330+
iter->scan_all_buffers = true;
331+
}
332+
304333
function void
305334
word_complete_iter_init(Buffer_ID buffer, Range_i64 range, Word_Complete_Iterator *iter){
306335
if (iter->app != 0 && iter->arena != 0){
307-
Base_Allocator *allocator = get_base_allocator_system();
308-
309336
Application_Links *app = iter->app;
310337
Arena *arena = iter->arena;
311-
312-
if (iter->already_used_table.allocator != 0){
313-
end_temp(iter->arena_restore);
314-
table_clear(&iter->already_used_table);
315-
}
316-
317-
block_zero_struct(iter);
318-
iter->app = app;
319-
iter->arena = arena;
320-
321-
Scratch_Block scratch(app);
322338
String_Const_u8 needle = push_buffer_range(app, arena, buffer, range);
323-
String_Match_List list = get_complete_list_raw(app, scratch, buffer, range, needle);
324-
325-
iter->arena_restore = begin_temp(arena);
326-
iter->first_buffer = buffer;
327-
iter->current_buffer = buffer;
328-
iter->needle = needle;
329-
330-
iter->already_used_table = make_table_Data_u64(allocator, 100);
331-
word_complete_list_extend_from_raw(app, arena, &list, &iter->list, &iter->already_used_table);
339+
word_complete_iter_init__inner(buffer, needle, range, iter);
340+
}
341+
}
342+
343+
function void
344+
word_complete_iter_init(Buffer_ID first_buffer, String_Const_u8 needle, Word_Complete_Iterator *iter){
345+
if (iter->app != 0 && iter->arena != 0){
346+
word_complete_iter_init__inner(first_buffer, needle, Ii64(), iter);
347+
}
348+
}
349+
350+
function void
351+
word_complete_iter_init(String_Const_u8 needle, Word_Complete_Iterator *iter){
352+
if (iter->app != 0 && iter->arena != 0){
353+
Application_Links *app = iter->app;
354+
Buffer_ID first_buffer = get_buffer_next(app, 0, Access_Read);
355+
word_complete_iter_init__inner(first_buffer, needle, Ii64(), iter);
332356
}
333357
}
334358

359+
function void
360+
word_complete_iter_stop_on_this_buffer(Word_Complete_Iterator *iter){
361+
iter->scan_all_buffers = false;
362+
}
363+
335364
function void
336365
word_complete_iter_next(Word_Complete_Iterator *it){
337366
for (;;){
@@ -346,6 +375,10 @@ word_complete_iter_next(Word_Complete_Iterator *it){
346375
break;
347376
}
348377

378+
if (!it->scan_all_buffers){
379+
break;
380+
}
381+
349382
Application_Links *app = it->app;
350383
Buffer_ID next = get_buffer_next_looped(app, it->current_buffer, Access_Read);
351384
if (next == it->first_buffer){

custom/4coder_search.h

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ struct Word_Complete_Iterator{
2020
Temp_Memory arena_restore;
2121
Buffer_ID first_buffer;
2222
Buffer_ID current_buffer;
23+
b32 scan_all_buffers;
2324
String_Const_u8 needle;
2425

2526
List_String_Const_u8 list;

custom/4coder_types.h

-1
Original file line numberDiff line numberDiff line change
@@ -469,7 +469,6 @@ api(custom)
469469
typedef u32 Glyph_Flag;
470470
enum{
471471
GlyphFlag_None = 0x0,
472-
GlyphFlag_Rotate90 = 0x1,
473472
};
474473

475474
api(custom)

custom/generated/command_metadata.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -501,8 +501,8 @@ static Command_Metadata fcoder_metacmd_table[245] = {
501501
{ PROC_LINKS(undo_all_buffers, 0), false, "undo_all_buffers", 16, "Advances backward through the undo history in the buffer containing the most recent regular edit.", 97, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1862 },
502502
{ PROC_LINKS(view_buffer_other_panel, 0), false, "view_buffer_other_panel", 23, "Set the other non-active panel to view the buffer that the active panel views, and switch to that panel.", 104, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1623 },
503503
{ PROC_LINKS(view_jump_list_with_lister, 0), false, "view_jump_list_with_lister", 26, "When executed on a buffer with jumps, creates a persistent lister for all the jumps", 83, "w:\\4ed\\code\\custom\\4coder_jump_lister.cpp", 41, 59 },
504-
{ PROC_LINKS(word_complete, 0), false, "word_complete", 13, "Iteratively tries completing the word to the left of the cursor with other words in open buffers that have the same prefix string.", 130, "w:\\4ed\\code\\custom\\4coder_search.cpp", 36, 397 },
505-
{ PROC_LINKS(word_complete_drop_down, 0), false, "word_complete_drop_down", 23, "Word complete with drop down menu.", 34, "w:\\4ed\\code\\custom\\4coder_search.cpp", 36, 644 },
504+
{ PROC_LINKS(word_complete, 0), false, "word_complete", 13, "Iteratively tries completing the word to the left of the cursor with other words in open buffers that have the same prefix string.", 130, "w:\\4ed\\code\\custom\\4coder_search.cpp", 36, 430 },
505+
{ PROC_LINKS(word_complete_drop_down, 0), false, "word_complete_drop_down", 23, "Word complete with drop down menu.", 34, "w:\\4ed\\code\\custom\\4coder_search.cpp", 36, 677 },
506506
{ PROC_LINKS(write_block, 0), false, "write_block", 11, "At the cursor, insert a block comment.", 38, "w:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 94 },
507507
{ PROC_LINKS(write_hack, 0), false, "write_hack", 10, "At the cursor, insert a '// HACK' comment, includes user name if it was specified in config.4coder.", 99, "w:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 82 },
508508
{ PROC_LINKS(write_note, 0), false, "write_note", 10, "At the cursor, insert a '// NOTE' comment, includes user name if it was specified in config.4coder.", 99, "w:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 88 },

ship_files/changes.txt

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11

22
4.1.6
33
+ In config.4coder "bind_by_physical_key" uses a key-layout that does not change with language
4+
+ Deprecated GlyphFlag_Rotate90, rotation of immediate mode text is entirely derived from the delta vector
45
+ Fix: notepad like mode scrolling only creates selection when holding mouse L-buttoon
56
+ Fix: on windows the window has the 4coder icon
67
+ Fix: by default platform layer uses key codes arranged by the system language

0 commit comments

Comments
 (0)