diff options
author | David Herrmann <dh.herrmann@googlemail.com> | 2013-01-24 14:11:22 +0100 |
---|---|---|
committer | David Herrmann <dh.herrmann@googlemail.com> | 2013-01-24 14:11:22 +0100 |
commit | ae25adc34fd835569e28b713408e0fea1bfdd3d1 (patch) | |
tree | b1699a5a2d85d9611c6c7004d2b116de40c98204 /src | |
parent | 7ca44910c2f00fd2854f8d7d0e37af3a517fdf5c (diff) |
text: pixman: add support for non x4-stride glyphs
pixman expects stride values to be a multiple of 4. However, the glyphs we
get may be of a different stride so copy it if it is.
Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/text_pixman.c | 43 |
1 files changed, 39 insertions, 4 deletions
diff --git a/src/text_pixman.c b/src/text_pixman.c index 3336653..a06209a 100644 --- a/src/text_pixman.c +++ b/src/text_pixman.c @@ -42,6 +42,7 @@ struct tp_glyph { const struct kmscon_glyph *glyph; pixman_image_t *surf; + uint8_t *data; }; struct tp_pixman { @@ -53,6 +54,7 @@ struct tp_pixman { pixman_image_t *surf[2]; unsigned int format[2]; + bool new_stride; bool use_indirect; uint8_t *data[2]; struct uterm_video_buffer vbuf; @@ -88,6 +90,7 @@ static void free_glyph(void *data) struct tp_glyph *glyph = data; pixman_image_unref(glyph->surf); + free(glyph->data); free(glyph); } @@ -266,8 +269,9 @@ static int find_glyph(struct kmscon_text *txt, struct tp_glyph **out, struct shl_hashtable *gtable; struct kmscon_font *font; const struct uterm_video_buffer *buf; - unsigned int format; - int ret; + uint8_t *dst, *src; + unsigned int format, i; + int ret, stride; bool res; if (bold) { @@ -302,6 +306,7 @@ static int find_glyph(struct kmscon_text *txt, struct tp_glyph **out, } buf = &glyph->glyph->buf; + stride = buf->stride; format = format_u2p(buf->format); glyph->surf = pixman_image_create_bits_no_clear(format, buf->width, @@ -309,9 +314,39 @@ static int find_glyph(struct kmscon_text *txt, struct tp_glyph **out, (void*)buf->data, buf->stride); if (!glyph->surf) { + stride = (buf->stride + 3) & ~0x3; + if (!tp->new_stride) { + tp->new_stride = true; + log_debug("wrong stride, copy buffer (%d => %d)", + buf->stride, stride); + } + + glyph->data = malloc(stride * buf->height); + if (!glyph->data) { + log_error("cannot allocate memory for glyph storage"); + ret = -ENOMEM; + goto err_free; + } + + src = buf->data; + dst = glyph->data; + for (i = 0; i < buf->height; ++i) { + memcpy(dst, src, buf->width); + dst += stride; + src += buf->stride; + } + + glyph->surf = pixman_image_create_bits_no_clear(format, + buf->width, + buf->height, + (void*) + glyph->data, + stride); + } + if (!glyph->surf) { log_error("cannot create pixman-glyph: %d %p %d %d %d %d", - ret, buf->data, format, buf->width, buf->height, - buf->stride); + ret, glyph->data ? glyph->data : buf->data, format, + buf->width, buf->height, stride); ret = -EFAULT; goto err_free; } |