Commit c5f45223 authored by Tobias Ellinghaus's avatar Tobias Ellinghaus

Put loading the dt logo into a helper function

parent e2deccec
......@@ -41,9 +41,16 @@
#include <config.h>
#endif
#include <librsvg/rsvg.h>
// ugh, ugly hack. why do people break stuff all the time?
#ifndef RSVG_CAIRO_H
#include <librsvg/rsvg-cairo.h>
#endif
#include "file_location.h"
#include "utility.h"
#include "common/grealpath.h"
#include "gui/gtk.h"
gchar *dt_util_dstrcat(gchar *str, const gchar *format, ...)
{
......@@ -340,7 +347,7 @@ static void easter(int Y, int* month, int *day)
}
// days are in [1..31], months are in [0..11], see "man localtime"
dt_logo_season_t get_logo_season(void)
dt_logo_season_t dt_util_get_logo_season(void)
{
time_t now;
time(&now);
......@@ -369,6 +376,73 @@ dt_logo_season_t get_logo_season(void)
return DT_LOGO_SEASON_NONE;
}
cairo_surface_t *dt_util_get_logo(float size)
{
GError *error = NULL;
cairo_surface_t *surface = NULL;
char datadir[PATH_MAX] = { 0 };
char *logo;
dt_logo_season_t season = dt_util_get_logo_season();
if(season != DT_LOGO_SEASON_NONE)
logo = g_strdup_printf("idbutton-%d.svg", (int)season);
else
logo = g_strdup("idbutton.svg");
dt_loc_get_datadir(datadir, sizeof(datadir));
char *dtlogo = g_build_filename(datadir, "pixmaps", logo, NULL);
RsvgHandle *svg = rsvg_handle_new_from_file(dtlogo, &error);
if(svg)
{
cairo_t *cr;
RsvgDimensionData dimension;
rsvg_handle_get_dimensions(svg, &dimension);
float ppd = darktable.gui ? darktable.gui->ppd : 1.0;
float svg_size = MAX(dimension.width, dimension.height);
float factor = size > 0.0 ? size / svg_size : -1.0 * size;
float final_width = dimension.width * factor * ppd,
final_height = dimension.height * factor * ppd;
int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, final_width);
guint8 *image_buffer = (guint8 *)calloc(stride * final_height, sizeof(guint8));
if(darktable.gui)
surface = dt_cairo_image_surface_create_for_data(image_buffer, CAIRO_FORMAT_ARGB32, final_width,
final_height, stride);
else // during startup we don't know ppd yet and darktable.gui isn't initialized yet.
surface = cairo_image_surface_create_for_data(image_buffer, CAIRO_FORMAT_ARGB32, final_width,
final_height, stride);
if(cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS)
{
fprintf(stderr, "warning: can't load darktable logo from SVG file `%s'\n", dtlogo);
cairo_surface_destroy(surface);
free(image_buffer);
image_buffer = NULL;
surface = NULL;
}
else
{
cr = cairo_create(surface);
cairo_scale(cr, factor, factor);
rsvg_handle_render_cairo(svg, cr);
cairo_destroy(cr);
cairo_surface_flush(surface);
}
g_object_unref(svg);
}
else
{
fprintf(stderr, "warning: can't load darktable logo from SVG file `%s'\n%s\n", dtlogo, error->message);
g_error_free(error);
}
g_free(logo);
g_free(dtlogo);
return surface;
}
// the following two functions (dt_util_latitude_str and dt_util_longitude_str) were taken from libosmgpsmap
// Copyright (C) 2013 John Stowers <john.stowers@gmail.com>
/* these can be overwritten with versions that support
......
......@@ -51,7 +51,9 @@ typedef enum dt_logo_season_t
} dt_logo_season_t;
/** returns the dt logo season to use right now */
dt_logo_season_t get_logo_season(void);
dt_logo_season_t dt_util_get_logo_season(void);
cairo_surface_t *dt_util_get_logo(float size);
gchar *dt_util_latitude_str(float latitude);
gchar *dt_util_longitude_str(float longitude);
......
......@@ -500,54 +500,18 @@ static void size_allocate_callback(GtkWidget *widget, GtkAllocation *allocation,
free(g->image_buffer);
/* load the dt logo as a brackground */
char filename[PATH_MAX] = { 0 };
char datadir[PATH_MAX] = { 0 };
char *logo;
dt_logo_season_t season = get_logo_season();
if(season != DT_LOGO_SEASON_NONE)
logo = g_strdup_printf("%%s/pixmaps/idbutton-%d.svg", (int)season);
g->image = dt_util_get_logo(MIN(allocation->width, allocation->height) * 0.75);
if(g->image)
{
g->image_buffer = cairo_image_surface_get_data(g->image);
g->image_width = cairo_image_surface_get_width(g->image);
g->image_height = cairo_image_surface_get_height(g->image);
}
else
logo = g_strdup("%s/pixmaps/idbutton.svg");
dt_loc_get_datadir(datadir, sizeof(datadir));
snprintf(filename, sizeof(filename), logo, datadir);
g_free(logo);
RsvgHandle *svg = rsvg_handle_new_from_file(filename, NULL);
if(svg)
{
cairo_surface_t *surface;
cairo_t *cr;
RsvgDimensionData dimension;
rsvg_handle_get_dimensions(svg, &dimension);
float svg_size = MAX(dimension.width, dimension.height);
float final_size = MIN(allocation->width, allocation->height) * 0.75;
float factor = final_size / svg_size;
float final_width = dimension.width * factor * darktable.gui->ppd,
final_height = dimension.height * factor * darktable.gui->ppd;
int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, final_width);
g->image_buffer = (guint8 *)calloc(stride * final_height, sizeof(guint8));
surface = dt_cairo_image_surface_create_for_data(g->image_buffer, CAIRO_FORMAT_ARGB32, final_width,
final_height, stride);
if(cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS)
{
free(g->image_buffer);
g->image_buffer = NULL;
}
else
{
cr = cairo_create(surface);
cairo_scale(cr, factor, factor);
rsvg_handle_render_cairo(svg, cr);
cairo_destroy(cr);
cairo_surface_flush(surface);
g->image = surface;
g->image_width = final_width / darktable.gui->ppd;
g->image_height = final_height / darktable.gui->ppd;
}
g_object_unref(svg);
g->image_buffer = NULL;
g->image_width = 0;
g->image_height = 0;
}
}
......
......@@ -722,58 +722,20 @@ static void _lib_import_update_preview(GtkFileChooser *file_chooser, gpointer da
if(no_preview_fallback || !have_preview)
{
/* load the dt logo as a brackground */
char dtlogo[PATH_MAX] = { 0 };
char datadir[PATH_MAX] = { 0 };
char *logo;
dt_logo_season_t season = get_logo_season();
if(season != DT_LOGO_SEASON_NONE)
logo = g_strdup_printf("%%s/pixmaps/idbutton-%d.svg", (int)season);
else
logo = g_strdup("%s/pixmaps/idbutton.svg");
dt_loc_get_datadir(datadir, sizeof(datadir));
snprintf(dtlogo, sizeof(dtlogo), logo, datadir);
g_free(logo);
RsvgHandle *svg = rsvg_handle_new_from_file(dtlogo, NULL);
if(svg)
cairo_surface_t *surface = dt_util_get_logo(128.0);
if(surface)
{
cairo_surface_t *surface;
cairo_t *cr;
RsvgDimensionData dimension;
rsvg_handle_get_dimensions(svg, &dimension);
float svg_size = MAX(dimension.width, dimension.height);
float final_size = 128;
float factor = final_size / svg_size;
float final_width = dimension.width * factor * darktable.gui->ppd,
final_height = dimension.height * factor * darktable.gui->ppd;
int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, final_width);
guint8 *image_buffer = (guint8 *)calloc(stride * final_height, sizeof(guint8));
surface = dt_cairo_image_surface_create_for_data(image_buffer, CAIRO_FORMAT_ARGB32, final_width,
final_height, stride);
if(cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS)
{
free(image_buffer);
image_buffer = NULL;
}
else
{
cr = cairo_create(surface);
cairo_scale(cr, factor, factor);
rsvg_handle_render_cairo(svg, cr);
cairo_destroy(cr);
cairo_surface_flush(surface);
pixbuf = gdk_pixbuf_get_from_surface(surface, 0, 0, final_width / darktable.gui->ppd,
final_height / darktable.gui->ppd);
cairo_surface_destroy(surface);
free(image_buffer);
}
g_object_unref(svg);
}
guint8 *image_buffer = cairo_image_surface_get_data(surface);
int image_width = cairo_image_surface_get_width(surface);
int image_height = cairo_image_surface_get_height(surface);
pixbuf = gdk_pixbuf_get_from_surface(surface, 0, 0, image_width, image_height);
cairo_surface_destroy(surface);
free(image_buffer);
have_preview = TRUE;
have_preview = TRUE;
}
}
if(have_preview) gtk_image_set_from_pixbuf(GTK_IMAGE(preview), pixbuf);
if(pixbuf) g_object_unref(pixbuf);
......
......@@ -79,8 +79,6 @@ int position()
void gui_init(dt_lib_module_t *self)
{
char filename[PATH_MAX] = { 0 };
char datadir[PATH_MAX] = { 0 };
/* initialize ui widgets */
dt_lib_darktable_t *d = (dt_lib_darktable_t *)g_malloc0(sizeof(dt_lib_darktable_t));
self->data = (void *)d;
......@@ -94,73 +92,30 @@ void gui_init(dt_lib_module_t *self)
G_CALLBACK(_lib_darktable_button_press_callback), self);
/* create a cairo surface of dt icon */
char *logo;
dt_logo_season_t season = get_logo_season();
if(season != DT_LOGO_SEASON_NONE)
logo = g_strdup_printf("%%s/pixmaps/idbutton-%d.%%s", (int)season);
else
logo = g_strdup("%s/pixmaps/idbutton.%s");
dt_loc_get_datadir(datadir, sizeof(datadir));
snprintf(filename, sizeof(filename), logo, datadir, "svg");
// first we try the SVG
d->image = dt_util_get_logo(DT_PIXEL_APPLY_DPI(-1.0));
if(d->image)
d->image_buffer = cairo_image_surface_get_data(d->image);
else
{
GError *error = NULL;
RsvgHandle *svg = rsvg_handle_new_from_file(filename, &error);
if(!svg || error)
{
fprintf(stderr,
"warning: can't load darktable logo from SVG file `%s', falling back to PNG version\n%s\n",
filename, error->message);
g_error_free(error);
error = NULL;
goto png_fallback;
}
// let's fall back to the PNG
char *logo;
char datadir[PATH_MAX] = { 0 };
cairo_surface_t *surface;
cairo_t *cr;
RsvgDimensionData dimension;
rsvg_handle_get_dimensions(svg, &dimension);
dt_loc_get_datadir(datadir, sizeof(datadir));
dt_logo_season_t season = dt_util_get_logo_season();
if(season != DT_LOGO_SEASON_NONE)
logo = g_strdup_printf("idbutton-%d.png", (int)season);
else
logo = g_strdup("idbutton.png");
char *filename = g_build_filename(datadir, "pixmaps", logo, NULL);
int width = DT_PIXEL_APPLY_DPI(dimension.width) * darktable.gui->ppd,
height = DT_PIXEL_APPLY_DPI(dimension.height) * darktable.gui->ppd;
int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width);
d->image_buffer = (guint8 *)calloc(stride * height, sizeof(guint8));
surface
= dt_cairo_image_surface_create_for_data(d->image_buffer, CAIRO_FORMAT_ARGB32, width, height, stride);
if(cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS)
{
free(d->image_buffer);
d->image_buffer = NULL;
g_object_unref(svg);
fprintf(stderr, "warning: can't load darktable logo from SVG file `%s', falling back to PNG version\n",
filename);
goto png_fallback;
}
cr = cairo_create(surface);
cairo_scale(cr, darktable.gui->dpi_factor, darktable.gui->dpi_factor);
rsvg_handle_render_cairo(svg, cr);
cairo_destroy(cr);
cairo_surface_flush(surface);
d->image = surface;
g_object_unref(svg);
}
goto done;
png_fallback:
// let's fall back to the PNG
{
cairo_surface_t *surface;
cairo_t *cr;
snprintf(filename, sizeof(filename), logo, datadir, "png");
surface = cairo_image_surface_create_from_png(filename);
g_free(logo);
g_free(filename);
if(cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS)
{
fprintf(stderr, "warning: can't load darktable logo from PNG file `%s'\n", filename);
......@@ -200,8 +155,6 @@ png_fallback:
}
done:
g_free(logo);
d->image_width = d->image ? dt_cairo_image_surface_get_width(d->image) : 0;
d->image_height = d->image ? dt_cairo_image_surface_get_height(d->image) : 0;
......@@ -292,7 +245,7 @@ static void _lib_darktable_show_about_dialog()
gtk_about_dialog_set_comments(GTK_ABOUT_DIALOG(dialog),
_("organize and develop images from digital cameras"));
gtk_about_dialog_set_website(GTK_ABOUT_DIALOG(dialog), "https://www.darktable.org/");
dt_logo_season_t season = get_logo_season();
dt_logo_season_t season = dt_util_get_logo_season();
char *icon;
if(season != DT_LOGO_SEASON_NONE)
icon = g_strdup_printf("darktable-%d", (int)season);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment