aboutsummaryrefslogtreecommitdiffstats
path: root/common.h
blob: 9ae654afc5b10bd9e1c09161d7de123e0a2db74e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
/* See LICENSE file for copyright and license details. */
#ifndef SCROLL_AMOUNT
# define SCROLL_AMOUNT 30
#endif
#ifndef DRAG_ICON_SIZE
# define DRAG_ICON_SIZE 128
#endif
#ifndef PREVIEW_WIDTH
# define PREVIEW_WIDTH 192
#endif
#ifndef PREVIEW_HEIGHT
# define PREVIEW_HEIGHT 256
#endif
#ifndef DEFAULT_CHEQUER_SIZE
# define DEFAULT_CHEQUER_SIZE 16
#endif
#ifndef INITIAL_COLLECTION_PANE_HEIGHT
# define INITIAL_COLLECTION_PANE_HEIGHT 160
#endif
#ifndef INITIAL_PROPERTY_PANE_HEIGHT
# define INITIAL_PROPERTY_PANE_HEIGHT 300
#endif

#if defined(__GNUC__)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
# pragma GCC diagnostic ignored "-Wstrict-prototypes"
#endif
#include <gdk/gdkkeysyms.h>
#include <gexiv2/gexiv2.h>
#include <gtk/gtk.h>
#include <librsvg/rsvg.h>
#include <libsimple.h>
#include <libsimple-arg.h>
#include <math.h>
#if defined(__GNUC__)
# pragma GCC diagnostic pop
#endif

#if defined(__GNUC__)
# pragma GCC diagnostic ignored "-Wunsuffixed-float-constants"
# pragma GCC diagnostic ignored "-Waggregate-return"
# pragma GCC diagnostic ignored "-Wsuggest-attribute=const"
# pragma GCC diagnostic ignored "-Wsuggest-attribute=pure"
#endif

#if defined(__GNUC__)
# define PURE __attribute__((__pure__))
#else
# define PURE
#endif

#include "logical-scroll-pane.h"


#define FLOAT_EQ(A, B) ((A) >= (B) && (A) <= (B))

#define COMMA ,


#define LIST_ORIENTATIONS(X, ...)\
	X(1, TRANS_NONE,          "Normal")               __VA_ARGS__\
	X(2, TRANS_FLOP,          "Flip horizontally")    __VA_ARGS__\
	X(3, TRANS_180_DEGREES,   "Rotate 180°")          __VA_ARGS__\
	X(4, TRANS_FLIP,          "Flip vertically")      __VA_ARGS__\
	X(5, TRANS_TRANSPOSE,     "Transpose")            __VA_ARGS__\
	X(6, TRANS_CLOCKWISE,     "Rotate 90° clockwise") __VA_ARGS__\
	X(7, TRANS_ANTITRANSPOSE, "Antitranspose")        __VA_ARGS__\
	X(8, TRANS_ANTICLOCKWISE, "Rotate 90° counterclockwise")

#define LIST_ZOOM_MODES(X, ...)\
	X(ZOOM_FIT_WIDTH,  width_fit_action,  "width",   "Fit to width",      1, 0, 0, HUGE_VAL) __VA_ARGS__\
	X(ZOOM_FIT_HEIGHT, height_fit_action, "height",  "Fit to height",     0, 1, 0, HUGE_VAL) __VA_ARGS__\
	X(ZOOM_FIT_WINDOW, window_fit_action, "window",  "Fit to window",     1, 1, 0, HUGE_VAL) __VA_ARGS__\
	X(ZOOM_BEST_FIT,   best_fit_action,   "best",    "Best fit",          1, 1, 0, 1.0)      __VA_ARGS__\
	X(ZOOM_STRETCH,    stretch_action,    "stretch", "Stretch to window", 1, 1, 1, HUGE_VAL)


enum toggle_group {
	GROUP_NONE,
	GROUP_ZOOM
};

enum zoom_mode {
	ZOOM_CUSTOM,
#define X(E, ...) E
	LIST_ZOOM_MODES(X, COMMA)
#undef X
};

enum transformation {
	/* NB! different order than in LIST_ORIENTATIONS */
	TRANS_NONE,          /* 1   */
	TRANS_CLOCKWISE,     /* r   */
	TRANS_180_DEGREES,   /* r²  */
	TRANS_ANTICLOCKWISE, /* r³  */
	TRANS_TRANSPOSE,     /* t   */
	TRANS_FLOP,          /* rt  */
	TRANS_ANTITRANSPOSE, /* r²t */
	TRANS_FLIP,          /* r³t */
	/*
	 * t² = r⁴ = 1
	 * trⁿ = r⁻ⁿt
	 */
	TRANS_NEGATIVE = 0x08
};

struct image {
	GdkPixbuf *raster;
	RsvgHandle *vector;
	int width;
	int height;
	int has_x_dpi;
	int has_y_dpi;
	enum transformation embedded_transformation;
	int has_transformer;
	cairo_matrix_t transformer;
	double x_dpi;
	double y_dpi;
};

struct file {
	char *path;
	off_t size;
	struct image image;
	char **exif_tags;
	GExiv2Metadata *exif;
};

typedef struct {
	double s;
	int i;
} Zoom;


/* collection.c */
extern GtkWidget *collection_view;
GtkWidget *create_collection_pane(void);
void set_collection_pane_visible(int visible);
void navigate_collection_drag(void);
void collection_files_changed(void);
void update_collection(void);
void collection_redraw_embedded_orientations(void);

/* dragging.c */
void set_image_drag_icon(GdkDragContext *context, struct image *image);
void set_up_dragging(void);

/* dropping.c */
size_t get_dropped_files(struct file **files_out, char **uris);
void set_up_dropping(void);

