rendering based of kb_text_shape data!

This commit is contained in:
Vicente Ferrari Smith 2025-07-10 18:51:09 +02:00
parent af1f9cfbeb
commit ad439a5509
13 changed files with 122 additions and 23 deletions

View File

@ -6,7 +6,7 @@
NAME :: "mexplore";
VERSION :: "0.1";
JAI_VERSION :: "beta 0.2.014, built on 24 May 2025";
RELEASE_DATE :: "9 July 2025, 09:01:30";
RELEASE_DATE :: "10 July 2025, 18:49:46";
GIT_BRANCH :: "main";
GIT_REVISION :: "d83f28c212c26e9aaef856dffd7eb64d22117083";
GIT_REVISION :: "af1f9cfbeb018704986b1d45d62c802538a29ef2";
DEBUG :: true;

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -57,12 +57,30 @@ main :: () {
init();
SDL_StartTextInput(window);
while (running) {
event : SDL_Event;
while (SDL_PollEvent(*event)) {
if (event.type == SDL_EVENT_QUIT) {
running = false;
while SDL_PollEvent(*event) {
if event.type == {
case SDL_EVENT_QUIT;
running = false;
case SDL_EVENT_TEXT_INPUT;
//input_state.last_char = xx it.utf32;
text : string = to_string(event.text.text);
text_utf32 : [..]u32;
defer array_free(text_utf32);
StringAt : u64;
while StringAt < xx text.count {
Decode : kbts_decode = kbts_DecodeUtf8(text.data + StringAt, xx text.count - StringAt);
StringAt += Decode.SourceCharactersConsumed;
if Decode.Valid {
array_add(*text_utf32, Decode.Codepoint);
}
}
}
}
@ -459,6 +477,8 @@ main :: () {
SDL_GL_SwapWindow(window);
}
SDL_StopTextInput(window);
SDL_GL_DestroyContext(gl_context);
SDL_DestroyWindow(window);
@ -466,6 +486,7 @@ main :: () {
}
init :: () {
window_proj = orthographic_gl(0.0, xx window_width, 0.0, xx window_height, -1.0, 1.0);
init_shaders();
init_texture(*normal_frame, "panel-border-000.png");

View File

@ -213,7 +213,7 @@ init_font :: (using font: *Font, filename: string, size: s32) {
}
}
render_text :: (font: *Font, text: string, pos: Vector2, window_space: bool = true, colour: Vector4 = .{1.0, 1.0, 1.0, 1.0},
render_text :: (font: *Font, text: string, pos: Vector2, size: Vector2, window_space: bool = true, colour: Vector4 = .{1.0, 1.0, 1.0, 1.0},
background: Vector4 = .{0.0, 0.0, 0.0, 0.0}, nice_background := false, count_descent: bool = false) {
if !text
@ -227,15 +227,20 @@ render_text :: (font: *Font, text: string, pos: Vector2, window_space: bool = tr
glDisable(GL_MULTISAMPLE);
if nice_background {
render_text(font, text, pos + .{3.0, -3.0}, window_space, v4(v3(0.0), 1.0), v4(0.0), false);
render_text(font, text, pos + .{3.0, -3.0}, size, window_space, v4(v3(0.0), 1.0), v4(0.0), false);
}
vertices : [..]vertex_p2_st2_col4;
defer array_free(vertices);
render_pos := pos;
text_utf32 : [..]u32;
defer array_free(text_utf32);
StringAt : u64;
while StringAt < xx text.count {
Decode : kbts_decode = kbts_DecodeUtf8(text.data, xx text.count);
Decode : kbts_decode = kbts_DecodeUtf8(text.data + StringAt, xx text.count - StringAt);
StringAt += Decode.SourceCharactersConsumed;
if Decode.Valid {
array_add(*text_utf32, Decode.Codepoint);
@ -245,7 +250,81 @@ render_text :: (font: *Font, text: string, pos: Vector2, window_space: bool = tr
Cursor : kbts_cursor;
Direction : kbts_direction = .KBTS_DIRECTION_NONE;
Script : kbts_script = .KBTS_SCRIPT_DONT_KNOW;
size, max_descent := ShapeText(font, *Cursor, text_utf32.data, xx text_utf32.count, Direction, Direction, Script);
Glyphs : *kbts_glyph = cast(*kbts_glyph, alloc(size_of(kbts_glyph) * text_utf32.count));
CodepointIndex : s32;
while CodepointIndex < xx text.count {
Glyphs[CodepointIndex] = kbts_CodepointToGlyph(*font.kb, text_utf32.data[CodepointIndex]);
CodepointIndex += 1;
}
State : *kbts_shape_state = kbts_CreateShapeState(*font.kb);
Config : kbts_shape_config = kbts_ShapeConfig(*font.kb, Script, .DONT_KNOW);
GlyphCount : u32 = xx text_utf32.count;
GlyphCapacity : u32 = GlyphCount;
while kbts_Shape(State, *Config, Direction, Direction, Glyphs, *GlyphCount, GlyphCapacity) {
Glyphs = cast(*kbts_glyph, realloc(Glyphs, size_of(kbts_glyph) * State.RequiredGlyphCapacity, size_of(kbts_glyph) * GlyphCapacity));
GlyphCapacity = State.RequiredGlyphCapacity;
}
GlyphIndex : u64;
while GlyphIndex < GlyphCount {
kglyph : *kbts_glyph = *Glyphs[GlyphIndex];
X, Y : s32;
kbts_PositionGlyph(*Cursor, kglyph, *X, *Y);
// x_offset : hb_position_t = glyph_pos[i].x_offset;
// y_offset : hb_position_t = glyph_pos[i].y_offset;
// x_advance : hb_position_t = glyph_pos[i].x_advance;
// y_advance : hb_position_t = glyph_pos[i].y_advance;
x_offset : float = xx FT_MulFix(Cursor.X, font.face.size.metrics.x_scale) >> 6;
y_offset : float = xx FT_MulFix(Cursor.Y, font.face.size.metrics.y_scale) >> 6;
glyph : *Glyph = table_find_pointer(*font.glyphs, kglyph.Id);
v0 : Vector2;
v1 : Vector2;
if count_descent {
v0 = render_pos + .{cast(float) x_offset + glyph.bearing_x,
cast(float) y_offset - glyph.bearing_y + size.y /*- max_descent*/};
} else {
v0 = render_pos + .{cast(float) x_offset + glyph.bearing_x,
cast(float) y_offset - (xx glyph.height - glyph.bearing_y)/* - glyph.height + draw_size.y*/};
}
v1 = v0 + Vector2.{cast(float) glyph.width, cast(float) glyph.height};
// #if Y_IS_UP {
// t0 := Vector2.{cast(float, glyph.x) / cast(float, ATLAS_SIZE), cast(float, glyph.y) / cast(float, ATLAS_SIZE)};
// t1 := t0 + Vector2.{cast(float, glyph.width) / cast(float, ATLAS_SIZE), -cast(float, glyph.height) / cast(float, ATLAS_SIZE)};
t0 := glyph.st0;
t1 := glyph.st1;
// } else {
// t0 := Vector2.{cast(float, glyph.x / ATLAS_SIZE), cast(float, glyph.y / ATLAS_SIZE)};
// t1 := t0 + .{cast(float, glyph.width / ATLAS_SIZE), cast(float, glyph.height / ATLAS_SIZE)};
// }
array_add(*vertices, .{v0, t0, colour});
array_add(*vertices, .{.{v0.x, v1.y}, .{t0.x, t1.y}, colour});
array_add(*vertices, .{.{v1.x, v0.y}, .{t1.x, t0.y}, colour});
array_add(*vertices, .{.{v1.x, v0.y}, .{t1.x, t0.y}, colour});
array_add(*vertices, .{.{v0.x, v1.y}, .{t0.x, t1.y}, colour});
array_add(*vertices, .{v1, t1, colour});
//render_pos += Vector2.{x_advance / 64.0, y_advance / 64.0};
GlyphIndex += 1;
}
free(Glyphs);
//size, max_descent := ShapeText(font, *Cursor, text_utf32.data, xx text_utf32.count, Direction, Direction, Script);
// buf : *hb_buffer_t = hb_buffer_create();
// hb_buffer_add_utf8(buf, text.data, xx text.count, 0, -1);
@ -266,10 +345,7 @@ render_text :: (font: *Font, text: string, pos: Vector2, window_space: bool = tr
// glyph_info : *hb_glyph_info_t = hb_buffer_get_glyph_infos(buf, *glyph_count);
// glyph_pos : *hb_glyph_position_t = hb_buffer_get_glyph_positions(buf, *glyph_count);
// vertices : [..]vertex_p2_st2_col4;
// defer array_free(vertices);
// render_pos := pos;
// draw_size, max_ascent, max_descent := calculate_string_draw_size(font, text);
@ -316,10 +392,10 @@ render_text :: (font: *Font, text: string, pos: Vector2, window_space: bool = tr
// }
// hb_buffer_destroy(buf);
// view := identity_of(Matrix4);
// proj := window_proj;
view := identity_of(Matrix4);
proj := window_proj;
// render_batch(.TRIANGLES, vertices, *text_shader, *font.texture, view, proj);
render_batch(.TRIANGLES, vertices, *text_shader, *font.texture, view, proj);
// Restore modified GL state
// restore_opengl_state(*opengl_state);
@ -784,7 +860,7 @@ PRIMITIVE_TYPE :: enum u8 {
render_batch :: (primitive_type: PRIMITIVE_TYPE, vertices: []$T, shader: *_Shader, texture: *Texture, view: Matrix4, proj: Matrix4) {
if !vertices {
logd("[Error] The batch has no vertices.");
log("[Error] The batch has no vertices.");
return;
}

View File

@ -469,7 +469,7 @@ ui_draw_label :: (using label: *Label) {
word_size, word_max_descent, read := next_word_size(label.font, string.{label.text.count, label.text.data}, idx, label.max_size.x);
if this_size.x + word_size.x > label.max_size.x {
render_text(font, .{row_end - row_start, label.text.data + row_start},
render_text(font, .{row_end - row_start, label.text.data + row_start}, this_size,
midline, colour = font_colour);
row_start = row_end;
midline.y += label.font.face.size.metrics.height >> 6;
@ -483,7 +483,7 @@ ui_draw_label :: (using label: *Label) {
if row_start < row_end {
render_text(font, .{row_end - row_start, label.text.data + row_start},
midline, colour = font_colour);
midline, this_size, colour = font_colour);
}
//label_size := Vector2.{xx Simp.prepare_text(font, text), xx font.character_height};
@ -950,7 +950,9 @@ ui_draw_text_input :: (using text_input: *TextInput) {
while i < text_input.text.count {
STB_TEXTEDIT_LAYOUTROW(*row, text_input, i);
render_text(font, .{row.num_chars, text_input.text.data + i}, .{draw_pos.x, draw_pos.y + row.ymin /*+ line.max_descent*/}, colour = font_colour);
render_text(font, .{row.num_chars, text_input.text.data + i},
.{draw_pos.x, draw_pos.y + row.ymin /*+ line.max_descent*/}, text_input.size,
colour = font_colour);
draw_pos.y -= row.baseline_y_delta;

8
ui.rad
View File

@ -2,20 +2,20 @@
recent_file: path: "src/text.jai"
recent_file: path: "src/ui.jai"
recent_file: path: "src/main.jai"
recent_file: path: "../../../../jai/modules/basic/array.jai"
recent_file: path: "../../../../jai/modules/basic/module.jai"
recent_file: path: "../../../../jai/modules/default_allocator/module.jai"
recent_file: path: "src/main.jai"
recent_file: path: "modules/kb_text_shape/kb_text_shape.h"
recent_file: path: "../../../../jai/modules/runtime_support.jai"
target:
{
executable: "bin/mexplore-debug.exe"
working_directory: "bin/"
working_directory: bin
enabled: 1
}
breakpoint:
{
source_location: "src/ui.jai:469:1"
hit_count: 1
source_location: "src/main.jai:72:1"
hit_count: 0
}