1 /*
2 * pixbufs.c
3 * Copyright 2010-2012 John Lindgren
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions, and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions, and the following disclaimer in the documentation
13 * provided with the distribution.
14 *
15 * This software is provided "as is" and without any warranty, express or
16 * implied. In no event shall the authors be liable for any damages arising from
17 * the use of this software.
18 */
19
20 #include <gdk-pixbuf/gdk-pixbuf.h>
21
22 #include <libaudcore/audstrings.h>
23 #include <libaudcore/drct.h>
24 #include <libaudcore/probe.h>
25 #include <libaudcore/runtime.h>
26
27 #include "internal.h"
28 #include "libaudgui-gtk.h"
29
30 static AudguiPixbuf current_pixbuf;
31
audgui_pixbuf_fallback()32 EXPORT AudguiPixbuf audgui_pixbuf_fallback ()
33 {
34 static AudguiPixbuf fallback;
35
36 if (! fallback)
37 {
38 GtkIconTheme * icon_theme = gtk_icon_theme_get_default ();
39 int icon_size = audgui_to_native_dpi (48);
40
41 fallback.capture (gtk_icon_theme_load_icon (icon_theme,
42 "audio-x-generic", icon_size, (GtkIconLookupFlags) 0, nullptr));
43 }
44
45 return fallback.ref ();
46 }
47
audgui_pixbuf_uncache()48 void audgui_pixbuf_uncache ()
49 {
50 current_pixbuf.clear ();
51 }
52
audgui_pixbuf_scale_within(AudguiPixbuf & pixbuf,int size)53 EXPORT void audgui_pixbuf_scale_within (AudguiPixbuf & pixbuf, int size)
54 {
55 int width = pixbuf.width ();
56 int height = pixbuf.height ();
57
58 if (width <= size && height <= size)
59 return;
60
61 if (width > height)
62 {
63 height = size * height / width;
64 width = size;
65 }
66 else
67 {
68 width = size * width / height;
69 height = size;
70 }
71
72 if (width < 1)
73 width = 1;
74 if (height < 1)
75 height = 1;
76
77 pixbuf.capture (gdk_pixbuf_scale_simple (pixbuf.get (), width, height, GDK_INTERP_BILINEAR));
78 }
79
audgui_pixbuf_request(const char * filename,bool * queued)80 EXPORT AudguiPixbuf audgui_pixbuf_request (const char * filename, bool * queued)
81 {
82 AudArtPtr art = aud_art_request (filename, AUD_ART_DATA, queued);
83
84 auto data = art.data ();
85 return data ? audgui_pixbuf_from_data (data->begin (), data->len ()) : AudguiPixbuf ();
86 }
87
audgui_pixbuf_request_current(bool * queued)88 EXPORT AudguiPixbuf audgui_pixbuf_request_current (bool * queued)
89 {
90 if (queued)
91 * queued = false;
92
93 if (! current_pixbuf)
94 {
95 String filename = aud_drct_get_filename ();
96 if (filename)
97 current_pixbuf = audgui_pixbuf_request (filename, queued);
98 }
99
100 return current_pixbuf.ref ();
101 }
102
audgui_pixbuf_from_data(const void * data,int64_t size)103 EXPORT AudguiPixbuf audgui_pixbuf_from_data (const void * data, int64_t size)
104 {
105 GdkPixbuf * pixbuf = nullptr;
106 GdkPixbufLoader * loader = gdk_pixbuf_loader_new ();
107 GError * error = nullptr;
108
109 if (gdk_pixbuf_loader_write (loader, (const unsigned char *) data, size,
110 & error) && gdk_pixbuf_loader_close (loader, & error))
111 {
112 if ((pixbuf = gdk_pixbuf_loader_get_pixbuf (loader)))
113 g_object_ref (pixbuf);
114 }
115 else
116 {
117 AUDWARN ("While loading pixbuf: %s\n", error->message);
118 g_error_free (error);
119 }
120
121 g_object_unref (loader);
122 return AudguiPixbuf (pixbuf);
123 }
124