diff --git a/data/core/docview.lua b/data/core/docview.lua index 57383da7..7e6dcf30 100644 --- a/data/core/docview.lua +++ b/data/core/docview.lua @@ -152,10 +152,12 @@ function DocView:get_x_offset_col(line, x) local text = self.doc.lines[line] local xoffset, last_i, i = 0, 1, 1 + local subpixel_scale = self:get_font():subpixel_scale(); + local x_subpixel = subpixel_scale * x + subpixel_scale / 2 for char in common.utf8_chars(text) do - local w = self:get_font():get_width(char) - if xoffset >= x then - return (xoffset - x > w / 2) and last_i or i + local w = self:get_font():get_width_subpixel(char) + if xoffset >= subpixel_scale * x then + return (xoffset - x_subpixel > w / 2) and last_i or i end xoffset = xoffset + w last_i = i diff --git a/lib/font_renderer/font_renderer.h b/lib/font_renderer/font_renderer.h index 69696340..019d2ae7 100644 --- a/lib/font_renderer/font_renderer.h +++ b/lib/font_renderer/font_renderer.h @@ -51,8 +51,6 @@ void FR_Blend_Glyph(FR_Renderer *font_renderer, const FR_Bitmap_Glyph_Metrics *glyph, FR_Color color); int FR_Subpixel_Scale(FR_Renderer *); -#define FR_XADVANCE_TO_PIXELS(x, scale) (((x) + (scale) / 2) / (scale)) - #ifdef __cplusplus } #endif diff --git a/src/api/renderer_font.c b/src/api/renderer_font.c index 0dea11ae..744ea808 100644 --- a/src/api/renderer_font.c +++ b/src/api/renderer_font.c @@ -66,7 +66,24 @@ static int f_gc(lua_State *L) { static int f_get_width(lua_State *L) { RenFont **self = luaL_checkudata(L, 1, API_TYPE_FONT); const char *text = luaL_checkstring(L, 2); - lua_pushnumber(L, ren_get_font_width(*self, text) ); + int subpixel_scale; + int w = ren_get_font_width(*self, text, &subpixel_scale); + lua_pushnumber(L, ren_font_subpixel_round(w, subpixel_scale, 0)); + return 1; +} + + +static int f_subpixel_scale(lua_State *L) { + RenFont **self = luaL_checkudata(L, 1, API_TYPE_FONT); + lua_pushnumber(L, ren_get_font_subpixel_scale(*self)); + return 1; +} + + +static int f_get_width_subpixel(lua_State *L) { + RenFont **self = luaL_checkudata(L, 1, API_TYPE_FONT); + const char *text = luaL_checkstring(L, 2); + lua_pushnumber(L, ren_get_font_width(*self, text, NULL)); return 1; } @@ -79,11 +96,13 @@ static int f_get_height(lua_State *L) { static const luaL_Reg lib[] = { - { "__gc", f_gc }, - { "load", f_load }, - { "set_tab_width", f_set_tab_width }, - { "get_width", f_get_width }, - { "get_height", f_get_height }, + { "__gc", f_gc }, + { "load", f_load }, + { "set_tab_width", f_set_tab_width }, + { "get_width", f_get_width }, + { "get_width_subpixel", f_get_width_subpixel }, + { "get_height", f_get_height }, + { "subpixel_scale", f_subpixel_scale }, { NULL, NULL } }; diff --git a/src/rencache.c b/src/rencache.c index 5c6de328..2c45baf4 100644 --- a/src/rencache.c +++ b/src/rencache.c @@ -130,10 +130,12 @@ void rencache_draw_rect(RenRect rect, RenColor color) { int rencache_draw_text(RenFont *font, const char *text, int x, int y, RenColor color) { + int subpixel_scale; RenRect rect; rect.x = x; rect.y = y; - rect.width = ren_get_font_width(font, text); + int w = ren_get_font_width(font, text, &subpixel_scale); + rect.width = ren_font_subpixel_round(w, subpixel_scale, 0); rect.height = ren_get_font_height(font); if (rects_overlap(screen_rect, rect)) { diff --git a/src/renderer.c b/src/renderer.c index 6b31aaca..262f5814 100644 --- a/src/renderer.c +++ b/src/renderer.c @@ -179,18 +179,20 @@ int ren_get_font_tab_width(RenFont *font) { } -int ren_get_font_width(RenFont *font, const char *text) { +int ren_get_font_width(RenFont *font, const char *text, int *subpixel_scale) { int x = 0; const char *p = text; unsigned codepoint; - const int subpixel_scale = FR_Subpixel_Scale(font->renderer); while (*p) { p = utf8_to_codepoint(p, &codepoint); GlyphSet *set = get_glyphset(font, codepoint); FR_Bitmap_Glyph_Metrics *g = &set->glyphs[codepoint & 0xff]; x += g->xadvance; } - return FR_XADVANCE_TO_PIXELS(x, subpixel_scale); + if (subpixel_scale) { + *subpixel_scale = FR_Subpixel_Scale(font->renderer); + } + return x; } @@ -282,7 +284,7 @@ void ren_draw_image(RenImage *image, RenRect *sub, int x, int y, RenColor color) } } -int ren_draw_text(RenFont *font, const char *text, int x, int y, RenColor color) { +void ren_draw_text(RenFont *font, const char *text, int x, int y, RenColor color) { const char *p = text; unsigned codepoint; SDL_Surface *surf = SDL_GetWindowSurface(window); @@ -299,5 +301,22 @@ int ren_draw_text(RenFont *font, const char *text, int x, int y, RenColor color) } x_mult += g->xadvance; } - return FR_XADVANCE_TO_PIXELS(x_mult, subpixel_scale); +} + + +int ren_font_subpixel_round(int width, int subpixel_scale, int orientation) { + int w_mult; + if (orientation < 0) { + w_mult = width; + } else if (orientation == 0) { + w_mult = width + subpixel_scale / 2; + } else { + w_mult = width + subpixel_scale - 1; + } + return w_mult / subpixel_scale; +} + + +int ren_get_font_subpixel_scale(RenFont *font) { + return FR_Subpixel_Scale(font->renderer); } diff --git a/src/renderer.h b/src/renderer.h index 3b041846..39551de8 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -34,11 +34,13 @@ RenFont* ren_load_font(const char *filename, float size, unsigned int renderer_f void ren_free_font(RenFont *font); void ren_set_font_tab_width(RenFont *font, int n); int ren_get_font_tab_width(RenFont *font); -int ren_get_font_width(RenFont *font, const char *text); +int ren_get_font_width(RenFont *font, const char *text, int *subpixel_scale); int ren_get_font_height(RenFont *font); +int ren_get_font_subpixel_scale(RenFont *font); +int ren_font_subpixel_round(int width, int subpixel_scale, int orientation); void ren_draw_rect(RenRect rect, RenColor color); void ren_draw_image(RenImage *image, RenRect *sub, int x, int y, RenColor color); -int ren_draw_text(RenFont *font, const char *text, int x, int y, RenColor color); +void ren_draw_text(RenFont *font, const char *text, int x, int y, RenColor color); #endif