summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/assets.c4
-rw-r--r--src/assets.h2
-rw-r--r--src/render.c174
-rw-r--r--src/render.h1
-rw-r--r--src/ui.c75
5 files changed, 162 insertions, 94 deletions
diff --git a/src/assets.c b/src/assets.c
index 0ba6192..d5f1540 100644
--- a/src/assets.c
+++ b/src/assets.c
@@ -129,6 +129,10 @@ bool assets_queue_worker_load_font(font *font)
new_glyph.xoff = xoff;
new_glyph.yoff = yoff;
+ stbtt_GetCodepointHMetrics(&info, i, &new_glyph.advance, &new_glyph.lsb);
+ new_glyph.advance *= scale;
+ new_glyph.lsb *= scale;
+
if (i == 'M') font->px_h = -yoff;
font->glyphs[i-TEXT_CHARSET_START] = new_glyph;
diff --git a/src/assets.h b/src/assets.h
index 1b76785..a9816b5 100644
--- a/src/assets.h
+++ b/src/assets.h
@@ -28,6 +28,8 @@ typedef struct t_glyph
{
s32 width;
s32 height;
+ s32 advance;
+ s32 lsb;
s32 xoff;
s32 yoff;
void *bitmap;
diff --git a/src/render.c b/src/render.c
index 666b2f9..7f61ce8 100644
--- a/src/render.c
+++ b/src/render.c
@@ -88,11 +88,8 @@ s32 render_text_ellipsed(font *font, s32 x, s32 y, s32 maxw, char *text, color t
s32 width = g.width;
- int advance, lsb, kern;
- stbtt_GetCodepointHMetrics(&font->info, ch, &advance, &lsb);
-
s32 y_ = y + font->px_h + g.yoff;
- s32 x_to_render = x_ + (lsb*font->scale);
+ s32 x_to_render = x_ + (g.lsb);
glTexCoord2i(0, 0); glVertex3i(x_to_render,y_, render_depth);
glTexCoord2i(0, 1); glVertex3i(x_to_render,y_+g.height, render_depth);
@@ -102,8 +99,8 @@ s32 render_text_ellipsed(font *font, s32 x, s32 y, s32 maxw, char *text, color t
glEnd();
/* add kerning */
- kern = stbtt_GetCodepointKernAdvance(&font->info, ch, ch_next);
- x_ += (advance*font->scale)+(kern*font->scale);
+ //kern = stbtt_GetCodepointKernAdvance(&font->info, ch, ch_next);
+ x_ += (g.advance);
if (!in_ellipse && (x_-x) > maxw-(font->glyphs['.'].width*3))
{
@@ -117,7 +114,7 @@ s32 render_text_ellipsed(font *font, s32 x, s32 y, s32 maxw, char *text, color t
return maxw;
}
-s32 render_text(font *font, s32 x, s32 y, char *text, color tint)
+s32 render_text_with_selection(font *font, s32 x, s32 y, char *text, color tint, s32 selection_start, s32 selection_length)
{
if (!font->loaded)
return 0;
@@ -127,6 +124,9 @@ s32 render_text(font *font, s32 x, s32 y, char *text, color tint)
s32 x_ = x;
utf8_int32_t ch;
+ s32 index = 0;
+ s32 selection_start_x = x_;
+ s32 selection_end_x = x_;
while((text = utf8codepoint(text, &ch)) && ch)
{
if (ch == 9) ch = 32;
@@ -144,11 +144,119 @@ s32 render_text(font *font, s32 x, s32 y, char *text, color tint)
s32 width = g.width;
- int advance, lsb, kern;
- stbtt_GetCodepointHMetrics(&font->info, ch, &advance, &lsb);
+ s32 y_ = y + font->px_h + g.yoff;
+ s32 x_to_render = x_ + (g.lsb);
+
+ glTexCoord2i(0, 0); glVertex3i(x_to_render,y_, render_depth);
+ glTexCoord2i(0, 1); glVertex3i(x_to_render,y_+g.height, render_depth);
+ glTexCoord2i(1, 1); glVertex3i(x_to_render+g.width,y_+g.height, render_depth);
+ glTexCoord2i(1, 0); glVertex3i(x_to_render+g.width,y_, render_depth);
+
+ glEnd();
+
+ /* add kerning */
+ //kern = stbtt_GetCodepointKernAdvance(&font->info, ch, ch_next);
+ x_ += (g.advance);
+
+ index++;
+ if (index == selection_start)
+ {
+ selection_start_x = x_;
+ }
+ if (index == selection_start+selection_length)
+ {
+ selection_end_x = x_;
+ }
+ }
+
+ glDisable(GL_TEXTURE_2D);
+
+ render_rectangle(selection_start_x, y-3, selection_end_x-selection_start_x, TEXTBOX_HEIGHT - 10, rgba(66, 134, 244, 120));
+
+ return x_ - x;
+}
+
+s32 render_text_with_cursor(font *font, s32 x, s32 y, char *text, color tint, s32 cursor_pos)
+{
+ if (!font->loaded)
+ return 0;
+
+ glEnable(GL_TEXTURE_2D);
+ glColor4f(tint.r/255.0f, tint.g/255.0f, tint.b/255.0f, tint.a/255.0f);
+
+ float x_ = x;
+ utf8_int32_t ch;
+ s32 index = 0;
+ s32 cursor_x = x_;
+ while((text = utf8codepoint(text, &ch)) && ch)
+ {
+ if (ch == 9) ch = 32;
+ utf8_int32_t ch_next;
+ utf8codepoint(text, &ch_next);
+ if (ch < TEXT_CHARSET_START || ch > TEXT_CHARSET_END)
+ {
+ ch = 0x3f;
+ }
+
+ glyph g = font->glyphs[ch];
+
+ glBindTexture(GL_TEXTURE_2D, g.textureID);
+ glBegin(GL_QUADS);
+
+ s32 y_ = y + font->px_h + g.yoff;
+ s32 x_to_render = x_ + (g.lsb);
+
+ glTexCoord2i(0, 0); glVertex3i(x_to_render,y_, render_depth);
+ glTexCoord2i(0, 1); glVertex3i(x_to_render,y_+g.height, render_depth);
+ glTexCoord2i(1, 1); glVertex3i(x_to_render+g.width,y_+g.height, render_depth);
+ glTexCoord2i(1, 0); glVertex3i(x_to_render+g.width,y_, render_depth);
+
+ glEnd();
+
+ /* add kerning */
+ //kern = stbtt_GetCodepointKernAdvance(&font->info, ch, ch_next);
+ x_ += (g.advance);
+ index++;
+
+ if (index == cursor_pos)
+ {
+ cursor_x = x_;
+ }
+ }
+ glDisable(GL_TEXTURE_2D);
+
+ render_rectangle(cursor_x, y-3, 2, TEXTBOX_HEIGHT - 10, global_ui_context.style.textbox_foreground);
+
+ return x_ - x;
+}
+
+s32 render_text(font *font, s32 x, s32 y, char *text, color tint)
+{
+ if (!font->loaded)
+ return 0;
+
+ glEnable(GL_TEXTURE_2D);
+ glColor4f(tint.r/255.0f, tint.g/255.0f, tint.b/255.0f, tint.a/255.0f);
+
+ s32 x_ = x;
+ utf8_int32_t ch;
+ while((text = utf8codepoint(text, &ch)) && ch)
+ {
+ if (ch == 9) ch = 32;
+ utf8_int32_t ch_next;
+ utf8codepoint(text, &ch_next);
+ if (ch < TEXT_CHARSET_START || ch > TEXT_CHARSET_END)
+ {
+ ch = 0x3f;
+ }
+
+ glyph g = font->glyphs[ch];
+
+ glBindTexture(GL_TEXTURE_2D, g.textureID);
+ glBegin(GL_QUADS);
s32 y_ = y + font->px_h + g.yoff;
- s32 x_to_render = x_ + (lsb*font->scale);
+ s32 x_to_render = x_ + (g.lsb);
glTexCoord2i(0, 0); glVertex3i(x_to_render,y_, render_depth);
glTexCoord2i(0, 1); glVertex3i(x_to_render,y_+g.height, render_depth);
@@ -158,8 +266,8 @@ s32 render_text(font *font, s32 x, s32 y, char *text, color tint)
glEnd();
/* add kerning */
- kern = stbtt_GetCodepointKernAdvance(&font->info, ch, ch_next);
- x_ += (advance*font->scale)+(kern*font->scale);
+ //kern = stbtt_GetCodepointKernAdvance(&font->info, ch, ch_next);
+ x_ += (g.advance);
}
glDisable(GL_TEXTURE_2D);
@@ -213,13 +321,8 @@ s32 render_text_cutoff(font *font, s32 x, s32 y, char *text, color tint, u16 cut
glBindTexture(GL_TEXTURE_2D, g.textureID);
glBegin(GL_QUADS);
- s32 width = g.width;
-
- int advance, lsb, kern;
- stbtt_GetCodepointHMetrics(&font->info, ch, &advance, &lsb);
-
s32 y__ = y_ + font->px_h + g.yoff;
- s32 x_to_render = x_ + (lsb*font->scale);
+ s32 x_to_render = x_ + (g.lsb);
glTexCoord2i(0, 0); glVertex3i(x_to_render,y__, render_depth);
glTexCoord2i(0, 1); glVertex3i(x_to_render,y__+g.height, render_depth);
@@ -229,8 +332,8 @@ s32 render_text_cutoff(font *font, s32 x, s32 y, char *text, color tint, u16 cut
glEnd();
/* add kerning */
- kern = stbtt_GetCodepointKernAdvance(&font->info, ch, ch_next);
- x_ += (advance*font->scale)+(kern*font->scale);
+ //kern = stbtt_GetCodepointKernAdvance(&font->info, ch, ch_next);
+ x_ += (g.advance);
if (x_ > x+cutoff_width)
{
@@ -271,13 +374,9 @@ s32 calculate_cursor_position(font *font, char *text, s32 click_x)
s32 width_next = font->glyphs[ch_next].width;
- int advance, lsb, kern;
- stbtt_GetCodepointHMetrics(&font->info, ch, &advance, &lsb);
-
/* add kerning */
- kern = stbtt_GetCodepointKernAdvance(&font->info, ch, ch_next);
- x += (advance*font->scale)+(kern*font->scale);
-
+ //kern = stbtt_GetCodepointKernAdvance(&font->info, ch, ch_next);
+ x += (g.advance);
if (x - (width_next/5) > click_x)
{
return index;
@@ -314,12 +413,9 @@ s32 calculate_text_width_from_upto(font *font, char *text, s32 from, s32 index)
if (i >= from)
{
- int advance, lsb, kern;
- stbtt_GetCodepointHMetrics(&font->info, ch, &advance, &lsb);
-
/* add kerning */
- kern = stbtt_GetCodepointKernAdvance(&font->info, ch, ch_next);
- x += (advance*font->scale)+(kern*font->scale);
+ //kern = stbtt_GetCodepointKernAdvance(&font->info, ch, ch_next);
+ x += (g.advance);
}
i++;
@@ -351,12 +447,9 @@ s32 calculate_text_width_upto(font *font, char *text, s32 index)
glyph g = font->glyphs[ch];
s32 width = g.width;
- int advance, lsb, kern;
- stbtt_GetCodepointHMetrics(&font->info, ch, &advance, &lsb);
-
/* add kerning */
- kern = stbtt_GetCodepointKernAdvance(&font->info, ch, ch_next);
- x += (advance*font->scale)+(kern*font->scale);
+ //kern = stbtt_GetCodepointKernAdvance(&font->info, ch, ch_next);
+ x += (g.advance);
i++;
}
@@ -369,7 +462,7 @@ s32 calculate_text_width(font *font, char *text)
if (!font->loaded)
return 0;
- s32 x = 0;
+ float x = 0;
utf8_int32_t ch;
while((text = utf8codepoint(text, &ch)) && ch)
{
@@ -384,12 +477,9 @@ s32 calculate_text_width(font *font, char *text)
glyph g = font->glyphs[ch];
s32 width = g.width;
- int advance, lsb, kern;
- stbtt_GetCodepointHMetrics(&font->info, ch, &advance, &lsb);
-
/* add kerning */
- kern = stbtt_GetCodepointKernAdvance(&font->info, ch, ch_next);
- x += (advance*font->scale)+(kern*font->scale);
+ //kern = stbtt_GetCodepointKernAdvance(&font->info, ch, ch_next);
+ x += (g.advance);
}
return x;
diff --git a/src/render.h b/src/render.h
index 4d29eea..de6ff6d 100644
--- a/src/render.h
+++ b/src/render.h
@@ -39,6 +39,7 @@ s32 render_text(font *font, s32 x, s32 y, char *text, color tint);
s32 render_text_ellipsed(font *font, s32 x, s32 y, s32 maxw, char *text, color tint);
s32 render_text_cutoff(font *font, s32 x, s32 y, char *text, color tint, u16 cutoff_width);
s32 render_text_vertical(font *font, s32 x, s32 y, char *text, color tint);
+s32 render_text_with_cursor(font *font, s32 x, s32 y, char *text, color tint, s32 cursor_pos);
s32 calculate_cursor_position(font *font, char *text, s32 click_x);
s32 calculate_text_width(font *font, char *text);
diff --git a/src/ui.c b/src/ui.c
index d8d3a16..ef71340 100644
--- a/src/ui.c
+++ b/src/ui.c
@@ -675,10 +675,6 @@ bool ui_push_textbox(textbox_state *state, char *placeholder)
}
s32 cursor_text_w;
- s32 cursor_x = 0;
-
- //if (!global_ui_context.keyboard->has_selection)
- //state->diff = 0;
// select first character on click
if (clicked_to_set_cursor)
@@ -780,10 +776,9 @@ bool ui_push_textbox(textbox_state *state, char *placeholder)
s32 text_w = calculate_text_width(global_ui_context.font_small, state->buffer);
- cursor_x = text_x + cursor_text_w - state->diff;
-
+#if 1
// change offset after cursor position change
- if (!is_selecting && !global_ui_context.keyboard->has_selection)
+ if (!is_selecting && !global_ui_context.keyboard->has_selection && !state->attempting_to_select)
{
if (cursor_text_w < state->diff)
{
@@ -794,6 +789,7 @@ bool ui_push_textbox(textbox_state *state, char *placeholder)
state->diff = (cursor_text_w) - (TEXTBOX_WIDTH - 10);
}
}
+#endif
// make sure offset is recalculated when text changes or a portion of text is changed so the textbox doesnt end up half empty
#if 1
@@ -839,24 +835,25 @@ bool ui_push_textbox(textbox_state *state, char *placeholder)
}
+#if 1
if (is_selecting)
{
// move text offset x when selecting so we can select more text than available on screen.
- if (global_ui_context.mouse->x < x + 10)
+ if (global_ui_context.mouse->x < x + 20)
{
s32 text_w = calculate_text_width(global_ui_context.font_small, state->buffer);
- if (text_w > TEXTBOX_WIDTH-10)
+ if (text_w > TEXTBOX_WIDTH-20)
{
state->diff -= TEXTBOX_SCROLL_X_SPEED;
if (state->diff < 0) state->diff = 0;
}
}
- if (global_ui_context.mouse->x > x + TEXTBOX_WIDTH - 10)
+ if (global_ui_context.mouse->x > x + TEXTBOX_WIDTH - 25)
{
s32 text_w = calculate_text_width(global_ui_context.font_small, state->buffer);
- s32 diff = text_w - TEXTBOX_WIDTH + 10;
+ s32 diff = text_w - TEXTBOX_WIDTH + 25;
- if (text_w > TEXTBOX_WIDTH-10)
+ if (text_w > TEXTBOX_WIDTH-25)
{
state->diff += TEXTBOX_SCROLL_X_SPEED;
if (state->diff > diff)
@@ -865,6 +862,7 @@ bool ui_push_textbox(textbox_state *state, char *placeholder)
}
///////////////////////////////////////////////////////////
}
+#endif
// change selection area based on cursor position.
// if double clicked to select the entire textbox we should only
@@ -894,44 +892,6 @@ bool ui_push_textbox(textbox_state *state, char *placeholder)
state->double_clicked_to_select = false;
}
}
-
- // render cursor
- if (state->state)
- {
- last_cursor_pos = global_ui_context.keyboard->cursor;
-
- s32 cursor_y = y + 4;
- s32 cursor_h = TEXTBOX_HEIGHT - 8;
- s32 cursor_w = 2;
-
- if (cursor_tick % 40 < 20 && !global_ui_context.keyboard->has_selection)
- render_rectangle(cursor_x, cursor_y, cursor_w, cursor_h, global_ui_context.style.textbox_foreground);
- }
-
-
- // render selection area
- if (global_ui_context.keyboard->has_selection && state->state)
- {
- char tmp_buffer[MAX_INPUT_LENGTH];
- utf8_str_copy_upto(state->buffer,
- global_ui_context.keyboard->selection_begin_offset,
- tmp_buffer);
-
- s32 selection_start_x = calculate_text_width(global_ui_context.font_small,
- tmp_buffer);
-
- utf8_str_copy_upto(
- utf8_str_upto(
- state->buffer,
- global_ui_context.keyboard->selection_begin_offset),
- global_ui_context.keyboard->selection_length,
- tmp_buffer);
-
- s32 selection_width = calculate_text_width(global_ui_context.font_small,
- tmp_buffer);
-
- render_rectangle(text_x - state->diff + selection_start_x, y+4, selection_width, TEXTBOX_HEIGHT-8, global_ui_context.style.textbox_active_border);
- }
#endif
if (!has_text)
@@ -941,8 +901,19 @@ bool ui_push_textbox(textbox_state *state, char *placeholder)
}
else
{
- render_text(global_ui_context.font_small, text_x - state->diff, text_y,
- state->buffer, global_ui_context.style.foreground);
+ s32 www;
+ last_cursor_pos = global_ui_context.keyboard->cursor;
+
+ if (global_ui_context.keyboard->has_selection && state->state && global_ui_context.keyboard->selection_length)
+ render_text_with_selection(global_ui_context.font_small, text_x - state->diff, text_y,
+ state->buffer, global_ui_context.style.foreground, global_ui_context.keyboard->selection_begin_offset,
+ global_ui_context.keyboard->selection_length);
+ else if (state->state)
+ render_text_with_cursor(global_ui_context.font_small, text_x - state->diff, text_y,
+ state->buffer, global_ui_context.style.foreground, global_ui_context.keyboard->cursor);
+ else
+ render_text(global_ui_context.font_small, text_x - state->diff, text_y,
+ state->buffer, global_ui_context.style.foreground);
}
ui_pop_scissor();