Introduce subpixel text positioning within rencache

In order to fix the issue with cursor positioning a subpixel-aware draw
text operation within rencache was required.

With this modification the cursor positioning problem is completely
resolved.

A new function renderer.draw_text_subpixel is introduced to perform
consecutive, inline, text drawings with subpixel accuracy.
This commit is contained in:
Francesco Abbate
2021-03-06 18:12:02 +01:00
parent 9ff6a0325e
commit 3426bc5d73
6 changed files with 51 additions and 24 deletions
+15 -8
View File
@@ -11,13 +11,15 @@
#define CELL_SIZE 96
#define COMMAND_BUF_SIZE (1024 * 512)
enum { FREE_FONT, SET_CLIP, DRAW_TEXT, DRAW_RECT };
enum { FREE_FONT, SET_CLIP, DRAW_TEXT, DRAW_RECT, DRAW_TEXT_SUBPIXEL };
typedef struct {
int type, size;
RenRect rect;
RenColor color;
RenFont *font;
short int subpixel_scale;
short int x_subpixel_offset;
int tab_width;
char text[0];
} Command;
@@ -128,29 +130,30 @@ void rencache_draw_rect(RenRect rect, RenColor color) {
}
}
int rencache_draw_text(RenFont *font, const char *text, int x, int y, RenColor color) {
int rencache_draw_text(RenFont *font, const char *text, int x, int y, RenColor color, bool draw_subpixel) {
int subpixel_scale;
int w_subpixel = ren_get_font_width(font, text, &subpixel_scale);
RenRect rect;
rect.x = x;
rect.x = (draw_subpixel ? ren_font_subpixel_round(x, subpixel_scale, -1) : x);
rect.y = y;
int w = ren_get_font_width(font, text, &subpixel_scale);
rect.width = ren_font_subpixel_round(w, subpixel_scale, 0);
rect.width = ren_font_subpixel_round(w_subpixel, subpixel_scale, 0);
rect.height = ren_get_font_height(font);
if (rects_overlap(screen_rect, rect)) {
int sz = strlen(text) + 1;
Command *cmd = push_command(DRAW_TEXT, sizeof(Command) + sz);
Command *cmd = push_command(draw_subpixel ? DRAW_TEXT_SUBPIXEL : DRAW_TEXT, sizeof(Command) + sz);
if (cmd) {
memcpy(cmd->text, text, sz);
cmd->color = color;
cmd->font = font;
cmd->rect = rect;
cmd->subpixel_scale = (draw_subpixel ? subpixel_scale : 1);
cmd->x_subpixel_offset = x - subpixel_scale * rect.x;
cmd->tab_width = ren_get_font_tab_width(font);
}
}
return x + rect.width;
return x + (draw_subpixel ? w_subpixel : rect.width);
}
@@ -261,6 +264,10 @@ void rencache_end_frame(void) {
ren_set_font_tab_width(cmd->font, cmd->tab_width);
ren_draw_text(cmd->font, cmd->text, cmd->rect.x, cmd->rect.y, cmd->color);
break;
case DRAW_TEXT_SUBPIXEL:
ren_set_font_tab_width(cmd->font, cmd->tab_width);
ren_draw_text_subpixel(cmd->font, cmd->text, cmd->subpixel_scale * cmd->rect.x + cmd->x_subpixel_offset, cmd->rect.y, cmd->color);
break;
}
}