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)
|
static void freeImageRep(gpointer item)
|
||||||
{
|
{
|
||||||
cairo_surface_t *cs = (cairo_surface_t *) item;
|
cairo_surface_t *cs = (cairo_surface_t *) item;
|
||||||
unsigned char *buf;
|
|
||||||
|
|
||||||
buf = cairo_image_surface_get_data(cs);
|
|
||||||
cairo_surface_destroy(cs);
|
cairo_surface_destroy(cs);
|
||||||
uiprivFree(buf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uiImage *uiNewImage(double width, double height)
|
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)
|
void uiImageAppend(uiImage *i, void *pixels, int pixelWidth, int pixelHeight, int byteStride)
|
||||||
{
|
{
|
||||||
cairo_surface_t *cs;
|
cairo_surface_t *cs;
|
||||||
unsigned char *buf, *p;
|
uint8_t *data, *pix;
|
||||||
uint8_t *src = (uint8_t *) pixels;
|
int realStride;
|
||||||
int cByteStride;
|
int x, y;
|
||||||
int n;
|
|
||||||
|
|
||||||
// unfortunately for optimal performance cairo expects its own stride values and we will have to reconcile them if they differ
|
// note that this is native-endian
|
||||||
cByteStride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, pixelWidth);
|
cs = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
|
||||||
buf = (unsigned char *) uiprivAlloc((cByteStride * pixelHeight) * sizeof (unsigned char), "unsigned char[]");
|
pixelWidth, pixelHeight);
|
||||||
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);
|
|
||||||
if (cairo_surface_status(cs) != CAIRO_STATUS_SUCCESS)
|
if (cairo_surface_status(cs) != CAIRO_STATUS_SUCCESS)
|
||||||
/* TODO */;
|
/* TODO */;
|
||||||
cairo_surface_flush(cs);
|
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);
|
g_ptr_array_add(i->images, cs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue