summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2020-11-25 14:32:00 -0500
committerLeo Tenenbaum <pommicket@gmail.com>2020-11-25 14:32:00 -0500
commit2a498a47fc8836eb2baae3a4fb9e7e0316402fa6 (patch)
treefe159650a35a773aa6eef979f5066434cca21c71
parentb58e9a3faa4e35ff6e872e28c7051fa19e2b11ad (diff)
cutting off text
-rw-r--r--buffer.c19
-rw-r--r--main.c16
-rw-r--r--text.c40
3 files changed, 56 insertions, 19 deletions
diff --git a/buffer.c b/buffer.c
index a1c0516..7fea0d3 100644
--- a/buffer.c
+++ b/buffer.c
@@ -118,15 +118,22 @@ void text_buffer_free(TextBuffer *buffer) {
}
// Render the text buffer in the given rectangle
-void text_buffer_render(TextBuffer *buffer, Font *font, float box_x, float box_y, float box_w, float box_h) {
+void text_buffer_render(TextBuffer *buffer, Font *font, float x1, float y1, float x2, float y2) {
mbstate_t mbstate = {0};
uint nblocks = buffer->nblocks;
TextBlock *blocks = buffer->blocks;
+ glBegin(GL_LINE_LOOP);
+ glVertex2f(x1,y1);
+ glVertex2f(x1,y2);
+ glVertex2f(x2,y2);
+ glVertex2f(x2,y1);
+ glEnd();
+
text_chars_begin(font);
TextRenderState text_state = {
- .x = box_x, .y = box_y,
- .min_x = box_x, .min_y = box_y,
- .max_x = box_x+box_w, .max_y = box_y+box_h
+ .x = x1, .y = y1 + text_font_char_height(font),
+ .min_x = x1, .min_y = y1,
+ .max_x = x2, .max_y = y2
};
for (uint block_idx = 0; block_idx < nblocks; ++block_idx) {
@@ -154,8 +161,8 @@ void text_buffer_render(TextBuffer *buffer, Font *font, float box_x, float box_y
}
switch (c) {
case L'\n':
- text_state.x = box_x;
- text_state.y -= text_font_char_height(font);
+ text_state.x = x1;
+ text_state.y += text_font_char_height(font);
break;
case L'\r': break; // for CRLF line endings
case L'\t':
diff --git a/main.c b/main.c
index d4c61d9..c655d42 100644
--- a/main.c
+++ b/main.c
@@ -1,3 +1,4 @@
+
#include "base.h"
no_warn_start
#if _WIN32
@@ -96,15 +97,20 @@ int main(void) {
glViewport(0, 0, window_width, window_height);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
- glOrtho(0, window_width, 0, window_height, -1, +1);
+ // pixel coordinates; down is positive y
+ glOrtho(0, window_width, window_height, 0, -1, +1);
glClearColor(0, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1,1,1);
- text_buffer_render(&text_buffer, font, 50, window_heightf-50, window_widthf-100, window_heightf-100);
- if (text_has_err()) {
- printf("Text error: %s\n", text_get_err());
- break;
+
+ {
+ float x1 = 50, y1 = 50, x2 = window_widthf-50, y2 = window_heightf-50;
+ text_buffer_render(&text_buffer, font, x1, y1, x2, y2);
+ if (text_has_err()) {
+ printf("Text error: %s\n", text_get_err());
+ break;
+ }
}
//text_buffer_print_debug(&text_buffer);
diff --git a/text.c b/text.c
index ddd7cdc..762bfd9 100644
--- a/text.c
+++ b/text.c
@@ -178,16 +178,40 @@ void text_render_char(Font *font, char32_t c, TextRenderState *state) {
stbtt_bakedchar *char_data = font->char_pages[page];
if (char_data) { // if page was successfully loaded
stbtt_aligned_quad q = {0};
- // because stb_truetype uses down is positive, we need to negate the y
- // coordinate, pass it into the function, then negate it back.
- state->y = -state->y;
stbtt_GetBakedQuad(char_data, font->tex_widths[page], font->tex_heights[page],
(int)index, &state->x, &state->y, &q, 1);
- state->y = -state->y;
- glTexCoord2f(q.s0,q.t1); glVertex2f(q.x0,-q.y1);
- glTexCoord2f(q.s1,q.t1); glVertex2f(q.x1,-q.y1);
- glTexCoord2f(q.s1,q.t0); glVertex2f(q.x1,-q.y0);
- glTexCoord2f(q.s0,q.t0); glVertex2f(q.x0,-q.y0);
+ float s0 = q.s0, t0 = q.t0;
+ float s1 = q.s1, t1 = q.t1;
+ float x0 = q.x0, y0 = q.y0;
+ float x1 = q.x1, y1 = q.y1;
+ float const min_x = state->min_x, max_x = state->max_x;
+ float const min_y = state->min_y, max_y = state->max_y;
+ if (x0 > max_x || y0 > max_y || x1 < min_x || y1 < min_y)
+ return;
+ if (x0 < min_x) {
+ // left side of character is clipped
+ s0 = (min_x-x0) / (x1-x0) * (s1-s0) + s0;
+ x0 = min_x;
+ }
+ if (x1 >= max_x) {
+ // right side of character is clipped
+ s1 = (max_x-x0) / (x1-x0) * (s1-s0) + s0;
+ x1 = max_x;
+ }
+ if (y0 < min_y) {
+ // top side of character is clipped
+ t0 = (min_y-y0) / (y1-y0) * (t1-t0) + t0;
+ y0 = min_y;
+ }
+ if (y1 >= max_y) {
+ // bottom side of character is clipped
+ t1 = (max_y-y0) / (y1-y0) * (t1-t0) + t0;
+ y1 = max_y;
+ }
+ glTexCoord2f(s0,t0); glVertex2f(x0,y0);
+ glTexCoord2f(s0,t1); glVertex2f(x0,y1);
+ glTexCoord2f(s1,t1); glVertex2f(x1,y1);
+ glTexCoord2f(s1,t0); glVertex2f(x1,y0);
}
}