~ubuntu-branches/ubuntu/saucy/openbox/saucy-proposed

« back to all changes in this revision

Viewing changes to obrender/image.c

  • Committer: Package Import Robot
  • Author(s): Julien Lavergne
  • Date: 2013-08-29 00:47:27 UTC
  • mfrom: (1.1.12)
  • Revision ID: package-import@ubuntu.com-20130829004727-isarfdp00eoloeeq
Tags: 3.5.2-0ubuntu1
* New upstream release. 
* debian/control & debian/*.install:
 - Update SONAME number.
* debian/*.symbols:
 - Update.
* debian/patches:
 - 04_xsession.desktop_translation.patch: Refresh.
 - 01_rc.xml.patch: Refresh.
 - 05_simplify_gnome_session.patch: Refresh.
 - 07_fix_xml_load_file.patch: Refresh.
 - 90_fix_link_obt.patch: Remove, merged upstream.
 - 675991_fix_crash_from_gtk3_apps.patch: Remove, merged upstream.
 - 666676_wrong_undecorated_window_placement.patch: Remove, merged upstream.
 - clever-rectangle-picking.patch: Remove, merged upstream.
 - use-nearest-monitor.patch: Remove, merged upstream.
 - 704724_fix_refers-to-autostart.sh.patch: Remove, merged upstream.
 - 91_fix_loose_focus.patch: Remove, merged upstream.
 - openbox-3.5.0-title-matching.patch: Refresh.
 - openbox-3.5.0-which-2.20.patch: Refresh.
 - 658081_fix_kde_menu.patch: Remove, merged upstream.
 - add_automake1.11_support.patch: Remove, merged upstream.

Show diffs side-by-side

added added

removed removed

Lines of Context:
24
24
#ifdef USE_IMLIB2
25
25
#include <Imlib2.h>
26
26
#endif
 
27
#ifdef USE_LIBRSVG
 
28
#include <librsvg/rsvg.h>
 
29
#endif
27
30
 
28
31
#include <glib.h>
29
32
 
463
466
    return self;
464
467
}
465
468
 
 
469
#if defined(USE_IMLIB2)
 
470
typedef struct _ImlibLoader ImlibLoader;
 
471
 
 
472
struct _ImlibLoader
 
473
{
 
474
    Imlib_Image img;
 
475
};
 
476
 
 
477
void DestroyImlibLoader(ImlibLoader *loader)
 
478
{
 
479
    if (!loader)
 
480
        return;
 
481
 
 
482
    imlib_free_image();
 
483
    g_slice_free(ImlibLoader, loader);
 
484
}
 
485
 
 
486
ImlibLoader* LoadWithImlib(gchar *path,
 
487
                           RrPixel32 **pixel_data,
 
488
                           gint *width,
 
489
                           gint *height)
 
490
{
 
491
    ImlibLoader *loader = g_slice_new0(ImlibLoader);
 
492
    if (!(loader->img = imlib_load_image(path))) {
 
493
        DestroyImlibLoader(loader);
 
494
        return NULL;
 
495
    }
 
496
 
 
497
    /* Get data and dimensions of the image.
 
498
 
 
499
       WARNING: This stuff is NOT threadsafe !!
 
500
    */
 
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();
 
505
 
 
506
    return loader;
 
507
}
 
508
#endif  /* USE_IMLIB2 */
 
509
 
 
510
#if defined(USE_LIBRSVG)
 
511
typedef struct _RsvgLoader RsvgLoader;
 
512
 
 
513
struct _RsvgLoader
 
514
{
 
515
    RsvgHandle *handle;
 
516
    cairo_surface_t *surface;
 
517
    RrPixel32 *pixel_data;
 
518
};
 
519
 
 
520
void DestroyRsvgLoader(RsvgLoader *loader)
 
521
{
 
522
    if (!loader)
 
523
        return;
 
524
 
 
525
    if (loader->pixel_data)
 
526
        g_free(loader->pixel_data);
 
527
    if (loader->surface)
 
528
        cairo_surface_destroy(loader->surface);
 
529
    if (loader->handle)
 
530
        g_object_unref(loader->handle);
 
531
    g_slice_free(RsvgLoader, loader);
 
532
}
 
533
 
 
534
RsvgLoader* LoadWithRsvg(gchar *path,
 
535
                         RrPixel32 **pixel_data,
 
536
                         gint *width,
 
537
                         gint *height)
 
538
{
 
539
    RsvgLoader *loader = g_slice_new0(RsvgLoader);
 
540
 
 
541
    if (!(loader->handle = rsvg_handle_new_from_file(path, NULL))) {
 
542
        DestroyRsvgLoader(loader);
 
543
        return NULL;
 
544
    }
 
545
 
 
546
    if (!rsvg_handle_close(loader->handle, NULL)) {
 
547
        DestroyRsvgLoader(loader);
 
548
        return NULL;
 
549
    }
 
550
 
 
551
    RsvgDimensionData dimension_data;
 
552
    rsvg_handle_get_dimensions(loader->handle, &dimension_data);
 
553
    *width = dimension_data.width;
 
554
    *height = dimension_data.height;
 
555
 
 
556
    loader->surface = cairo_image_surface_create(
 
557
        CAIRO_FORMAT_ARGB32, *width, *height);
 
558
 
 
559
    cairo_t* context = cairo_create(loader->surface);
 
560
    gboolean success = rsvg_handle_render_cairo(loader->handle, context);
 
561
    cairo_destroy(context);
 
562
 
 
563
    if (!success) {
 
564
        DestroyRsvgLoader(loader);
 
565
        return NULL;
 
566
    }
 
567
 
 
568
    loader->pixel_data = g_new(guint32, *width * *height);
 
569
 
 
570
    /*
 
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.
 
574
    */
 
575
 
 
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);
 
581
 
 
582
    guint32 *out_row = loader->pixel_data;
 
583
 
 
584
    guint32 *in_row =
 
585
        (guint32*)cairo_image_surface_get_data(loader->surface);
 
586
    gint in_stride = cairo_image_surface_get_stride(loader->surface);
 
587
 
 
588
    gint y;
 
589
    for (y = 0; y < *height; ++y) {
 
590
        gint x;
 
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;
 
596
            out_row[x] =
 
597
                ((r * 256 / (a + 1)) << RrDefaultRedOffset) +
 
598
                ((g * 256 / (a + 1)) << RrDefaultGreenOffset) +
 
599
                ((b * 256 / (a + 1)) << RrDefaultBlueOffset) +
 
600
                (a << RrDefaultAlphaOffset);
 
601
        }
 
602
        in_row += in_stride / 4;
 
603
        out_row += *width;
 
604
    }
 
605
 
 
606
    *pixel_data = loader->pixel_data;
 
607
 
 
608
    return loader;
 
609
}
 
610
#endif  /* USE_LIBRSVG */
 
611
 
466
612
RrImage* RrImageNewFromName(RrImageCache *cache, const gchar *name)
467
613
{
468
 
#ifndef USE_IMLIB2
469
 
    return NULL;
470
 
#else
471
614
    RrImage *self;
472
615
    RrImageSet *set;
473
 
    Imlib_Image img;
474
616
    gint w, h;
475
617
    RrPixel32 *data;
476
618
    gchar *path;
 
619
    gboolean loaded;
 
620
 
 
621
#if defined(USE_IMLIB2)
 
622
    ImlibLoader *imlib_loader = NULL;
 
623
#endif
 
624
#if defined(USE_LIBRSVG)
 
625
    RsvgLoader *rsvg_loader = NULL;
 
626
#endif
477
627
 
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);
490
640
 
491
 
    if (!(img = imlib_load_image(path)))
 
641
    loaded = FALSE;
 
642
#if defined(USE_LIBRSVG)
 
643
    if (!loaded) {
 
644
        rsvg_loader = LoadWithRsvg(path, &data, &w, &h);
 
645
        loaded = !!rsvg_loader;
 
646
    }
 
647
#endif
 
648
#if defined(USE_IMLIB2)
 
649
    if (!loaded) {
 
650
        imlib_loader = LoadWithImlib(path, &data, &w, &h);
 
651
        loaded = !!imlib_loader;
 
652
    }
 
653
#endif
 
654
 
 
655
    if (!loaded) {
492
656
        g_message("Cannot load image \"%s\" from file \"%s\"", name, path);
 
657
        g_free(path);
 
658
#if defined(USE_LIBRSVG)
 
659
        DestroyRsvgLoader(rsvg_loader);
 
660
#endif
 
661
#if defined(USE_IMLIB2)
 
662
        DestroyImlibLoader(imlib_loader);
 
663
#endif
 
664
        return NULL;
 
665
    }
 
666
 
493
667
    g_free(path);
494
668
 
495
 
    if (!img)
496
 
        return NULL;
497
 
 
498
 
    /* Get data and dimensions of the image.
499
 
 
500
 
       WARNING: This stuff is NOT threadsafe !!
501
 
    */
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();
506
 
 
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
509
671
       cache.
517
679
    self = RrImageNewFromData(cache, data, w, h);
518
680
    RrImageSetAddName(self->set, name);
519
681
 
520
 
    imlib_free_image();
 
682
#if defined(USE_LIBRSVG)
 
683
    DestroyRsvgLoader(rsvg_loader);
 
684
#endif
 
685
#if defined(USE_IMLIB2)
 
686
    DestroyImlibLoader(imlib_loader);
 
687
#endif
 
688
 
521
689
    return self;
522
 
#endif
523
690
}
524
691
 
525
692
/************************************************************************