diff --git a/src/console.c b/src/console.c index 58e3588..5501775 100644 --- a/src/console.c +++ b/src/console.c @@ -1255,6 +1255,8 @@ void kmscon_console_draw(struct kmscon_console *con, bool cursor_done = false; int ret, warned = 0; uint64_t time_prep = 0, time_draw = 0, time_rend = 0; + const uint32_t *ch; + size_t len; if (!con || !draw_cb) return; @@ -1318,7 +1320,11 @@ void kmscon_console_draw(struct kmscon_console *con, if (con->flags & KMSCON_CONSOLE_INVERSE) attr.inverse = !attr.inverse; - ret = draw_cb(con, cell->ch, j, i, &attr, data); + ch = tsm_symbol_get(NULL, &cell->ch, &len); + if (cell->ch == ' ' || cell->ch == 0) + len = 0; + ret = draw_cb(con, cell->ch, ch, len, j, i, &attr, + data); if (ret && warned++ < 3) { log_debug("cannot draw glyph at %ux%u via text-renderer", j, i); @@ -1332,7 +1338,7 @@ void kmscon_console_draw(struct kmscon_console *con, if (!(con->flags & KMSCON_CONSOLE_HIDE_CURSOR)) { if (!(con->flags & KMSCON_CONSOLE_INVERSE)) attr.inverse = !attr.inverse; - draw_cb(con, 0, cur_x, i, &attr, data); + draw_cb(con, 0, NULL, 0, cur_x, i, &attr, data); } } } diff --git a/src/console.h b/src/console.h index 2bc590c..b49c590 100644 --- a/src/console.h +++ b/src/console.h @@ -68,7 +68,9 @@ struct kmscon_console_attr { typedef int (*kmscon_console_prepare_cb) (struct kmscon_console *con, void *data); typedef int (*kmscon_console_draw_cb) (struct kmscon_console *con, - tsm_symbol_t ch, + uint32_t id, + const uint32_t *ch, + size_t len, unsigned int posx, unsigned int posy, const struct kmscon_console_attr *attr, diff --git a/src/text.c b/src/text.c index fa1c301..f39d255 100644 --- a/src/text.c +++ b/src/text.c @@ -431,7 +431,9 @@ int kmscon_text_prepare(struct kmscon_text *txt) /** * kmscon_text_draw: * @txt: valid text renderer - * @ch: symbol you want to draw + * @id: a unique ID that identifies @ch globally + * @ch: ucs4 symbol you want to draw + * @len: length of @ch or 0 for empty cell * @posx: X-position of the glyph * @posy: Y-position of the glyph * @attr: glyph attributes @@ -443,16 +445,17 @@ int kmscon_text_prepare(struct kmscon_text *txt) * * Returns: 0 on success or negative error code if this glyph couldn't be drawn. */ -int kmscon_text_draw(struct kmscon_text *txt, tsm_symbol_t ch, - unsigned int posx, unsigned int posy, - const struct kmscon_console_attr *attr) +int kmscon_text_draw(struct kmscon_text *txt, + uint32_t id, const uint32_t *ch, size_t len, + unsigned int posx, unsigned int posy, + const struct kmscon_console_attr *attr) { if (!txt || !txt->rendering) return -EINVAL; if (posx >= txt->cols || posy >= txt->rows || !attr) return -EINVAL; - return txt->ops->draw(txt, ch, posx, posy, attr); + return txt->ops->draw(txt, id, ch, len, posx, posy, attr); } /** @@ -503,11 +506,12 @@ int kmscon_text_prepare_cb(struct kmscon_console *con, void *data) return kmscon_text_prepare(data); } -int kmscon_text_draw_cb(struct kmscon_console *con, tsm_symbol_t ch, +int kmscon_text_draw_cb(struct kmscon_console *con, + uint32_t id, const uint32_t *ch, size_t len, unsigned int posx, unsigned int posy, const struct kmscon_console_attr *attr, void *data) { - return kmscon_text_draw(data, ch, posx, posy, attr); + return kmscon_text_draw(data, id, ch, len, posx, posy, attr); } int kmscon_text_render_cb(struct kmscon_console *con, void *data) diff --git a/src/text.h b/src/text.h index bb6f61d..6a3ca74 100644 --- a/src/text.h +++ b/src/text.h @@ -41,7 +41,6 @@ #include #include #include "console.h" -#include "tsm_unicode.h" #include "uterm.h" /* fonts */ @@ -87,7 +86,8 @@ struct kmscon_font_ops { int (*init) (struct kmscon_font *out, const struct kmscon_font_attr *attr); void (*destroy) (struct kmscon_font *font); - int (*render) (struct kmscon_font *font, tsm_symbol_t sym, + int (*render) (struct kmscon_font *font, + uint32_t id, const uint32_t *ch, size_t len, const struct kmscon_glyph **out); int (*render_empty) (struct kmscon_font *font, const struct kmscon_glyph **out); @@ -104,7 +104,8 @@ int kmscon_font_find(struct kmscon_font **out, void kmscon_font_ref(struct kmscon_font *font); void kmscon_font_unref(struct kmscon_font *font); -int kmscon_font_render(struct kmscon_font *font, tsm_symbol_t sym, +int kmscon_font_render(struct kmscon_font *font, + uint32_t id, const uint32_t *ch, size_t len, const struct kmscon_glyph **out); int kmscon_font_render_empty(struct kmscon_font *font, const struct kmscon_glyph **out); @@ -135,7 +136,8 @@ struct kmscon_text_ops { int (*set) (struct kmscon_text *txt); void (*unset) (struct kmscon_text *txt); int (*prepare) (struct kmscon_text *txt); - int (*draw) (struct kmscon_text *txt, tsm_symbol_t ch, + int (*draw) (struct kmscon_text *txt, + uint32_t id, const uint32_t *ch, size_t len, unsigned int posx, unsigned int posy, const struct kmscon_console_attr *attr); int (*render) (struct kmscon_text *txt); @@ -157,14 +159,16 @@ unsigned int kmscon_text_get_cols(struct kmscon_text *txt); unsigned int kmscon_text_get_rows(struct kmscon_text *txt); int kmscon_text_prepare(struct kmscon_text *txt); -int kmscon_text_draw(struct kmscon_text *txt, tsm_symbol_t ch, - unsigned int posx, unsigned int posy, - const struct kmscon_console_attr *attr); +int kmscon_text_draw(struct kmscon_text *txt, + uint32_t id, const uint32_t *ch, size_t len, + unsigned int posx, unsigned int posy, + const struct kmscon_console_attr *attr); int kmscon_text_render(struct kmscon_text *txt); void kmscon_text_abort(struct kmscon_text *txt); int kmscon_text_prepare_cb(struct kmscon_console *con, void *data); -int kmscon_text_draw_cb(struct kmscon_console *con, tsm_symbol_t ch, +int kmscon_text_draw_cb(struct kmscon_console *con, + uint32_t id, const uint32_t *ch, size_t len, unsigned int posx, unsigned int posy, const struct kmscon_console_attr *attr, void *data); int kmscon_text_render_cb(struct kmscon_console *con, void *data); diff --git a/src/text_bblit.c b/src/text_bblit.c index 1a7a446..af5ee5b 100644 --- a/src/text_bblit.c +++ b/src/text_bblit.c @@ -38,7 +38,6 @@ #include #include "log.h" #include "text.h" -#include "tsm_unicode.h" #include "uterm.h" #define LOG_SUBSYSTEM "text_bblit" @@ -58,17 +57,18 @@ static int bblit_set(struct kmscon_text *txt) return 0; } -static int bblit_draw(struct kmscon_text *txt, tsm_symbol_t ch, +static int bblit_draw(struct kmscon_text *txt, + uint32_t id, const uint32_t *ch, size_t len, unsigned int posx, unsigned int posy, const struct kmscon_console_attr *attr) { const struct kmscon_glyph *glyph; int ret; - if (ch == 0 || ch == ' ') { + if (!len) { ret = kmscon_font_render_empty(txt->font, &glyph); } else { - ret = kmscon_font_render(txt->font, ch, &glyph); + ret = kmscon_font_render(txt->font, id, ch, len, &glyph); } if (ret) { diff --git a/src/text_bbulk.c b/src/text_bbulk.c index abb3d81..b6a42b5 100644 --- a/src/text_bbulk.c +++ b/src/text_bbulk.c @@ -38,7 +38,6 @@ #include #include "log.h" #include "text.h" -#include "tsm_unicode.h" #include "uterm.h" #define LOG_SUBSYSTEM "text_bbulk" @@ -110,7 +109,8 @@ static void bbulk_unset(struct kmscon_text *txt) bb->reqs = NULL; } -static int bbulk_draw(struct kmscon_text *txt, tsm_symbol_t ch, +static int bbulk_draw(struct kmscon_text *txt, + uint32_t id, const uint32_t *ch, size_t len, unsigned int posx, unsigned int posy, const struct kmscon_console_attr *attr) { @@ -119,10 +119,10 @@ static int bbulk_draw(struct kmscon_text *txt, tsm_symbol_t ch, int ret; struct uterm_video_blend_req *req; - if (ch == 0 || ch == ' ') { + if (!len) { ret = kmscon_font_render_empty(txt->font, &glyph); } else { - ret = kmscon_font_render(txt->font, ch, &glyph); + ret = kmscon_font_render(txt->font, id, ch, len, &glyph); } if (ret) { diff --git a/src/text_font.c b/src/text_font.c index bff6ee3..72c2295 100644 --- a/src/text_font.c +++ b/src/text_font.c @@ -449,7 +449,9 @@ void kmscon_font_unref(struct kmscon_font *font) /** * kmscon_font_render: * @font: Valid font object - * @sym: Symbol to find a glyph for + * @id: Unique ID that identifies @ch globally + * @ch: Symbol to find a glyph for + * @len: Length of @ch * @out: Output buffer for glyph * * Renders the glyph for symbol @sym and places a pointer to the glyph in @out. @@ -460,13 +462,14 @@ void kmscon_font_unref(struct kmscon_font *font) * * Returns: 0 on success, negative error code on failure */ -int kmscon_font_render(struct kmscon_font *font, tsm_symbol_t sym, +int kmscon_font_render(struct kmscon_font *font, + uint32_t id, const uint32_t *ch, size_t len, const struct kmscon_glyph **out) { - if (!font || !out) + if (!font || !out || !ch || !len) return -EINVAL; - return font->ops->render(font, sym, out); + return font->ops->render(font, id, ch, len, out); } /** diff --git a/src/text_font_8x16.c b/src/text_font_8x16.c index 78eac77..b419cfc 100644 --- a/src/text_font_8x16.c +++ b/src/text_font_8x16.c @@ -49,7 +49,6 @@ #include #include "log.h" #include "text.h" -#include "tsm_unicode.h" #include "uterm.h" #define LOG_SUBSYSTEM "text_font_8x16" @@ -82,18 +81,13 @@ static void kmscon_font_8x16_destroy(struct kmscon_font *font) } static int kmscon_font_8x16_render(struct kmscon_font *font, - tsm_symbol_t sym, + uint32_t id, const uint32_t *ch, size_t len, const struct kmscon_glyph **out) { - const uint32_t *val; - size_t len; - - val = tsm_symbol_get(NULL, &sym, &len); - if (len > 1 || *val >= 256) + if (len > 1 || *ch >= 256) return -ERANGE; - *out = &kmscon_font_8x16_glyphs[*val]; - + *out = &kmscon_font_8x16_glyphs[*ch]; return 0; } diff --git a/src/text_font_freetype2.c b/src/text_font_freetype2.c index b22aaf0..8ab749a 100644 --- a/src/text_font_freetype2.c +++ b/src/text_font_freetype2.c @@ -48,7 +48,6 @@ #include "shl_dlist.h" #include "shl_hashtable.h" #include "text.h" -#include "tsm_unicode.h" #include "uterm.h" #define LOG_SUBSYSTEM "text_font_freetype2" @@ -139,7 +138,7 @@ static void manager__unref() } static int get_glyph(struct face *face, struct kmscon_glyph **out, - tsm_symbol_t ch) + uint32_t id, const uint32_t *ch, size_t len) { struct kmscon_glyph *glyph; struct glyph *data; @@ -147,15 +146,13 @@ static int get_glyph(struct face *face, struct kmscon_glyph **out, FT_UInt idx; FT_Bitmap *bmap; FT_GlyphSlot slot; - size_t len; - const uint32_t *val; bool res; unsigned int i, j, wmax, hmax, idx1, idx2; int ret, hoff1, hoff2, woff1, woff2; pthread_mutex_lock(&face->glyph_lock); res = shl_hashtable_find(face->glyphs, (void**)&glyph, - (void*)(long)ch); + (void*)(long)id); pthread_mutex_unlock(&face->glyph_lock); if (res) { *out = glyph; @@ -181,13 +178,12 @@ static int get_glyph(struct face *face, struct kmscon_glyph **out, * TODO: Fix this by drawing all related characters into a single glyph * and saving it or simply refer to the pango backend which already does * that. */ - val = tsm_symbol_get(NULL, &ch, &len); - if (len > 1 || !*val) { + if (!*ch) { ret = -ERANGE; goto out_glyph; } - idx = FT_Get_Char_Index(face->face, *val); + idx = FT_Get_Char_Index(face->face, *ch); err = FT_Load_Glyph(face->face, idx, FT_LOAD_DEFAULT); if (err) { ret = -ERANGE; @@ -269,7 +265,7 @@ static int get_glyph(struct face *face, struct kmscon_glyph **out, } pthread_mutex_lock(&face->glyph_lock); - ret = shl_hashtable_insert(face->glyphs, (void*)(long)ch, glyph); + ret = shl_hashtable_insert(face->glyphs, (void*)(long)id, glyph); pthread_mutex_unlock(&face->glyph_lock); if (ret) { log_error("cannot add glyph to hashtable"); @@ -537,6 +533,7 @@ static int generate_specials(struct face *face) size_t s; struct kmscon_glyph *g; int ret; + static const uint32_t question_mark = '?'; face->empty.data = NULL; face->empty.buf.width = face->real_attr.width; @@ -550,7 +547,7 @@ static int generate_specials(struct face *face) memset(face->empty.buf.data, 0, s); - ret = get_glyph(face, &g, tsm_symbol_make('?')); + ret = get_glyph(face, &g, question_mark, &question_mark, 1); if (ret) { memcpy(&face->inval, &face->empty, sizeof(face->inval)); } else { @@ -565,8 +562,8 @@ static int kmscon_font_freetype2_init(struct kmscon_font *out, { struct face *face = NULL; int ret; - tsm_symbol_t ch; - unsigned int i, width; + unsigned int width; + uint32_t i; struct kmscon_glyph *glyph; struct glyph *data; @@ -593,8 +590,7 @@ static int kmscon_font_freetype2_init(struct kmscon_font *out, if (face->shrink) { width = 0; for (i = 0x20; i < 0x7f; ++i) { - ch = tsm_symbol_make(i); - ret = get_glyph(face, &glyph, ch); + ret = get_glyph(face, &glyph, i, &i, 1); if (ret) continue; data = glyph->data; @@ -636,8 +632,8 @@ static void kmscon_font_freetype2_destroy(struct kmscon_font *font) manager_put_face(face); } -static int kmscon_font_freetype2_render(struct kmscon_font *font, - tsm_symbol_t sym, +static int kmscon_font_freetype2_render(struct kmscon_font *font, uint32_t id, + const uint32_t *ch, size_t len, const struct kmscon_glyph **out) { struct kmscon_glyph *glyph; @@ -645,7 +641,7 @@ static int kmscon_font_freetype2_render(struct kmscon_font *font, struct face *face; int ret; - ret = get_glyph(font->data, &glyph, sym); + ret = get_glyph(font->data, &glyph, id, ch, len); if (ret) return ret; diff --git a/src/text_font_pango.c b/src/text_font_pango.c index 9cd0849..65c086d 100644 --- a/src/text_font_pango.c +++ b/src/text_font_pango.c @@ -110,21 +110,21 @@ static void manager__unref() } static int get_glyph(struct face *face, struct kmscon_glyph **out, - tsm_symbol_t ch) + uint32_t id, const uint32_t *ch, size_t len) { struct kmscon_glyph *glyph; PangoLayout *layout; PangoRectangle rec; PangoLayoutLine *line; FT_Bitmap bitmap; - size_t len, cnt; - const char *val; + size_t ulen, cnt; + char *val; bool res; int ret; pthread_mutex_lock(&face->glyph_lock); res = shl_hashtable_find(face->glyphs, (void**)&glyph, - (void*)(long)ch); + (void*)(long)id); pthread_mutex_unlock(&face->glyph_lock); if (res) { *out = glyph; @@ -149,9 +149,13 @@ static int get_glyph(struct face *face, struct kmscon_glyph **out, /* no line spacing */ pango_layout_set_spacing(layout, 0); - val = tsm_symbol_get_u8(NULL, ch, &len); - pango_layout_set_text(layout, val, len); - tsm_symbol_free_u8(val); + val = tsm_ucs4_to_utf8_alloc(ch, len, &ulen); + if (!val) { + ret = -ERANGE; + goto out_glyph; + } + pango_layout_set_text(layout, val, ulen); + free(val); cnt = pango_layout_get_line_count(layout); if (cnt == 0) { @@ -190,7 +194,7 @@ static int get_glyph(struct face *face, struct kmscon_glyph **out, pango_ft2_render_layout_line(&bitmap, line, -rec.x, -rec.y); pthread_mutex_lock(&face->glyph_lock); - ret = shl_hashtable_insert(face->glyphs, (void*)(long)ch, glyph); + ret = shl_hashtable_insert(face->glyphs, (void*)(long)id, glyph); pthread_mutex_unlock(&face->glyph_lock); if (ret) { log_error("cannot add glyph to hashtable"); @@ -386,14 +390,14 @@ static void kmscon_font_pango_destroy(struct kmscon_font *font) manager_put_face(face); } -static int kmscon_font_pango_render(struct kmscon_font *font, - tsm_symbol_t sym, +static int kmscon_font_pango_render(struct kmscon_font *font, uint32_t id, + const uint32_t *ch, size_t len, const struct kmscon_glyph **out) { struct kmscon_glyph *glyph; int ret; - ret = get_glyph(font->data, &glyph, sym); + ret = get_glyph(font->data, &glyph, id, ch, len); if (ret) return ret; @@ -404,13 +408,16 @@ static int kmscon_font_pango_render(struct kmscon_font *font, static int kmscon_font_pango_render_empty(struct kmscon_font *font, const struct kmscon_glyph **out) { - return kmscon_font_pango_render(font, ' ', out); + static const uint32_t empty_char = ' '; + return kmscon_font_pango_render(font, empty_char, &empty_char, 1, out); } static int kmscon_font_pango_render_inval(struct kmscon_font *font, const struct kmscon_glyph **out) { - return kmscon_font_pango_render(font, '?', out); + static const uint32_t question_mark = '?'; + return kmscon_font_pango_render(font, question_mark, &question_mark, 1, + out); } static const struct kmscon_font_ops kmscon_font_pango_ops = { diff --git a/src/text_font_unifont.c b/src/text_font_unifont.c index 93ecb00..d2b863b 100644 --- a/src/text_font_unifont.c +++ b/src/text_font_unifont.c @@ -44,7 +44,6 @@ #include #include "log.h" #include "text.h" -#include "tsm_unicode.h" #include "uterm.h" #define LOG_SUBSYSTEM "text_font_unifont" @@ -77,19 +76,14 @@ static void kmscon_font_unifont_destroy(struct kmscon_font *font) log_debug("unloading static unifont font"); } -static int kmscon_font_unifont_render(struct kmscon_font *font, - tsm_symbol_t sym, +static int kmscon_font_unifont_render(struct kmscon_font *font, uint32_t id, + const uint32_t *ch, size_t len, const struct kmscon_glyph **out) { - const uint32_t *val; - size_t len; - - val = tsm_symbol_get(NULL, &sym, &len); - if (len > 1 || *val >= kmscon_text_font_unifont_data_hex_len) + if (len > 1 || *ch >= kmscon_text_font_unifont_data_hex_len) return -ERANGE; - *out = &kmscon_text_font_unifont_data_hex_glyphs[*val]; - + *out = &kmscon_text_font_unifont_data_hex_glyphs[*ch]; return 0; } diff --git a/src/text_gltex.c b/src/text_gltex.c index e71d923..ce028ba 100644 --- a/src/text_gltex.c +++ b/src/text_gltex.c @@ -50,7 +50,6 @@ #include "shl_hashtable.h" #include "static_gl.h" #include "text.h" -#include "tsm_unicode.h" #include "uterm.h" #define LOG_SUBSYSTEM "text_gltex" @@ -367,7 +366,7 @@ err_free: } static int find_glyph(struct kmscon_text *txt, struct glyph **out, - tsm_symbol_t ch) + uint32_t id, const uint32_t *ch, size_t len) { struct gltex *gt = txt->data; struct atlas *atlas; @@ -378,7 +377,7 @@ static int find_glyph(struct kmscon_text *txt, struct glyph **out, uint8_t *packed_data, *dst, *src; res = shl_hashtable_find(gt->glyphs, (void**)&glyph, - (void*)(unsigned long)ch); + (void*)(unsigned long)id); if (res) { *out = glyph; return 0; @@ -393,10 +392,10 @@ static int find_glyph(struct kmscon_text *txt, struct glyph **out, return -ENOMEM; memset(glyph, 0, sizeof(*glyph)); - if (ch == 0 || ch == ' ') { + if (!len) { ret = kmscon_font_render_empty(txt->font, &glyph->glyph); } else { - ret = kmscon_font_render(txt->font, ch, &glyph->glyph); + ret = kmscon_font_render(txt->font, id, ch, len, &glyph->glyph); } if (ret) { @@ -480,7 +479,7 @@ static int find_glyph(struct kmscon_text *txt, struct glyph **out, glyph->atlas = atlas; glyph->texoff = atlas->fill; - ret = shl_hashtable_insert(gt->glyphs, (void*)(long)ch, glyph); + ret = shl_hashtable_insert(gt->glyphs, (void*)(long)id, glyph); if (ret) goto err_free; @@ -521,7 +520,8 @@ static int gltex_prepare(struct kmscon_text *txt) return 0; } -static int gltex_draw(struct kmscon_text *txt, tsm_symbol_t ch, +static int gltex_draw(struct kmscon_text *txt, + uint32_t id, const uint32_t *ch, size_t len, unsigned int posx, unsigned int posy, const struct kmscon_console_attr *attr) { @@ -530,7 +530,7 @@ static int gltex_draw(struct kmscon_text *txt, tsm_symbol_t ch, struct glyph *glyph; int ret, i, idx; - ret = find_glyph(txt, &glyph, ch); + ret = find_glyph(txt, &glyph, id, ch, len); if (ret) return ret; atlas = glyph->atlas;