Implement unicode character replacements
Useful to draw whitespaces with alternate characters and colors without slowing down the text rendering. A new API is implemented. A renderer.replacements object can be created to list the replacements. In turns the function renderer.draw_text and draw_text_subpixel now accept two optional arguments for replacements.
This commit is contained in:
parent
ed6ba64542
commit
3b040aabc7
|
@ -6,6 +6,12 @@ This files document the changes done in Lite XL for each release.
|
||||||
|
|
||||||
Add `system.set_window_opacity` function.
|
Add `system.set_window_opacity` function.
|
||||||
|
|
||||||
|
Add codepoint replacement API to support natively the "draw whitespaces" option.
|
||||||
|
It replace the `drawwhitespace` plugin. If can be configured using the
|
||||||
|
`config.draw_whitespace` boolean variable and enabled and disables using the
|
||||||
|
commands `draw-whitespace:toggle`, `draw-whitespace:enable`,
|
||||||
|
`draw-whitespace:disable`.
|
||||||
|
|
||||||
### 1.16.5
|
### 1.16.5
|
||||||
|
|
||||||
Hotfix for Github's issue https://github.com/franko/lite-xl/issues/122
|
Hotfix for Github's issue https://github.com/franko/lite-xl/issues/122
|
||||||
|
|
|
@ -59,7 +59,7 @@ end
|
||||||
|
|
||||||
|
|
||||||
function command.add_defaults()
|
function command.add_defaults()
|
||||||
local reg = { "core", "root", "command", "doc", "findreplace", "files" }
|
local reg = { "core", "root", "command", "doc", "findreplace", "files", "drawwhitespace" }
|
||||||
for _, name in ipairs(reg) do
|
for _, name in ipairs(reg) do
|
||||||
require("core.commands." .. name)
|
require("core.commands." .. name)
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
local command = require "core.command"
|
||||||
|
local config = require "core.config"
|
||||||
|
|
||||||
|
command.add(nil, {
|
||||||
|
["draw-whitespace:toggle"] = function()
|
||||||
|
config.draw_whitespace = not config.draw_whitespace
|
||||||
|
end,
|
||||||
|
|
||||||
|
["draw-whitespace:disable"] = function()
|
||||||
|
config.draw_whitespace = false
|
||||||
|
end,
|
||||||
|
|
||||||
|
["draw-whitespace:enable"] = function()
|
||||||
|
config.draw_whitespace = true
|
||||||
|
end,
|
||||||
|
})
|
|
@ -21,6 +21,7 @@ config.max_project_files = 2000
|
||||||
config.transitions = true
|
config.transitions = true
|
||||||
config.animation_rate = 1.0
|
config.animation_rate = 1.0
|
||||||
config.blink_period = 0.8
|
config.blink_period = 0.8
|
||||||
|
config.draw_whitespace = false
|
||||||
|
|
||||||
-- Disable plugin loading setting to false the config entry
|
-- Disable plugin loading setting to false the config entry
|
||||||
-- of the same name.
|
-- of the same name.
|
||||||
|
|
|
@ -314,7 +314,11 @@ function DocView:draw_line_text(idx, x, y)
|
||||||
local tx, ty = subpixel_scale * x, y + self:get_line_text_y_offset()
|
local tx, ty = subpixel_scale * x, y + self:get_line_text_y_offset()
|
||||||
for _, type, text in self.doc.highlighter:each_token(idx) do
|
for _, type, text in self.doc.highlighter:each_token(idx) do
|
||||||
local color = style.syntax[type]
|
local color = style.syntax[type]
|
||||||
tx = renderer.draw_text_subpixel(font, text, tx, ty, color)
|
if config.draw_whitespace then
|
||||||
|
tx = renderer.draw_text_subpixel(font, text, tx, ty, color, core.replacements, style.syntax.comment)
|
||||||
|
else
|
||||||
|
tx = renderer.draw_text_subpixel(font, text, tx, ty, color)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -345,6 +345,14 @@ function core.remove_project_directory(path)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
local function whitespace_replacements()
|
||||||
|
local r = renderer.replacements.new()
|
||||||
|
r:add(" ", "·")
|
||||||
|
r:add("\t", "»")
|
||||||
|
return r
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
function core.init()
|
function core.init()
|
||||||
command = require "core.command"
|
command = require "core.command"
|
||||||
keymap = require "core.keymap"
|
keymap = require "core.keymap"
|
||||||
|
@ -416,6 +424,7 @@ function core.init()
|
||||||
core.redraw = true
|
core.redraw = true
|
||||||
core.visited_files = {}
|
core.visited_files = {}
|
||||||
core.restart_request = false
|
core.restart_request = false
|
||||||
|
core.replacements = whitespace_replacements()
|
||||||
|
|
||||||
core.root_view = RootView()
|
core.root_view = RootView()
|
||||||
core.command_view = CommandView()
|
core.command_view = CommandView()
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include "lualib.h"
|
#include "lualib.h"
|
||||||
|
|
||||||
#define API_TYPE_FONT "Font"
|
#define API_TYPE_FONT "Font"
|
||||||
|
#define API_TYPE_REPLACE "Replace"
|
||||||
|
|
||||||
void api_load_libs(lua_State *L);
|
void api_load_libs(lua_State *L);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
#include "api.h"
|
||||||
|
#include "renderer.h"
|
||||||
|
|
||||||
|
|
||||||
|
static int f_new(lua_State *L) {
|
||||||
|
CPReplaceTable *rep_table = lua_newuserdata(L, sizeof(CPReplaceTable));
|
||||||
|
luaL_setmetatable(L, API_TYPE_REPLACE);
|
||||||
|
ren_cp_replace_init(rep_table);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int f_gc(lua_State *L) {
|
||||||
|
CPReplaceTable *rep_table = luaL_checkudata(L, 1, API_TYPE_REPLACE);
|
||||||
|
ren_cp_replace_free(rep_table);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int f_add(lua_State *L) {
|
||||||
|
CPReplaceTable *rep_table = luaL_checkudata(L, 1, API_TYPE_REPLACE);
|
||||||
|
const char *src = luaL_checkstring(L, 2);
|
||||||
|
const char *dst = luaL_checkstring(L, 3);
|
||||||
|
ren_cp_replace_add(rep_table, src, dst);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static const luaL_Reg lib[] = {
|
||||||
|
{ "__gc", f_gc },
|
||||||
|
{ "new", f_new },
|
||||||
|
{ "add", f_add },
|
||||||
|
{ NULL, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
int luaopen_renderer_replacements(lua_State *L) {
|
||||||
|
luaL_newmetatable(L, API_TYPE_REPLACE);
|
||||||
|
luaL_setfuncs(L, lib, 0);
|
||||||
|
lua_pushvalue(L, -1);
|
||||||
|
lua_setfield(L, -2, "__index");
|
||||||
|
return 1;
|
||||||
|
}
|
|
@ -71,28 +71,37 @@ static int f_draw_rect(lua_State *L) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int draw_text_subpixel_impl(lua_State *L, bool draw_subpixel) {
|
||||||
static int f_draw_text(lua_State *L) {
|
|
||||||
RenFont **font = luaL_checkudata(L, 1, API_TYPE_FONT);
|
RenFont **font = luaL_checkudata(L, 1, API_TYPE_FONT);
|
||||||
const char *text = luaL_checkstring(L, 2);
|
const char *text = luaL_checkstring(L, 2);
|
||||||
int x = luaL_checknumber(L, 3);
|
/* The coordinate below will be in subpixels iff draw_subpixel is true.
|
||||||
|
Otherwise it will be in pixels. */
|
||||||
|
int x_subpixel = luaL_checknumber(L, 3);
|
||||||
int y = luaL_checknumber(L, 4);
|
int y = luaL_checknumber(L, 4);
|
||||||
RenColor color = checkcolor(L, 5, 255);
|
RenColor color = checkcolor(L, 5, 255);
|
||||||
x = rencache_draw_text(*font, text, x, y, color, false);
|
|
||||||
lua_pushnumber(L, x);
|
CPReplaceTable *rep_table;
|
||||||
|
RenColor replace_color;
|
||||||
|
if (lua_gettop(L) >= 7) {
|
||||||
|
rep_table = luaL_checkudata(L, 6, API_TYPE_REPLACE);
|
||||||
|
replace_color = checkcolor(L, 7, 255);
|
||||||
|
} else {
|
||||||
|
rep_table = NULL;
|
||||||
|
replace_color = (RenColor) {0};
|
||||||
|
}
|
||||||
|
|
||||||
|
x_subpixel = rencache_draw_text(*font, text, x_subpixel, y, color, draw_subpixel, rep_table, replace_color);
|
||||||
|
lua_pushnumber(L, x_subpixel);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int f_draw_text(lua_State *L) {
|
||||||
|
return draw_text_subpixel_impl(L, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int f_draw_text_subpixel(lua_State *L) {
|
static int f_draw_text_subpixel(lua_State *L) {
|
||||||
RenFont **font = luaL_checkudata(L, 1, API_TYPE_FONT);
|
return draw_text_subpixel_impl(L, true);
|
||||||
const char *text = luaL_checkstring(L, 2);
|
|
||||||
int x_subpixel = luaL_checknumber(L, 3);
|
|
||||||
int y = luaL_checknumber(L, 4);
|
|
||||||
RenColor color = checkcolor(L, 5, 255);
|
|
||||||
x_subpixel = rencache_draw_text(*font, text, x_subpixel, y, color, true);
|
|
||||||
lua_pushnumber(L, x_subpixel);
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -110,10 +119,13 @@ static const luaL_Reg lib[] = {
|
||||||
|
|
||||||
|
|
||||||
int luaopen_renderer_font(lua_State *L);
|
int luaopen_renderer_font(lua_State *L);
|
||||||
|
int luaopen_renderer_replacements(lua_State *L);
|
||||||
|
|
||||||
int luaopen_renderer(lua_State *L) {
|
int luaopen_renderer(lua_State *L) {
|
||||||
luaL_newlib(L, lib);
|
luaL_newlib(L, lib);
|
||||||
luaopen_renderer_font(L);
|
luaopen_renderer_font(L);
|
||||||
lua_setfield(L, -2, "font");
|
lua_setfield(L, -2, "font");
|
||||||
|
luaopen_renderer_replacements(L);
|
||||||
|
lua_setfield(L, -2, "replacements");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
lite_sources = [
|
lite_sources = [
|
||||||
'api/api.c',
|
'api/api.c',
|
||||||
|
'api/cp_replace.c',
|
||||||
'api/renderer.c',
|
'api/renderer.c',
|
||||||
'api/renderer_font.c',
|
'api/renderer_font.c',
|
||||||
'api/system.c',
|
'api/system.c',
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "rencache.h"
|
#include "rencache.h"
|
||||||
|
|
||||||
|
@ -14,13 +15,16 @@
|
||||||
enum { FREE_FONT, SET_CLIP, DRAW_TEXT, DRAW_RECT, DRAW_TEXT_SUBPIXEL };
|
enum { FREE_FONT, SET_CLIP, DRAW_TEXT, DRAW_RECT, DRAW_TEXT_SUBPIXEL };
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int type, size;
|
int8_t type;
|
||||||
|
int8_t tab_size;
|
||||||
|
int8_t subpixel_scale;
|
||||||
|
int8_t x_subpixel_offset;
|
||||||
|
int32_t size;
|
||||||
RenRect rect;
|
RenRect rect;
|
||||||
RenColor color;
|
RenColor color;
|
||||||
RenFont *font;
|
RenFont *font;
|
||||||
short int subpixel_scale;
|
CPReplaceTable *replacements;
|
||||||
short int x_subpixel_offset;
|
RenColor replace_color;
|
||||||
int tab_size;
|
|
||||||
char text[0];
|
char text[0];
|
||||||
} Command;
|
} Command;
|
||||||
|
|
||||||
|
@ -130,7 +134,10 @@ void rencache_draw_rect(RenRect rect, RenColor color) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int rencache_draw_text(RenFont *font, const char *text, int x, int y, RenColor color, bool draw_subpixel) {
|
int rencache_draw_text(RenFont *font,
|
||||||
|
const char *text, int x, int y, RenColor color, bool draw_subpixel,
|
||||||
|
CPReplaceTable *replacements, RenColor replace_color)
|
||||||
|
{
|
||||||
int subpixel_scale;
|
int subpixel_scale;
|
||||||
int w_subpixel = ren_get_font_width(font, text, &subpixel_scale);
|
int w_subpixel = ren_get_font_width(font, text, &subpixel_scale);
|
||||||
RenRect rect;
|
RenRect rect;
|
||||||
|
@ -150,6 +157,8 @@ int rencache_draw_text(RenFont *font, const char *text, int x, int y, RenColor c
|
||||||
cmd->subpixel_scale = (draw_subpixel ? subpixel_scale : 1);
|
cmd->subpixel_scale = (draw_subpixel ? subpixel_scale : 1);
|
||||||
cmd->x_subpixel_offset = x - subpixel_scale * rect.x;
|
cmd->x_subpixel_offset = x - subpixel_scale * rect.x;
|
||||||
cmd->tab_size = ren_get_font_tab_size(font);
|
cmd->tab_size = ren_get_font_tab_size(font);
|
||||||
|
cmd->replacements = replacements;
|
||||||
|
cmd->replace_color = replace_color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -262,11 +271,14 @@ void rencache_end_frame(void) {
|
||||||
break;
|
break;
|
||||||
case DRAW_TEXT:
|
case DRAW_TEXT:
|
||||||
ren_set_font_tab_size(cmd->font, cmd->tab_size);
|
ren_set_font_tab_size(cmd->font, cmd->tab_size);
|
||||||
ren_draw_text(cmd->font, cmd->text, cmd->rect.x, cmd->rect.y, cmd->color);
|
ren_draw_text(cmd->font, cmd->text, cmd->rect.x, cmd->rect.y, cmd->color,
|
||||||
|
cmd->replacements, cmd->replace_color);
|
||||||
break;
|
break;
|
||||||
case DRAW_TEXT_SUBPIXEL:
|
case DRAW_TEXT_SUBPIXEL:
|
||||||
ren_set_font_tab_size(cmd->font, cmd->tab_size);
|
ren_set_font_tab_size(cmd->font, cmd->tab_size);
|
||||||
ren_draw_text_subpixel(cmd->font, cmd->text, cmd->subpixel_scale * cmd->rect.x + cmd->x_subpixel_offset, cmd->rect.y, cmd->color);
|
ren_draw_text_subpixel(cmd->font, cmd->text,
|
||||||
|
cmd->subpixel_scale * cmd->rect.x + cmd->x_subpixel_offset, cmd->rect.y, cmd->color,
|
||||||
|
cmd->replacements, cmd->replace_color);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ void rencache_show_debug(bool enable);
|
||||||
void rencache_free_font(RenFont *font);
|
void rencache_free_font(RenFont *font);
|
||||||
void rencache_set_clip_rect(RenRect rect);
|
void rencache_set_clip_rect(RenRect rect);
|
||||||
void rencache_draw_rect(RenRect rect, RenColor color);
|
void rencache_draw_rect(RenRect rect, RenColor color);
|
||||||
int rencache_draw_text(RenFont *font, const char *text, int x, int y, RenColor color, bool draw_subpixel);
|
int rencache_draw_text(RenFont *font, const char *text, int x, int y, RenColor color, bool draw_subpixel, CPReplaceTable *replacements, RenColor replace_color);
|
||||||
void rencache_invalidate(void);
|
void rencache_invalidate(void);
|
||||||
void rencache_begin_frame(void);
|
void rencache_begin_frame(void);
|
||||||
void rencache_end_frame(void);
|
void rencache_end_frame(void);
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include "font_renderer.h"
|
#include "font_renderer.h"
|
||||||
|
|
||||||
#define MAX_GLYPHSET 256
|
#define MAX_GLYPHSET 256
|
||||||
|
#define REPLACEMENT_CHUNK_SIZE 8
|
||||||
|
|
||||||
struct RenImage {
|
struct RenImage {
|
||||||
RenColor *pixels;
|
RenColor *pixels;
|
||||||
|
@ -60,6 +61,37 @@ static const char* utf8_to_codepoint(const char *p, unsigned *dst) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ren_cp_replace_init(CPReplaceTable *rep_table) {
|
||||||
|
rep_table->size = 0;
|
||||||
|
rep_table->replacements = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ren_cp_replace_free(CPReplaceTable *rep_table) {
|
||||||
|
free(rep_table->replacements);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ren_cp_replace_add(CPReplaceTable *rep_table, const char *src, const char *dst) {
|
||||||
|
int table_size = rep_table->size;
|
||||||
|
if (table_size % REPLACEMENT_CHUNK_SIZE == 0) {
|
||||||
|
CPReplace *old_replacements = rep_table->replacements;
|
||||||
|
const int new_size = (table_size / REPLACEMENT_CHUNK_SIZE + 1) * REPLACEMENT_CHUNK_SIZE;
|
||||||
|
rep_table->replacements = malloc(new_size * sizeof(CPReplace));
|
||||||
|
if (!rep_table->replacements) {
|
||||||
|
rep_table->replacements = old_replacements;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
memcpy(rep_table->replacements, old_replacements, table_size * sizeof(CPReplace));
|
||||||
|
free(old_replacements);
|
||||||
|
}
|
||||||
|
CPReplace *rep = &rep_table->replacements[table_size];
|
||||||
|
utf8_to_codepoint(src, &rep->codepoint_src);
|
||||||
|
utf8_to_codepoint(dst, &rep->codepoint_dst);
|
||||||
|
rep_table->size = table_size + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void ren_init(SDL_Window *win) {
|
void ren_init(SDL_Window *win) {
|
||||||
assert(win);
|
assert(win);
|
||||||
window = win;
|
window = win;
|
||||||
|
@ -291,31 +323,55 @@ void ren_draw_image(RenImage *image, RenRect *sub, int x, int y, RenColor color)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int codepoint_replace(CPReplaceTable *rep_table, unsigned *codepoint) {
|
||||||
|
for (int i = 0; i < rep_table->size; i++) {
|
||||||
|
const CPReplace *rep = &rep_table->replacements[i];
|
||||||
|
if (*codepoint == rep->codepoint_src) {
|
||||||
|
*codepoint = rep->codepoint_dst;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void ren_draw_text_subpixel(RenFont *font, const char *text, int x_subpixel, int y, RenColor color) {
|
|
||||||
|
void ren_draw_text_subpixel(RenFont *font, const char *text, int x_subpixel, int y, RenColor color,
|
||||||
|
CPReplaceTable *replacements, RenColor replace_color)
|
||||||
|
{
|
||||||
const char *p = text;
|
const char *p = text;
|
||||||
unsigned codepoint;
|
unsigned codepoint;
|
||||||
SDL_Surface *surf = SDL_GetWindowSurface(window);
|
SDL_Surface *surf = SDL_GetWindowSurface(window);
|
||||||
FR_Color color_fr = { .r = color.r, .g = color.g, .b = color.b };
|
const FR_Color color_fr = { .r = color.r, .g = color.g, .b = color.b };
|
||||||
while (*p) {
|
while (*p) {
|
||||||
|
FR_Color color_rep;
|
||||||
p = utf8_to_codepoint(p, &codepoint);
|
p = utf8_to_codepoint(p, &codepoint);
|
||||||
GlyphSet *set = get_glyphset(font, codepoint);
|
GlyphSet *set = get_glyphset(font, codepoint);
|
||||||
FR_Bitmap_Glyph_Metrics *g = &set->glyphs[codepoint & 0xff];
|
FR_Bitmap_Glyph_Metrics *g = &set->glyphs[codepoint & 0xff];
|
||||||
|
const int xadvance_original_cp = g->xadvance;
|
||||||
|
const int replaced = replacements ? codepoint_replace(replacements, &codepoint) : 0;
|
||||||
|
if (replaced) {
|
||||||
|
set = get_glyphset(font, codepoint);
|
||||||
|
g = &set->glyphs[codepoint & 0xff];
|
||||||
|
color_rep = (FR_Color) { .r = replace_color.r, .g = replace_color.g, .b = replace_color.b};
|
||||||
|
} else {
|
||||||
|
color_rep = color_fr;
|
||||||
|
}
|
||||||
if (color.a != 0) {
|
if (color.a != 0) {
|
||||||
FR_Blend_Glyph(font->renderer, &clip,
|
FR_Blend_Glyph(font->renderer, &clip,
|
||||||
x_subpixel, y, (uint8_t *) surf->pixels, surf->w, set->image, g, color_fr);
|
x_subpixel, y, (uint8_t *) surf->pixels, surf->w, set->image, g, color_rep);
|
||||||
}
|
}
|
||||||
x_subpixel += g->xadvance;
|
x_subpixel += xadvance_original_cp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void 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) {
|
CPReplaceTable *replacements, RenColor replace_color)
|
||||||
|
{
|
||||||
const int subpixel_scale = FR_Subpixel_Scale(font->renderer);
|
const int subpixel_scale = FR_Subpixel_Scale(font->renderer);
|
||||||
ren_draw_text_subpixel(font, text, subpixel_scale * x, y, color);
|
ren_draw_text_subpixel(font, text, subpixel_scale * x, y, color, replacements, replace_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Could be declared as static inline
|
||||||
int ren_font_subpixel_round(int width, int subpixel_scale, int orientation) {
|
int ren_font_subpixel_round(int width, int subpixel_scale, int orientation) {
|
||||||
int w_mult;
|
int w_mult;
|
||||||
if (orientation < 0) {
|
if (orientation < 0) {
|
||||||
|
@ -332,3 +388,4 @@ int ren_font_subpixel_round(int width, int subpixel_scale, int orientation) {
|
||||||
int ren_get_font_subpixel_scale(RenFont *font) {
|
int ren_get_font_subpixel_scale(RenFont *font) {
|
||||||
return FR_Subpixel_Scale(font->renderer);
|
return FR_Subpixel_Scale(font->renderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,19 @@ enum {
|
||||||
typedef struct { uint8_t b, g, r, a; } RenColor;
|
typedef struct { uint8_t b, g, r, a; } RenColor;
|
||||||
typedef struct { int x, y, width, height; } RenRect;
|
typedef struct { int x, y, width, height; } RenRect;
|
||||||
|
|
||||||
|
struct CPReplace {
|
||||||
|
unsigned codepoint_src;
|
||||||
|
unsigned codepoint_dst;
|
||||||
|
};
|
||||||
|
typedef struct CPReplace CPReplace;
|
||||||
|
|
||||||
|
|
||||||
|
struct CPReplaceTable {
|
||||||
|
int size;
|
||||||
|
CPReplace *replacements;
|
||||||
|
};
|
||||||
|
typedef struct CPReplaceTable CPReplaceTable;
|
||||||
|
|
||||||
|
|
||||||
void ren_init(SDL_Window *win);
|
void ren_init(SDL_Window *win);
|
||||||
void ren_update_rects(RenRect *rects, int count);
|
void ren_update_rects(RenRect *rects, int count);
|
||||||
|
@ -41,7 +54,12 @@ int ren_font_subpixel_round(int width, int subpixel_scale, int orientation);
|
||||||
|
|
||||||
void ren_draw_rect(RenRect rect, RenColor color);
|
void ren_draw_rect(RenRect rect, RenColor color);
|
||||||
void ren_draw_image(RenImage *image, RenRect *sub, int x, int y, RenColor color);
|
void ren_draw_image(RenImage *image, RenRect *sub, int x, int y, RenColor color);
|
||||||
void 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, CPReplaceTable *replacements, RenColor replace_color);
|
||||||
void ren_draw_text_subpixel(RenFont *font, const char *text, int x_subpixel, int y, RenColor color);
|
void ren_draw_text_subpixel(RenFont *font, const char *text, int x_subpixel, int y, RenColor color, CPReplaceTable *replacements, RenColor replace_color);
|
||||||
|
|
||||||
|
void ren_cp_replace_init(CPReplaceTable *rep_table);
|
||||||
|
void ren_cp_replace_free(CPReplaceTable *rep_table);
|
||||||
|
void ren_cp_replace_add(CPReplaceTable *rep_table, const char *src, const char *dst);
|
||||||
|
void ren_cp_replace_clear(CPReplaceTable *rep_table);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue