From 55a4329f3e1cfab55cd4418fdbc9f24e890dfa54 Mon Sep 17 00:00:00 2001 From: Aetf Date: Mon, 28 May 2018 12:18:18 +0800 Subject: [PATCH 1/2] text: font: implement italics --- src/font.h | 2 +- src/font_pango.c | 40 ++++++++++++++++++++++++---------------- src/text_bblit.c | 9 +++++++-- src/text_bbulk.c | 9 +++++++-- src/text_gltex.c | 9 +++++++-- src/text_pixman.c | 9 +++++++-- 6 files changed, 53 insertions(+), 25 deletions(-) diff --git a/src/font.h b/src/font.h index d7c4cd6..d02e2d5 100644 --- a/src/font.h +++ b/src/font.h @@ -52,6 +52,7 @@ struct kmscon_font_attr { unsigned int points; bool bold; bool italic; + bool underline; unsigned int height; unsigned int width; }; @@ -72,7 +73,6 @@ struct kmscon_font { const struct kmscon_font_ops *ops; struct kmscon_font_attr attr; unsigned int baseline; - bool underline; void *data; }; diff --git a/src/font_pango.c b/src/font_pango.c index 4fca9c0..6b9dae4 100644 --- a/src/font_pango.c +++ b/src/font_pango.c @@ -110,10 +110,11 @@ static void manager__unref() } static int get_glyph(struct face *face, struct kmscon_glyph **out, - uint32_t id, const uint32_t *ch, size_t len, bool underline) + uint32_t id, const uint32_t *ch, size_t len, const struct kmscon_font_attr *attr) { struct kmscon_glyph *glyph; PangoLayout *layout; + PangoAttrList *attrlist; PangoRectangle rec; PangoLayoutLine *line; FT_Bitmap bitmap; @@ -150,6 +151,12 @@ static int get_glyph(struct face *face, struct kmscon_glyph **out, glyph->width = cwidth; layout = pango_layout_new(face->ctx); + attrlist = pango_layout_get_attributes(layout); + if (attrlist == NULL) { + attrlist = pango_attr_list_new(); + pango_layout_set_attributes(layout, attrlist); + pango_attr_list_unref(attrlist); + } /* render one line only */ pango_layout_set_height(layout, 0); @@ -157,21 +164,22 @@ static int get_glyph(struct face *face, struct kmscon_glyph **out, /* no line spacing */ pango_layout_set_spacing(layout, 0); - /* underline if requested */ - PangoAttrList* attrlist = pango_layout_get_attributes(layout); - if (underline) { - if (attrlist == NULL) { - attrlist = pango_attr_list_new(); - pango_layout_set_attributes(layout, attrlist); - pango_attr_list_unref(attrlist); - } - pango_attr_list_change(attrlist, - pango_attr_underline_new(PANGO_UNDERLINE_SINGLE)); + /* underline if requested */ + if (attr->underline) { + pango_attr_list_change(attrlist, + pango_attr_underline_new(PANGO_UNDERLINE_SINGLE)); } else { - if (attrlist != NULL) { - pango_attr_list_change(attrlist, - pango_attr_underline_new(PANGO_UNDERLINE_NONE)); - } + pango_attr_list_change(attrlist, + pango_attr_underline_new(PANGO_UNDERLINE_NONE)); + } + + /* italic if requested */ + if (attr->italic) { + pango_attr_list_change(attrlist, + pango_attr_style_new(PANGO_STYLE_ITALIC)); + } else { + pango_attr_list_change(attrlist, + pango_attr_style_new(PANGO_STYLE_NORMAL)); } val = tsm_ucs4_to_utf8_alloc(ch, len, &ulen); @@ -422,7 +430,7 @@ static int kmscon_font_pango_render(struct kmscon_font *font, uint32_t id, struct kmscon_glyph *glyph; int ret; - ret = get_glyph(font->data, &glyph, id, ch, len, font->underline); + ret = get_glyph(font->data, &glyph, id, ch, len, &font->attr); if (ret) return ret; diff --git a/src/text_bblit.c b/src/text_bblit.c index e051f69..5abc925 100644 --- a/src/text_bblit.c +++ b/src/text_bblit.c @@ -80,9 +80,14 @@ static int bblit_draw(struct kmscon_text *txt, font = txt->font; if (attr->underline) - font->underline = true; + font->attr.underline = true; else - font->underline = false; + font->attr.underline = false; + + if (attr->italic) + font->attr.italic = true; + else + font->attr.italic = false; if (!len) { ret = kmscon_font_render_empty(font, &glyph); diff --git a/src/text_bbulk.c b/src/text_bbulk.c index 6a2076a..1d28920 100644 --- a/src/text_bbulk.c +++ b/src/text_bbulk.c @@ -133,9 +133,14 @@ static int bbulk_draw(struct kmscon_text *txt, font = txt->font; if (attr->underline) - font->underline = true; + font->attr.underline = true; else - font->underline = false; + font->attr.underline = false; + + if (attr->italic) + font->attr.italic = true; + else + font->attr.italic = false; if (!len) { ret = kmscon_font_render_empty(font, &glyph); diff --git a/src/text_gltex.c b/src/text_gltex.c index 27eec3f..597778a 100644 --- a/src/text_gltex.c +++ b/src/text_gltex.c @@ -402,9 +402,14 @@ static int find_glyph(struct kmscon_text *txt, struct glyph **out, } if (attr->underline) - font->underline = true; + font->attr.underline = true; else - font->underline = false; + font->attr.underline = false; + + if (attr->italic) + font->attr.italic = true; + else + font->attr.italic = false; res = shl_hashtable_find(gtable, (void**)&glyph, (void*)(unsigned long)id); diff --git a/src/text_pixman.c b/src/text_pixman.c index c48ccef..549b64a 100644 --- a/src/text_pixman.c +++ b/src/text_pixman.c @@ -283,9 +283,14 @@ static int find_glyph(struct kmscon_text *txt, struct tp_glyph **out, } if (attr->underline) - font->underline = true; + font->attr.underline = true; else - font->underline = false; + font->attr.underline = false; + + if (attr->italic) + font->attr.italic = true; + else + font->attr.italic = false; res = shl_hashtable_find(gtable, (void**)&glyph, (void*)(unsigned long)id); From dd73e291cfcd0c73da2c0e9ac6ad3accb607f4bc Mon Sep 17 00:00:00 2001 From: Aetf Date: Mon, 28 May 2018 14:14:56 +0800 Subject: [PATCH 2/2] font: fix caching issues --- configure.ac | 2 +- src/font.c | 2 +- src/font.h | 4 ++-- src/font_8x16.c | 2 +- src/font_pango.c | 8 ++++---- src/font_unifont.c | 15 ++++++++------- src/text.c | 4 ++-- src/text.h | 6 +++--- src/text_bblit.c | 2 +- src/text_bbulk.c | 2 +- src/text_gltex.c | 8 ++++---- src/text_pixman.c | 8 ++++---- 12 files changed, 32 insertions(+), 31 deletions(-) diff --git a/configure.ac b/configure.ac index eb3020f..63598b4 100644 --- a/configure.ac +++ b/configure.ac @@ -51,7 +51,7 @@ PKG_CHECK_MODULES([XKBCOMMON], [xkbcommon]) AC_SUBST(XKBCOMMON_CFLAGS) AC_SUBST(XKBCOMMON_LIBS) -PKG_CHECK_MODULES([TSM], [libtsm]) +PKG_CHECK_MODULES([TSM], [libtsm >= 4.0.0]) AC_SUBST(TSM_CFLAGS) AC_SUBST(TSM_LIBS) diff --git a/src/font.c b/src/font.c index c6ad8c1..aed333f 100644 --- a/src/font.c +++ b/src/font.c @@ -396,7 +396,7 @@ void kmscon_font_unref(struct kmscon_font *font) */ SHL_EXPORT int kmscon_font_render(struct kmscon_font *font, - uint32_t id, const uint32_t *ch, size_t len, + uint64_t id, const uint32_t *ch, size_t len, const struct kmscon_glyph **out) { if (!font || !out || !ch || !len) diff --git a/src/font.h b/src/font.h index d02e2d5..6493cad 100644 --- a/src/font.h +++ b/src/font.h @@ -83,7 +83,7 @@ struct kmscon_font_ops { const struct kmscon_font_attr *attr); void (*destroy) (struct kmscon_font *font); int (*render) (struct kmscon_font *font, - uint32_t id, const uint32_t *ch, size_t len, + uint64_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); @@ -101,7 +101,7 @@ void kmscon_font_ref(struct kmscon_font *font); void kmscon_font_unref(struct kmscon_font *font); int kmscon_font_render(struct kmscon_font *font, - uint32_t id, const uint32_t *ch, size_t len, + uint64_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); diff --git a/src/font_8x16.c b/src/font_8x16.c index 830bc30..eafd631 100644 --- a/src/font_8x16.c +++ b/src/font_8x16.c @@ -81,7 +81,7 @@ static void kmscon_font_8x16_destroy(struct kmscon_font *font) } static int kmscon_font_8x16_render(struct kmscon_font *font, - uint32_t id, const uint32_t *ch, size_t len, + uint64_t id, const uint32_t *ch, size_t len, const struct kmscon_glyph **out) { if (len > 1 || *ch >= 256) diff --git a/src/font_pango.c b/src/font_pango.c index 6b9dae4..26c6208 100644 --- a/src/font_pango.c +++ b/src/font_pango.c @@ -110,7 +110,7 @@ static void manager__unref() } static int get_glyph(struct face *face, struct kmscon_glyph **out, - uint32_t id, const uint32_t *ch, size_t len, const struct kmscon_font_attr *attr) + uint64_t id, const uint32_t *ch, size_t len, const struct kmscon_font_attr *attr) { struct kmscon_glyph *glyph; PangoLayout *layout; @@ -132,7 +132,7 @@ static int get_glyph(struct face *face, struct kmscon_glyph **out, pthread_mutex_lock(&face->glyph_lock); res = shl_hashtable_find(face->glyphs, (void**)&glyph, - (void*)(long)id); + (void*)(uint64_t)id); pthread_mutex_unlock(&face->glyph_lock); if (res) { *out = glyph; @@ -227,7 +227,7 @@ static int get_glyph(struct face *face, struct kmscon_glyph **out, pango_ft2_render_layout_line(&bitmap, line, -rec.x, face->baseline); pthread_mutex_lock(&face->glyph_lock); - ret = shl_hashtable_insert(face->glyphs, (void*)(long)id, glyph); + ret = shl_hashtable_insert(face->glyphs, (void*)(uint64_t)id, glyph); pthread_mutex_unlock(&face->glyph_lock); if (ret) { log_error("cannot add glyph to hashtable"); @@ -423,7 +423,7 @@ static void kmscon_font_pango_destroy(struct kmscon_font *font) manager_put_face(face); } -static int kmscon_font_pango_render(struct kmscon_font *font, uint32_t id, +static int kmscon_font_pango_render(struct kmscon_font *font, uint64_t id, const uint32_t *ch, size_t len, const struct kmscon_glyph **out) { diff --git a/src/font_unifont.c b/src/font_unifont.c index cdedbca..494d2d4 100644 --- a/src/font_unifont.c +++ b/src/font_unifont.c @@ -42,6 +42,7 @@ #include #include #include +#include #include "font.h" #include "shl_hashtable.h" #include "shl_log.h" @@ -105,7 +106,7 @@ static void unfold(uint8_t *dst, uint8_t val) *dst = 0xff * !!val; } -static int find_glyph(uint32_t id, const struct kmscon_glyph **out) +static int find_glyph(uint32_t ch, const struct kmscon_glyph **out) { struct kmscon_glyph *g; int ret; @@ -124,21 +125,21 @@ static int find_glyph(uint32_t id, const struct kmscon_glyph **out) } } else { res = shl_hashtable_find(cache, (void**)out, - (void*)(long)id); + (void*)(uint64_t)ch); if (res) { ret = 0; goto out_unlock; } } - if (id > 0xffff) { + if (ch > 0xffff) { ret = -ERANGE; goto out_unlock; } start = _binary_src_font_unifont_data_bin_start; end = _binary_src_font_unifont_data_bin_end; - d = &start[id]; + d = &start[ch]; if (d >= end) { ret = -ERANGE; @@ -186,7 +187,7 @@ static int find_glyph(uint32_t id, const struct kmscon_glyph **out) unfold(&g->buf.data[i * 8 + 7], d->data[i] & 0x01); } - ret = shl_hashtable_insert(cache, (void*)(long)id, g); + ret = shl_hashtable_insert(cache, (void*)(uint64_t)ch, g); if (ret) { log_error("cannot insert glyph into glyph-cache: %d", ret); goto err_data; @@ -240,14 +241,14 @@ static void kmscon_font_unifont_destroy(struct kmscon_font *font) cache_unref(); } -static int kmscon_font_unifont_render(struct kmscon_font *font, uint32_t id, +static int kmscon_font_unifont_render(struct kmscon_font *font, uint64_t id, const uint32_t *ch, size_t len, const struct kmscon_glyph **out) { if (len > 1) return -ERANGE; - return find_glyph(id, out); + return find_glyph(id & TSM_UCS4_MAX, out); } static int kmscon_font_unifont_render_inval(struct kmscon_font *font, diff --git a/src/text.c b/src/text.c index d7e5f0e..24b579b 100644 --- a/src/text.c +++ b/src/text.c @@ -381,7 +381,7 @@ 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, - uint32_t id, const uint32_t *ch, size_t len, + uint64_t id, const uint32_t *ch, size_t len, unsigned int width, unsigned int posx, unsigned int posy, const struct tsm_screen_attr *attr) @@ -438,7 +438,7 @@ void kmscon_text_abort(struct kmscon_text *txt) } int kmscon_text_draw_cb(struct tsm_screen *con, - uint32_t id, const uint32_t *ch, size_t len, + uint64_t id, const uint32_t *ch, size_t len, unsigned int width, unsigned int posx, unsigned int posy, const struct tsm_screen_attr *attr, diff --git a/src/text.h b/src/text.h index 902e3cd..570df6b 100644 --- a/src/text.h +++ b/src/text.h @@ -68,7 +68,7 @@ struct kmscon_text_ops { void (*unset) (struct kmscon_text *txt); int (*prepare) (struct kmscon_text *txt); int (*draw) (struct kmscon_text *txt, - uint32_t id, const uint32_t *ch, size_t len, + uint64_t id, const uint32_t *ch, size_t len, unsigned int width, unsigned int posx, unsigned int posy, const struct tsm_screen_attr *attr); @@ -93,7 +93,7 @@ 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, - uint32_t id, const uint32_t *ch, size_t len, + uint64_t id, const uint32_t *ch, size_t len, unsigned int width, unsigned int posx, unsigned int posy, const struct tsm_screen_attr *attr); @@ -101,7 +101,7 @@ int kmscon_text_render(struct kmscon_text *txt); void kmscon_text_abort(struct kmscon_text *txt); int kmscon_text_draw_cb(struct tsm_screen *con, - uint32_t id, const uint32_t *ch, size_t len, + uint64_t id, const uint32_t *ch, size_t len, unsigned int width, unsigned int posx, unsigned int posy, const struct tsm_screen_attr *attr, diff --git a/src/text_bblit.c b/src/text_bblit.c index 5abc925..2b5ff2c 100644 --- a/src/text_bblit.c +++ b/src/text_bblit.c @@ -62,7 +62,7 @@ static int bblit_set(struct kmscon_text *txt) } static int bblit_draw(struct kmscon_text *txt, - uint32_t id, const uint32_t *ch, size_t len, + uint64_t id, const uint32_t *ch, size_t len, unsigned int width, unsigned int posx, unsigned int posy, const struct tsm_screen_attr *attr) diff --git a/src/text_bbulk.c b/src/text_bbulk.c index 1d28920..3801c34 100644 --- a/src/text_bbulk.c +++ b/src/text_bbulk.c @@ -111,7 +111,7 @@ static void bbulk_unset(struct kmscon_text *txt) } static int bbulk_draw(struct kmscon_text *txt, - uint32_t id, const uint32_t *ch, size_t len, + uint64_t id, const uint32_t *ch, size_t len, unsigned int width, unsigned int posx, unsigned int posy, const struct tsm_screen_attr *attr) diff --git a/src/text_gltex.c b/src/text_gltex.c index 597778a..afee079 100644 --- a/src/text_gltex.c +++ b/src/text_gltex.c @@ -381,7 +381,7 @@ err_free: } static int find_glyph(struct kmscon_text *txt, struct glyph **out, - uint32_t id, const uint32_t *ch, size_t len, const struct tsm_screen_attr *attr) + uint64_t id, const uint32_t *ch, size_t len, const struct tsm_screen_attr *attr) { struct gltex *gt = txt->data; struct atlas *atlas; @@ -412,7 +412,7 @@ static int find_glyph(struct kmscon_text *txt, struct glyph **out, font->attr.italic = false; res = shl_hashtable_find(gtable, (void**)&glyph, - (void*)(unsigned long)id); + (void*)(uint64_t)id); if (res) { *out = glyph; return 0; @@ -515,7 +515,7 @@ static int find_glyph(struct kmscon_text *txt, struct glyph **out, glyph->atlas = atlas; glyph->texoff = atlas->fill; - ret = shl_hashtable_insert(gtable, (void*)(long)id, glyph); + ret = shl_hashtable_insert(gtable, (void*)(uint64_t)id, glyph); if (ret) goto err_free; @@ -553,7 +553,7 @@ static int gltex_prepare(struct kmscon_text *txt) } static int gltex_draw(struct kmscon_text *txt, - uint32_t id, const uint32_t *ch, size_t len, + uint64_t id, const uint32_t *ch, size_t len, unsigned int width, unsigned int posx, unsigned int posy, const struct tsm_screen_attr *attr) diff --git a/src/text_pixman.c b/src/text_pixman.c index 549b64a..d287088 100644 --- a/src/text_pixman.c +++ b/src/text_pixman.c @@ -262,7 +262,7 @@ static void tp_unset(struct kmscon_text *txt) } static int find_glyph(struct kmscon_text *txt, struct tp_glyph **out, - uint32_t id, const uint32_t *ch, size_t len, const struct tsm_screen_attr *attr) + uint64_t id, const uint32_t *ch, size_t len, const struct tsm_screen_attr *attr) { struct tp_pixman *tp = txt->data; struct tp_glyph *glyph; @@ -293,7 +293,7 @@ static int find_glyph(struct kmscon_text *txt, struct tp_glyph **out, font->attr.italic = false; res = shl_hashtable_find(gtable, (void**)&glyph, - (void*)(unsigned long)id); + (void*)(uint64_t)id); if (res) { *out = glyph; return 0; @@ -361,7 +361,7 @@ static int find_glyph(struct kmscon_text *txt, struct tp_glyph **out, goto err_free; } - ret = shl_hashtable_insert(gtable, (void*)(long)id, glyph); + ret = shl_hashtable_insert(gtable, (void*)(uint64_t)id, glyph); if (ret) goto err_pixman; @@ -397,7 +397,7 @@ static int tp_prepare(struct kmscon_text *txt) } static int tp_draw(struct kmscon_text *txt, - uint32_t id, const uint32_t *ch, size_t len, + uint64_t id, const uint32_t *ch, size_t len, unsigned int width, unsigned int posx, unsigned int posy, const struct tsm_screen_attr *attr)