diff options
author | Oyvind Kolas <pippin@gimp.org> | 2015-07-28 17:38:52 +0200 |
---|---|---|
committer | Oyvind Kolas <pippin@gimp.org> | 2015-07-28 17:38:52 +0200 |
commit | 64ea85ad169b9ee7dee52f6e7fd0adc67fc20528 (patch) | |
tree | 980d8838f9301a86919c974382fc3bac7861b922 | |
parent | c2aba45298c74228c9667cc3f3112c63c7482146 (diff) |
revert premature integration of image viewer
-rw-r--r-- | bin/Makefile.am | 11 | ||||
-rw-r--r-- | bin/gegl.c | 8 | ||||
-rw-r--r-- | bin/mrg-ui.c | 1410 | ||||
-rw-r--r-- | configure.ac | 42 |
4 files changed, 3 insertions, 1468 deletions
diff --git a/bin/Makefile.am b/bin/Makefile.am index 91fc956a..24e77b41 100644 --- a/bin/Makefile.am +++ b/bin/Makefile.am @@ -22,13 +22,12 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/gegl/property-types AM_CFLAGS = \ - $(DEP_CFLAGS) $(BABL_CFLAGS) $(PNG_CFLAGS) \ - $(MRG_CFLAGS) $(GEXIV2_CFLAGS) + $(DEP_CFLAGS) $(BABL_CFLAGS) $(PNG_CFLAGS) + AM_LDFLAGS = \ $(no_undefined) ../gegl/libgegl-$(GEGL_API_VERSION).la \ - $(DEP_LIBS) $(BABL_LIBS) $(PNG_LIBS) $(LIBSPIRO) $(MATH_LIB) \ - $(MRG_LIBS) $(GEXIV2_LIBS) + $(DEP_LIBS) $(BABL_LIBS) $(PNG_LIBS) $(LIBSPIRO) $(MATH_LIB) bin_PROGRAMS = gegl gegl-tester @@ -42,10 +41,6 @@ gegl_SOURCES = \ gegl_tester_SOURCES = \ gegl-tester.c -if HAVE_MRG -gegl_SOURCES += mrg-ui.c -endif - if HAVE_SPIRO gegl_SOURCES += gegl-path-spiro.h gegl-path-spiro.c endif @@ -76,8 +76,6 @@ static gboolean file_is_gegl_xml (const gchar *path) return FALSE; } -int mrg_ui_main (int argc, char **argv); - gint main (gint argc, gchar **argv) @@ -173,12 +171,6 @@ main (gint argc, script = g_strdup (DEFAULT_COMPOSITION); } } - - if (o->mode == GEGL_RUN_MODE_DISPLAY) - { - mrg_ui_main (argc, argv); - return 0; - } gegl = gegl_node_new_from_xml (script, path_root); diff --git a/bin/mrg-ui.c b/bin/mrg-ui.c deleted file mode 100644 index d3c36b22..00000000 --- a/bin/mrg-ui.c +++ /dev/null @@ -1,1410 +0,0 @@ -/* This file is part of GEGL editor -- an mrg frontend for GEGL - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. - * - * Copyright (C) 2015 Øyvind Kolås pippin@gimp.org - */ - -#define _BSD_SOURCE -#define _DEFAULT_SOURCE - -#include "config.h" - -#if HAVE_MRG - -#include <string.h> -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <dirent.h> -#include <mrg.h> -#include <gegl.h> -#include <gexiv2/gexiv2.h> -#include <gegl-paramspecs.h> - -typedef struct ActionData { - const char *label; - float priority; - const char *op_name; -} ActionData; - -ActionData actions[]={ - {"rotate", 10, "gegl:rotate"}, - {"crop", 20, "gegl:crop"}, - {"color temperature", 50, "gegl:color-temperature"}, - {"exposure", 60, "gegl:exposure"}, - {"levels", 60, "gegl:levels"}, - {"threshold", 70, "gegl:threshold"}, - {NULL, 0, NULL}, /* sentinel */ -}; - -static char *suffix = "-giev"; - -#define USE_MIPMAPS 1 -#define DEBUG_OP_LIST 1 - -typedef struct _State State; -struct _State { - void (*ui) (Mrg *mrg, void *state); - Mrg *mrg; - - char *path; - char *giev_path; - GeglBuffer *buffer; - GeglNode *gegl; - GeglNode *sink; - GeglNode *source; - GeglNode *load; - GeglNode *save; - GeglNode *active; - - GeglNode *rotate; - int rev; - float u, v; - float scale; - int show_actions; - int show_controls; - - float render_quality; - float preview_quality; -}; - -void gegl_meta_set (const char *path, const char *meta_data); -char * gegl_meta_get (const char *path); - -static char *suffix_path (const char *path); -static char *unsuffix_path (const char *path); -static int is_giev_path (const char *path); - -static void contrasty_stroke (cairo_t *cr); - -static void mrg_gegl_blit (Mrg *mrg, - float x0, float y0, - float width, float height, - GeglNode *node, - float u, float v, - float scale, - float preview_multiplier); - -static void load_path (State *o); - -static void go_next (State *o); -static void go_prev (State *o); - - -static void go_next_cb (MrgEvent *event, void *data1, void *data2); -static void go_prev_cb (MrgEvent *event, void *data1, void *data2); - -static void leave_editor (State *o); - -static void drag_preview (MrgEvent *e); -static void load_into_buffer (State *o, const char *path); - -static GeglNode *locate_node (State *o, const char *op_name); - -static void zoom_to_fit (State *o); - -static void zoom_to_fit_buffer (State *o); - -static void zoom_fit_cb (MrgEvent *e, void *data1, void *data2); -static int deferred_zoom_to_fit (Mrg *mrg, void *data); - -static void pan_left_cb (MrgEvent *event, void *data1, void *data2); - -static void pan_right_cb (MrgEvent *event, void *data1, void *data2); - -static void pan_down_cb (MrgEvent *event, void *data1, void *data2); - -static void pan_up_cb (MrgEvent *event, void *data1, void *data2); - -static void get_coords (State *o, float screen_x, float screen_y, float *gegl_x, float *gegl_y); - -static void preview_more_cb (MrgEvent *event, void *data1, void *data2); - -static void preview_less_cb (MrgEvent *event, void *data1, void *data2); - -static void zoom_1_cb (MrgEvent *event, void *data1, void *data2); - -static void zoom_in_cb (MrgEvent *event, void *data1, void *data2); - -static void zoom_out_cb (MrgEvent *event, void *data1, void *data2); - -static void toggle_actions_cb (MrgEvent *event, void *data1, void *data2); - -static void toggle_fullscreen_cb (MrgEvent *event, void *data1, void *data2); - - -static void activate_op_cb (MrgEvent *event, void *data1, void *data2); - - -static void disable_filter_cb (MrgEvent *event, void *data1, void *data2); - -static void apply_filter_cb (MrgEvent *event, void *data1, void *data2); -static void discard_cb (MrgEvent *event, void *data1, void *data2); -static void save_cb (MrgEvent *event, void *data1, void *data2); - - - - -static void toggle_show_controls_cb (MrgEvent *event, void *data1, void *data2); - -static void gegl_ui (Mrg *mrg, void *data); -int mrg_ui_main (int argc, char **argv); - -void gegl_meta_set (const char *path, const char *meta_data); -char * gegl_meta_get (const char *path); - -static State *hack_state = NULL; // XXX: this shoudl be factored away - -int mrg_ui_main (int argc, char **argv) -{ - Mrg *mrg = mrg_new (1024, 768, NULL); - State o = {NULL,}; -#ifdef USE_MIPMAPS - g_setenv ("GEGL_MIPMAP_RENDERING", "1", TRUE); -#endif - g_setenv ("BABL_TOLERANCE", "0.1", TRUE); - - gegl_init (&argc, &argv); - o.gegl = gegl_node_new (); - o.mrg = mrg; - o.scale = 1.0; - o.render_quality = 1.0; - o.preview_quality = 4.0; - - if (access (argv[1], F_OK) != -1) - o.path = strdup (argv[1]); - else - { - printf ("usage: %s <full-path-to-image>\n", argv[0]); - return -1; - } - - load_path (&o); - mrg_set_ui (mrg, gegl_ui, &o); - hack_state = &o; - mrg_main (mrg); - - g_object_unref (o.gegl); - if (o.buffer) - { - g_object_unref (o.buffer); - o.buffer = NULL; - } - gegl_exit (); - return 0; -} - -static void on_pan_drag (MrgEvent *e, void *data1, void *data2) -{ - State *o = data1; - if (e->type == MRG_DRAG_MOTION) - { - o->u -= (e->delta_x ); - o->v -= (e->delta_y ); - mrg_queue_draw (e->mrg, NULL); - } - drag_preview (e); -} - -static void prop_double_drag_cb (MrgEvent *e, void *data1, void *data2) -{ - GeglNode *node = data1; - GParamSpec *pspec = data2; - GeglParamSpecDouble *gspec = data2; - gdouble value = 0.0; - float range = gspec->ui_maximum - gspec->ui_minimum; - - value = e->x / mrg_width (e->mrg); - value = value * range + gspec->ui_minimum; - gegl_node_set (node, pspec->name, value, NULL); - - drag_preview (e); - - mrg_queue_draw (e->mrg, NULL); -} - -static void draw_gegl_generic (State *state, Mrg *mrg, cairo_t *cr, GeglNode *node) -{ - const gchar* op_name = gegl_node_get_operation (node); - mrg_set_edge_left (mrg, mrg_width (mrg) * 0.1); - mrg_set_edge_top (mrg, mrg_height (mrg) * 0.1); - mrg_set_font_size (mrg, mrg_height (mrg) * 0.07); - mrg_set_style (mrg, "color:white; background-color: transparent"); - - cairo_save (cr); - mrg_printf (mrg, "%s\n", op_name); - { - guint n_props; - GParamSpec **pspecs = gegl_operation_list_properties (op_name, &n_props); - - if (pspecs) - { - int tot_pos = 0; - int pos_no = 0; - - for (gint i = 0; i < n_props; i++) - { - if (g_type_is_a (pspecs[i]->value_type, G_TYPE_DOUBLE) || - g_type_is_a (pspecs[i]->value_type, G_TYPE_INT) || - g_type_is_a (pspecs[i]->value_type, G_TYPE_STRING) || - g_type_is_a (pspecs[i]->value_type, G_TYPE_BOOLEAN)) - tot_pos ++; - } - - for (gint i = 0; i < n_props; i++) - { - mrg_set_xy (mrg, mrg_em(mrg), mrg_height (mrg) - mrg_em (mrg) * ((tot_pos-pos_no))); - - if (g_type_is_a (pspecs[i]->value_type, G_TYPE_DOUBLE)) - { - float xpos; - GeglParamSpecDouble *geglspec = (void*)pspecs[i]; - gdouble value; - gegl_node_get (node, pspecs[i]->name, &value, NULL); - - cairo_rectangle (cr, 0, - mrg_height (mrg) - mrg_em (mrg) * ((tot_pos-pos_no+1)), - mrg_width (mrg), mrg_em(mrg)); - cairo_set_source_rgba (cr, 0,0,0, 0.5); - - mrg_listen (mrg, MRG_DRAG, prop_double_drag_cb, node,(void*)pspecs[i]); - - cairo_fill (cr); - xpos = (value - geglspec->ui_minimum) / (geglspec->ui_maximum - geglspec->ui_minimum); - cairo_rectangle (cr, xpos * mrg_width(mrg) - mrg_em(mrg)/4, - mrg_height (mrg) - mrg_em (mrg) * ((tot_pos-pos_no+1)), - mrg_em(mrg)/2, mrg_em(mrg)); - cairo_set_source_rgba (cr, 1,1,1, 0.5); - cairo_fill (cr); - - mrg_printf (mrg, "%s:%f\n", pspecs[i]->name, value); - pos_no ++; - } - else if (g_type_is_a (pspecs[i]->value_type, G_TYPE_INT)) - { - gint value; - gegl_node_get (node, pspecs[i]->name, &value, NULL); - mrg_printf (mrg, "%s:%i\n", pspecs[i]->name, value); - pos_no ++; - } - else if (g_type_is_a (pspecs[i]->value_type, G_TYPE_STRING)) - { - char *value = NULL; - gegl_node_get (node, pspecs[i]->name, &value, NULL); - pos_no ++; - mrg_printf (mrg, "%s:%s\n", pspecs[i]->name, value); - if (value) g_free (value); - } - else if (g_type_is_a (pspecs[i]->value_type, G_TYPE_BOOLEAN)) - { - gboolean value = FALSE; - gegl_node_get (node, pspecs[i]->name, &value, NULL); - pos_no ++; - mrg_printf (mrg, "%s:%i\n", pspecs[i]->name, value); - } - - } - g_free (pspecs); - } - } - - cairo_restore (cr); - mrg_set_style (mrg, "color:yellow; background-color: transparent"); -} - -static void crop_drag_ul (MrgEvent *e, void *data1, void *data2) -{ - GeglNode *node = data1; - double x,y,width,height; - double x0, y0, x1, y1; - gegl_node_get (node, "x", &x, "y", &y, "width", &width, "height", &height, NULL); - x0 = x; y0 = y; x1 = x0 + width; y1 = y + height; - - if (e->type == MRG_DRAG_MOTION) - { - x0 += e->delta_x; - y0 += e->delta_y; - - x=x0; - y=y0; - width = x1 - x0; - height = y1 - y0; - gegl_node_set (node, "x", x, "y", y, "width", width, "height", height, NULL); - - mrg_queue_draw (e->mrg, NULL); - } - - drag_preview (e); -} - -static void crop_drag_lr (MrgEvent *e, void *data1, void *data2) -{ - GeglNode *node = data1; - double x,y,width,height; - double x0, y0, x1, y1; - gegl_node_get (node, "x", &x, "y", &y, "width", &width, "height", &height, NULL); - x0 = x; y0 = y; x1 = x0 + width; y1 = y + height; - - if (e->type == MRG_DRAG_MOTION) - { - x1 += e->delta_x; - y1 += e->delta_y; - - x=x0; - y=y0; - width = x1 - x0; - height = y1 - y0; - gegl_node_set (node, "x", x, "y", y, "width", width, "height", height, NULL); - - mrg_queue_draw (e->mrg, NULL); - } - - drag_preview (e); -} - -static void crop_drag_rotate (MrgEvent *e, void *data1, void *data2) -{ - State *o = hack_state; - double degrees; - gegl_node_get (o->rotate, "degrees", °rees, NULL); - - if (e->type == MRG_DRAG_MOTION) - { - degrees += e->delta_x / 100.0; - - gegl_node_set (o->rotate, "degrees", degrees, NULL); - - mrg_queue_draw (e->mrg, NULL); - } - - drag_preview (e); -} - -static void draw_gegl_crop (State *o, Mrg *mrg, cairo_t *cr, GeglNode *node) -{ - const gchar* op_name = gegl_node_get_operation (node); - float dim = mrg_height (mrg) * 0.1 / o->scale; - double x,y,width,height; - double x0, y0, x1, y1; - - mrg_set_edge_left (mrg, mrg_width (mrg) * 0.1); - mrg_set_edge_top (mrg, mrg_height (mrg) * 0.1); - mrg_set_font_size (mrg, mrg_height (mrg) * 0.07); - mrg_set_style (mrg, "color:white; background-color: transparent"); - - cairo_save (cr); - mrg_printf (mrg, "%s\n", op_name); - - cairo_translate (cr, -o->u, -o->v); - cairo_scale (cr, o->scale, o->scale); - - gegl_node_get (node, "x", &x, "y", &y, "width", &width, "height", &height, NULL); - x0 = x; y0 = y; x1 = x0 + width; y1 = y + height; - - cairo_rectangle (cr, x0, y0, dim, dim); - mrg_listen (mrg, MRG_DRAG, crop_drag_ul, node, NULL); - contrasty_stroke (cr); - - cairo_rectangle (cr, x1-dim, y1-dim, dim, dim); - mrg_listen (mrg, MRG_DRAG, crop_drag_lr, node, NULL); - contrasty_stroke (cr); - - cairo_rectangle (cr, x0+dim, y0+dim, width-dim-dim, height-dim-dim); - mrg_listen (mrg, MRG_DRAG, crop_drag_rotate, node, NULL); - cairo_new_path (cr); - - cairo_restore (cr); - mrg_set_style (mrg, "color:yellow; background-color: transparent"); -} - -static void ui_op_draw_apply_disable (State *o) -{ - Mrg *mrg = o->mrg; - mrg_set_font_size (mrg, mrg_height (mrg) * 0.1); - mrg_set_xy (mrg, 0, mrg_em(mrg)); - mrg_text_listen (mrg, MRG_PRESS, disable_filter_cb, o, NULL); - mrg_printf (mrg, "X"); - mrg_text_listen_done (mrg); - mrg_set_xy (mrg, mrg_width(mrg) - mrg_em (mrg), mrg_em(mrg)); - mrg_text_listen (mrg, MRG_PRESS, apply_filter_cb, o, NULL); - mrg_printf (mrg, "O"); - mrg_text_listen_done (mrg); -} - -static void ui_active_op (State *o) -{ - Mrg *mrg = o->mrg; - cairo_t *cr = mrg_cr (mrg); - char *opname = NULL; - g_object_get (o->active, "operation", &opname, NULL); - - if (!strcmp (opname, "gegl:crop")) { - zoom_to_fit_buffer (o); - draw_gegl_crop (o, mrg, cr, o->active); - ui_op_draw_apply_disable (o); - } - else - { - draw_gegl_generic (o, mrg, cr, o->active); - ui_op_draw_apply_disable (o); - } -} - -static void ui_debug_op_chain (State *o) -{ - Mrg *mrg = o->mrg; - GeglNode *iter; - mrg_set_edge_top (mrg, mrg_height (mrg) * 0.2); - iter = o->sink; - while (iter) - { - char *opname = NULL; - g_object_get (iter, "operation", &opname, NULL); - if (iter == o->active) - mrg_printf (mrg, "[%s]", opname); - else - mrg_printf (mrg, "%s", opname); - mrg_printf (mrg, "\n"); - - g_free (opname); - iter = gegl_node_get_producer (iter, "input", NULL); - } -} - -static void ui_actions (State *o) -{ - Mrg *mrg = o->mrg; - int i; - cairo_t *cr = mrg_cr (mrg); - mrg_set_edge_left (mrg, mrg_width (mrg) * 0.25); - mrg_set_edge_top (mrg, mrg_height (mrg) * 0.1); - mrg_set_font_size (mrg, mrg_height (mrg) * 0.08); - - for (i = 0; actions[i].label; i ++) - { - mrg_text_listen (mrg, MRG_PRESS, activate_op_cb, o, &actions[i]); - if (locate_node (o, actions[i].op_name)) - mrg_printf (mrg, "-"); - mrg_printf (mrg, "%s\n", actions[i].label); - mrg_text_listen_done (mrg); - } - - mrg_print (mrg, "\n"); - mrg_printf (mrg, "existing\n"); - mrg_text_listen (mrg, MRG_PRESS, discard_cb, o, NULL); - mrg_printf (mrg, "discard\n"); - mrg_text_listen_done (mrg); - cairo_scale (cr, mrg_width(mrg), mrg_height(mrg)); - cairo_new_path (cr); - cairo_arc (cr, 0.9, 0.1, 0.1, 0.0, G_PI * 2); - mrg_listen (mrg, MRG_PRESS, toggle_actions_cb, o, NULL); - contrasty_stroke (cr); -} - -static void ui_viewer (State *o) -{ - Mrg *mrg = o->mrg; - cairo_t *cr = mrg_cr (mrg); - cairo_rectangle (cr, 0,0, mrg_width(mrg), mrg_height(mrg)); - mrg_listen (mrg, MRG_DRAG, on_pan_drag, o, NULL); - cairo_new_path (cr); - cairo_scale (cr, mrg_width(mrg), mrg_height(mrg)); - cairo_move_to (cr, 0.2, 0.8); - cairo_line_to (cr, 0.2, 1.0); - cairo_line_to (cr, 0.0, 0.9); - cairo_close_path (cr); - mrg_listen (mrg, MRG_PRESS, go_prev_cb, o, NULL); - if (o->show_controls) - contrasty_stroke (cr); - else - cairo_new_path (cr); - - cairo_move_to (cr, 0.8, 0.8); - cairo_line_to (cr, 0.8, 1.0); - cairo_line_to (cr, 1.0, 0.9); - cairo_close_path (cr); - - mrg_listen (mrg, MRG_PRESS, go_next_cb, o, NULL); - if (o->show_controls) - contrasty_stroke (cr); - else - cairo_new_path (cr); - - cairo_arc (cr, 0.9, 0.1, 0.1, 0.0, G_PI * 2); - mrg_listen (mrg, MRG_PRESS, toggle_actions_cb, o, NULL); - - if (o->show_controls) - contrasty_stroke (cr); - else - cairo_new_path (cr); -} - -static void toggle_show_controls_cb (MrgEvent *event, void *data1, void *data2) -{ - State *o = data1; - o->show_controls = !o->show_controls; - mrg_queue_draw (o->mrg, NULL); -} - -static void gegl_ui (Mrg *mrg, void *data) -{ - State *o = data; - mrg_gegl_blit (mrg, - 0, 0, - mrg_width (mrg), mrg_height (mrg), - o->sink, - o->u, o->v, - o->scale, - o->render_quality); - - if (o->show_controls) - { - mrg_printf (mrg, "%s\n", o->path); -#if DEBUG_OP_LIST - ui_debug_op_chain (o); -#endif - } - - if (o->show_actions) - { - ui_actions (o); - mrg_add_binding (mrg, "return", NULL, NULL, toggle_actions_cb, o); - } - else if (o->active) - { - ui_active_op (o); - mrg_add_binding (mrg, "return", NULL, NULL, apply_filter_cb, o); - mrg_add_binding (mrg, "escape", NULL, NULL, disable_filter_cb, o); - } - else - { - ui_viewer (o); - mrg_add_binding (mrg, "return", NULL, NULL, toggle_actions_cb, o); - } - - mrg_add_binding (mrg, "left", NULL, NULL, pan_left_cb, o); - mrg_add_binding (mrg, "right", NULL, NULL, pan_right_cb, o); - mrg_add_binding (mrg, "up", NULL, NULL, pan_up_cb, o); - mrg_add_binding (mrg, "down", NULL, NULL, pan_down_cb, o); - mrg_add_binding (mrg, "+", NULL, NULL, zoom_in_cb, o); - mrg_add_binding (mrg, "=", NULL, NULL, zoom_in_cb, o); - mrg_add_binding (mrg, "-", NULL, NULL, zoom_out_cb, o); - mrg_add_binding (mrg, "1", NULL, NULL, zoom_1_cb, o); - mrg_add_binding (mrg, "m", NULL, NULL, zoom_fit_cb, o); - - mrg_add_binding (mrg, "control-q", NULL, NULL, mrg_quit_cb, o); - mrg_add_binding (mrg, "m", NULL, NULL, zoom_fit_cb, o); - mrg_add_binding (mrg, "q", NULL, NULL, mrg_quit_cb, o); - mrg_add_binding (mrg, "x", NULL, NULL, discard_cb, o); - mrg_add_binding (mrg, "f", NULL, NULL, toggle_fullscreen_cb, o); - mrg_add_binding (mrg, "F11", NULL, NULL, toggle_fullscreen_cb, o); - mrg_add_binding (mrg, "tab", NULL, NULL, toggle_show_controls_cb, o); - mrg_add_binding (mrg, "space", NULL, NULL, go_next_cb , o); - mrg_add_binding (mrg, "n", NULL, NULL, go_next_cb, o); - mrg_add_binding (mrg, "p", NULL, NULL, go_prev_cb, o); - mrg_add_binding (mrg, "backspace", NULL, NULL, go_prev_cb, o); - - mrg_add_binding (mrg, ",", NULL, NULL, preview_less_cb, o); - mrg_add_binding (mrg, ".", NULL, NULL, preview_more_cb, o); -} - -/***********************************************/ - -static char *suffix_path (const char *path) -{ - char *ret, *last_dot; - - if (!path) - return NULL; - ret = malloc (strlen (path) + strlen (suffix) + 3); - strcpy (ret, path); - last_dot = strrchr (ret, '.'); - if (last_dot) - { - char *extension = strdup (last_dot + 1); - sprintf (last_dot, "%s.%s", suffix, extension); - free (extension); - } - else - { - sprintf (ret, "%s%s", path, suffix); - } - return ret; -} - -static char *unsuffix_path (const char *path) -{ - char *ret = NULL, *last_dot, *extension; - char *suf; - - if (!path) - return NULL; - ret = malloc (strlen (path) + 4); - strcpy (ret, path); - last_dot = strrchr (ret, '.'); - extension = strdup (last_dot + 1); - - suf = strstr(ret, suffix); - sprintf (suf, ".%s", extension); - free (extension); - return ret; -} - -static int is_giev_path (const char *path) -{ - if (strstr (path, suffix)) return 1; - return 0; -} - -static void contrasty_stroke (cairo_t *cr) -{ - double x0 = 6.0, y0 = 6.0; - double x1 = 4.0, y1 = 4.0; - - cairo_device_to_user_distance (cr, &x0, &y0); - cairo_device_to_user_distance (cr, &x1, &y1); - cairo_set_source_rgba (cr, 0,0,0,0.5); - cairo_set_line_width (cr, y0); - cairo_stroke_preserve (cr); - cairo_set_source_rgba (cr, 1,1,1,0.5); - cairo_set_line_width (cr, y1); - cairo_stroke (cr); -} - -static unsigned char *copy_buf = NULL; -static int copy_buf_len = 0; - -static void mrg_gegl_blit (Mrg *mrg, - float x0, float y0, - float width, float height, - GeglNode *node, - float u, float v, - float scale, - float preview_multiplier) -{ - float fake_factor = preview_multiplier; - GeglRectangle bounds; - - cairo_t *cr = mrg_cr (mrg); - cairo_surface_t *surface = NULL; - - if (!node) - return; - - bounds = gegl_node_get_bounding_box (node); - - if (width == -1 && height == -1) - { - width = bounds.width; - height = bounds.height; - } - - if (width == -1) - width = bounds.width * height / bounds.height; - if (height == -1) - height = bounds.height * width / bounds.width; - - width /= fake_factor; - height /= fake_factor; - u /= fake_factor; - v /= fake_factor; - - if (copy_buf_len < width * height * 4) - { - if (copy_buf) - free (copy_buf); - copy_buf_len = width * height * 4; - copy_buf = malloc (copy_buf_len); - } - { - static int foo = 0; - unsigned char *buf = copy_buf; - GeglRectangle roi = {u, v, width, height}; - static const Babl *fmt = NULL; - -foo++; - if (!fmt) fmt = babl_format ("cairo-RGB24"); - gegl_node_blit (node, scale / fake_factor, &roi, fmt, buf, width * 4, - GEGL_BLIT_DEFAULT); - surface = cairo_image_surface_create_for_data (buf, CAIRO_FORMAT_RGB24, width, height, width * 4); - } - - cairo_save (cr); - cairo_surface_set_device_scale (surface, 1.0/fake_factor, 1.0/fake_factor); - - width *= fake_factor; - height *= fake_factor; - u *= fake_factor; - v *= fake_factor; - - cairo_rectangle (cr, x0, y0, width, height); - - cairo_clip (cr); - cairo_translate (cr, x0 * fake_factor, y0 * fake_factor); - cairo_pattern_set_filter (cairo_get_source (cr), CAIRO_FILTER_NEAREST); - cairo_set_source_surface (cr, surface, 0, 0); - - cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); - cairo_paint (cr); - cairo_surface_destroy (surface); - cairo_restore (cr); -} - -static void load_path (State *o) -{ - char *path; - char *meta; - if (is_giev_path (o->path)) - { - if (o->giev_path) - free (o->giev_path); - o->giev_path = o->path; - o->path = unsuffix_path (o->giev_path); - } - else - { - if (o->giev_path) - free (o->giev_path); - o->giev_path = suffix_path (o->path); - } - path = o->path; - - if (access (o->giev_path, F_OK) != -1) - path = o->giev_path; - - g_object_unref (o->gegl); - o->gegl = NULL; - - meta = gegl_meta_get (path); - if (meta) - { - GSList *nodes, *n; - o->gegl = gegl_node_new_from_xml (meta, NULL); - o->sink = gegl_node_new_child (o->gegl, - "operation", "gegl:nop", NULL); - o->source = NULL; - gegl_node_link_many ( - gegl_node_get_producer (o->gegl, "input", NULL), o->sink, NULL); - nodes = gegl_node_get_children (o->gegl); - for (n = nodes; n; n=n->next) - { - const char *op_name = gegl_node_get_operation (n->data); - if (!strcmp (op_name, "gegl:load")) - { - GeglNode *load; - gchar *path; - gegl_node_get (n->data, "path", &path, NULL); - load_into_buffer (o, path); - gegl_node_set (n->data, "operation", "gegl:nop", NULL); - o->source = n->data; - load = gegl_node_new_child (o->gegl, "operation", "gegl:buffer-source", - "buffer", o->buffer, NULL); - gegl_node_link_many (load, o->source, NULL); - g_free (path); - break; - } - } - o->save = gegl_node_new_child (o->gegl, - "operation", "gegl:save", - "path", path, - NULL); - } - else - { - o->gegl = gegl_node_new (); - o->sink = gegl_node_new_child (o->gegl, - "operation", "gegl:nop", NULL); - o->source = gegl_node_new_child (o->gegl, - "operation", "gegl:nop", NULL); - load_into_buffer (o, path); - o->load = gegl_node_new_child (o->gegl, - "operation", "gegl:buffer-source", - NULL); - o->save = gegl_node_new_child (o->gegl, - "operation", "gegl:save", - "path", o->giev_path, - NULL); - gegl_node_link_many (o->load, o->source, o->sink, NULL); - gegl_node_set (o->load, "buffer", o->buffer, NULL); - } - zoom_to_fit (o); - - mrg_queue_draw (o->mrg, NULL); - o->rev = 0; -} - - -static void go_next (State *o) -{ - char *lastslash = strrchr (o->path, '/'); - if (lastslash) - { - struct dirent **namelist; - int n; - - if (lastslash == o->path) - lastslash[1] = '\0'; - else - lastslash[0] = '\0'; - - n = scandir (o->path, &namelist, NULL, alphasort); - if (n) - { - int i; - int done = 0; - for (i = 0; i < n; i ++) - { - if (!done && !strcmp (namelist[i]->d_name, lastslash+1) && i + 1 < n) - { - char *tmp = malloc (strlen (o->path) + 2 + strlen (namelist[i+1]->d_name)); - sprintf (tmp, "%s/%s", o->path, namelist[i+1]->d_name); - free (o->path); - o->path = tmp; - load_path (o); - done = 1; - } - free (namelist[i]); - } - free (namelist); - - if (!done) - lastslash[0] = '/'; - } - mrg_queue_draw (o->mrg, NULL); - } -} - -static void go_prev (State *o) -{ - char *lastslash; - if (access (o->giev_path, F_OK) != -1) - { - /* we need to skip from the -giev one, when walking the dir alphabetically backwards */ - char *tmp = o->path; - o->path = o->giev_path; - o->giev_path = tmp; - } - lastslash = strrchr (o->path, '/'); - if (lastslash) - { - struct dirent **namelist; - int n; - - if (lastslash == o->path) - lastslash[1] = '\0'; - else - lastslash[0] = '\0'; - - n = scandir (o->path, &namelist, NULL, alphasort); - if (n) - { - int i; - int done = 0; - for (i = 0; i < n; i ++) - { - if (!done && i > 0 && - (namelist[i]->d_name[0] != '.') && - (namelist[i-1]->d_name[0] != '.') && - !strcmp (namelist[i]->d_name, lastslash+1)) - { - char *tmp = malloc (strlen (o->path) + 2 + strlen (namelist[i-1]->d_name)); - sprintf (tmp, "%s/%s", o->path, namelist[i-1]->d_name); - free (o->path); - o->path = tmp; - load_path (o); - done = 1; - } - } - for (i = 0; i < n; i ++) - free (namelist[i]); - free (namelist); - if (!done) - lastslash[0] = '/'; - } - } -} - -static void go_next_cb (MrgEvent *event, void *data1, void *data2) -{ - State *o = data1; - if (o->rev) - save_cb (event, data1, data2); - go_next (data1); - o->active = NULL; - mrg_event_stop_propagate (event); -} - -static void go_prev_cb (MrgEvent *event, void *data1, void *data2) -{ - State *o = data1; - if (o->rev) - save_cb (event, data1, data2); - go_prev (data1); - o->active = NULL; - mrg_event_stop_propagate (event); -} - -static void leave_editor (State *o) -{ - char *opname = NULL; - g_object_get (o->active, "operation", &opname, NULL); - if (!strcmp (opname, "gegl:crop")) - { - zoom_to_fit (o); - } -} - -static void drag_preview (MrgEvent *e) -{ - State *o = hack_state; - static float old_factor = 1; - switch (e->type) - { - case MRG_DRAG_PRESS: - old_factor = o->render_quality; - if (o->render_quality < o->preview_quality) - o->render_quality = o->preview_quality; - break; - case MRG_DRAG_RELEASE: - o->render_quality = old_factor; - mrg_queue_draw (e->mrg, NULL); - break; - default: - break; - } -} - -static void load_into_buffer (State *o, const char *path) -{ - GeglNode *gegl, *load, *sink; - GeglBuffer *tempbuf; - - if (o->buffer) - { - g_object_unref (o->buffer); - o->buffer = NULL; - } - - gegl = gegl_node_new (); - load = gegl_node_new_child (gegl, "operation", "gegl:load", - "path", path, - NULL); - sink = gegl_node_new_child (gegl, "operation", "gegl:buffer-sink", - "buffer", &(o->buffer), - NULL); - gegl_node_link_many (load, sink, NULL); - gegl_node_process (sink); - g_object_unref (gegl); - - tempbuf = gegl_buffer_new (gegl_buffer_get_extent (o->buffer), - babl_format ("RGBA float")); - - gegl_buffer_copy (o->buffer, NULL, GEGL_ABYSS_NONE, tempbuf, NULL); - g_object_unref (o->buffer); - o->buffer = tempbuf; -} - -static GeglNode *locate_node (State *o, const char *op_name) -{ - GeglNode *iter = o->sink; - while (iter) - { - char *opname = NULL; - g_object_get (iter, "operation", &opname, NULL); - if (!strcmp (opname, op_name)) - return iter; - g_free (opname); - iter = gegl_node_get_producer (iter, "input", NULL); - } - return NULL; -} -static void zoom_to_fit (State *o) -{ - Mrg *mrg = o->mrg; - GeglRectangle rect = gegl_node_get_bounding_box (o->sink); - float scale, scale2; - - scale = 1.0 * mrg_width (mrg) / rect.width; - scale2 = 1.0 * mrg_height (mrg) / rect.height; - - if (scale2 < scale) scale = scale2; - - o->scale = scale; - - o->u = -(mrg_width (mrg) - rect.width * scale) / 2; - o->v = -(mrg_height (mrg) - rect.height * scale) / 2; - - o->u += rect.x * scale; - o->v += rect.y * scale; - - mrg_queue_draw (mrg, NULL); -} - -static void zoom_to_fit_buffer (State *o) -{ - Mrg *mrg = o->mrg; - GeglRectangle rect = *gegl_buffer_get_extent (o->buffer); - float scale, scale2; - - scale = 1.0 * mrg_width (mrg) / rect.width; - scale2 = 1.0 * mrg_height (mrg) / rect.height; - - if (scale2 < scale) scale = scale2; - - o->scale = scale; - o->u = -(mrg_width (mrg) - rect.width * scale) / 2; - o->v = -(mrg_height (mrg) - rect.height * scale) / 2; - o->u += rect.x * scale; - o->v += rect.y * scale; - mrg_queue_draw (mrg, NULL); -} - -static void zoom_fit_cb (MrgEvent *e, void *data1, void *data2) -{ - zoom_to_fit (data1); -} - -static int deferred_zoom_to_fit (Mrg *mrg, void *data) -{ - zoom_to_fit (data); - return 0; -} - -static void pan_left_cb (MrgEvent *event, void *data1, void *data2) -{ - State *o = data1; - float amount = mrg_width (event->mrg) * 0.1; - o->u = o->u - amount; - mrg_queue_draw (o->mrg, NULL); -} - -static void pan_right_cb (MrgEvent *event, void *data1, void *data2) -{ - State *o = data1; - float amount = mrg_width (event->mrg) * 0.1; - o->u = o->u + amount; - mrg_queue_draw (o->mrg, NULL); -} - -static void pan_down_cb (MrgEvent *event, void *data1, void *data2) -{ - State *o = data1; - float amount = mrg_width (event->mrg) * 0.1; - o->v = o->v + amount; - mrg_queue_draw (o->mrg, NULL); -} - -static void pan_up_cb (MrgEvent *event, void *data1, void *data2) -{ - State *o = data1; - float amount = mrg_width (event->mrg) * 0.1; - o->v = o->v - amount; - mrg_queue_draw (o->mrg, NULL); -} - -static void get_coords (State *o, float screen_x, float screen_y, float *gegl_x, float *gegl_y) -{ - float scale = o->scale; - *gegl_x = (o->u + screen_x) / scale; - *gegl_y = (o->v + screen_y) / scale; -} - -static void preview_more_cb (MrgEvent *event, void *data1, void *data2) -{ - State *o = data1; - o->render_quality *= 2; - mrg_queue_draw (o->mrg, NULL); -} - -static void preview_less_cb (MrgEvent *event, void *data1, void *data2) -{ - State *o = data1; - o->render_quality /= 2; - if (o->render_quality <= 1.0) - o->render_quality = 1.0; - mrg_queue_draw (o->mrg, NULL); -} - -static void zoom_1_cb (MrgEvent *event, void *data1, void *data2) -{ - State *o = data1; - float x, y; - get_coords (o, mrg_width(o->mrg)/2, mrg_height(o->mrg)/2, &x, &y); - o->scale = 1.0; - o->u = x * o->scale - mrg_width(o->mrg)/2; - o->v = y * o->scale - mrg_height(o->mrg)/2; - mrg_queue_draw (o->mrg, NULL); -} - -static void zoom_in_cb (MrgEvent *event, void *data1, void *data2) -{ - State *o = data1; - float x, y; - get_coords (o, mrg_width(o->mrg)/2, mrg_height(o->mrg)/2, &x, &y); - o->scale = o->scale * 1.1; - o->u = x * o->scale - mrg_width(o->mrg)/2; - o->v = y * o->scale - mrg_height(o->mrg)/2; - mrg_queue_draw (o->mrg, NULL); -} - -static void zoom_out_cb (MrgEvent *event, void *data1, void *data2) -{ - State *o = data1; - float x, y; - get_coords (o, mrg_width(o->mrg)/2, mrg_height(o->mrg)/2, &x, &y); - o->scale = o->scale / 1.1; - o->u = x * o->scale - mrg_width(o->mrg)/2; - o->v = y * o->scale - mrg_height(o->mrg)/2; - mrg_queue_draw (o->mrg, NULL); -} - -static void toggle_actions_cb (MrgEvent *event, void *data1, void *data2) -{ - State *o = data1; - o->show_actions = !o->show_actions; - mrg_queue_draw (o->mrg, NULL); -} - -static void toggle_fullscreen_cb (MrgEvent *event, void *data1, void *data2) -{ - State *o = data1; - mrg_set_fullscreen (event->mrg, !mrg_is_fullscreen (event->mrg)); - mrg_event_stop_propagate (event); - mrg_add_timeout (event->mrg, 250, deferred_zoom_to_fit, o); -} - - -static void activate_op_cb (MrgEvent *event, void *data1, void *data2) -{ - State *o = data1; - GeglNode *found; - ActionData *ad = data2; - o->show_actions = 0; - o->rev ++; - found = locate_node (o, ad->op_name); - if (found) - { - o->active = found; - if (!strcmp (ad->op_name, "gegl:crop")) - o->rotate = locate_node (o, "gegl:rotate"); - } - else - { - if (!strcmp (ad->op_name, "gegl:rotate")) - { - const GeglRectangle *extent = gegl_buffer_get_extent (o->buffer); - o->active = gegl_node_new_child (o->gegl, - "operation", ad->op_name, NULL); - gegl_node_set (o->active, "origin-x", extent->width * 0.5, - "origin-y", extent->height * 0.5, - "degrees", 0.0, - NULL); - } else if (!strcmp (ad->op_name, "gegl:crop")) - { - const GeglRectangle *extent = gegl_buffer_get_extent (o->buffer); - o->active = gegl_node_new_child (o->gegl, - "operation", ad->op_name, NULL); - gegl_node_set (o->active, "x", 0.0, - "y", 0.0, - "width", extent->width * 1.0, - "height", extent->height * 1.0, - NULL); - o->rotate = gegl_node_new_child (o->gegl, - "operation", "gegl:rotate", NULL); - gegl_node_set (o->rotate, "origin-x", extent->width * 0.5, - "origin-y", extent->height * 0.5, - "degrees", 0.0, - NULL); - - gegl_node_link_many (gegl_node_get_producer (o->sink, "input", NULL), - o->rotate, - o->sink, - NULL); - - } else - { - o->active = gegl_node_new_child (o->gegl, "operation", ad->op_name, NULL); - } - - gegl_node_link_many (gegl_node_get_producer (o->sink, "input", NULL), - o->active, - o->sink, - NULL); - } - mrg_queue_draw (o->mrg, NULL); -} - -static void disable_filter_cb (MrgEvent *event, void *data1, void *data2) -{ - State *o = data1; - GeglNode *iter = o->sink; - GeglNode *prev = NULL; - GeglNode *next = NULL; - while (iter) - { - prev = iter; - iter = gegl_node_get_producer (iter, "input", NULL); - if (o->active == iter) - { - next = gegl_node_get_producer (iter, "input", NULL); - break; - } - } - gegl_node_link_many (next, prev, NULL); - leave_editor (o); - gegl_node_remove_child (o->gegl, o->active); - o->active = NULL; - mrg_queue_draw (o->mrg, NULL); -} - -static void apply_filter_cb (MrgEvent *event, void *data1, void *data2) -{ - State *o = data1; - leave_editor (o); - o->active = NULL; - mrg_queue_draw (o->mrg, NULL); -} - -static void discard_cb (MrgEvent *event, void *data1, void *data2) -{ - State *o = data1; - char *old_path = strdup (o->path); - char *tmp; - char *lastslash; - go_next_cb (event, data1, data2); - if (!strcmp (old_path, o->path)) - { - go_prev_cb (event, data1, data2); - } - tmp = strdup (old_path); - lastslash = strrchr (tmp, '/'); - if (lastslash) - { - char command[2048]; - if (lastslash == tmp) - lastslash[1] = '\0'; - else - lastslash[0] = '\0'; - - sprintf (command, "mkdir %s/.discard > /dev/null 2>&1", tmp); - system (command); - sprintf (command, "mv %s %s/.discard", old_path, tmp); - system (command); - } - free (tmp); - free (old_path); -} - -static void save_cb (MrgEvent *event, void *data1, void *data2) -{ - GeglNode *load; - State *o = data1; - gchar *path; - char *xml; - - gegl_node_link_many (o->sink, o->save, NULL); - gegl_node_process (o->save); - gegl_node_get (o->save, "path", &path, NULL); - fprintf (stderr, "saved to %s\n", path); - - load = gegl_node_new_child (o->gegl, "operation", "gegl:load", - "path", o->path, - NULL); - gegl_node_link_many (load, o->source, NULL); - xml = gegl_node_to_xml (o->sink, NULL); - gegl_node_remove_child (o->gegl, load); - gegl_node_link_many (o->load, o->source, NULL); - gegl_meta_set (path, xml); - g_free (xml); - o->rev = 0; -} - -#if 0 -void gegl_node_defaults (GeglNode *node) -{ - const gchar* op_name = gegl_node_get_operation (node); - { - guint n_props; - GParamSpec **pspecs = gegl_operation_list_properties (op_name, &n_props); - if (pspecs) - { - for (gint i = 0; i < n_props; i++) - { - if (g_type_is_a (pspecs[i]->value_type, G_TYPE_DOUBLE)) - { - GParamSpecDouble *pspec = (void*)pspecs[i]; - gegl_node_set (node, pspecs[i]->name, pspec->default_value, NULL); - } - else if (g_type_is_a (pspecs[i]->value_type, G_TYPE_INT)) - { - GParamSpecInt *pspec = (void*)pspecs[i]; - gegl_node_set (node, pspecs[i]->name, pspec->default_value, NULL); - } - else if (g_type_is_a (pspecs[i]->value_type, G_TYPE_STRING)) - { - GParamSpecString *pspec = (void*)pspecs[i]; - gegl_node_set (node, pspecs[i]->name, pspec->default_value, NULL); - } - } - g_free (pspecs); - } - } -} -#endif - -/* loads the source image corresponding to o->path into o->buffer and - * creates live gegl pipeline, or nops.. rigs up o->giev_path to be - * the location where default saves ends up. - */ -void -gegl_meta_set (const char *path, - const char *meta_data) -{ - GError *error = NULL; - GExiv2Metadata *e2m = gexiv2_metadata_new (); - gexiv2_metadata_open_path (e2m, path, &error); - if (error) - { - g_warning ("%s", error->message); - } - else - { - if (gexiv2_metadata_has_tag (e2m, "Xmp.xmp.GEGL")) - gexiv2_metadata_clear_tag (e2m, "Xmp.xmp.GEGL"); - - gexiv2_metadata_set_tag_string (e2m, "Xmp.xmp.GEGL", meta_data); - gexiv2_metadata_save_file (e2m, path, &error); - if (error) - g_warning ("%s", error->message); - } - gexiv2_metadata_free (e2m); -} - -char * -gegl_meta_get (const char *path) -{ - gchar *ret = NULL; - GError *error = NULL; - GExiv2Metadata *e2m = gexiv2_metadata_new (); - gexiv2_metadata_open_path (e2m, path, &error); - if (error) - g_warning ("%s", error->message); - else - ret = gexiv2_metadata_get_tag_string (e2m, "Xmp.xmp.GEGL"); - gexiv2_metadata_free (e2m); - return ret; -} - -#endif diff --git a/configure.ac b/configure.ac index 949ecaba..ae31682a 100644 --- a/configure.ac +++ b/configure.ac @@ -646,46 +646,6 @@ AM_CONDITIONAL(HAVE_DOT, test "x$have_dot" = "xyes") AM_PATH_PYTHON([2.5.0],, [:]) AM_CONDITIONAL([HAVE_PYTHON], [test "$PYTHON" != :]) -############### -# Check for mrg -############### - -AC_ARG_WITH(mrg, [ --without-mrg build without mrg support]) - -have_mrg="no" -if test "x$with_mrg" != "xno"; then - PKG_CHECK_MODULES(MRG, mrg, - AC_DEFINE(HAVE_MRG, 1, - [Define to 1 if the mrg library is available]) - have_mrg="yes", - have_mrg="no (mrg not found)") -fi - -AM_CONDITIONAL(HAVE_MRG, test "$have_mrg" = "yes") - -AC_SUBST(MRG_CFLAGS) -AC_SUBST(MRG_LIBS) - -################## -# Check for gexiv2 -################## - -AC_ARG_WITH(gexiv2, [ --without-gexiv2 build without gexiv2 support]) - -have_gexiv2="no" -if test "x$with_gexiv2" != "xno"; then - PKG_CHECK_MODULES(GEXIV2, gexiv2, - AC_DEFINE(HAVE_GEXIV2, 1, - [Define to 1 if the gexiv2 library is available]) - have_gexiv2="yes", - have_gexiv2="no (gexiv2 not found)") -fi - -AM_CONDITIONAL(HAVE_GEXIV2, test "$have_gexiv2" = "yes") - -AC_SUBST(GEXIV2_CFLAGS) -AC_SUBST(GEXIV2_LIBS) - ################# # Check for Cairo ################# @@ -1324,7 +1284,6 @@ Optional features: Optional dependencies: asciidoc: $have_asciidoc enscript: $have_enscript - mrg: $have_mrg Ruby: $have_ruby Lua: $have_lua Cairo: $have_cairo @@ -1344,7 +1303,6 @@ Optional dependencies: V4L2: $have_libv4l2 spiro: $spiro_ok EXIV: $have_exiv2 - gexiv2: $have_gexiv2 umfpack: $have_umfpack webp: $have_webp poly2tri-c: $have_p2tc |