469
#if defined(USE_IMLIB2)
470
typedef struct _ImlibLoader ImlibLoader;
477
void DestroyImlibLoader(ImlibLoader *loader)
483
g_slice_free(ImlibLoader, loader);
486
ImlibLoader* LoadWithImlib(gchar *path,
487
RrPixel32 **pixel_data,
491
ImlibLoader *loader = g_slice_new0(ImlibLoader);
492
if (!(loader->img = imlib_load_image(path))) {
493
DestroyImlibLoader(loader);
497
/* Get data and dimensions of the image.
499
WARNING: This stuff is NOT threadsafe !!
501
imlib_context_set_image(loader->img);
502
*pixel_data = imlib_image_get_data_for_reading_only();
503
*width = imlib_image_get_width();
504
*height = imlib_image_get_height();
508
#endif /* USE_IMLIB2 */
510
#if defined(USE_LIBRSVG)
511
typedef struct _RsvgLoader RsvgLoader;
516
cairo_surface_t *surface;
517
RrPixel32 *pixel_data;
520
void DestroyRsvgLoader(RsvgLoader *loader)
525
if (loader->pixel_data)
526
g_free(loader->pixel_data);
528
cairo_surface_destroy(loader->surface);
530
g_object_unref(loader->handle);
531
g_slice_free(RsvgLoader, loader);
534
RsvgLoader* LoadWithRsvg(gchar *path,
535
RrPixel32 **pixel_data,
539
RsvgLoader *loader = g_slice_new0(RsvgLoader);
541
if (!(loader->handle = rsvg_handle_new_from_file(path, NULL))) {
542
DestroyRsvgLoader(loader);
546
if (!rsvg_handle_close(loader->handle, NULL)) {
547
DestroyRsvgLoader(loader);
551
RsvgDimensionData dimension_data;
552
rsvg_handle_get_dimensions(loader->handle, &dimension_data);
553
*width = dimension_data.width;
554
*height = dimension_data.height;
556
loader->surface = cairo_image_surface_create(
557
CAIRO_FORMAT_ARGB32, *width, *height);
559
cairo_t* context = cairo_create(loader->surface);
560
gboolean success = rsvg_handle_render_cairo(loader->handle, context);
561
cairo_destroy(context);
564
DestroyRsvgLoader(loader);
568
loader->pixel_data = g_new(guint32, *width * *height);
571
Cairo has its data in ARGB with premultiplied alpha, but RrPixel32
572
non-premultipled, so convert that. Also, RrPixel32 doesn't allow
573
strides not equal to the width of the image.
576
/* Verify that RrPixel32 has the same ordering as cairo. */
577
g_assert(RrDefaultAlphaOffset == 24);
578
g_assert(RrDefaultRedOffset == 16);
579
g_assert(RrDefaultGreenOffset == 8);
580
g_assert(RrDefaultBlueOffset == 0);
582
guint32 *out_row = loader->pixel_data;
585
(guint32*)cairo_image_surface_get_data(loader->surface);
586
gint in_stride = cairo_image_surface_get_stride(loader->surface);
589
for (y = 0; y < *height; ++y) {
591
for (x = 0; x < *width; ++x) {
592
guchar a = in_row[x] >> 24;
593
guchar r = (in_row[x] >> 16) & 0xff;
594
guchar g = (in_row[x] >> 8) & 0xff;
595
guchar b = in_row[x] & 0xff;
597
((r * 256 / (a + 1)) << RrDefaultRedOffset) +
598
((g * 256 / (a + 1)) << RrDefaultGreenOffset) +
599
((b * 256 / (a + 1)) << RrDefaultBlueOffset) +
600
(a << RrDefaultAlphaOffset);
602
in_row += in_stride / 4;
606
*pixel_data = loader->pixel_data;
610
#endif /* USE_LIBRSVG */
466
612
RrImage* RrImageNewFromName(RrImageCache *cache, const gchar *name)
621
#if defined(USE_IMLIB2)
622
ImlibLoader *imlib_loader = NULL;
624
#if defined(USE_LIBRSVG)
625
RsvgLoader *rsvg_loader = NULL;
478
628
g_return_val_if_fail(cache != NULL, NULL);
479
629
g_return_val_if_fail(name != NULL, NULL);
488
638
/* XXX find the path via freedesktop icon spec (use obt) ! */
489
639
path = g_strdup(name);
491
if (!(img = imlib_load_image(path)))
642
#if defined(USE_LIBRSVG)
644
rsvg_loader = LoadWithRsvg(path, &data, &w, &h);
645
loaded = !!rsvg_loader;
648
#if defined(USE_IMLIB2)
650
imlib_loader = LoadWithImlib(path, &data, &w, &h);
651
loaded = !!imlib_loader;
492
656
g_message("Cannot load image \"%s\" from file \"%s\"", name, path);
658
#if defined(USE_LIBRSVG)
659
DestroyRsvgLoader(rsvg_loader);
661
#if defined(USE_IMLIB2)
662
DestroyImlibLoader(imlib_loader);
498
/* Get data and dimensions of the image.
500
WARNING: This stuff is NOT threadsafe !!
502
imlib_context_set_image(img);
503
data = imlib_image_get_data_for_reading_only();
504
w = imlib_image_get_width();
505
h = imlib_image_get_height();
507
669
/* get an RrImage that contains an RrImageSet with this picture in it.
508
670
the RrImage might be new, or reused if the picture was already in the