/* * Copyright 2012, Red Hat, Inc. * Copyright 2012, Soren Sandmann * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * * Author: Soren Sandmann */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include "gtk-utils.h" typedef struct { GtkBuilder * builder; pixman_image_t * original; GtkAdjustment * scale_x_adjustment; GtkAdjustment * scale_y_adjustment; GtkAdjustment * rotate_adjustment; GtkAdjustment * subsample_adjustment; int scaled_width; int scaled_height; } app_t; static GtkWidget * get_widget (app_t *app, const char *name) { GtkWidget *widget = GTK_WIDGET (gtk_builder_get_object (app->builder, name)); if (!widget) g_error ("Widget %s not found\n", name); return widget; } static double min4 (double a, double b, double c, double d) { double m1, m2; m1 = MIN (a, b); m2 = MIN (c, d); return MIN (m1, m2); } static double max4 (double a, double b, double c, double d) { double m1, m2; m1 = MAX (a, b); m2 = MAX (c, d); return MAX (m1, m2); } static void compute_extents (pixman_f_transform_t *trans, double *sx, double *sy) { double min_x, max_x, min_y, max_y; pixman_f_vector_t v[4] = { { { 1, 1, 1 } }, { { -1, 1, 1 } }, { { -1, -1, 1 } }, { { 1, -1, 1 } }, }; pixman_f_transform_point (trans, &v[0]); pixman_f_transform_point (trans, &v[1]); pixman_f_transform_point (trans, &v[2]); pixman_f_transform_point (trans, &v[3]); min_x = min4 (v[0].v[0], v[1].v[0], v[2].v[0], v[3].v[0]); max_x = max4 (v[0].v[0], v[1].v[0], v[2].v[0], v[3].v[0]); min_y = min4 (v[0].v[1], v[1].v[1], v[2].v[1], v[3].v[1]); max_y = max4 (v[0].v[1], v[1].v[1], v[2].v[1], v[3].v[1]); *sx = (max_x - min_x) / 2.0; *sy = (max_y - min_y) / 2.0; } typedef struct { char name [20]; int value; } named_int_t; static const named_int_t filters[] = { { "Box", PIXMAN_KERNEL_BOX }, { "Impulse", PIXMAN_KERNEL_IMPULSE }, { "Linear", PIXMAN_KERNEL_LINEAR }, { "Cubic", PIXMAN_KERNEL_CUBIC }, { "Lanczos2", PIXMAN_KERNEL_LANCZOS2 }, { "Lanczos3", PIXMAN_KERNEL_LANCZOS3 }, { "Lanczos3 Stretched", PIXMAN_KERNEL_LANCZOS3_STRETCHED }, { "Gaussian", PIXMAN_KERNEL_GAUSSIAN }, }; static const named_int_t repeats[] = { { "None", PIXMAN_REPEAT_NONE }, { "Normal", PIXMAN_REPEAT_NORMAL }, { "Reflect", PIXMAN_REPEAT_REFLECT }, { "Pad", PIXMAN_REPEAT_PAD }, }; static int get_value (app_t *app, const named_int_t table[], const char *box_name) { GtkComboBox *box = GTK_COMBO_BOX (get_widget (app, box_name)); return table[gtk_combo_box_get_active (box)].value; } static void copy_to_counterpart (app_t *app, GObject *object) { static const char *xy_map[] = { "reconstruct_x_combo_box", "reconstruct_y_combo_box", "sample_x_combo_box", "sample_y_combo_box", "scale_x_adjustment", "scale_y_adjustment", }; GObject *counterpart = NULL; int i; for (i = 0; i < G_N_ELEMENTS (xy_map); i += 2) { GObject *x = gtk_builder_get_object (app->builder, xy_map[i]); GObject *y = gtk_builder_get_object (app->builder, xy_map[i + 1]); if (object == x) counterpart = y; if (object == y) counterpart = x; } if (!counterpart) return; if (GTK_IS_COMBO_BOX (counterpart)) { gtk_combo_box_set_active ( GTK_COMBO_BOX (counterpart), gtk_combo_box_get_active ( GTK_COMBO_BOX (object))); } else if (GTK_IS_ADJUSTMENT (counterpart)) { gtk_adjustment_set_value ( GTK_ADJUSTMENT (counterpart), gtk_adjustment_get_value ( GTK_ADJUSTMENT (object))); } } static double to_scale (double v) { return pow (1.15, v); } static void rescale (GtkWidget *may_be_n