text: add render-support for multi-cell glyphs

Multi-cell glyphs are glyphs that span across multiple horizontal cells.
The font renderers already support this. This patch fixes the console
renderers to take advantage of this.

Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
This commit is contained in:
David Herrmann committed 2012-12-10 16:00:08 +01:00
1 parent 0de1de25fd
commit 1657bb9a3a
8 files changed
+48 -18

No files matched your search

+5 -2
View File
@@ -447,6 +447,7 @@ int kmscon_text_prepare(struct kmscon_text *txt)
* @id: a unique ID that identifies @ch globally
* @ch: ucs4 symbol you want to draw
* @len: length of @ch or 0 for empty cell
* @width: cell-width of character
* @posx: X-position of the glyph
* @posy: Y-position of the glyph
* @attr: glyph attributes
@@ -460,6 +461,7 @@ 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,
unsigned int width,
unsigned int posx, unsigned int posy,
const struct tsm_screen_attr *attr)
{
@@ -468,7 +470,7 @@ int kmscon_text_draw(struct kmscon_text *txt,
if (posx >= txt->cols || posy >= txt->rows || !attr)
return -EINVAL;
return txt->ops->draw(txt, id, ch, len, posx, posy, attr);
return txt->ops->draw(txt, id, ch, len, width, posx, posy, attr);
}
/**
@@ -521,10 +523,11 @@ int kmscon_text_prepare_cb(struct tsm_screen *con, void *data)
int kmscon_text_draw_cb(struct tsm_screen *con,
uint32_t id, const uint32_t *ch, size_t len,
unsigned int width,
unsigned int posx, unsigned int posy,
const struct tsm_screen_attr *attr, void *data)
{
return kmscon_text_draw(data, id, ch, len, posx, posy, attr);
return kmscon_text_draw(data, id, ch, len, width, posx, posy, attr);
}
int kmscon_text_render_cb(struct tsm_screen *con, void *data)
+3
View File
@@ -140,6 +140,7 @@ struct kmscon_text_ops {
int (*prepare) (struct kmscon_text *txt);
int (*draw) (struct kmscon_text *txt,
uint32_t id, const uint32_t *ch, size_t len,
unsigned int width,
unsigned int posx, unsigned int posy,
const struct tsm_screen_attr *attr);
int (*render) (struct kmscon_text *txt);
@@ -164,6 +165,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,
unsigned int width,
unsigned int posx, unsigned int posy,
const struct tsm_screen_attr *attr);
int kmscon_text_render(struct kmscon_text *txt);
@@ -172,6 +174,7 @@ void kmscon_text_abort(struct kmscon_text *txt);
int kmscon_text_prepare_cb(struct tsm_screen *con, void *data);
int kmscon_text_draw_cb(struct tsm_screen *con,
uint32_t id, const uint32_t *ch, size_t len,
unsigned int width,
unsigned int posx, unsigned int posy,
const struct tsm_screen_attr *attr, void *data);
int kmscon_text_render_cb(struct tsm_screen *con, void *data);
+4
View File
@@ -63,6 +63,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,
unsigned int width,
unsigned int posx, unsigned int posy,
const struct tsm_screen_attr *attr)
{
@@ -70,6 +71,9 @@ static int bblit_draw(struct kmscon_text *txt,
int ret;
struct kmscon_font *font;
if (!width)
return 0;
if (attr->bold)
font = txt->bold_font;
else
+6
View File
@@ -112,6 +112,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,
unsigned int width,
unsigned int posx, unsigned int posy,
const struct tsm_screen_attr *attr)
{
@@ -121,6 +122,11 @@ static int bbulk_draw(struct kmscon_text *txt,
struct uterm_video_blend_req *req;
struct kmscon_font *font;
if (!width) {
bb->reqs[posy * txt->cols + posx].buf = NULL;
return 0;
}
if (attr->bold)
font = txt->bold_font;
else
+19 -13
View File
@@ -277,7 +277,7 @@ static unsigned int next_pow2(unsigned int num)
}
/* returns an atlas with at least 1 free glyph position; NULL on error */
static struct atlas *get_atlas(struct kmscon_text *txt)
static struct atlas *get_atlas(struct kmscon_text *txt, unsigned int num)
{
struct gltex *gt = txt->data;
struct atlas *atlas;
@@ -289,7 +289,7 @@ static struct atlas *get_atlas(struct kmscon_text *txt)
if (!shl_dlist_empty(&gt->atlases)) {
atlas = shl_dlist_entry(gt->atlases.next, struct atlas,
list);
if (atlas->fill < atlas->count)
if (atlas->fill + num <= atlas->count)
return atlas;
}
@@ -408,10 +408,6 @@ static int find_glyph(struct kmscon_text *txt, struct glyph **out,
return 0;
}
atlas = get_atlas(txt);
if (!atlas)
return -EFAULT;
glyph = malloc(sizeof(*glyph));
if (!glyph)
return -ENOMEM;
@@ -428,6 +424,12 @@ static int find_glyph(struct kmscon_text *txt, struct glyph **out,
goto err_free;
}
atlas = get_atlas(txt, glyph->glyph->width);
if (!atlas) {
ret = -EFAULT;
goto err_free;
}
/* Funnily, not all OpenGLESv2 implementations support specifying the
* stride of a texture. Therefore, we then need to create a
* temporary image with a stride equal to the image width for loading
@@ -507,7 +509,7 @@ static int find_glyph(struct kmscon_text *txt, struct glyph **out,
if (ret)
goto err_free;
++atlas->fill;
atlas->fill += glyph->glyph->width;
*out = glyph;
return 0;
@@ -542,6 +544,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,
unsigned int width,
unsigned int posx, unsigned int posy,
const struct tsm_screen_attr *attr)
{
@@ -550,6 +553,9 @@ static int gltex_draw(struct kmscon_text *txt,
struct glyph *glyph;
int ret, i, idx;
if (!width)
return 0;
ret = find_glyph(txt, &glyph, id, ch, len, attr->bold);
if (ret)
return ret;
@@ -567,7 +573,7 @@ static int gltex_draw(struct kmscon_text *txt,
atlas->cache_pos[atlas->cache_num * 2 * 6 + 3] =
gt->advance_y * posy + gt->advance_y - 1;
atlas->cache_pos[atlas->cache_num * 2 * 6 + 4] =
gt->advance_x * posx + gt->advance_x - 1;
gt->advance_x * posx + width * gt->advance_x - 1;
atlas->cache_pos[atlas->cache_num * 2 * 6 + 5] =
gt->advance_y * posy + gt->advance_y - 1;
@@ -576,11 +582,11 @@ static int gltex_draw(struct kmscon_text *txt,
atlas->cache_pos[atlas->cache_num * 2 * 6 + 7] =
gt->advance_y * posy - 1;
atlas->cache_pos[atlas->cache_num * 2 * 6 + 8] =
gt->advance_x * posx + gt->advance_x - 1;
gt->advance_x * posx + width * gt->advance_x - 1;
atlas->cache_pos[atlas->cache_num * 2 * 6 + 9] =
gt->advance_y * posy + gt->advance_y - 1;
atlas->cache_pos[atlas->cache_num * 2 * 6 + 10] =
gt->advance_x * posx + gt->advance_x - 1;
gt->advance_x * posx + width * gt->advance_x - 1;
atlas->cache_pos[atlas->cache_num * 2 * 6 + 11] =
gt->advance_y * posy - 1;
@@ -588,14 +594,14 @@ static int gltex_draw(struct kmscon_text *txt,
atlas->cache_texpos[atlas->cache_num * 2 * 6 + 1] = 0.0;
atlas->cache_texpos[atlas->cache_num * 2 * 6 + 2] = glyph->texoff;
atlas->cache_texpos[atlas->cache_num * 2 * 6 + 3] = 1.0;
atlas->cache_texpos[atlas->cache_num * 2 * 6 + 4] = glyph->texoff + 1;
atlas->cache_texpos[atlas->cache_num * 2 * 6 + 4] = glyph->texoff + width;
atlas->cache_texpos[atlas->cache_num * 2 * 6 + 5] = 1.0;
atlas->cache_texpos[atlas->cache_num * 2 * 6 + 6] = glyph->texoff;
atlas->cache_texpos[atlas->cache_num * 2 * 6 + 7] = 0.0;
atlas->cache_texpos[atlas->cache_num * 2 * 6 + 8] = glyph->texoff + 1;
atlas->cache_texpos[atlas->cache_num * 2 * 6 + 8] = glyph->texoff + width;
atlas->cache_texpos[atlas->cache_num * 2 * 6 + 9] = 1.0;
atlas->cache_texpos[atlas->cache_num * 2 * 6 + 10] = glyph->texoff + 1;
atlas->cache_texpos[atlas->cache_num * 2 * 6 + 10] = glyph->texoff + width;
atlas->cache_texpos[atlas->cache_num * 2 * 6 + 11] = 0.0;
for (i = 0; i < 6; ++i) {
+6 -3
View File
@@ -45,6 +45,7 @@
struct cell {
tsm_symbol_t ch;
unsigned int width;
struct tsm_screen_attr attr;
};
@@ -108,6 +109,7 @@ struct tsm_screen {
static void cell_init(struct tsm_screen *con, struct cell *cell)
{
cell->ch = 0;
cell->width = 1;
memcpy(&cell->attr, &con->def_attr, sizeof(cell->attr));
}
@@ -1843,8 +1845,8 @@ void tsm_screen_draw(struct tsm_screen *con,
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);
ret = draw_cb(con, cell->ch, ch, len, cell->width,
j, i, &attr, data);
if (ret && warned++ < 3) {
llog_debug(con,
"cannot draw glyph at %ux%u via text-renderer",
@@ -1860,7 +1862,8 @@ void tsm_screen_draw(struct tsm_screen *con,
if (!(con->flags & TSM_SCREEN_HIDE_CURSOR)) {
if (!(con->flags & TSM_SCREEN_INVERSE))
attr.inverse = !attr.inverse;
draw_cb(con, 0, NULL, 0, cur_x, i, &attr, data);
draw_cb(con, 0, NULL, 0, 1,
cur_x, i, &attr, data);
}
}
}
+1
View File
@@ -96,6 +96,7 @@ typedef int (*tsm_screen_draw_cb) (struct tsm_screen *con,
uint32_t id,
const uint32_t *ch,
size_t len,
unsigned int width,
unsigned int posx,
unsigned int posy,
const struct tsm_screen_attr *attr,
+4
View File
@@ -88,6 +88,7 @@ struct wlt_terminal {
static int draw_cell(struct tsm_screen *scr,
uint32_t id, const uint32_t *ch, size_t len,
unsigned int chwidth,
unsigned int posx, unsigned int posy,
const struct tsm_screen_attr *attr, void *data)
{
@@ -100,6 +101,9 @@ static int draw_cell(struct tsm_screen *scr,
unsigned int fr, fg, fb, br, bg, bb;
uint32_t val;
if (!chwidth)
return 0;
if (!len)
ret = kmscon_font_render_empty(term->font_normal, &glyph);
else