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:
parent
e098cb5585
commit
869992010c
50
unix/image.c
50
unix/image.c
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue