29 #define G_LOG_DOMAIN "Helpers.IconFetcher"
40 #include "nkutils-xdg-theme.h"
89 g_free ( entry->
name );
91 for ( GList *iter = g_list_first ( entry->
sizes ); iter; iter = g_list_next ( iter ) ) {
94 cairo_surface_destroy ( sentry->
surface );
98 g_list_free ( entry->
sizes );
106 static const gchar *
const icon_fallback_themes[] = {
138 cairo_surface_t* surface = 0;
139 unsigned char * data = 0;
140 unsigned char * rgb = 0;
142 jpeg_read_header ( cinfo, TRUE );
143 jpeg_start_decompress ( cinfo );
145 surface = cairo_image_surface_create ( CAIRO_FORMAT_RGB24, cinfo->image_width, cinfo->image_height );
146 data = cairo_image_surface_get_data ( surface );
147 rgb = (
unsigned char *) ( malloc ( cinfo->output_width * cinfo->output_components ) );
149 while ( cinfo->output_scanline < cinfo->output_height ) {
151 int scanline = cinfo->output_scanline * cairo_image_surface_get_stride ( surface );
153 jpeg_read_scanlines ( cinfo, &rgb, 1 );
155 for ( i = 0; i < cinfo->output_width; i++ ) {
156 int offset = scanline + ( i * 4 );
158 data[offset + 3] = 255;
159 data[offset + 2] = rgb[( i * 3 )];
160 data[offset + 1] = rgb[( i * 3 ) + 1];
161 data[offset ] = rgb[( i * 3 ) + 2];
167 jpeg_finish_decompress ( cinfo );
168 jpeg_destroy_decompress ( cinfo );
170 cairo_surface_mark_dirty ( surface );
177 struct jpeg_decompress_struct cinfo;
178 struct jpeg_error_mgr jerr;
179 cairo_surface_t * surface;
182 if ( ( infile = fopen ( file,
"rb" ) ) == NULL ) {
186 cinfo.err = jpeg_std_error ( &jerr );
188 jpeg_create_decompress ( &cinfo );
189 jpeg_stdio_src ( &cinfo, infile );
200 g_debug (
"starting up icon fetching thread." );
204 const gchar *themes[] = {
209 const gchar *icon_path;
210 gchar *icon_path_ = NULL;
212 if ( g_path_is_absolute ( sentry->
entry->
name ) ) {
217 if ( icon_path_ == NULL ) {
218 g_debug (
"failed to get icon %s(%d): n/a", sentry->
entry->
name, sentry->
size );
222 g_debug (
"found icon %s(%d): %s", sentry->
entry->
name, sentry->
size, icon_path );
225 cairo_surface_t *icon_surf = NULL;
226 if ( g_str_has_suffix ( icon_path,
".png" ) ) {
227 icon_surf = cairo_image_surface_create_from_png ( icon_path );
229 else if ( g_str_has_suffix ( icon_path,
".jpeg" ) || g_str_has_suffix ( icon_path,
".jpg" ) ) {
232 else if ( g_str_has_suffix ( icon_path,
".svg" ) ) {
236 g_debug (
"icon type not yet supported: %s", icon_path );
239 if ( cairo_surface_status ( icon_surf ) == CAIRO_STATUS_SUCCESS ) {
240 float sw = sentry->
size / (float) cairo_image_surface_get_width ( icon_surf );
241 float sh = sentry->
size / (float) cairo_image_surface_get_height ( icon_surf );
243 float scale = ( sw > sh ) ? sh : sw;
245 cairo_surface_t * surface = cairo_image_surface_create (
246 cairo_image_surface_get_format ( icon_surf ),
247 cairo_image_surface_get_width ( icon_surf ) * scale,
248 cairo_image_surface_get_height ( icon_surf ) * scale );
250 cairo_t *d = cairo_create ( surface );
251 cairo_scale ( d, scale, scale );
252 cairo_set_source_surface ( d, icon_surf, 0.0, 0.0 );
253 cairo_pattern_set_filter ( cairo_get_source ( d ), CAIRO_FILTER_FAST );
257 cairo_surface_destroy ( icon_surf );
262 if ( cairo_surface_status ( icon_surf ) != CAIRO_STATUS_SUCCESS ) {
263 g_debug (
"icon failed to open: %s(%d): %s", sentry->
entry->
name, sentry->
size, icon_path );
264 cairo_surface_destroy ( icon_surf );
269 g_free ( icon_path_ );
275 g_debug (
"Query: %s(%d)", name, size );
277 if ( entry == NULL ) {
279 entry->
name = g_strdup ( name );
283 for ( GList *iter = g_list_first ( entry->
sizes ); iter; iter = g_list_next ( iter ) ) {
285 if ( sentry->
size == size ) {
294 sentry->
entry = entry;
297 entry->
sizes = g_list_prepend ( entry->
sizes, sentry );
302 g_thread_pool_push (
tpool, sentry, NULL );