/* events.c */
void open_action(GtkAction *action, void *user);
void reload_action(GtkAction *action, void *user);
void print_action(GtkAction *action, void *user);
void properties_action(GtkAction *action, void *user);
void property_pane_action(GtkToggleAction *action, void *user);
void collection_pane_action(GtkToggleAction *action, void *user);
void preferences_action(GtkAction *action, void *user);
void close_action(GtkAction *action, void *user);
void fullscreen_action(GtkToggleAction *action, void *user);
void reset_transformations_action(GtkAction *action, void *user);
void rotate_clockwise_action(GtkAction *action, void *user);
void rotate_180_degrees_action(GtkAction *action, void *user);
void rotate_anticlockwise_action(GtkAction *action, void *user);
void flop_action(GtkAction *action, void *user);
void flip_action(GtkAction *action, void *user);
void transpose_action(GtkAction *action, void *user);
void antitranspose_action(GtkAction *action, void *user);
void invert_action(GtkToggleAction *action, void *user);
void zoom_in_action(GtkAction *action, void *user);
void zoom_out_action(GtkAction *action, void *user);
void normal_size_action(GtkToggleAction *action, void *user);
#define X(E, A, ...) void A(GtkToggleAction *action, void *user)
LIST_ZOOM_MODES(X, ;);
#undef X
void next_action(GtkAction *action, void *user);
void previous_action(GtkAction *action, void *user);
void first_action(GtkAction *action, void *user);
void last_action(GtkAction *action, void *user);
int key_pressed(GtkWidget *widget, GdkEventKey *event, void *user);
int scroll_event(GtkWidget *widget, GdkEventScroll *event, void *user);

/* files.c */
extern struct file *files;
extern size_t nfiles;
extern size_t current_file;
void destroy_file(struct file *file);
void free_files(void);
size_t files_from_array(struct file *selected_files, size_t nselected_files);
size_t files_from_list(struct file **files_out, GSList *selected_files);
int set_files_from_argv(int argc, char **argv);
struct file *get_file(void);
int navigate_without_redraw(size_t jump, size_t move);

/* filters.c */
void add_image_filters(GtkFileChooser *chooser);
void free_image_filters(void);

/* image.c */
extern GdkPixbuf *transformed_raster;
void forget_transformed_raster(void);
int get_image(struct image *image_out);
int get_original_image(struct image *image_out);

/* opening.c */
int load_image(struct file *file, int errors_to_stderr);
GtkFileChooser *construct_chooser(void);

/* printing.c */
void open_print(struct image *image);

/* render.c */
GdkPixbuf *rasterise(RsvgHandle *vector, int width, int height);
void paint_image(cairo_t *cr, struct image *image);

/* preferences.c */
extern cairo_filter_t scaling_filter;
extern GdkColor chequer_colours[2];
extern uint16_t chequer_alphas[2];
extern int chequered_background;
extern int chequer_size;
extern int apply_embedded_orientation;
extern int normal_size_is_physical_size; /* TODO implement */
void open_preferences(void);
int parse_and_set_scaling_filter(const char *s);
int parse_and_set_chequer_size(const char *s);
int parse_and_set_chequer_colours(const char *s);

/* properties.c */
GtkWidget *create_property_table(struct file *file);
void open_properties(struct file *file);

/* transform.c */
extern enum transformation trans;
enum transformation multiply_transformations(enum transformation augment, enum transformation augend);
int apply_transformations(struct image *image, struct image *image_out);
GdkPixbuf *transform_raster(GdkPixbuf *raster, enum transformation transformation);
enum transformation inverse_transformation(enum transformation t);
enum transformation reset_transformations_without_redraw(void);
int add_transformation_without_redraw(enum transformation augment);
int swaps_dimensions(enum transformation t);
void transform_point(enum transformation t, double *x, double *y, double *w, double *h);
int get_affine_matrix(cairo_matrix_t *matrix_out, enum transformation t, int width, int height);
enum transformation orientation_to_transformation(int orientation);

/* ui.c */
extern GtkWidget *window;
extern GtkWidget *display_area;
extern GtkWidget *scroll;
extern GtkToggleAction *fullscreen;
void set_up_ui(void);
void set_actions_sensitive(void);
void clear_toggles(enum toggle_group group, GtkToggleAction *except);
void set_fullscreen_mode(int active);
void set_visible_panes(int property, int collection);
void set_property_pane_visible(int visible);
void set_zoom_mode_toggle(void);
void update_property_pane(void);
int activate_fullscreen(void *user);
int deactivate_fullscreen(void *user);
void set_statusbar_message(const char *message);
void free_ui(void);

/* zoom.c */
extern Zoom zoom;
extern enum zoom_mode zoom_mode;
extern const Zoom normal_zoom;
int zoom_eq(Zoom a, Zoom b);
double get_zoom(Zoom z);
Zoom make_zoom(double s);
Zoom zoom_in(Zoom z);
Zoom zoom_out(Zoom z);
Zoom calculate_zoom_mode(struct image *image, enum zoom_mode mode);
int parse_and_set_zoom_mode(const char *s);

/* gbild.c */
int expose_image(GtkWidget *widget, GdkEventExpose *event, void *user);
void add_images(struct file *new_files, size_t nnew_files);
void set_images_from_array(struct file *selected_files, size_t nselected_files);
void set_images_from_list(GSList *selected_files);
void scroll_by(double horizontally, double vertically);
void set_zoom_around_point(Zoom new_zoom, double x, double y);
void set_zoom_around_centre(Zoom new_zoom);
void set_zoom_and_recentre(Zoom new_zoom);
void reload_redraw(void);
void transform_redraw(enum transformation augment);
void navigate_redraw(void);
int recalculate_zoom_mode(void *user);