Fixed uiImage on GTK+. Also changed it to have cairo manage memory and decide best parameters for us. I forgot to mention that the fix on OS X did this there too. Also made sure we use cairo surfaces properly this time.

This commit is contained in:
Pietro Gagliardi 2018-08-30 11:07:59 -04:00
parent e098cb5585
commit 869992010c
1 changed files with 31 additions and 19 deletions

View File

@ -10,11 +10,8 @@ struct uiImage {
static void freeImageRep(gpointer item)
{
cairo_surface_t *cs = (cairo_surface_t *) item;
unsigned char *buf;
buf = cairo_image_surface_get_data(cs);
cairo_surface_destroy(cs);
uiprivFree(buf);
}
uiImage *uiNewImage(double width, double height)
@ -37,26 +34,41 @@ void uiFreeImage(uiImage *i)
void uiImageAppend(uiImage *i, void *pixels, int pixelWidth, int pixelHeight, int byteStride)
{
cairo_surface_t *cs;
unsigned char *buf, *p;
uint8_t *src = (uint8_t *) pixels;
int cByteStride;
int n;
uint8_t *data, *pix;
int realStride;
int x, y;
// unfortunately for optimal performance cairo expects its own stride values and we will have to reconcile them if they differ
cByteStride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, pixelWidth);
buf = (unsigned char *) uiprivAlloc((cByteStride * pixelHeight) * sizeof (unsigned char), "unsigned char[]");
p = buf;
for (n = 0; n < byteStride * pixelHeight; n += byteStride) {
memmove(p, src + n, cByteStride);
p += cByteStride;
}
// also note that stride here is also in bytes
cs = cairo_image_surface_create_for_data(buf, CAIRO_FORMAT_ARGB32,
pixelWidth, pixelHeight,
cByteStride);
// note that this is native-endian
cs = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
pixelWidth, pixelHeight);
if (cairo_surface_status(cs) != CAIRO_STATUS_SUCCESS)
/* TODO */;
cairo_surface_flush(cs);
pix = (uint8_t *) pixels;
data = (uint8_t *) cairo_image_surface_get_data(cs);
realStride = cairo_image_surface_get_stride(cs);
for (y = 0; y < pixelHeight; y++) {
for (x = 0; x < pixelWidth * 4; x += 4) {
union {
uint32_t v32;
uint8_t v8[4];
} v;
v.v32 = ((uint32_t) (pix[x + 3])) << 24;
v.v32 |= ((uint32_t) (pix[x])) << 16;
v.v32 |= ((uint32_t) (pix[x + 1])) << 8;
v.v32 |= ((uint32_t) (pix[x + 2]));
data[x] = v.v8[0];
data[x + 1] = v.v8[1];
data[x + 2] = v.v8[2];
data[x + 3] = v.v8[3];
}
pix += byteStride;
data += realStride;
}
cairo_surface_mark_dirty(cs);
g_ptr_array_add(i->images, cs);
}