Mercurial > geeqie.yaz
annotate src/image.c @ 22:e9625635e162
remove extra newline
author | gqview |
---|---|
date | Sat, 05 Mar 2005 21:40:46 +0000 |
parents | 25335c62cd9b |
children | 17acca639a86 |
rev | line source |
---|---|
1 | 1 /* |
9 | 2 * GQview |
3 * (C) 2004 John Ellis | |
1 | 4 * |
5 * Author: John Ellis | |
6 * | |
9 | 7 * This software is released under the GNU General Public License (GNU GPL). |
8 * Please read the included file COPYING for more information. | |
9 * This software comes with no warranty of any kind, use at your own risk! | |
1 | 10 */ |
11 | |
9 | 12 |
1 | 13 #include "gqview.h" |
14 #include "image.h" | |
9 | 15 |
16 | |
17 #include "image-load.h" | |
18 #include "collect.h" | |
19 #include "exif.h" | |
20 #include "pixbuf_util.h" | |
21 #include "ui_fileops.h" | |
22 | |
23 #include <math.h> | |
24 | |
25 | |
14
25335c62cd9b
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
13
diff
changeset
|
26 /* size to use when breaking up image pane for rendering */ |
12
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
27 #define IMAGE_TILE_SIZE 512 |
14
25335c62cd9b
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
13
diff
changeset
|
28 |
25335c62cd9b
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
13
diff
changeset
|
29 /* default min and max zoom */ |
9 | 30 #define IMAGE_ZOOM_MIN -32.0 |
31 #define IMAGE_ZOOM_MAX 32.0 | |
32 | |
33 /* size of the image loader buffer (512 bytes x defined number) */ | |
34 #define IMAGE_LOAD_BUFFER_COUNT 8 | |
35 | |
36 /* define this so that more bytes are read per idle loop on larger images (> 1MB) */ | |
37 #define IMAGE_THROTTLE_LARGER_IMAGES 1 | |
38 | |
39 /* throttle factor to increase read bytes by (2 is double, 3 is triple, etc.) */ | |
40 #define IMAGE_THROTTLE_FACTOR 4 | |
41 | |
42 /* the file size at which throttling take place */ | |
43 #define IMAGE_THROTTLE_THRESHOLD 1048576 | |
44 | |
45 /* distance to drag mouse to disable image flip */ | |
46 #define IMAGE_DRAG_SCROLL_THRESHHOLD 4 | |
47 | |
14
25335c62cd9b
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
13
diff
changeset
|
48 /* increase pan rate when holding down shift */ |
25335c62cd9b
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
13
diff
changeset
|
49 #define IMAGE_PAN_SHIFT_MULTIPLIER 6 |
25335c62cd9b
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
13
diff
changeset
|
50 |
9 | 51 /* alpha channel checkerboard background (same as gimp) */ |
52 #define IMAGE_ALPHA_CHECK1 0x00999999 | |
53 #define IMAGE_ALPHA_CHECK2 0x00666666 | |
54 #define IMAGE_ALPHA_CHECK_SIZE 16 | |
55 | |
56 #define IMAGE_AUTO_REFRESH_TIME 3000 | |
57 | |
58 /* when scaling image to below this size, use nearest pixel for scaling | |
59 * (below about 4, the other scale types become slow generating their conversion tables) | |
60 */ | |
61 #define IMAGE_MIN_SCALE_SIZE 8 | |
62 | |
63 | |
64 typedef enum { | |
65 TILE_RENDER_NONE = 0, /* do nothing */ | |
66 TILE_RENDER_AREA, /* render an area of the tile */ | |
67 TILE_RENDER_ALL /* render the whole tile */ | |
68 } TileRenderType; | |
69 | |
70 typedef struct _ImageTile ImageTile; | |
71 struct _ImageTile | |
72 { | |
73 GdkPixmap *pixmap; /* off screen buffer */ | |
74 GdkPixbuf *pixbuf; /* pixbuf area for zooming */ | |
75 gint x; /* x offset into image */ | |
76 gint y; /* y offset into image */ | |
77 gint w; /* width that is visible (may be less if at edge of image) */ | |
78 gint h; /* height '' */ | |
79 | |
80 gint blank; | |
81 | |
82 /* render_todo: (explanation) | |
83 NONE do nothing | |
84 AREA render area of tile, usually only used when loading an image | |
85 note: will jump to an ALL if render_done is not ALL. | |
86 ALL render entire tile, if never done before w/ ALL, for expose events *only* | |
87 */ | |
88 | |
89 TileRenderType render_todo; /* what to do (see above) */ | |
90 TileRenderType render_done; /* highest that has been done before on tile */ | |
91 }; | |
92 | |
93 typedef struct _QueueData QueueData; | |
94 struct _QueueData | |
95 { | |
96 ImageTile *it; | |
97 gint x; | |
98 gint y; | |
99 gint w; | |
100 gint h; | |
101 gint new_data; | |
102 }; | |
103 | |
104 typedef struct _CacheData CacheData; | |
105 struct _CacheData | |
106 { | |
107 GdkPixmap *pixmap; | |
108 GdkPixbuf *pixbuf; | |
109 ImageTile *it; | |
110 guint size; | |
111 }; | |
112 | |
113 typedef struct _OverlayData OverlayData; | |
114 struct _OverlayData | |
115 { | |
116 gint id; | |
117 | |
118 GdkPixbuf *pixbuf; | |
119 | |
120 gint x; | |
121 gint y; | |
122 gint relative; /* x,y coordinates are relative, negative values start bottom right */ | |
123 | |
124 gint visible; | |
125 gint always; /* hide temporarily when scrolling */ | |
126 }; | |
127 | |
12
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
128 /* needed to be declared before the source_tile stuff */ |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
129 static void image_pixbuf_sync(ImageWindow *imd, gdouble zoom, gint blank, gint new); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
130 static void image_zoom_sync(ImageWindow *imd, gdouble zoom, |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
131 gint force, gint blank, gint new, |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
132 gint center_point, gint px, gint py); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
133 static void image_queue(ImageWindow *imd, gint x, gint y, gint w, gint h, |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
134 gint clamp, TileRenderType render, gint new_data); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
135 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
136 static gint util_clip_region(gint x, gint y, gint w, gint h, |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
137 gint clip_x, gint clip_y, gint clip_w, gint clip_h, |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
138 gint *rx, gint *ry, gint *rw, gint *rh); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
139 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
140 /* |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
141 *------------------------------------------------------------------- |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
142 * source tiles |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
143 *------------------------------------------------------------------- |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
144 */ |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
145 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
146 typedef struct _SourceTile SourceTile; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
147 struct _SourceTile |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
148 { |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
149 gint x; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
150 gint y; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
151 GdkPixbuf *pixbuf; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
152 gint blank; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
153 }; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
154 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
155 static void source_tile_free(SourceTile *st) |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
156 { |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
157 if (!st) return; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
158 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
159 if (st->pixbuf) gdk_pixbuf_unref(st->pixbuf); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
160 g_free(st); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
161 } |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
162 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
163 static void source_tile_free_all(ImageWindow *imd) |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
164 { |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
165 GList *work; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
166 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
167 work = imd->source_tiles; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
168 while (work) |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
169 { |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
170 SourceTile *st = work->data; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
171 work = work->next; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
172 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
173 source_tile_free(st); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
174 } |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
175 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
176 g_list_free(imd->source_tiles); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
177 imd->source_tiles = NULL; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
178 } |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
179 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
180 static gint source_tile_visible(ImageWindow *imd, SourceTile *st) |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
181 { |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
182 gint x, y, w, h; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
183 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
184 if (!st) return FALSE; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
185 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
186 x = (imd->x_scroll / IMAGE_TILE_SIZE) * IMAGE_TILE_SIZE; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
187 y = (imd->y_scroll / IMAGE_TILE_SIZE) * IMAGE_TILE_SIZE; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
188 w = ((imd->x_scroll + imd->vis_width) / IMAGE_TILE_SIZE) * IMAGE_TILE_SIZE + IMAGE_TILE_SIZE; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
189 h = ((imd->y_scroll + imd->vis_height) / IMAGE_TILE_SIZE) * IMAGE_TILE_SIZE + IMAGE_TILE_SIZE; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
190 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
191 return !((double)st->x * imd->scale < (double)x || |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
192 (double)(st->x + imd->source_tile_width) * imd->scale > (double)w || |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
193 (double)st->y * imd->scale < (double)y || |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
194 (double)(st->y + imd->source_tile_height) * imd->scale > (double)h); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
195 } |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
196 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
197 static SourceTile *source_tile_new(ImageWindow *imd, gint x, gint y) |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
198 { |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
199 SourceTile *st = NULL; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
200 gint count; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
201 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
202 if (imd->source_tiles_cache_size < 4) imd->source_tiles_cache_size = 4; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
203 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
204 if (imd->source_tile_width < 1 || imd->source_tile_height < 1) |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
205 { |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
206 printf("warning: source tile size too small %d x %d\n", imd->source_tile_width, imd->source_tile_height); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
207 return NULL; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
208 } |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
209 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
210 count = g_list_length(imd->source_tiles); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
211 if (count >= imd->source_tiles_cache_size) |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
212 { |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
213 GList *work; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
214 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
215 work = g_list_last(imd->source_tiles); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
216 while (work && count >= imd->source_tiles_cache_size) |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
217 { |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
218 SourceTile *needle; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
219 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
220 needle = work->data; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
221 work = work->prev; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
222 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
223 if (!source_tile_visible(imd, needle)) |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
224 { |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
225 imd->source_tiles = g_list_remove(imd->source_tiles, needle); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
226 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
227 if (imd->func_tile_dispose) |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
228 { |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
229 if (debug) printf("tile dispose: %d x %d @ %d x %d\n", |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
230 needle->x, needle->y, imd->x_scroll, imd->y_scroll); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
231 imd->func_tile_dispose(imd, needle->x, needle->y, |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
232 imd->source_tile_width, imd->source_tile_height, |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
233 needle->pixbuf, imd->data_tile); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
234 } |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
235 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
236 if (!st) |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
237 { |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
238 st = needle; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
239 } |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
240 else |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
241 { |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
242 source_tile_free(needle); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
243 } |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
244 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
245 count--; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
246 } |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
247 else if (debug) |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
248 { |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
249 printf("we still think %d x %d is visble\n", needle->x, needle->y); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
250 } |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
251 } |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
252 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
253 if (debug) |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
254 { |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
255 printf("cache count %d, max is %d\n", count, imd->source_tiles_cache_size); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
256 } |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
257 } |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
258 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
259 if (!st) |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
260 { |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
261 st = g_new0(SourceTile, 1); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
262 st->pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
263 imd->source_tile_width, imd->source_tile_height); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
264 } |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
265 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
266 st->x = (x / imd->source_tile_width) * imd->source_tile_width; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
267 st->y = (y / imd->source_tile_height) * imd->source_tile_height; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
268 st->blank = TRUE; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
269 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
270 imd->source_tiles = g_list_prepend(imd->source_tiles, st); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
271 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
272 if (debug) |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
273 { |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
274 printf("tile request: %d x %d\n", st->x, st->y); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
275 if (!source_tile_visible(imd, st)) printf("tile request for invisible tile!\n"); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
276 } |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
277 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
278 return st; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
279 } |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
280 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
281 static void image_tile_invalidate(ImageWindow *imd, gint x, gint y, gint w, gint h) |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
282 { |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
283 gint i, j; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
284 gint x1, x2; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
285 gint y1, y2; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
286 GList *work; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
287 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
288 x1 = (gint)floor(x / imd->tile_width) * imd->tile_width; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
289 x2 = (gint)ceil((x + w) / imd->tile_width) * imd->tile_width; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
290 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
291 y1 = (gint)floor(y / imd->tile_height) * imd->tile_height; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
292 y2 = (gint)ceil((y + h) / imd->tile_height) * imd->tile_height; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
293 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
294 work = g_list_nth(imd->tiles, y1 / imd->tile_height * imd->tile_cols + (x1 / imd->tile_width)); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
295 for (j = y1; j <= y2; j += imd->tile_height) |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
296 { |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
297 GList *tmp; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
298 tmp = work; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
299 for (i = x1; i <= x2; i += imd->tile_width) |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
300 { |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
301 if (tmp) |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
302 { |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
303 ImageTile *it = tmp->data; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
304 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
305 it->render_done = TILE_RENDER_NONE; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
306 it->render_todo = TILE_RENDER_ALL; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
307 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
308 tmp = tmp->next; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
309 } |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
310 } |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
311 work = g_list_nth(work, imd->tile_cols); /* step 1 row */ |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
312 } |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
313 } |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
314 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
315 static SourceTile *source_tile_request(ImageWindow *imd, gint x, gint y) |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
316 { |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
317 SourceTile *st; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
318 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
319 st = source_tile_new(imd, x, y); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
320 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
321 if (imd->func_tile_request && |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
322 imd->func_tile_request(imd, st->x, st->y, |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
323 imd->source_tile_width, imd->source_tile_height, st->pixbuf, imd->data_tile)) |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
324 { |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
325 st->blank = FALSE; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
326 } |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
327 #if 0 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
328 /* fixme: somehow invalidate the new st region */ |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
329 image_queue(imd, st->x, st->y, imd->source_tile_width, imd->source_tile_height, FALSE, TILE_RENDER_AREA, TRUE); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
330 #endif |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
331 image_tile_invalidate(imd, st->x * imd->scale, st->y * imd->scale, |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
332 imd->source_tile_width * imd->scale, imd->source_tile_height * imd->scale); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
333 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
334 return st; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
335 } |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
336 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
337 static SourceTile *source_tile_find(ImageWindow *imd, gint x, gint y) |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
338 { |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
339 GList *work; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
340 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
341 work = imd->source_tiles; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
342 while (work) |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
343 { |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
344 SourceTile *st = work->data; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
345 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
346 if (x >= st->x && x < st->x + imd->source_tile_width && |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
347 y >= st->y && y < st->y + imd->source_tile_height) |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
348 { |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
349 if (work != imd->source_tiles) |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
350 { |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
351 imd->source_tiles = g_list_remove_link(imd->source_tiles, work); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
352 imd->source_tiles = g_list_concat(work, imd->source_tiles); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
353 } |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
354 return st; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
355 } |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
356 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
357 work = work->next; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
358 } |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
359 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
360 return NULL; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
361 } |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
362 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
363 static GList *source_tile_compute_region(ImageWindow *imd, gint x, gint y, gint w, gint h, gint request) |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
364 { |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
365 gint x1, y1; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
366 GList *list = NULL; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
367 gint sx, sy; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
368 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
369 if (x < 0) x = 0; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
370 if (y < 0) y = 0; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
371 if (w > imd->image_width) w = imd->image_width; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
372 if (h > imd->image_height) h = imd->image_height; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
373 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
374 sx = (x / imd->source_tile_width) * imd->source_tile_width; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
375 sy = (y / imd->source_tile_height) * imd->source_tile_height; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
376 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
377 for (x1 = sx; x1 < x + w; x1+= imd->source_tile_width) |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
378 { |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
379 for (y1 = sy; y1 < y + h; y1 += imd->source_tile_height) |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
380 { |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
381 SourceTile *st; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
382 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
383 st = source_tile_find(imd, x1, y1); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
384 if (!st && request) st = source_tile_request(imd, x1, y1); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
385 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
386 if (st) list = g_list_prepend(list, st); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
387 } |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
388 } |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
389 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
390 return g_list_reverse(list); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
391 } |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
392 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
393 static void source_tile_changed(ImageWindow *imd, gint x, gint y, gint width, gint height) |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
394 { |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
395 GList *work; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
396 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
397 work = imd->source_tiles; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
398 while (work) |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
399 { |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
400 SourceTile *st; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
401 gint rx, ry, rw, rh; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
402 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
403 st = work->data; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
404 work = work->next; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
405 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
406 if (util_clip_region(st->x, st->y, imd->source_tile_width, imd->source_tile_height, |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
407 x, y, width, height, |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
408 &rx, &ry, &rw, &rh)) |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
409 { |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
410 GdkPixbuf *pixbuf; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
411 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
412 pixbuf = gdk_pixbuf_new_subpixbuf(st->pixbuf, rx - st->x, ry - st->y, rw, rh); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
413 if (imd->func_tile_request && |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
414 imd->func_tile_request(imd, rx, ry, rw, rh, pixbuf, imd->data_tile)) |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
415 { |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
416 image_tile_invalidate(imd, rx * imd->scale, ry * imd->scale, rw * imd->scale, rh * imd->scale); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
417 } |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
418 g_object_unref(pixbuf); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
419 } |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
420 } |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
421 } |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
422 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
423 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
424 static gint source_tile_render(ImageWindow *imd, ImageTile *it, |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
425 gint x, gint y, gint w, gint h, |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
426 gint new_data, gint fast) |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
427 { |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
428 GList *list; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
429 GList *work; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
430 gint draw = FALSE; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
431 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
432 if (imd->zoom == 1.0 || imd->scale == 1.0) |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
433 { |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
434 list = source_tile_compute_region(imd, it->x + x, it->y + y, w, h, TRUE); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
435 work = list; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
436 while (work) |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
437 { |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
438 SourceTile *st; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
439 gint rx, ry, rw, rh; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
440 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
441 st = work->data; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
442 work = work->next; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
443 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
444 if (util_clip_region(st->x, st->y, imd->source_tile_width, imd->source_tile_height, |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
445 it->x + x, it->y + y, w, h, |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
446 &rx, &ry, &rw, &rh)) |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
447 { |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
448 if (st->blank) |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
449 { |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
450 gdk_draw_rectangle(it->pixmap, imd->image->style->black_gc, TRUE, |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
451 rx - st->x, ry - st->y, rw, rh); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
452 } |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
453 else /* (imd->zoom == 1.0 || imd->scale == 1.0) */ |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
454 { |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
455 gdk_draw_pixbuf(it->pixmap, |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
456 imd->image->style->fg_gc[GTK_WIDGET_STATE(imd->image)], |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
457 st->pixbuf, |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
458 rx - st->x, ry - st->y, |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
459 rx - it->x, ry - it->y, |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
460 rw, rh, |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
461 (GdkRgbDither)dither_quality, rx, ry); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
462 } |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
463 } |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
464 } |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
465 } |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
466 else |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
467 { |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
468 double scale_x, scale_y; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
469 gint sx, sy, sw, sh; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
470 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
471 if (imd->image_width == 0 || imd->image_height == 0) return FALSE; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
472 scale_x = (double)imd->width / imd->image_width; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
473 scale_y = (double)imd->height / imd->image_height; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
474 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
475 sx = (double)(it->x + x) / scale_x; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
476 sy = (double)(it->y + y) / scale_y; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
477 sw = (double)w / scale_x; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
478 sh = (double)h / scale_y; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
479 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
480 if (imd->width < IMAGE_MIN_SCALE_SIZE || imd->height < IMAGE_MIN_SCALE_SIZE) fast = TRUE; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
481 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
482 #if 0 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
483 /* draws red over draw region, to check for leaks (regions not filled) */ |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
484 pixbuf_draw_rect(it->pixbuf, x, y, w, h, 255, 0, 0, 255, FALSE); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
485 #endif |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
486 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
487 list = source_tile_compute_region(imd, sx, sy, sw, sh, TRUE); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
488 work = list; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
489 while (work) |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
490 { |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
491 SourceTile *st; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
492 gint rx, ry, rw, rh; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
493 gint stx, sty, stw, sth; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
494 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
495 st = work->data; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
496 work = work->next; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
497 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
498 stx = floor((double)st->x * scale_x); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
499 sty = floor((double)st->y * scale_y); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
500 stw = ceil ((double)(st->x + imd->source_tile_width) * scale_x) - stx; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
501 sth = ceil ((double)(st->y + imd->source_tile_height) * scale_y) - sty; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
502 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
503 if (util_clip_region(stx, sty, stw, sth, |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
504 it->x + x, it->y + y, w, h, |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
505 &rx, &ry, &rw, &rh)) |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
506 { |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
507 if (st->blank) |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
508 { |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
509 gdk_draw_rectangle(it->pixmap, imd->image->style->black_gc, TRUE, |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
510 rx - st->x, ry - st->y, rw, rh); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
511 } |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
512 else |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
513 { |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
514 double offset_x; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
515 double offset_y; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
516 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
517 /* may need to use unfloored stx,sty values here */ |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
518 offset_x = ((double)stx < (double)it->x) ? |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
519 (double)stx - (double)it->x : 0.0; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
520 offset_y = ((double)sty < (double)it->y) ? |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
521 (double)sty - (double)it->y : 0.0; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
522 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
523 gdk_pixbuf_scale(st->pixbuf, it->pixbuf, rx - it->x, ry - it->y, rw, rh, |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
524 (double) 0.0 + rx - it->x + offset_x, |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
525 (double) 0.0 + ry - it->y + offset_y, |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
526 scale_x, scale_y, |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
527 (fast) ? GDK_INTERP_NEAREST : (GdkInterpType)zoom_quality); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
528 draw = TRUE; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
529 } |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
530 } |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
531 } |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
532 } |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
533 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
534 g_list_free(list); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
535 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
536 return draw; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
537 } |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
538 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
539 static void image_source_tile_unset(ImageWindow *imd) |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
540 { |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
541 source_tile_free_all(imd); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
542 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
543 imd->source_tiles_enabled = FALSE; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
544 } |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
545 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
546 void image_set_image_as_tiles(ImageWindow *imd, gint width, gint height, |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
547 gint tile_width, gint tile_height, gint cache_size, |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
548 ImageTileRequestFunc func_tile_request, |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
549 ImageTileDisposeFunc func_tile_dispose, |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
550 gpointer data, |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
551 gdouble zoom) |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
552 { |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
553 /* FIXME: unset any current image */ |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
554 image_source_tile_unset(imd); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
555 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
556 if (tile_width < 32 || tile_height < 32) |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
557 { |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
558 printf("warning: tile size too small %d x %d (min 32x32)\n", tile_width, tile_height); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
559 return; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
560 } |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
561 if (width < 32 || height < 32) |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
562 { |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
563 printf("warning: tile canvas too small %d x %d (min 32x32)\n", width, height); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
564 return; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
565 } |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
566 if (!func_tile_request) |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
567 { |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
568 printf("warning: tile request function is null\n"); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
569 } |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
570 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
571 printf("Setting source tiles to size %d x %d, grid is %d x %d\n", tile_width, tile_height, width, height); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
572 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
573 if (cache_size < 4) cache_size = 4; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
574 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
575 imd->source_tiles_enabled = TRUE; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
576 imd->source_tiles_cache_size = cache_size; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
577 imd->source_tile_width = tile_width; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
578 imd->source_tile_height = tile_height; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
579 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
580 imd->image_width = width; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
581 imd->image_height = height; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
582 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
583 imd->func_tile_request = func_tile_request; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
584 imd->func_tile_dispose = func_tile_dispose; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
585 imd->data_tile = data; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
586 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
587 image_zoom_sync(imd, zoom, TRUE, FALSE, TRUE, FALSE, 0, 0); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
588 } |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
589 |
9 | 590 |
591 static void image_queue_clear(ImageWindow *imd); | |
592 | |
593 static void image_update_title(ImageWindow *imd); | |
594 static void image_update_util(ImageWindow *imd); | |
595 static void image_complete_util(ImageWindow *imd, gint preload); | |
596 | |
597 static void image_button_do(ImageWindow *imd, GdkEventButton *bevent); | |
598 | |
599 static void image_overlay_draw(ImageWindow *imd, gint x, gint y, gint w, gint h); | |
600 static void image_overlay_queue_all(ImageWindow *imd); | |
601 | |
602 static void image_scroller_timer_set(ImageWindow *imd, gint start); | |
603 | |
604 | |
605 static gint util_clip_region(gint x, gint y, gint w, gint h, | |
606 gint clip_x, gint clip_y, gint clip_w, gint clip_h, | |
607 gint *rx, gint *ry, gint *rw, gint *rh) | |
608 { | |
609 if (clip_x + clip_w <= x || | |
610 clip_x >= x + w || | |
611 clip_y + clip_h <= y || | |
612 clip_y >= y + h) | |
613 { | |
614 return FALSE; | |
615 } | |
616 | |
617 *rx = MAX(x, clip_x); | |
618 *rw = MIN((x + w), (clip_x + clip_w)) - *rx; | |
619 | |
620 *ry = MAX(y, clip_y); | |
621 *rh = MIN((y + h), (clip_y + clip_h)) - *ry; | |
622 | |
623 return TRUE; | |
624 } | |
625 | |
1 | 626 |
627 /* | |
9 | 628 *------------------------------------------------------------------- |
629 * tile cache | |
630 *------------------------------------------------------------------- | |
1 | 631 */ |
632 | |
9 | 633 static gint pixmap_calc_size(GdkPixmap *pixmap) |
634 { | |
635 gint w, h, d; | |
636 | |
637 d = gdk_drawable_get_depth(pixmap); | |
638 gdk_drawable_get_size(pixmap, &w, &h); | |
639 return w * h * (d / 8); | |
640 } | |
641 | |
642 static void image_tile_cache_remove(ImageWindow *imd, ImageTile *it) | |
643 { | |
644 GList *work; | |
645 | |
646 work = imd->tile_cache; | |
647 while(work) | |
648 { | |
649 CacheData *cd = work->data; | |
650 work = work->next; | |
651 | |
652 if (cd->it == it) | |
653 { | |
654 imd->tile_cache = g_list_remove(imd->tile_cache, cd); | |
655 imd->tile_cache_size -= cd->size; | |
656 g_free(cd); | |
657 } | |
658 } | |
659 } | |
660 | |
661 static void image_tile_cache_free(ImageWindow *imd, CacheData *cd) | |
1 | 662 { |
9 | 663 imd->tile_cache = g_list_remove(imd->tile_cache, cd); |
664 if (cd->pixmap) | |
665 { | |
666 g_object_unref(cd->it->pixmap); | |
667 cd->it->pixmap = NULL; | |
668 cd->it->render_done = TILE_RENDER_NONE; | |
669 } | |
670 if (cd->pixbuf) | |
671 { | |
672 gdk_pixbuf_unref(cd->it->pixbuf); | |
673 cd->it->pixbuf = NULL; | |
674 } | |
675 imd->tile_cache_size -= cd->size; | |
676 g_free(cd); | |
677 } | |
678 | |
679 static void image_tile_cache_free_space(ImageWindow *imd, gint space, ImageTile *it) | |
680 { | |
12
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
681 GList *work; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
682 gint tile_max; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
683 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
684 work = g_list_last(imd->tile_cache); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
685 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
686 if (imd->source_tiles_enabled && imd->scale < 1.0) |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
687 { |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
688 gint tiles; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
689 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
690 tiles = (imd->vis_width / IMAGE_TILE_SIZE + 1) * (imd->vis_width / IMAGE_TILE_SIZE + 1); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
691 tile_max = MAX(tiles * IMAGE_TILE_SIZE * IMAGE_TILE_SIZE * 3, |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
692 (gint)((double)tile_cache_max * 1048576.0 * imd->scale)); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
693 } |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
694 else |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
695 { |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
696 tile_max = tile_cache_max * 1048576; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
697 } |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
698 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
699 while (work && imd->tile_cache_size > 0 && imd->tile_cache_size + space > tile_max) |
1 | 700 { |
9 | 701 CacheData *cd = work->data; |
702 work = work->prev; | |
703 if (cd->it != it) image_tile_cache_free(imd, cd); | |
1 | 704 } |
705 } | |
706 | |
9 | 707 static void image_tile_cache_add(ImageWindow *imd, ImageTile *it, |
708 GdkPixmap *pixmap, GdkPixbuf *pixbuf, guint size) | |
709 { | |
710 CacheData *cd; | |
711 | |
712 cd = g_new(CacheData, 1); | |
713 cd->pixmap = pixmap; | |
714 cd->pixbuf = pixbuf; | |
715 cd->it = it; | |
716 cd->size = size; | |
717 | |
718 imd->tile_cache = g_list_prepend(imd->tile_cache, cd); | |
719 | |
720 imd->tile_cache_size += cd->size; | |
721 } | |
722 | |
723 static void image_tile_prepare(ImageWindow *imd, ImageTile *it) | |
1 | 724 { |
9 | 725 if (!it->pixmap) |
726 { | |
727 GdkPixmap *pixmap; | |
728 guint size; | |
729 | |
730 pixmap = gdk_pixmap_new(imd->image->window, imd->tile_width, imd->tile_height, -1); | |
731 | |
732 size = pixmap_calc_size(pixmap); | |
733 image_tile_cache_free_space(imd, size, it); | |
734 | |
735 it->pixmap = pixmap; | |
736 image_tile_cache_add(imd, it, pixmap, NULL, size); | |
737 } | |
738 | |
12
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
739 if ((imd->zoom != 1.0 || imd->source_tiles_enabled || (imd->pixbuf && gdk_pixbuf_get_has_alpha(imd->pixbuf)) ) && |
9 | 740 !it->pixbuf) |
741 { | |
742 GdkPixbuf *pixbuf; | |
743 guint size; | |
744 | |
12
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
745 if (imd->pixbuf) |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
746 { |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
747 pixbuf = gdk_pixbuf_new(gdk_pixbuf_get_colorspace(imd->pixbuf), |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
748 gdk_pixbuf_get_has_alpha(imd->pixbuf), |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
749 gdk_pixbuf_get_bits_per_sample(imd->pixbuf), |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
750 imd->tile_width, imd->tile_height); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
751 } |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
752 else |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
753 { |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
754 pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, imd->tile_width, imd->tile_height); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
755 } |
9 | 756 |
757 size = gdk_pixbuf_get_rowstride(pixbuf) * imd->tile_height; | |
758 image_tile_cache_free_space(imd, size, it); | |
759 | |
760 it->pixbuf = pixbuf; | |
761 image_tile_cache_add(imd, it, NULL, pixbuf, size); | |
762 } | |
1 | 763 } |
764 | |
9 | 765 /* |
766 *------------------------------------------------------------------- | |
767 * tiles | |
768 *------------------------------------------------------------------- | |
769 */ | |
770 | |
771 static ImageTile *image_tile_new(gint w, gint h) | |
1 | 772 { |
9 | 773 ImageTile *it; |
774 | |
775 it = g_new0(ImageTile, 1); | |
776 it->w = w; | |
777 it->h = h; | |
778 it->pixmap = NULL; | |
779 it->pixbuf = NULL; | |
780 it->blank = TRUE; | |
781 it->render_todo = TILE_RENDER_NONE; | |
782 it->render_done = TILE_RENDER_NONE; | |
783 | |
784 return it; | |
1 | 785 } |
786 | |
9 | 787 static void image_tile_free(ImageTile *it) |
788 { | |
789 if (!it) return; | |
790 | |
791 if (it->pixbuf) gdk_pixbuf_unref(it->pixbuf); | |
792 if (it->pixmap) g_object_unref(it->pixmap); | |
793 | |
794 g_free(it); | |
795 } | |
796 | |
797 static void image_tile_sync_count(ImageWindow *imd, gint n) | |
1 | 798 { |
9 | 799 gint l; |
800 | |
801 l = g_list_length(imd->tiles); | |
802 | |
803 if (l == n) return; | |
804 | |
805 if (l < n) | |
1 | 806 { |
9 | 807 while (l < n) |
808 { | |
809 imd->tiles = g_list_prepend(imd->tiles, image_tile_new(imd->tile_width, imd->tile_height)); | |
810 l++; | |
811 } | |
1 | 812 } |
813 else | |
814 { | |
9 | 815 /* This should remove from the tail of the GList, but with large images there are many tiles, |
816 * making this significantly faster for those cases. | |
817 */ | |
818 while (l > n && imd->tiles) | |
819 { | |
820 ImageTile *it = imd->tiles->data; | |
821 imd->tiles = g_list_remove(imd->tiles, it); | |
822 image_tile_cache_remove(imd, it); | |
823 image_tile_free(it); | |
824 l--; | |
825 } | |
826 } | |
827 } | |
828 | |
829 static void image_tile_sync(ImageWindow *imd, gint width, gint height, gint blank) | |
830 { | |
831 gint rows; | |
832 gint x, y; | |
833 GList *work; | |
834 | |
835 imd->tile_cols = (width + imd->tile_width - 1) / imd->tile_width; | |
836 | |
837 rows = (height + imd->tile_height - 1) / imd->tile_height; | |
838 | |
839 image_tile_sync_count(imd, imd->tile_cols * rows); | |
840 | |
841 x = y = 0; | |
842 work = imd->tiles; | |
843 while(work) | |
844 { | |
845 ImageTile *it = work->data; | |
846 work = work->next; | |
847 | |
848 it->x = x; | |
849 it->y = y; | |
850 if (x + imd->tile_width > width) | |
851 { | |
852 it->w = width - x; | |
853 } | |
854 else | |
855 { | |
856 it->w = imd->tile_width; | |
857 } | |
858 if (y + imd->tile_height > height) | |
859 { | |
860 it->h = height - y; | |
861 } | |
862 else | |
863 { | |
864 it->h = imd->tile_height; | |
865 } | |
866 | |
867 it->blank = blank; | |
868 it->render_todo = TILE_RENDER_NONE; | |
869 it->render_done = TILE_RENDER_NONE; | |
870 | |
871 x += imd->tile_width; | |
872 if (x >= width) | |
873 { | |
874 x = 0; | |
875 y += imd->tile_height; | |
876 } | |
877 } | |
878 | |
879 /* all it's are now useless in queue */ | |
880 image_queue_clear(imd); | |
881 } | |
882 | |
883 static void image_tile_render(ImageWindow *imd, ImageTile *it, | |
884 gint x, gint y, gint w, gint h, | |
885 gint new_data, gint fast) | |
886 { | |
887 gint has_alpha; | |
888 gint draw = FALSE; | |
889 | |
12
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
890 if (it->render_todo == TILE_RENDER_NONE && it->pixmap && !new_data) return; |
9 | 891 |
892 if (it->render_done != TILE_RENDER_ALL) | |
893 { | |
894 x = 0; | |
895 y = 0; | |
896 w = it->w; | |
897 h = it->h; | |
898 if (!fast) it->render_done = TILE_RENDER_ALL; | |
899 } | |
900 else if (it->render_todo != TILE_RENDER_AREA) | |
901 { | |
902 if (!fast) it->render_todo = TILE_RENDER_NONE; | |
903 return; | |
1 | 904 } |
905 | |
9 | 906 if (!fast) it->render_todo = TILE_RENDER_NONE; |
907 | |
908 if (new_data) it->blank = FALSE; | |
909 | |
910 image_tile_prepare(imd, it); | |
12
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
911 has_alpha = (imd->pixbuf && gdk_pixbuf_get_has_alpha(imd->pixbuf)); |
9 | 912 |
913 /* FIXME checker colors for alpha should be configurable, | |
914 * also should be drawn for blank = TRUE | |
915 */ | |
916 | |
917 if (it->blank) | |
918 { | |
919 /* no data, do fast rect fill */ | |
920 gdk_draw_rectangle(it->pixmap, imd->image->style->black_gc, TRUE, | |
921 0, 0, it->w, it->h); | |
922 } | |
12
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
923 else if (imd->source_tiles_enabled) |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
924 { |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
925 draw = source_tile_render(imd, it, x, y, w, h, new_data, fast); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
926 } |
9 | 927 else if (imd->zoom == 1.0 || imd->scale == 1.0) |
928 { | |
929 if (has_alpha) | |
930 { | |
931 gdk_pixbuf_composite_color(imd->pixbuf, it->pixbuf, x, y, w, h, | |
932 (double) 0.0 - it->x, | |
933 (double) 0.0 - it->y, | |
934 1.0, 1.0, GDK_INTERP_NEAREST, | |
935 255, it->x + x, it->y + y, | |
936 IMAGE_ALPHA_CHECK_SIZE, IMAGE_ALPHA_CHECK1, IMAGE_ALPHA_CHECK2); | |
937 draw = TRUE; | |
938 } | |
939 else | |
940 { | |
941 /* faster, simple */ | |
942 gdk_draw_pixbuf(it->pixmap, | |
943 imd->image->style->fg_gc[GTK_WIDGET_STATE(imd->image)], | |
944 imd->pixbuf, | |
945 it->x + x, it->y + y, | |
946 x, y, | |
947 w, h, | |
948 (GdkRgbDither)dither_quality, it->x + x, it->y + y); | |
949 } | |
950 } | |
951 else | |
952 { | |
953 double scale_x, scale_y; | |
954 | |
955 if (imd->image_width == 0 || imd->image_height == 0) return; | |
956 scale_x = (double)imd->width / imd->image_width; | |
957 scale_y = (double)imd->height / imd->image_height; | |
958 | |
959 /* HACK: The pixbuf scalers get kinda buggy(crash) with extremely | |
960 * small sizes for anything but GDK_INTERP_NEAREST | |
961 */ | |
962 if (imd->width < IMAGE_MIN_SCALE_SIZE || imd->height < IMAGE_MIN_SCALE_SIZE) fast = TRUE; | |
963 | |
964 if (!has_alpha) | |
965 { | |
966 gdk_pixbuf_scale(imd->pixbuf, it->pixbuf, x, y, w, h, | |
967 (double) 0.0 - it->x, | |
968 (double) 0.0 - it->y, | |
969 scale_x, scale_y, | |
970 (fast) ? GDK_INTERP_NEAREST : (GdkInterpType)zoom_quality); | |
971 } | |
972 else | |
973 { | |
974 gdk_pixbuf_composite_color(imd->pixbuf, it->pixbuf, x, y, w, h, | |
975 (double) 0.0 - it->x, | |
976 (double) 0.0 - it->y, | |
977 scale_x, scale_y, | |
978 (fast) ? GDK_INTERP_NEAREST : (GdkInterpType)zoom_quality, | |
979 255, it->x + x, it->y + y, | |
980 IMAGE_ALPHA_CHECK_SIZE, IMAGE_ALPHA_CHECK1, IMAGE_ALPHA_CHECK2); | |
981 } | |
982 draw = TRUE; | |
983 } | |
984 | |
985 if (draw && it->pixbuf && !it->blank) | |
986 { | |
987 gdk_draw_pixbuf(it->pixmap, | |
988 imd->image->style->fg_gc[GTK_WIDGET_STATE(imd->image)], | |
989 it->pixbuf, | |
990 x, y, | |
991 x, y, | |
992 w, h, | |
993 (GdkRgbDither)dither_quality, it->x + x, it->y + y); | |
994 } | |
995 } | |
996 | |
997 static void image_tile_expose(ImageWindow *imd, ImageTile *it, | |
998 gint x, gint y, gint w, gint h, | |
999 gint new_data, gint fast) | |
1000 { | |
1001 image_tile_render(imd, it, x, y, w, h, new_data, fast); | |
1002 | |
1003 gdk_draw_drawable(imd->image->window, imd->image->style->fg_gc[GTK_WIDGET_STATE(imd->image)], | |
1004 it->pixmap, x, y, | |
1005 imd->x_offset + (it->x - imd->x_scroll) + x, imd->y_offset + (it->y - imd->y_scroll) + y, w, h); | |
1006 | |
1007 if (imd->overlay_list) | |
1008 { | |
1009 image_overlay_draw(imd, imd->x_offset + (it->x - imd->x_scroll) + x, | |
1010 imd->y_offset + (it->y - imd->y_scroll) + y, | |
1011 w, h); | |
1012 } | |
1013 } | |
1014 | |
1015 static gint image_tile_is_visible(ImageWindow *imd, ImageTile *it) | |
1016 { | |
1017 return (it->x + it->w >= imd->x_scroll && it->x <= imd->x_scroll + imd->window_width - imd->x_offset * 2 && | |
1018 it->y + it->h >= imd->y_scroll && it->y <= imd->y_scroll + imd->window_height - imd->y_offset * 2); | |
1 | 1019 } |
1020 | |
1021 /* | |
9 | 1022 *------------------------------------------------------------------- |
1023 * render queue | |
1024 *------------------------------------------------------------------- | |
1025 */ | |
1026 | |
1027 | |
1028 static gint image_queue_draw_idle_cb(gpointer data) | |
1029 { | |
1030 ImageWindow *imd = data; | |
1031 QueueData *qd; | |
1032 gint fast; | |
1033 | |
12
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
1034 if ((!imd->pixbuf && !imd->source_tiles_enabled) || (!imd->draw_queue && !imd->draw_queue_2pass) || imd->draw_idle_id == -1) |
9 | 1035 { |
1036 if (!imd->completed) image_complete_util(imd, FALSE); | |
1037 | |
1038 imd->draw_idle_id = -1; | |
1039 return FALSE; | |
1040 } | |
1041 | |
1042 if (imd->draw_queue) | |
1043 { | |
1044 qd = imd->draw_queue->data; | |
1045 fast = (two_pass_zoom && (GdkInterpType)zoom_quality != GDK_INTERP_NEAREST && imd->scale != 1.0); | |
1046 } | |
1047 else | |
1048 { | |
1049 if (imd->il) | |
1050 { | |
1051 /* still loading, wait till done (also drops the higher priority) */ | |
1052 | |
1053 imd->draw_idle_id = g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, | |
1054 image_queue_draw_idle_cb, imd, NULL); | |
1055 imd->draw_idle_high = FALSE; | |
1056 return FALSE; | |
1057 } | |
1058 qd = imd->draw_queue_2pass->data; | |
1059 fast = FALSE; | |
1060 } | |
1061 | |
1062 if (GTK_WIDGET_REALIZED(imd->image)) | |
1063 { | |
1064 if (image_tile_is_visible(imd, qd->it)) | |
1065 { | |
1066 image_tile_expose(imd, qd->it, qd->x, qd->y, qd->w, qd->h, qd->new_data, fast); | |
1067 } | |
1068 else if (qd->new_data) | |
1069 { | |
1070 /* if new pixel data, and we already have a pixmap, update the tile */ | |
1071 qd->it->blank = FALSE; | |
1072 if (qd->it->pixmap && qd->it->render_done == TILE_RENDER_ALL) | |
1073 { | |
1074 image_tile_render(imd, qd->it, qd->x, qd->y, qd->w, qd->h, qd->new_data, fast); | |
1075 } | |
1076 } | |
1077 } | |
1078 | |
1079 if (imd->draw_queue) | |
1080 { | |
1081 imd->draw_queue = g_list_remove(imd->draw_queue, qd); | |
1082 if (fast) | |
1083 { | |
1084 imd->draw_queue_2pass = g_list_append(imd->draw_queue_2pass, qd); | |
1085 } | |
1086 else | |
1087 { | |
1088 g_free(qd); | |
1089 } | |
1090 } | |
1091 else | |
1092 { | |
1093 imd->draw_queue_2pass = g_list_remove(imd->draw_queue_2pass, qd); | |
1094 g_free(qd); | |
1095 } | |
1096 | |
1097 if (!imd->draw_queue && !imd->draw_queue_2pass) | |
1098 { | |
1099 if (!imd->completed) image_complete_util(imd, FALSE); | |
1100 | |
1101 imd->draw_idle_id = -1; | |
1102 return FALSE; | |
1103 } | |
1104 | |
1105 return TRUE; | |
1106 } | |
1107 | |
1108 static QueueData *image_queue_combine(ImageWindow *imd, QueueData *qd) | |
1109 { | |
1110 QueueData *found = NULL; | |
1111 GList *work; | |
1112 | |
1113 work = imd->draw_queue; | |
1114 while (work && !found) | |
1115 { | |
1116 found = work->data; | |
1117 work = work->next; | |
1118 | |
1119 if (found->it != qd->it) found = NULL; | |
1120 } | |
1121 | |
1122 if (found) | |
1123 { | |
1124 if (found->x + found->w < qd->x + qd->w) found->w += (qd->x + qd->w) - (found->x + found->w); | |
1125 if (found->x > qd->x) | |
1126 { | |
1127 found->w += found->x - qd->x; | |
1128 found->x = qd->x; | |
1129 } | |
1130 | |
1131 if (found->y + found->h < qd->y + qd->h) found->h += (qd->y + qd->h) - (found->y + found->h); | |
1132 if (found->y > qd->y) | |
1133 { | |
1134 found->h += found->y - qd->y; | |
1135 found->y = qd->y; | |
1136 } | |
1137 found->new_data |= qd->new_data; | |
1138 } | |
1139 | |
1140 return found; | |
1141 } | |
1142 | |
1143 static gint image_clamp_to_visible(ImageWindow *imd, gint *x, gint *y, gint *w, gint *h) | |
1144 { | |
1145 gint nx, ny; | |
1146 gint nw, nh; | |
1147 gint vx, vy; | |
1148 gint vw, vh; | |
1149 | |
1150 vw = imd->vis_width; | |
1151 vh = imd->vis_height; | |
1152 | |
1153 vx = imd->x_scroll; | |
1154 vy = imd->y_scroll; | |
1155 | |
1156 if (*x + *w < vx || *x > vx + vw || *y + *h < vy || *y > vy + vh) return FALSE; | |
1157 | |
1158 /* now clamp it */ | |
1159 nx = CLAMP(*x, vx, vx + vw); | |
1160 nw = CLAMP(*w - (nx - *x), 1, vw); | |
1161 | |
1162 ny = CLAMP(*y, vy, vy + vh); | |
1163 nh = CLAMP(*h - (ny - *y), 1, vh); | |
1164 | |
1165 *x = nx; | |
1166 *y = ny; | |
1167 *w = nw; | |
1168 *h = nh; | |
1169 | |
1170 return TRUE; | |
1171 } | |
1172 | |
1173 static gint image_queue_to_tiles(ImageWindow *imd, gint x, gint y, gint w, gint h, | |
1174 gint clamp, TileRenderType render, gint new_data) | |
1175 { | |
1176 gint i, j; | |
1177 gint x1, x2; | |
1178 gint y1, y2; | |
1179 GList *work; | |
1180 | |
1181 if (clamp && !image_clamp_to_visible(imd, &x, &y, &w, &h)) return FALSE; | |
1182 | |
1183 x1 = (gint)floor(x / imd->tile_width) * imd->tile_width; | |
1184 x2 = (gint)ceil((x + w) / imd->tile_width) * imd->tile_width; | |
1185 | |
1186 y1 = (gint)floor(y / imd->tile_height) * imd->tile_height; | |
1187 y2 = (gint)ceil((y + h) / imd->tile_height) * imd->tile_height; | |
1188 | |
1189 work = g_list_nth(imd->tiles, y1 / imd->tile_height * imd->tile_cols + (x1 / imd->tile_width)); | |
1190 for (j = y1; j <= y2; j += imd->tile_height) | |
1191 { | |
1192 GList *tmp; | |
1193 tmp = work; | |
1194 for (i = x1; i <= x2; i += imd->tile_width) | |
1195 { | |
1196 if (tmp) | |
1197 { | |
1198 ImageTile *it = tmp->data; | |
1199 QueueData *qd; | |
1200 | |
1201 if ((render == TILE_RENDER_ALL && it->render_done != TILE_RENDER_ALL) || | |
1202 (render == TILE_RENDER_AREA && it->render_todo != TILE_RENDER_ALL)) | |
1203 { | |
1204 it->render_todo = render; | |
1205 } | |
1206 | |
1207 qd = g_new(QueueData, 1); | |
1208 qd->it = it; | |
1209 qd->new_data = new_data; | |
1210 | |
1211 if (i < x) | |
1212 { | |
1213 qd->x = x - i; | |
1214 } | |
1215 else | |
1216 { | |
1217 qd->x = 0; | |
1218 } | |
1219 qd->w = x + w - i - qd->x; | |
1220 if (qd->x + qd->w > imd->tile_width) qd->w = imd->tile_width - qd->x; | |
1221 | |
1222 | |
1223 if (j < y) | |
1224 { | |
1225 qd->y = y - j; | |
1226 } | |
1227 else | |
1228 { | |
1229 qd->y = 0; | |
1230 } | |
1231 qd->h = y + h - j - qd->y; | |
1232 if (qd->y + qd->h > imd->tile_height) qd->h = imd->tile_height - qd->y; | |
1233 | |
1234 if (qd->w < 1 || qd->h < 1 || /* <--- sanity checks, rare cases cause this */ | |
1235 image_queue_combine(imd, qd)) | |
1236 { | |
1237 g_free(qd); | |
1238 } | |
1239 else | |
1240 { | |
1241 imd->draw_queue = g_list_append(imd->draw_queue, qd); | |
1242 } | |
1243 | |
1244 tmp = tmp->next; | |
1245 } | |
1246 } | |
1247 work = g_list_nth(work, imd->tile_cols); /* step 1 row */ | |
1248 } | |
1249 | |
1250 return TRUE; | |
1251 } | |
1252 | |
1253 static void image_queue(ImageWindow *imd, gint x, gint y, gint w, gint h, | |
1254 gint clamp, TileRenderType render, gint new_data) | |
1255 { | |
1256 gint nx, ny; | |
1257 | |
1258 nx = CLAMP(x, 0, imd->width - 1); | |
1259 ny = CLAMP(y, 0, imd->height - 1); | |
1260 w -= (nx - x); | |
1261 h -= (ny - y); | |
1262 w = CLAMP(w, 0, imd->width - nx); | |
1263 h = CLAMP(h, 0, imd->height - ny); | |
1264 if (w < 1 || h < 1) return; | |
1265 | |
1266 if (image_queue_to_tiles(imd, nx, ny, w, h, clamp, render, new_data) && | |
1267 ((!imd->draw_queue && !imd->draw_queue_2pass) || imd->draw_idle_id == -1 || !imd->draw_idle_high)) | |
1268 { | |
1269 if (imd->draw_idle_id != -1) g_source_remove(imd->draw_idle_id); | |
1270 imd->draw_idle_id = g_idle_add_full(GDK_PRIORITY_REDRAW, | |
1271 image_queue_draw_idle_cb, imd, NULL); | |
1272 imd->draw_idle_high = TRUE; | |
1273 } | |
1274 } | |
1275 | |
1276 static void image_queue_list_free(GList *list) | |
1277 { | |
1278 GList *work; | |
1279 | |
1280 work = list; | |
1281 while (work) | |
1282 { | |
1283 QueueData *qd; | |
1284 | |
1285 qd = work->data; | |
1286 work = work->next; | |
1287 g_free(qd); | |
1288 } | |
1289 | |
1290 g_list_free(list); | |
1291 } | |
1292 | |
1293 static void image_queue_clear(ImageWindow *imd) | |
1294 { | |
1295 image_queue_list_free(imd->draw_queue); | |
1296 imd->draw_queue = NULL; | |
1297 | |
1298 image_queue_list_free(imd->draw_queue_2pass); | |
1299 imd->draw_queue_2pass = NULL; | |
1300 | |
1301 if (imd->draw_idle_id != -1) g_source_remove(imd->draw_idle_id); | |
1302 imd->draw_idle_id = -1; | |
1303 } | |
1304 | |
1305 /* | |
1306 *------------------------------------------------------------------- | |
1307 * core calculations | |
1308 *------------------------------------------------------------------- | |
1309 */ | |
1310 | |
1311 static gint image_top_window_sizable(ImageWindow *imd) | |
1 | 1312 { |
1313 if (!imd->top_window) return FALSE; | |
1314 if (!fit_window) return FALSE; | |
9 | 1315 if (!imd->top_window_sync) return FALSE; |
1316 if (!imd->image->window) return FALSE; | |
1317 if (window_maximized(imd->top_window)) return FALSE; | |
1318 | |
1319 return TRUE; | |
1320 } | |
1321 | |
1322 static gint image_size_top_window(ImageWindow *imd, gint w, gint h) | |
1323 { | |
1324 gint ww, wh; | |
1325 | |
1326 if (!image_top_window_sizable(imd)) return FALSE; | |
1 | 1327 |
1328 if (limit_window_size) | |
1329 { | |
1330 gint sw = gdk_screen_width() * max_window_size / 100; | |
1331 gint sh = gdk_screen_height() * max_window_size / 100; | |
1332 | |
1333 if (w > sw) w = sw; | |
1334 if (h > sh) h = sh; | |
1335 } | |
1336 | |
9 | 1337 w += (imd->top_window->allocation.width - imd->image->allocation.width); |
1338 h += (imd->top_window->allocation.height - imd->image->allocation.height); | |
1339 | |
1340 gdk_drawable_get_size(imd->top_window->window, &ww, &wh); | |
1341 if (w == ww && h == wh) return FALSE; | |
1 | 1342 |
1343 gdk_window_resize(imd->top_window->window, w, h); | |
1344 | |
1345 return TRUE; | |
1346 } | |
1347 | |
9 | 1348 static void image_redraw(ImageWindow *imd, gint new_data) |
1349 { | |
1350 image_queue_clear(imd); | |
1351 image_queue(imd, 0, 0, imd->width, imd->height, TRUE, TILE_RENDER_ALL, new_data); | |
1352 } | |
1353 | |
1354 static void image_border_draw(ImageWindow *imd, gint x, gint y, gint w, gint h) | |
1 | 1355 { |
9 | 1356 gint rx, ry, rw, rh; |
1357 | |
1358 if (!imd->image->window) return; | |
1359 | |
12
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
1360 if (!imd->pixbuf && !imd->source_tiles_enabled) |
9 | 1361 { |
1362 if (util_clip_region(x, y, w, h, | |
1363 0, 0, | |
1364 imd->window_width, imd->window_height, | |
1365 &rx, &ry, &rw, &rh)) | |
1366 { | |
1367 gdk_window_clear_area(imd->image->window, rx, ry, rw, rh); | |
1368 image_overlay_draw(imd, rx, ry, rw, rh); | |
1369 } | |
1370 return; | |
1371 } | |
1372 | |
1373 if (imd->vis_width < imd->window_width) | |
1 | 1374 { |
9 | 1375 if (imd->x_offset > 0 && |
1376 util_clip_region(x, y, w, h, | |
1377 0, 0, | |
1378 imd->x_offset, imd->window_height, | |
1379 &rx, &ry, &rw, &rh)) | |
1380 { | |
1381 gdk_window_clear_area(imd->image->window, rx, ry, rw, rh); | |
1382 image_overlay_draw(imd, rx, ry, rw, rh); | |
1383 } | |
1384 if (imd->window_width - imd->vis_width - imd->x_offset > 0 && | |
1385 util_clip_region(x, y, w, h, | |
1386 imd->x_offset + imd->vis_width, 0, | |
1387 imd->window_width - imd->vis_width - imd->x_offset, imd->window_height, | |
1388 &rx, &ry, &rw, &rh)) | |
1389 { | |
1390 gdk_window_clear_area(imd->image->window, rx, ry, rw, rh); | |
1391 image_overlay_draw(imd, rx, ry, rw, rh); | |
1392 } | |
1 | 1393 } |
9 | 1394 if (imd->vis_height < imd->window_height) |
1 | 1395 { |
9 | 1396 if (imd->y_offset > 0 && |
1397 util_clip_region(x, y, w, h, | |
1398 imd->x_offset, 0, | |
1399 imd->vis_width, imd->y_offset, | |
1400 &rx, &ry, &rw, &rh)) | |
1401 { | |
1402 gdk_window_clear_area(imd->image->window, rx, ry, rw, rh); | |
1403 image_overlay_draw(imd, rx, ry, rw, rh); | |
1404 } | |
1405 if (imd->window_height - imd->vis_height - imd->y_offset > 0 && | |
1406 util_clip_region(x, y, w, h, | |
1407 imd->x_offset, imd->y_offset + imd->vis_height, | |
1408 imd->vis_width, imd->window_height - imd->vis_height - imd->y_offset, | |
1409 &rx, &ry, &rw, &rh)) | |
1410 { | |
1411 gdk_window_clear_area(imd->image->window, rx, ry, rw, rh); | |
1412 image_overlay_draw(imd, rx, ry, rw, rh); | |
1413 } | |
1 | 1414 } |
1415 } | |
1416 | |
9 | 1417 static void image_border_clear(ImageWindow *imd) |
1 | 1418 { |
9 | 1419 image_border_draw(imd, 0, 0, imd->window_width, imd->window_height); |
1 | 1420 } |
1421 | |
12
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
1422 static void image_scroll_notify(ImageWindow *imd) |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
1423 { |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
1424 if (imd->func_scroll_notify && imd->scale) |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
1425 { |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
1426 imd->func_scroll_notify(imd, |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
1427 (gint)((gdouble)imd->x_scroll / imd->scale), |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
1428 (gint)((gdouble)imd->y_scroll / imd->scale), |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
1429 (gint)((gdouble)imd->image_width - imd->vis_width / imd->scale), |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
1430 (gint)((gdouble)imd->image_height - imd->vis_height / imd->scale), |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
1431 imd->data_scroll_notify); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
1432 } |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
1433 } |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
1434 |
9 | 1435 static gint image_scroll_clamp(ImageWindow *imd) |
1 | 1436 { |
9 | 1437 gint old_xs; |
1438 gint old_ys; | |
1439 | |
1440 if (imd->zoom == 0.0) | |
1 | 1441 { |
9 | 1442 imd->x_scroll = 0; |
1443 imd->y_scroll = 0; | |
12
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
1444 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
1445 image_scroll_notify(imd); |
9 | 1446 return FALSE; |
1447 } | |
1448 | |
1449 old_xs = imd->x_scroll; | |
1450 old_ys = imd->y_scroll; | |
1451 | |
1452 if (imd->x_offset > 0) | |
1453 { | |
1454 imd->x_scroll = 0; | |
1 | 1455 } |
1456 else | |
1457 { | |
9 | 1458 imd->x_scroll = CLAMP(imd->x_scroll, 0, imd->width - imd->vis_width); |
1 | 1459 } |
9 | 1460 |
1461 if (imd->y_offset > 0) | |
1 | 1462 { |
9 | 1463 imd->y_scroll = 0; |
1 | 1464 } |
1465 else | |
1466 { | |
9 | 1467 imd->y_scroll = CLAMP(imd->y_scroll, 0, imd->height - imd->vis_height); |
1 | 1468 } |
1469 | |
12
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
1470 image_scroll_notify(imd); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
1471 |
9 | 1472 return (old_xs != imd->x_scroll || old_ys != imd->y_scroll); |
1473 } | |
1474 | |
1475 static gint image_zoom_clamp(ImageWindow *imd, gdouble zoom, gint force, gint new) | |
1476 { | |
1477 gint w, h; | |
1478 gdouble scale; | |
1479 | |
12
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
1480 zoom = CLAMP(zoom, imd->zoom_min, imd->zoom_max); |
9 | 1481 |
1482 if (imd->zoom == zoom && !force) return FALSE; | |
1483 | |
1484 w = imd->image_width; | |
1485 h = imd->image_height; | |
1486 | |
1487 if (zoom == 0.0 && !imd->pixbuf) | |
1 | 1488 { |
9 | 1489 scale = 1.0; |
1 | 1490 } |
9 | 1491 else if (zoom == 0.0) |
1 | 1492 { |
9 | 1493 gint max_w; |
1494 gint max_h; | |
1495 gint sizeable; | |
1496 | |
1497 sizeable = (new && image_top_window_sizable(imd)); | |
1498 | |
1499 if (sizeable) | |
1 | 1500 { |
9 | 1501 max_w = gdk_screen_width(); |
1502 max_h = gdk_screen_height(); | |
1503 | |
1 | 1504 if (limit_window_size) |
1505 { | |
9 | 1506 max_w = max_w * max_window_size / 100; |
1507 max_h = max_h * max_window_size / 100; | |
1508 } | |
1509 } | |
1510 else | |
1511 { | |
1512 max_w = imd->window_width; | |
1513 max_h = imd->window_height; | |
1514 } | |
1515 | |
1516 if ((zoom_to_fit_expands && !sizeable) || w > max_w || h > max_h) | |
1517 { | |
1518 if ((gdouble)max_w / w > (gdouble)max_h / h) | |
1519 { | |
1520 scale = (gdouble)max_h / h; | |
1521 h = max_h; | |
1522 w = w * scale + 0.5; | |
1523 if (w > max_w) w = max_w; | |
1 | 1524 } |
1525 else | |
1526 { | |
9 | 1527 scale = (gdouble)max_w / w; |
1528 w = max_w; | |
1529 h = h * scale + 0.5; | |
1530 if (h > max_h) h = max_h; | |
1 | 1531 } |
1532 if (w < 1) w = 1; | |
1533 if (h < 1) h = 1; | |
1534 } | |
9 | 1535 else |
1536 { | |
1537 scale = 1.0; | |
1538 } | |
1 | 1539 } |
9 | 1540 else if (zoom > 0.0) /* zoom orig, in */ |
1 | 1541 { |
9 | 1542 scale = zoom; |
1543 w = w * scale; | |
1544 h = h * scale; | |
1 | 1545 } |
9 | 1546 else /* zoom out */ |
1547 { | |
1548 scale = 1.0 / (0.0 - zoom); | |
1549 w = w * scale; | |
1550 h = h * scale; | |
1551 } | |
1552 | |
1553 imd->zoom = zoom; | |
1 | 1554 imd->width = w; |
1555 imd->height = h; | |
9 | 1556 imd->scale = scale; |
1557 | |
1558 return TRUE; | |
1 | 1559 } |
1560 | |
9 | 1561 static gint image_size_clamp(ImageWindow *imd) |
1 | 1562 { |
9 | 1563 gint old_vw, old_vh; |
1564 | |
1565 old_vw = imd->vis_width; | |
1566 old_vh = imd->vis_height; | |
1567 | |
1568 if (imd->width < imd->window_width) | |
1 | 1569 { |
9 | 1570 imd->vis_width = imd->width; |
1571 imd->x_offset = (imd->window_width - imd->width) / 2; | |
1 | 1572 } |
1573 else | |
1574 { | |
9 | 1575 imd->vis_width = imd->window_width; |
1576 imd->x_offset = 0; | |
1 | 1577 } |
1578 | |
9 | 1579 if (imd->height < imd->window_height) |
1 | 1580 { |
9 | 1581 imd->vis_height = imd->height; |
1582 imd->y_offset = (imd->window_height - imd->height) / 2; | |
1 | 1583 } |
1584 else | |
1585 { | |
9 | 1586 imd->vis_height = imd->window_height; |
1587 imd->y_offset = 0; | |
1 | 1588 } |
1589 | |
9 | 1590 return (old_vw != imd->vis_width || old_vh != imd->vis_height); |
1591 } | |
1592 | |
1593 static void image_size_sync(ImageWindow *imd, gint new_width, gint new_height) | |
1594 { | |
1595 if (imd->window_width == new_width && imd->window_height == new_height) return; | |
1596 | |
1597 imd->window_width = new_width; | |
1598 imd->window_height = new_height; | |
1599 | |
1600 if (imd->zoom == 0.0) image_zoom_clamp(imd, 0.0, TRUE, FALSE); | |
1601 | |
1602 image_size_clamp(imd); | |
1603 image_scroll_clamp(imd); | |
1604 | |
12
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
1605 #if 0 |
9 | 1606 gtk_widget_set_size_request(imd->image, imd->window_width, imd->window_height); |
12
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
1607 #endif |
9 | 1608 |
1609 /* ensure scroller remains visible */ | |
1610 if (imd->scroller_overlay != -1) | |
1 | 1611 { |
9 | 1612 gint update = FALSE; |
1613 | |
1614 if (imd->scroller_x > new_width) | |
1615 { | |
1616 imd->scroller_x = new_width; | |
1617 imd->scroller_xpos = new_width; | |
1618 update = TRUE; | |
1619 } | |
1620 if (imd->scroller_y > new_height) | |
1621 { | |
1622 imd->scroller_y = new_height; | |
1623 imd->scroller_ypos = new_height; | |
1624 update = TRUE; | |
1625 } | |
1626 | |
1627 if (update) | |
1628 { | |
1629 GdkPixbuf *pixbuf; | |
1630 | |
1631 if (image_overlay_get(imd, imd->scroller_overlay, &pixbuf, NULL, NULL)) | |
1632 { | |
1633 gint w, h; | |
1634 | |
1635 w = gdk_pixbuf_get_width(pixbuf); | |
1636 h = gdk_pixbuf_get_height(pixbuf); | |
1637 image_overlay_set(imd, imd->scroller_overlay, pixbuf, | |
1638 imd->scroller_x - w / 2, imd->scroller_y - h / 2); | |
1639 } | |
1640 } | |
1 | 1641 } |
9 | 1642 |
1643 /* clear any borders */ | |
1644 image_border_clear(imd); | |
1645 | |
1646 image_tile_sync(imd, imd->width, imd->height, FALSE); | |
1647 #if 0 | |
1648 /* no longer needed? (expose event should be doing this for us) */ | |
1649 image_redraw(imd, FALSE); | |
1650 #endif | |
1651 | |
1652 if (imd->title_show_zoom) image_update_title(imd); | |
1653 image_update_util(imd); | |
1 | 1654 } |
1655 | |
1656 /* | |
9 | 1657 *------------------------------------------------------------------- |
1658 * misc | |
1659 *------------------------------------------------------------------- | |
1660 */ | |
1661 | |
1662 static void image_update_title(ImageWindow *imd) | |
1 | 1663 { |
9 | 1664 gchar *title = NULL; |
1665 gchar *zoom = NULL; | |
1666 gchar *collection = NULL; | |
1667 | |
1668 if (!imd->top_window) return; | |
1669 | |
1670 if (imd->collection && collection_to_number(imd->collection) >= 0) | |
1671 { | |
1672 const gchar *name; | |
1673 name = imd->collection->name; | |
1674 if (!name) name = _("Untitled"); | |
1675 collection = g_strdup_printf(" (Collection %s)", name); | |
1676 } | |
1677 | |
1678 if (imd->title_show_zoom) | |
1 | 1679 { |
9 | 1680 gchar *buf = image_zoom_get_as_text(imd); |
1681 zoom = g_strconcat(" [", buf, "]", NULL); | |
1682 g_free(buf); | |
1 | 1683 } |
1684 | |
9 | 1685 title = g_strdup_printf("%s%s%s%s%s%s", |
1686 imd->title ? imd->title : "", | |
1687 imd->image_name ? imd->image_name : "", | |
1688 zoom ? zoom : "", | |
1689 collection ? collection : "", | |
1690 imd->image_name ? " - " : "", | |
1691 imd->title_right ? imd->title_right : ""); | |
1692 | |
1693 gtk_window_set_title(GTK_WINDOW(imd->top_window), title); | |
1694 | |
1695 g_free(title); | |
1696 g_free(zoom); | |
1697 g_free(collection); | |
1698 } | |
1699 | |
1700 static void image_update_util(ImageWindow *imd) | |
1701 { | |
1702 if (imd->func_update) imd->func_update(imd, imd->data_update); | |
1 | 1703 } |
1704 | |
9 | 1705 static void image_complete_util(ImageWindow *imd, gint preload) |
1706 { | |
1707 if (imd->il && imd->pixbuf != image_loader_get_pixbuf(imd->il)) return; | |
1708 | |
1709 if (debug) printf("image load completed \"%s\" (%s)\n", | |
1710 (preload) ? imd->read_ahead_path : imd->image_path, | |
1711 (preload) ? "preload" : "current"); | |
1712 | |
1713 if (!preload) imd->completed = TRUE; | |
1714 if (imd->func_complete) imd->func_complete(imd, preload, imd->data_complete); | |
1715 } | |
1716 | |
1717 static void image_new_util(ImageWindow *imd) | |
1718 { | |
1719 if (imd->func_new) imd->func_new(imd, imd->data_new); | |
1720 } | |
1721 | |
1722 static void image_scroll_real(ImageWindow *imd, gint x, gint y) | |
1 | 1723 { |
9 | 1724 gint old_x, old_y; |
1725 gint x_off, y_off; | |
1726 gint w, h; | |
1727 | |
12
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
1728 if (!imd->pixbuf && !imd->source_tiles_enabled) return; |
9 | 1729 |
1730 old_x = imd->x_scroll; | |
1731 old_y = imd->y_scroll; | |
1732 | |
1733 imd->x_scroll += x; | |
1734 imd->y_scroll += y; | |
1735 | |
1736 image_scroll_clamp(imd); | |
1737 if (imd->x_scroll == old_x && imd->y_scroll == old_y) return; | |
1738 | |
1739 if (imd->overlay_list) | |
1 | 1740 { |
9 | 1741 gint new_x, new_y; |
1742 | |
1743 new_x = imd->x_scroll; | |
1744 new_y = imd->y_scroll; | |
1745 imd->x_scroll = old_x; | |
1746 imd->y_scroll = old_y; | |
1747 image_overlay_queue_all(imd); | |
1748 imd->x_scroll = new_x; | |
1749 imd->y_scroll = new_y; | |
1 | 1750 } |
1751 | |
9 | 1752 x_off = imd->x_scroll - old_x; |
1753 y_off = imd->y_scroll - old_y; | |
1754 | |
1755 w = imd->vis_width - abs(x_off); | |
1756 h = imd->vis_height - abs(y_off); | |
1757 | |
1758 if (w < 1 || h < 1) | |
1 | 1759 { |
9 | 1760 /* scrolled completely to new material */ |
1761 image_queue(imd, 0, 0, imd->width, imd->height, TRUE, TILE_RENDER_ALL, FALSE); | |
1762 return; | |
1 | 1763 } |
1764 else | |
1765 { | |
9 | 1766 gint x1, y1; |
1767 gint x2, y2; | |
1768 GdkGC *gc; | |
1769 | |
1770 if (x_off < 0) | |
1771 { | |
1772 x1 = abs(x_off); | |
1773 x2 = 0; | |
1774 } | |
1775 else | |
1776 { | |
1777 x1 = 0; | |
1778 x2 = abs(x_off); | |
1779 } | |
1780 | |
1781 if (y_off < 0) | |
1782 { | |
1783 y1 = abs(y_off); | |
1784 y2 = 0; | |
1785 } | |
1786 else | |
1787 { | |
1788 y1 = 0; | |
1789 y2 = abs(y_off); | |
1790 } | |
1791 | |
1792 gc = gdk_gc_new(imd->image->window); | |
1793 gdk_gc_set_exposures(gc, TRUE); | |
1794 gdk_draw_drawable(imd->image->window, gc, | |
1795 imd->image->window, | |
1796 x2 + imd->x_offset, y2 + imd->y_offset, | |
1797 x1 + imd->x_offset, y1 + imd->y_offset, w, h); | |
1798 g_object_unref(gc); | |
1799 | |
1800 if (imd->overlay_list) | |
1801 { | |
1802 image_overlay_queue_all(imd); | |
1803 } | |
1804 | |
1805 w = imd->vis_width - w; | |
1806 h = imd->vis_height - h; | |
1807 | |
1808 if (w > 0) | |
1809 { | |
1810 image_queue(imd, | |
1811 x_off > 0 ? imd->x_scroll + (imd->vis_width - w) : imd->x_scroll, imd->y_scroll, | |
1812 w, imd->vis_height, TRUE, TILE_RENDER_ALL, FALSE); | |
1813 } | |
1814 if (h > 0) | |
1815 { | |
1816 /* FIXME, to optimize this, remove overlap */ | |
1817 image_queue(imd, | |
1818 imd->x_scroll, y_off > 0 ? imd->y_scroll + (imd->vis_height - h) : imd->y_scroll, | |
1819 imd->vis_width, h, TRUE, TILE_RENDER_ALL, FALSE); | |
1820 } | |
1 | 1821 } |
1822 } | |
1823 | |
9 | 1824 static void widget_set_cursor(GtkWidget *widget, gint icon) |
1 | 1825 { |
1826 GdkCursor *cursor; | |
1827 | |
9 | 1828 if (!widget->window) return; |
1829 | |
1 | 1830 if (icon == -1) |
1831 { | |
1832 cursor = NULL; | |
1833 } | |
1834 else | |
1835 { | |
1836 cursor = gdk_cursor_new (icon); | |
1837 } | |
1838 | |
9 | 1839 gdk_window_set_cursor(widget->window, cursor); |
1840 | |
1841 if (cursor) gdk_cursor_unref(cursor); | |
1842 } | |
1843 | |
1844 /* | |
1845 *------------------------------------------------------------------- | |
1846 * image pixbuf handling | |
1847 *------------------------------------------------------------------- | |
1848 */ | |
1849 | |
1850 static void image_zoom_sync(ImageWindow *imd, gdouble zoom, | |
1851 gint force, gint blank, gint new, | |
1852 gint center_point, gint px, gint py) | |
1853 { | |
1854 gdouble old_scale; | |
1855 gint old_cx, old_cy; | |
1856 gint clamped; | |
1857 gint sized; | |
1858 | |
1859 old_scale = imd->scale; | |
1860 if (center_point) | |
1861 { | |
1862 px = CLAMP(px, 0, imd->width); | |
1863 py = CLAMP(py, 0, imd->height); | |
1864 old_cx = imd->x_scroll + (px - imd->x_offset); | |
1865 old_cy = imd->y_scroll + (py - imd->y_offset); | |
1866 } | |
1867 else | |
1868 { | |
1869 px = py = 0; | |
1870 old_cx = imd->x_scroll + imd->vis_width / 2; | |
1871 old_cy = imd->y_scroll + imd->vis_height / 2; | |
1872 } | |
1873 | |
1874 if (!image_zoom_clamp(imd, zoom, force, new)) return; | |
1875 | |
1876 clamped = image_size_clamp(imd); | |
1877 sized = image_size_top_window(imd, imd->width, imd->height); | |
1878 | |
1879 if (force) | |
1880 { | |
1881 /* force means new image, so update scroll offset per options */ | |
1882 switch (scroll_reset_method) | |
1883 { | |
1884 case SCROLL_RESET_NOCHANGE: | |
1885 /* maintain old scroll position, do nothing */ | |
1886 break; | |
1887 case SCROLL_RESET_CENTER: | |
1888 /* center new image */ | |
1889 imd->x_scroll = ((double)imd->image_width / 2.0 * imd->scale) - imd->vis_width / 2; | |
1890 imd->y_scroll = ((double)imd->image_height / 2.0 * imd->scale) - imd->vis_height / 2; | |
1891 break; | |
1892 case SCROLL_RESET_TOPLEFT: | |
1893 default: | |
1894 /* reset to upper left */ | |
1895 imd->x_scroll = 0; | |
1896 imd->y_scroll = 0; | |
1897 break; | |
1898 } | |
1899 } | |
1900 else | |
1901 { | |
1902 /* user zoom does not force, so keep visible center point */ | |
1903 if (center_point) | |
1904 { | |
1905 imd->x_scroll = old_cx / old_scale * imd->scale - (px - imd->x_offset); | |
1906 imd->y_scroll = old_cy / old_scale * imd->scale - (py - imd->y_offset); | |
1907 } | |
1908 else | |
1909 { | |
1910 imd->x_scroll = old_cx / old_scale * imd->scale - (imd->vis_width / 2); | |
1911 imd->y_scroll = old_cy / old_scale * imd->scale - (imd->vis_height / 2); | |
1912 } | |
1913 } | |
1914 image_scroll_clamp(imd); | |
1915 | |
1916 image_tile_sync(imd, imd->width, imd->height, blank); | |
1917 | |
1918 /* If the window was not sized, redraw the image - we know there will be no size/expose signal. | |
1919 * But even if a size is claimed, there is no guarantee that the window manager will allow it, | |
1920 * so redraw the window anyway :/ | |
1921 */ | |
1922 if (sized || clamped) image_border_clear(imd); | |
1923 image_redraw(imd, FALSE); | |
1924 | |
1925 if (imd->title_show_zoom) image_update_title(imd); | |
1926 image_update_util(imd); | |
1927 } | |
1928 | |
1929 static void image_pixbuf_sync(ImageWindow *imd, gdouble zoom, gint blank, gint new) | |
1930 { | |
1931 if (!imd->pixbuf) | |
1932 { | |
1933 /* no pixbuf so just clear the window */ | |
1934 imd->image_width = 0; | |
1935 imd->image_height = 0; | |
1936 imd->scale = 1.0; | |
1937 | |
1938 if (imd->image->window) | |
1939 { | |
1940 gdk_window_clear(imd->image->window); | |
1941 image_overlay_draw(imd, 0, 0, imd->window_width, imd->window_height); | |
1942 } | |
1943 | |
1944 image_update_util(imd); | |
1945 | |
1946 return; | |
1947 } | |
1948 | |
1949 imd->image_width = gdk_pixbuf_get_width(imd->pixbuf); | |
1950 imd->image_height = gdk_pixbuf_get_height(imd->pixbuf); | |
1951 | |
1952 #if 0 | |
1953 /* reset scrolling */ | |
1954 imd->x_scroll = 0; | |
1955 imd->y_scroll = 0; | |
1956 #endif | |
1957 | |
1958 image_zoom_sync(imd, zoom, TRUE, blank, new, FALSE, 0, 0); | |
1959 } | |
1960 | |
1961 static void image_set_pixbuf(ImageWindow *imd, GdkPixbuf *pixbuf, gdouble zoom, gint new) | |
1962 { | |
1963 if (pixbuf) g_object_ref(pixbuf); | |
1964 if (imd->pixbuf) g_object_unref(imd->pixbuf); | |
1965 imd->pixbuf = pixbuf; | |
1966 | |
1967 image_pixbuf_sync(imd, zoom, FALSE, new); | |
1968 } | |
1969 | |
1970 static void image_alter_real(ImageWindow *imd, AlterType type, gint clamp) | |
1971 { | |
1972 GdkPixbuf *new = NULL; | |
1973 gint x, y; | |
1974 gint t; | |
1975 | |
1976 imd->delay_alter_type = ALTER_NONE; | |
1977 | |
1978 if (!imd->pixbuf) return; | |
1979 | |
1980 x = imd->x_scroll + (imd->vis_width / 2); | |
1981 y = imd->y_scroll + (imd->vis_height / 2); | |
1982 | |
1983 switch (type) | |
1984 { | |
1985 case ALTER_ROTATE_90: | |
1986 new = pixbuf_copy_rotate_90(imd->pixbuf, FALSE); | |
1987 t = x; | |
1988 x = imd->height - y; | |
1989 y = t; | |
1990 break; | |
1991 case ALTER_ROTATE_90_CC: | |
1992 new = pixbuf_copy_rotate_90(imd->pixbuf, TRUE); | |
1993 t = x; | |
1994 x = y; | |
1995 y = imd->width - t; | |
1996 break; | |
1997 case ALTER_ROTATE_180: | |
1998 new = pixbuf_copy_mirror(imd->pixbuf, TRUE, TRUE); | |
1999 x = imd->width - x; | |
2000 y = imd->height - y; | |
2001 break; | |
2002 case ALTER_MIRROR: | |
2003 new = pixbuf_copy_mirror(imd->pixbuf, TRUE, FALSE); | |
2004 x = imd->width - x; | |
2005 break; | |
2006 case ALTER_FLIP: | |
2007 new = pixbuf_copy_mirror(imd->pixbuf, FALSE, TRUE); | |
2008 y = imd->height - y; | |
2009 break; | |
2010 case ALTER_NONE: | |
2011 default: | |
2012 return; | |
2013 break; | |
2014 } | |
2015 | |
2016 if (!new) return; | |
2017 | |
2018 if (clamp) | |
2019 { | |
2020 image_set_pixbuf(imd, new, imd->zoom, TRUE); | |
2021 g_object_unref(new); | |
2022 | |
2023 if (imd->zoom != 0.0) | |
2024 { | |
2025 image_scroll(imd, x - (imd->vis_width / 2), y - (imd->vis_height / 2)); | |
2026 } | |
2027 } | |
2028 else | |
2029 { | |
2030 g_object_unref(imd->pixbuf); | |
2031 imd->pixbuf = new; | |
2032 } | |
1 | 2033 } |
2034 | |
9 | 2035 static void image_post_process(ImageWindow *imd, gint clamp) |
2036 { | |
2037 if (exif_rotate_enable && imd->pixbuf) | |
2038 { | |
2039 ExifData *ed; | |
2040 gint orientation; | |
2041 | |
2042 ed = exif_read(imd->image_path); | |
2043 if (ed && exif_get_integer(ed, "Orientation", &orientation)) | |
2044 { | |
2045 /* see http://jpegclub.org/exif_orientation.html | |
2046 1 2 3 4 5 6 7 8 | |
2047 | |
2048 888888 888888 88 88 8888888888 88 88 8888888888 | |
2049 88 88 88 88 88 88 88 88 88 88 88 88 | |
2050 8888 8888 8888 8888 88 8888888888 8888888888 88 | |
2051 88 88 88 88 | |
2052 88 88 888888 888888 | |
2053 */ | |
2054 | |
2055 switch (orientation) | |
2056 { | |
2057 case EXIF_ORIENTATION_TOP_LEFT: | |
2058 /* normal -- nothing to do */ | |
2059 break; | |
2060 case EXIF_ORIENTATION_TOP_RIGHT: | |
2061 /* mirrored */ | |
2062 imd->delay_alter_type = ALTER_MIRROR; | |
2063 break; | |
2064 case EXIF_ORIENTATION_BOTTOM_RIGHT: | |
2065 /* upside down */ | |
2066 imd->delay_alter_type = ALTER_ROTATE_180; | |
2067 break; | |
2068 case EXIF_ORIENTATION_BOTTOM_LEFT: | |
2069 /* flipped */ | |
2070 imd->delay_alter_type = ALTER_FLIP; | |
2071 break; | |
2072 case EXIF_ORIENTATION_LEFT_TOP: | |
2073 /* not implemented -- too wacky to fix in one step */ | |
2074 break; | |
2075 case EXIF_ORIENTATION_RIGHT_TOP: | |
2076 /* rotated -90 (270) */ | |
2077 imd->delay_alter_type = ALTER_ROTATE_90; | |
2078 break; | |
2079 case EXIF_ORIENTATION_RIGHT_BOTTOM: | |
2080 /* not implemented -- too wacky to fix in one step */ | |
2081 break; | |
2082 case EXIF_ORIENTATION_LEFT_BOTTOM: | |
2083 /* rotated 90 */ | |
2084 imd->delay_alter_type = ALTER_ROTATE_90_CC; | |
2085 break; | |
2086 default: | |
2087 /* The other values are out of range */ | |
2088 break; | |
2089 } | |
2090 } | |
2091 exif_free(ed); | |
2092 } | |
2093 | |
2094 if (imd->delay_alter_type != ALTER_NONE) | |
2095 { | |
2096 image_alter_real(imd, imd->delay_alter_type, clamp); | |
2097 } | |
2098 } | |
2099 | |
2100 /* | |
2101 *------------------------------------------------------------------- | |
2102 * read ahead (prebuffer) | |
2103 *------------------------------------------------------------------- | |
2104 */ | |
2105 | |
2106 static void image_read_ahead_cancel(ImageWindow *imd) | |
2107 { | |
2108 if (debug) printf("read ahead cancelled for :%s\n", imd->read_ahead_path); | |
2109 | |
2110 image_loader_free(imd->read_ahead_il); | |
2111 imd->read_ahead_il = NULL; | |
2112 | |
2113 if (imd->read_ahead_pixbuf) g_object_unref(imd->read_ahead_pixbuf); | |
2114 imd->read_ahead_pixbuf = NULL; | |
2115 | |
2116 g_free(imd->read_ahead_path); | |
2117 imd->read_ahead_path = NULL; | |
2118 } | |
2119 | |
2120 static void image_read_ahead_done_cb(ImageLoader *il, gpointer data) | |
2121 { | |
2122 ImageWindow *imd = data; | |
2123 | |
2124 if (debug) printf("read ahead done for :%s\n", imd->read_ahead_path); | |
2125 | |
2126 imd->read_ahead_pixbuf = image_loader_get_pixbuf(imd->read_ahead_il); | |
2127 if (imd->read_ahead_pixbuf) | |
2128 { | |
2129 g_object_ref(imd->read_ahead_pixbuf); | |
2130 } | |
2131 else | |
2132 { | |
2133 imd->read_ahead_pixbuf = pixbuf_inline(PIXBUF_INLINE_BROKEN); | |
2134 } | |
2135 image_loader_free(imd->read_ahead_il); | |
2136 imd->read_ahead_il = NULL; | |
2137 | |
2138 image_complete_util(imd, TRUE); | |
2139 } | |
2140 | |
2141 static void image_read_ahead_error_cb(ImageLoader *il, gpointer data) | |
2142 { | |
2143 /* we even treat errors as success, maybe at least some of the file was ok */ | |
2144 image_read_ahead_done_cb(il, data); | |
2145 } | |
2146 | |
2147 static void image_read_ahead_start(ImageWindow *imd) | |
2148 { | |
2149 /* already started ? */ | |
2150 if (!imd->read_ahead_path || imd->read_ahead_il || imd->read_ahead_pixbuf) return; | |
2151 | |
2152 /* still loading ?, do later */ | |
2153 if (imd->il) return; | |
2154 | |
2155 if (debug) printf("read ahead started for :%s\n", imd->read_ahead_path); | |
2156 | |
2157 imd->read_ahead_il = image_loader_new(imd->read_ahead_path); | |
2158 | |
2159 image_loader_set_error_func(imd->read_ahead_il, image_read_ahead_error_cb, imd); | |
2160 if (!image_loader_start(imd->read_ahead_il, image_read_ahead_done_cb, imd)) | |
2161 { | |
2162 image_read_ahead_cancel(imd); | |
2163 image_complete_util(imd, TRUE); | |
2164 } | |
2165 } | |
2166 | |
2167 static void image_read_ahead_set(ImageWindow *imd, const gchar *path) | |
2168 { | |
2169 if (imd->read_ahead_path && path && strcmp(imd->read_ahead_path, path) == 0) return; | |
2170 | |
2171 image_read_ahead_cancel(imd); | |
2172 | |
2173 imd->read_ahead_path = g_strdup(path); | |
2174 | |
2175 if (debug) printf("read ahead set to :%s\n", imd->read_ahead_path); | |
2176 | |
2177 image_read_ahead_start(imd); | |
2178 } | |
2179 | |
2180 /* | |
2181 *------------------------------------------------------------------- | |
2182 * post buffering | |
2183 *------------------------------------------------------------------- | |
2184 */ | |
2185 | |
2186 static void image_post_buffer_set(ImageWindow *imd, const gchar *path, GdkPixbuf *pixbuf) | |
2187 { | |
2188 g_free(imd->prev_path); | |
2189 if (imd->prev_pixbuf) g_object_unref(imd->prev_pixbuf); | |
2190 | |
2191 if (path && pixbuf) | |
2192 { | |
2193 imd->prev_path = g_strdup(path); | |
2194 | |
2195 g_object_ref(pixbuf); | |
2196 imd->prev_pixbuf = pixbuf; | |
2197 } | |
2198 else | |
2199 { | |
2200 imd->prev_path = NULL; | |
2201 imd->prev_pixbuf = NULL; | |
2202 } | |
2203 | |
2204 if (debug) printf("post buffer set: %s\n", path); | |
2205 } | |
2206 | |
2207 static gint image_post_buffer_get(ImageWindow *imd) | |
2208 { | |
2209 gint success; | |
2210 | |
2211 if (imd->prev_pixbuf && | |
2212 imd->image_path && imd->prev_path && strcmp(imd->image_path, imd->prev_path) == 0) | |
2213 { | |
2214 if (imd->pixbuf) g_object_unref(imd->pixbuf); | |
2215 imd->pixbuf = imd->prev_pixbuf; | |
2216 success = TRUE; | |
2217 } | |
2218 else | |
2219 { | |
2220 if (imd->prev_pixbuf) g_object_unref(imd->prev_pixbuf); | |
2221 success = FALSE; | |
2222 } | |
2223 | |
2224 imd->prev_pixbuf = NULL; | |
2225 | |
2226 g_free(imd->prev_path); | |
2227 imd->prev_path = NULL; | |
2228 | |
2229 return success; | |
2230 } | |
2231 | |
2232 /* | |
2233 *------------------------------------------------------------------- | |
2234 * loading | |
2235 *------------------------------------------------------------------- | |
2236 */ | |
2237 | |
2238 static void image_load_pixbuf_ready(ImageWindow *imd) | |
2239 { | |
2240 if (imd->pixbuf || !imd->il) return; | |
2241 | |
2242 imd->pixbuf = image_loader_get_pixbuf(imd->il); | |
2243 | |
2244 if (imd->pixbuf) g_object_ref(imd->pixbuf); | |
2245 | |
2246 image_pixbuf_sync(imd, imd->zoom, TRUE, TRUE); | |
2247 } | |
2248 | |
2249 static void image_load_area_cb(ImageLoader *il, guint x, guint y, guint w, guint h, gpointer data) | |
2250 { | |
2251 ImageWindow *imd = data; | |
2252 | |
2253 if (imd->delay_flip && | |
2254 imd->pixbuf != image_loader_get_pixbuf(il)) | |
2255 { | |
2256 return; | |
2257 } | |
2258 | |
2259 if (!imd->pixbuf) image_load_pixbuf_ready(imd); | |
2260 | |
2261 if (imd->scale != 1.0) | |
2262 { | |
2263 x = (guint) floor((double)x * imd->scale); | |
2264 y = (guint) floor((double)y * imd->scale); | |
2265 w = (guint) ceil((double)w * imd->scale); | |
2266 h = (guint) ceil((double)h * imd->scale); | |
2267 | |
2268 if (w == 0) w = 1; | |
2269 if (h == 0) h = 1; | |
2270 | |
2271 if ((GdkInterpType)zoom_quality != GDK_INTERP_NEAREST) | |
2272 { | |
2273 /* some scaling types use surrounding pixels to smooth the image, | |
2274 * this will expand the new area to cover up for faint black | |
2275 * lines caused by previous renders with non-complete image | |
2276 */ | |
2277 y -= 1; | |
2278 h += 2; | |
2279 } | |
2280 | |
2281 } | |
2282 | |
2283 image_queue(imd, (gint) x, (gint) y, (gint) w, (gint) h, FALSE, TILE_RENDER_AREA, TRUE); | |
2284 } | |
2285 | |
2286 static void image_load_done_cb(ImageLoader *il, gpointer data) | |
1 | 2287 { |
2288 ImageWindow *imd = data; | |
9 | 2289 |
2290 if (debug) printf ("image done\n"); | |
2291 | |
2292 if (imd->delay_flip && | |
2293 imd->pixbuf != image_loader_get_pixbuf(imd->il)) | |
2294 { | |
2295 if (imd->pixbuf) g_object_unref(imd->pixbuf); | |
2296 imd->pixbuf = image_loader_get_pixbuf(imd->il); | |
2297 if (imd->pixbuf) g_object_ref(imd->pixbuf); | |
2298 image_pixbuf_sync(imd, imd->zoom, FALSE, TRUE); | |
2299 } | |
2300 | |
2301 image_loader_free(imd->il); | |
2302 imd->il = NULL; | |
2303 | |
2304 image_post_process(imd, TRUE); | |
2305 | |
2306 image_read_ahead_start(imd); | |
2307 } | |
2308 | |
2309 static void image_load_error_cb(ImageLoader *il, gpointer data) | |
2310 { | |
2311 if (debug) printf ("image error\n"); | |
2312 | |
2313 /* even on error handle it like it was done, | |
2314 * since we have a pixbuf with _something_ */ | |
2315 | |
2316 image_load_done_cb(il, data); | |
2317 } | |
2318 | |
2319 #ifdef IMAGE_THROTTLE_LARGER_IMAGES | |
2320 static void image_load_buffer_throttle(ImageLoader *il) | |
2321 { | |
2322 if (!il || il->bytes_total < IMAGE_THROTTLE_THRESHOLD) return; | |
2323 | |
2324 /* Larger image files usually have larger chunks of data per pixel... | |
2325 * So increase the buffer read size so that the rendering chunks called | |
2326 * are also larger. | |
2327 */ | |
2328 | |
2329 image_loader_set_buffer_size(il, IMAGE_LOAD_BUFFER_COUNT * IMAGE_THROTTLE_FACTOR); | |
2330 } | |
2331 #endif | |
2332 | |
2333 /* this read ahead is located here merely for the callbacks, above */ | |
2334 | |
2335 static gint image_read_ahead_check(ImageWindow *imd) | |
2336 { | |
2337 if (!imd->read_ahead_path) return FALSE; | |
2338 if (imd->il) return FALSE; | |
2339 | |
2340 if (!imd->image_path || strcmp(imd->read_ahead_path, imd->image_path) != 0) | |
2341 { | |
2342 image_read_ahead_cancel(imd); | |
2343 return FALSE; | |
2344 } | |
2345 | |
2346 if (imd->read_ahead_il) | |
2347 { | |
2348 imd->il = imd->read_ahead_il; | |
2349 imd->read_ahead_il = NULL; | |
2350 | |
2351 /* override the old signals */ | |
2352 image_loader_set_area_ready_func(imd->il, image_load_area_cb, imd); | |
2353 image_loader_set_error_func(imd->il, image_load_error_cb, imd); | |
2354 image_loader_set_buffer_size(imd->il, IMAGE_LOAD_BUFFER_COUNT); | |
2355 | |
2356 #ifdef IMAGE_THROTTLE_LARGER_IMAGES | |
2357 image_load_buffer_throttle(imd->il); | |
2358 #endif | |
2359 | |
2360 /* do this one directly (probably should add a set func) */ | |
2361 imd->il->func_done = image_load_done_cb; | |
2362 | |
2363 if (!imd->delay_flip) | |
2364 { | |
2365 if (imd->pixbuf) g_object_unref(imd->pixbuf); | |
2366 imd->pixbuf = image_loader_get_pixbuf(imd->il); | |
2367 if (imd->pixbuf) g_object_ref(imd->pixbuf); | |
2368 } | |
2369 | |
2370 image_read_ahead_cancel(imd); | |
2371 return TRUE; | |
2372 } | |
2373 else if (imd->read_ahead_pixbuf) | |
2374 { | |
2375 if (imd->pixbuf) g_object_unref(imd->pixbuf); | |
2376 imd->pixbuf = imd->read_ahead_pixbuf; | |
2377 imd->read_ahead_pixbuf = NULL; | |
2378 | |
2379 image_read_ahead_cancel(imd); | |
2380 | |
2381 image_post_process(imd, FALSE); | |
2382 return TRUE; | |
2383 } | |
2384 | |
2385 image_read_ahead_cancel(imd); | |
2386 return FALSE; | |
2387 } | |
2388 | |
2389 static gint image_load_begin(ImageWindow *imd, const gchar *path) | |
2390 { | |
2391 if (debug) printf ("image begin \n"); | |
2392 | |
2393 if (imd->il) return FALSE; | |
2394 | |
2395 imd->completed = FALSE; | |
2396 | |
2397 if (image_post_buffer_get(imd)) | |
2398 { | |
2399 if (debug) printf("from post buffer: %s\n", imd->image_path); | |
2400 | |
2401 image_pixbuf_sync(imd, imd->zoom, FALSE, TRUE); | |
2402 return TRUE; | |
2403 } | |
2404 | |
2405 if (image_read_ahead_check(imd)) | |
2406 { | |
2407 if (debug) printf("from read ahead buffer: %s\n", imd->image_path); | |
2408 | |
2409 if (!imd->delay_flip || !imd->il) image_pixbuf_sync(imd, imd->zoom, FALSE, TRUE); | |
2410 return TRUE; | |
2411 } | |
2412 | |
2413 if (!imd->delay_flip && imd->pixbuf) | |
2414 { | |
2415 g_object_unref(imd->pixbuf); | |
2416 imd->pixbuf = NULL; | |
2417 } | |
2418 | |
2419 imd->il = image_loader_new(path); | |
2420 | |
2421 image_loader_set_area_ready_func(imd->il, image_load_area_cb, imd); | |
2422 image_loader_set_error_func(imd->il, image_load_error_cb, imd); | |
2423 image_loader_set_buffer_size(imd->il, IMAGE_LOAD_BUFFER_COUNT); | |
2424 | |
2425 if (!image_loader_start(imd->il, image_load_done_cb, imd)) | |
2426 { | |
2427 if (debug) printf("image start error\n"); | |
2428 | |
2429 image_loader_free(imd->il); | |
2430 imd->il = NULL; | |
2431 | |
2432 image_complete_util(imd, FALSE); | |
2433 | |
2434 return FALSE; | |
2435 } | |
2436 | |
2437 #ifdef IMAGE_THROTTLE_LARGER_IMAGES | |
2438 image_load_buffer_throttle(imd->il); | |
2439 #endif | |
2440 | |
2441 if (!imd->delay_flip && !imd->pixbuf) image_load_pixbuf_ready(imd); | |
2442 | |
2443 return TRUE; | |
2444 } | |
2445 | |
2446 static void image_reset(ImageWindow *imd) | |
2447 { | |
2448 /* stops anything currently being done */ | |
2449 | |
2450 if (debug) printf("image reset\n"); | |
2451 | |
2452 image_loader_free(imd->il); | |
2453 imd->il = NULL; | |
2454 | |
2455 image_queue_clear(imd); | |
2456 imd->delay_alter_type = ALTER_NONE; | |
2457 } | |
2458 | |
2459 /* | |
2460 *------------------------------------------------------------------- | |
2461 * image changer | |
2462 *------------------------------------------------------------------- | |
2463 */ | |
2464 | |
2465 static void image_change_complete(ImageWindow *imd, gdouble zoom, gint new) | |
2466 { | |
2467 gint sync = TRUE; | |
2468 | |
12
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
2469 image_source_tile_unset(imd); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
2470 |
9 | 2471 imd->zoom = zoom; /* store the zoom, needed by the loader */ |
2472 | |
2473 image_reset(imd); | |
2474 | |
2475 if (imd->image_path && isfile(imd->image_path)) | |
2476 { | |
2477 if (image_load_begin(imd, imd->image_path)) | |
2478 { | |
2479 imd->unknown = FALSE; | |
2480 sync = FALSE; | |
2481 } | |
2482 else | |
2483 { | |
2484 if (imd->pixbuf) g_object_unref(imd->pixbuf); | |
2485 imd->pixbuf = pixbuf_inline(PIXBUF_INLINE_BROKEN); | |
2486 imd->unknown = TRUE; | |
2487 } | |
2488 imd->size = filesize(imd->image_path); | |
2489 imd->mtime = filetime(imd->image_path); | |
2490 } | |
2491 else | |
2492 { | |
2493 if (imd->pixbuf) g_object_unref(imd->pixbuf); | |
2494 imd->pixbuf = NULL; | |
2495 | |
2496 if (imd->image_path) | |
2497 { | |
2498 imd->pixbuf = pixbuf_inline(PIXBUF_INLINE_BROKEN); | |
2499 imd->mtime = filetime(imd->image_path); | |
2500 } | |
2501 else | |
2502 { | |
2503 imd->pixbuf = NULL; | |
2504 imd->mtime = 0; | |
2505 } | |
2506 imd->unknown = TRUE; | |
2507 imd->size = 0; | |
2508 } | |
2509 | |
2510 if (sync) | |
2511 { | |
2512 image_pixbuf_sync(imd, zoom, FALSE, new); | |
2513 } | |
2514 else | |
2515 { | |
2516 image_update_util(imd); | |
2517 } | |
2518 } | |
2519 | |
2520 static void image_change_real(ImageWindow *imd, const gchar *path, | |
2521 CollectionData *cd, CollectInfo *info, gdouble zoom) | |
2522 { | |
2523 GdkPixbuf *prev_pixbuf = NULL; | |
2524 gchar *prev_path = NULL; | |
2525 gint prev_clear = FALSE; | |
2526 | |
2527 imd->collection = cd; | |
2528 imd->collection_info = info; | |
2529 | |
2530 if (enable_read_ahead && imd->image_path && imd->pixbuf) | |
2531 { | |
2532 if (imd->il) | |
2533 { | |
2534 /* current image is not finished */ | |
2535 prev_clear = TRUE; | |
2536 } | |
2537 else | |
2538 { | |
2539 prev_path = g_strdup(imd->image_path); | |
2540 prev_pixbuf = imd->pixbuf; | |
2541 g_object_ref(prev_pixbuf); | |
2542 } | |
2543 } | |
2544 | |
2545 g_free(imd->image_path); | |
2546 imd->image_path = g_strdup(path); | |
2547 imd->image_name = filename_from_path(imd->image_path); | |
2548 | |
2549 image_change_complete(imd, zoom, TRUE); | |
2550 | |
2551 if (prev_pixbuf) | |
2552 { | |
2553 image_post_buffer_set(imd, prev_path, prev_pixbuf); | |
2554 g_free(prev_path); | |
2555 g_object_unref(prev_pixbuf); | |
2556 } | |
2557 else if (prev_clear) | |
2558 { | |
2559 image_post_buffer_set(imd, NULL, NULL); | |
2560 } | |
2561 | |
2562 image_update_title(imd); | |
2563 image_new_util(imd); | |
2564 } | |
2565 | |
2566 /* | |
2567 *------------------------------------------------------------------- | |
2568 * callbacks | |
2569 *------------------------------------------------------------------- | |
2570 */ | |
2571 | |
2572 static gint image_expose_cb(GtkWidget *widget, GdkEventExpose *event, gpointer data) | |
2573 { | |
2574 gint x, y; | |
2575 | |
2576 ImageWindow *imd = data; | |
2577 | |
2578 image_border_draw(imd, event->area.x, event->area.y, | |
2579 event->area.width, event->area.height); | |
2580 | |
2581 /* image */ | |
2582 x = MAX(0, (gint)event->area.x - imd->x_offset + imd->x_scroll); | |
2583 y = MAX(0, (gint)event->area.y - imd->y_offset + imd->y_scroll); | |
2584 | |
2585 image_queue(imd, x, y, | |
2586 MIN((gint)event->area.width, imd->width - x), | |
2587 MIN((gint)event->area.height, imd->height - y), | |
2588 FALSE, TILE_RENDER_ALL, FALSE); | |
2589 | |
2590 return TRUE; | |
2591 } | |
2592 | |
2593 static void image_size_cb(GtkWidget *widget, GtkAllocation *allocation, gpointer data) | |
2594 { | |
2595 ImageWindow *imd = data; | |
2596 | |
2597 image_size_sync(imd, allocation->width, allocation->height); | |
2598 } | |
2599 | |
2600 /* | |
2601 *------------------------------------------------------------------- | |
2602 * focus stuff | |
2603 *------------------------------------------------------------------- | |
2604 */ | |
2605 | |
2606 static void image_focus_paint(ImageWindow *imd, gint has_focus, GdkRectangle *area) | |
2607 { | |
2608 GtkWidget *widget; | |
2609 | |
2610 widget = imd->widget; | |
2611 if (!widget->window) return; | |
2612 | |
2613 if (has_focus) | |
2614 { | |
2615 gtk_paint_focus (widget->style, widget->window, GTK_STATE_ACTIVE, | |
2616 area, widget, "image_window", | |
2617 widget->allocation.x, widget->allocation.y, | |
2618 widget->allocation.width - 1, widget->allocation.height - 1); | |
2619 } | |
2620 else | |
2621 { | |
2622 gtk_paint_shadow (widget->style, widget->window, GTK_STATE_NORMAL, GTK_SHADOW_IN, | |
2623 area, widget, "image_window", | |
2624 widget->allocation.x, widget->allocation.y, | |
2625 widget->allocation.width - 1, widget->allocation.height - 1); | |
2626 } | |
2627 } | |
2628 | |
2629 static gint image_focus_expose(GtkWidget *widget, GdkEventExpose *event, gpointer data) | |
2630 { | |
2631 ImageWindow *imd = data; | |
2632 | |
2633 image_focus_paint(imd, GTK_WIDGET_HAS_FOCUS(widget), &event->area); | |
2634 return TRUE; | |
2635 } | |
2636 | |
2637 static gint image_focus_in_cb(GtkWidget *widget, GdkEventFocus *event, gpointer data) | |
2638 { | |
2639 ImageWindow *imd = data; | |
2640 | |
2641 GTK_WIDGET_SET_FLAGS(imd->widget, GTK_HAS_FOCUS); | |
2642 image_focus_paint(imd, TRUE, NULL); | |
2643 | |
2644 return TRUE; | |
2645 } | |
2646 | |
2647 static gint image_focus_out_cb(GtkWidget *widget, GdkEventFocus *event, gpointer data) | |
2648 { | |
2649 ImageWindow *imd = data; | |
2650 | |
2651 GTK_WIDGET_UNSET_FLAGS(imd->widget, GTK_HAS_FOCUS); | |
2652 image_focus_paint(imd, FALSE, NULL); | |
2653 | |
2654 return TRUE; | |
2655 } | |
2656 | |
2657 | |
2658 /* | |
2659 *------------------------------------------------------------------- | |
2660 * overlays | |
2661 *------------------------------------------------------------------- | |
2662 */ | |
2663 | |
2664 static void image_overlay_draw(ImageWindow *imd, gint x, gint y, gint w, gint h) | |
2665 { | |
2666 GList *work; | |
2667 | |
2668 work = imd->overlay_list; | |
2669 while (work) | |
2670 { | |
2671 OverlayData *od; | |
2672 gint px, py, pw, ph; | |
2673 gint rx, ry, rw, rh; | |
2674 | |
2675 od = work->data; | |
2676 work = work->next; | |
2677 | |
2678 if (!od->visible) continue; | |
2679 | |
2680 pw = gdk_pixbuf_get_width(od->pixbuf); | |
2681 ph = gdk_pixbuf_get_height(od->pixbuf); | |
2682 px = od->x; | |
2683 py = od->y; | |
2684 | |
2685 if (od->relative) | |
2686 { | |
2687 if (px < 0) px = imd->window_width - pw + px; | |
2688 if (py < 0) py = imd->window_height - ph + py; | |
2689 } | |
2690 | |
2691 if (util_clip_region(x, y, w, h, px, py, pw, ph, &rx, &ry, &rw, &rh)) | |
2692 { | |
2693 gdk_draw_pixbuf(imd->image->window, | |
2694 imd->image->style->fg_gc[GTK_WIDGET_STATE(imd->image)], | |
2695 od->pixbuf, | |
2696 rx - px, ry - py, | |
2697 rx, ry, rw, rh, | |
2698 (GdkRgbDither)dither_quality, rx, ry); | |
2699 } | |
2700 } | |
2701 } | |
2702 | |
2703 static void image_overlay_queue_draw(ImageWindow *imd, OverlayData *od, gint hidden) | |
2704 { | |
2705 gint x, y, w, h; | |
2706 gint old_vis; | |
2707 | |
2708 w = gdk_pixbuf_get_width(od->pixbuf); | |
2709 h = gdk_pixbuf_get_height(od->pixbuf); | |
2710 x = od->x; | |
2711 y = od->y; | |
2712 | |
2713 if (od->relative) | |
2714 { | |
2715 if (x < 0) x = imd->window_width - w + x; | |
2716 if (y < 0) y = imd->window_height - h + y; | |
2717 } | |
2718 | |
2719 image_queue(imd, imd->x_scroll - imd->x_offset + x, | |
2720 imd->y_scroll - imd->y_offset + y, | |
2721 w, h, | |
2722 FALSE, TILE_RENDER_ALL, FALSE); | |
2723 | |
2724 old_vis = od->visible; | |
2725 if (hidden) od->visible = FALSE; | |
2726 image_border_draw(imd, x, y, w, h); | |
2727 od->visible = old_vis; | |
2728 } | |
2729 | |
2730 static void image_overlay_queue_all(ImageWindow *imd) | |
2731 { | |
2732 GList *work; | |
2733 | |
2734 work = imd->overlay_list; | |
2735 while (work) | |
2736 { | |
2737 OverlayData *od = work->data; | |
2738 work = work->next; | |
2739 | |
2740 image_overlay_queue_draw(imd, od, FALSE); | |
2741 } | |
2742 } | |
2743 | |
2744 static OverlayData *image_overlay_find(ImageWindow *imd, gint id) | |
2745 { | |
2746 GList *work; | |
2747 | |
2748 work = imd->overlay_list; | |
2749 while (work) | |
2750 { | |
2751 OverlayData *od = work->data; | |
2752 work = work->next; | |
2753 | |
2754 if (od->id == id) return od; | |
2755 } | |
2756 | |
2757 return NULL; | |
2758 } | |
2759 | |
2760 gint image_overlay_add(ImageWindow *imd, GdkPixbuf *pixbuf, gint x, gint y, | |
2761 gint relative, gint always) | |
2762 { | |
2763 OverlayData *od; | |
2764 gint id; | |
2765 | |
2766 if (!imd || !pixbuf) return -1; | |
2767 | |
2768 id = 1; | |
2769 while (image_overlay_find(imd, id)) id++; | |
2770 | |
2771 od = g_new0(OverlayData, 1); | |
2772 od->id = id; | |
2773 od->pixbuf = pixbuf; | |
2774 g_object_ref(G_OBJECT(od->pixbuf)); | |
2775 od->x = x; | |
2776 od->y = y; | |
2777 od->relative = relative; | |
2778 od->visible = TRUE; | |
2779 od->always = always; | |
2780 | |
2781 imd->overlay_list = g_list_append(imd->overlay_list, od); | |
2782 | |
2783 image_overlay_queue_draw(imd, od, FALSE); | |
2784 | |
2785 return od->id; | |
2786 } | |
2787 | |
2788 static void image_overlay_free(ImageWindow *imd, OverlayData *od) | |
2789 { | |
2790 imd->overlay_list = g_list_remove(imd->overlay_list, od); | |
2791 | |
2792 if (od->pixbuf) g_object_unref(G_OBJECT(od->pixbuf)); | |
2793 g_free(od); | |
2794 } | |
2795 | |
2796 static void image_overlay_list_clear(ImageWindow *imd) | |
2797 { | |
2798 while (imd->overlay_list) | |
2799 { | |
2800 OverlayData *od; | |
2801 | |
2802 od = imd->overlay_list->data; | |
2803 image_overlay_free(imd, od); | |
2804 } | |
2805 } | |
2806 | |
2807 void image_overlay_set(ImageWindow *imd, gint id, GdkPixbuf *pixbuf, gint x, gint y) | |
2808 { | |
2809 OverlayData *od; | |
2810 | |
2811 if (!imd) return; | |
2812 | |
2813 od = image_overlay_find(imd, id); | |
2814 if (!od) return; | |
2815 | |
2816 if (pixbuf) | |
2817 { | |
2818 image_overlay_queue_draw(imd, od, TRUE); | |
2819 | |
2820 g_object_ref(G_OBJECT(pixbuf)); | |
2821 g_object_unref(G_OBJECT(od->pixbuf)); | |
2822 od->pixbuf = pixbuf; | |
2823 | |
2824 od->x = x; | |
2825 od->y = y; | |
2826 | |
2827 image_overlay_queue_draw(imd, od, FALSE); | |
2828 } | |
2829 else | |
2830 { | |
2831 image_overlay_queue_draw(imd, od, TRUE); | |
2832 image_overlay_free(imd, od); | |
2833 } | |
2834 } | |
2835 | |
2836 gint image_overlay_get(ImageWindow *imd, gint id, GdkPixbuf **pixbuf, gint *x, gint *y) | |
2837 { | |
2838 OverlayData *od; | |
2839 | |
2840 if (!imd) return FALSE; | |
2841 | |
2842 od = image_overlay_find(imd, id); | |
2843 if (!od) return FALSE; | |
2844 | |
2845 if (pixbuf) *pixbuf = od->pixbuf; | |
2846 if (x) *x = od->x; | |
2847 if (y) *y = od->y; | |
2848 | |
2849 return TRUE; | |
2850 } | |
2851 | |
2852 void image_overlay_remove(ImageWindow *imd, gint id) | |
2853 { | |
2854 image_overlay_set(imd, id, NULL, 0, 0); | |
2855 } | |
2856 | |
2857 /* | |
2858 *------------------------------------------------------------------- | |
2859 * scroller | |
2860 *------------------------------------------------------------------- | |
2861 */ | |
2862 | |
2863 #define SCROLLER_UPDATES_PER_SEC 30 | |
2864 #define SCROLLER_DEAD_ZONE 6 | |
2865 | |
2866 | |
2867 static gboolean image_scroller_update_cb(gpointer data) | |
2868 { | |
2869 ImageWindow *imd = data; | |
2870 gint x, y; | |
2871 gint xinc, yinc; | |
2872 | |
2873 /* this was a simple scroll by difference between scroller and mouse position, | |
2874 * but all this math results in a smoother result and accounts for a dead zone. | |
2875 */ | |
2876 | |
2877 if (abs(imd->scroller_xpos - imd->scroller_x) < SCROLLER_DEAD_ZONE) | |
2878 { | |
2879 x = 0; | |
2880 } | |
2881 else | |
2882 { | |
2883 gint shift = SCROLLER_DEAD_ZONE / 2 * SCROLLER_UPDATES_PER_SEC; | |
2884 x = (imd->scroller_xpos - imd->scroller_x) / 2 * SCROLLER_UPDATES_PER_SEC; | |
2885 x += (x > 0) ? -shift : shift; | |
2886 } | |
2887 | |
2888 if (abs(imd->scroller_ypos - imd->scroller_y) < SCROLLER_DEAD_ZONE) | |
2889 { | |
2890 y = 0; | |
2891 } | |
2892 else | |
2893 { | |
2894 gint shift = SCROLLER_DEAD_ZONE / 2 * SCROLLER_UPDATES_PER_SEC; | |
2895 y = (imd->scroller_ypos - imd->scroller_y) / 2 * SCROLLER_UPDATES_PER_SEC; | |
2896 y += (y > 0) ? -shift : shift; | |
2897 } | |
2898 | |
2899 if (abs(x) < SCROLLER_DEAD_ZONE * SCROLLER_UPDATES_PER_SEC) | |
2900 { | |
2901 xinc = x; | |
2902 } | |
2903 else | |
2904 { | |
2905 xinc = imd->scroller_xinc; | |
2906 | |
2907 if (x >= 0) | |
2908 { | |
2909 if (xinc < 0) xinc = 0; | |
2910 if (x < xinc) xinc = x; | |
2911 if (x > xinc) xinc = MIN(xinc + x / SCROLLER_UPDATES_PER_SEC, x); | |
2912 } | |
2913 else | |
2914 { | |
2915 if (xinc > 0) xinc = 0; | |
2916 if (x > xinc) xinc = x; | |
2917 if (x < xinc) xinc = MAX(xinc + x / SCROLLER_UPDATES_PER_SEC, x); | |
2918 } | |
2919 } | |
2920 | |
2921 if (abs(y) < SCROLLER_DEAD_ZONE * SCROLLER_UPDATES_PER_SEC) | |
2922 { | |
2923 yinc = y; | |
2924 } | |
2925 else | |
2926 { | |
2927 yinc = imd->scroller_yinc; | |
2928 | |
2929 if (y >= 0) | |
2930 { | |
2931 if (yinc < 0) yinc = 0; | |
2932 if (y < yinc) yinc = y; | |
2933 if (y > yinc) yinc = MIN(yinc + y / SCROLLER_UPDATES_PER_SEC, y); | |
2934 } | |
2935 else | |
2936 { | |
2937 if (yinc > 0) yinc = 0; | |
2938 if (y > yinc) yinc = y; | |
2939 if (y < yinc) yinc = MAX(yinc + y / SCROLLER_UPDATES_PER_SEC, y); | |
2940 } | |
2941 } | |
2942 | |
2943 imd->scroller_xinc = xinc; | |
2944 imd->scroller_yinc = yinc; | |
2945 | |
2946 xinc = xinc / SCROLLER_UPDATES_PER_SEC; | |
2947 yinc = yinc / SCROLLER_UPDATES_PER_SEC; | |
2948 | |
2949 image_scroll(imd, xinc, yinc); | |
2950 | |
2951 return TRUE; | |
2952 } | |
2953 | |
2954 static void image_scroller_timer_set(ImageWindow *imd, gint start) | |
2955 { | |
2956 if (imd->scroller_id != -1) | |
2957 { | |
2958 g_source_remove(imd->scroller_id); | |
2959 imd->scroller_id = -1; | |
2960 } | |
2961 | |
2962 if (start) | |
2963 { | |
2964 imd->scroller_id = g_timeout_add(1000 / SCROLLER_UPDATES_PER_SEC, | |
2965 image_scroller_update_cb, imd); | |
2966 } | |
2967 } | |
2968 | |
2969 static void image_scroller_start(ImageWindow *imd, gint x, gint y) | |
2970 { | |
2971 if (imd->scroller_overlay == -1) | |
2972 { | |
2973 GdkPixbuf *pixbuf; | |
2974 gint w, h; | |
2975 | |
2976 pixbuf = pixbuf_inline(PIXBUF_INLINE_SCROLLER); | |
2977 w = gdk_pixbuf_get_width(pixbuf); | |
2978 h = gdk_pixbuf_get_height(pixbuf); | |
2979 | |
2980 imd->scroller_overlay = image_overlay_add(imd, pixbuf, x - w / 2, y - h / 2, FALSE, TRUE); | |
2981 } | |
2982 | |
2983 imd->scroller_x = x; | |
2984 imd->scroller_y = y; | |
2985 imd->scroller_xpos = x; | |
2986 imd->scroller_ypos = y; | |
2987 | |
2988 image_scroller_timer_set(imd, TRUE); | |
2989 } | |
2990 | |
2991 static void image_scroller_stop(ImageWindow *imd) | |
2992 { | |
2993 if (imd->scroller_id == -1) return; | |
2994 | |
2995 image_overlay_remove(imd, imd->scroller_overlay); | |
2996 imd->scroller_overlay = -1; | |
2997 | |
2998 image_scroller_timer_set(imd, FALSE); | |
2999 } | |
3000 | |
3001 /* | |
3002 *------------------------------------------------------------------- | |
3003 * mouse stuff | |
3004 *------------------------------------------------------------------- | |
3005 */ | |
3006 | |
3007 static gint image_mouse_motion_cb(GtkWidget *widget, GdkEventButton *bevent, gpointer data) | |
3008 { | |
3009 ImageWindow *imd = data; | |
14
25335c62cd9b
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
13
diff
changeset
|
3010 gint accel; |
9 | 3011 |
3012 if (imd->scroller_id != -1) | |
3013 { | |
3014 imd->scroller_xpos = bevent->x; | |
3015 imd->scroller_ypos = bevent->y; | |
3016 } | |
3017 | |
3018 if (!imd->in_drag || !gdk_pointer_is_grabbed()) return FALSE; | |
3019 | |
3020 if (imd->drag_moved < IMAGE_DRAG_SCROLL_THRESHHOLD) | |
1 | 3021 { |
3022 imd->drag_moved++; | |
3023 } | |
3024 else | |
3025 { | |
9 | 3026 widget_set_cursor (imd->image, GDK_FLEUR); |
1 | 3027 } |
3028 | |
14
25335c62cd9b
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
13
diff
changeset
|
3029 if (bevent->state & GDK_SHIFT_MASK) |
25335c62cd9b
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
13
diff
changeset
|
3030 { |
25335c62cd9b
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
13
diff
changeset
|
3031 accel = IMAGE_PAN_SHIFT_MULTIPLIER; |
25335c62cd9b
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
13
diff
changeset
|
3032 } |
25335c62cd9b
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
13
diff
changeset
|
3033 else |
25335c62cd9b
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
13
diff
changeset
|
3034 { |
25335c62cd9b
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
13
diff
changeset
|
3035 accel = 1; |
25335c62cd9b
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
13
diff
changeset
|
3036 } |
25335c62cd9b
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
13
diff
changeset
|
3037 |
9 | 3038 /* do the scroll */ |
14
25335c62cd9b
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
13
diff
changeset
|
3039 image_scroll_real(imd, (imd->drag_last_x - bevent->x) * accel, |
25335c62cd9b
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
13
diff
changeset
|
3040 (imd->drag_last_y - bevent->y) * accel); |
1 | 3041 |
3042 imd->drag_last_x = bevent->x; | |
3043 imd->drag_last_y = bevent->y; | |
9 | 3044 |
3045 return FALSE; | |
1 | 3046 } |
3047 | |
9 | 3048 static gint image_mouse_press_cb(GtkWidget *widget, GdkEventButton *bevent, gpointer data) |
1 | 3049 { |
3050 ImageWindow *imd = data; | |
9 | 3051 |
3052 if (imd->scroller_id != -1) return TRUE; | |
3053 | |
1 | 3054 switch (bevent->button) |
3055 { | |
3056 case 1: | |
3057 imd->in_drag = TRUE; | |
3058 imd->drag_last_x = bevent->x; | |
3059 imd->drag_last_y = bevent->y; | |
3060 imd->drag_moved = 0; | |
9 | 3061 gdk_pointer_grab(imd->image->window, FALSE, |
3062 GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK, | |
1 | 3063 NULL, NULL, bevent->time); |
9 | 3064 gtk_grab_add(imd->image); |
1 | 3065 break; |
3066 case 2: | |
3067 imd->drag_moved = 0; | |
3068 break; | |
3069 case 3: | |
9 | 3070 image_button_do(imd, bevent); |
4 | 3071 break; |
1 | 3072 default: |
3073 break; | |
3074 } | |
9 | 3075 |
3076 gtk_widget_grab_focus(imd->widget); | |
3077 | |
3078 return FALSE; | |
1 | 3079 } |
3080 | |
9 | 3081 static gint image_mouse_release_cb(GtkWidget *widget, GdkEventButton *bevent, gpointer data) |
1 | 3082 { |
3083 ImageWindow *imd = data; | |
9 | 3084 |
3085 if (imd->scroller_id != -1) | |
1 | 3086 { |
9 | 3087 image_scroller_stop(imd); |
3088 return TRUE; | |
1 | 3089 } |
3090 | |
9 | 3091 if (gdk_pointer_is_grabbed() && GTK_WIDGET_HAS_GRAB(imd->image)) |
1 | 3092 { |
9 | 3093 gtk_grab_remove(imd->image); |
3094 gdk_pointer_ungrab(bevent->time); | |
3095 widget_set_cursor(imd->image, -1); | |
1 | 3096 } |
3097 | |
14
25335c62cd9b
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
13
diff
changeset
|
3098 if (imd->drag_moved < IMAGE_DRAG_SCROLL_THRESHHOLD) |
1 | 3099 { |
14
25335c62cd9b
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
13
diff
changeset
|
3100 if (bevent->button == 1 && (bevent->state & GDK_SHIFT_MASK)) |
25335c62cd9b
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
13
diff
changeset
|
3101 { |
25335c62cd9b
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
13
diff
changeset
|
3102 image_scroller_start(imd, bevent->x, bevent->y); |
25335c62cd9b
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
13
diff
changeset
|
3103 } |
25335c62cd9b
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
13
diff
changeset
|
3104 else if (bevent->button == 1 || bevent->button == 2) |
25335c62cd9b
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
13
diff
changeset
|
3105 { |
25335c62cd9b
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
13
diff
changeset
|
3106 image_button_do(imd, bevent); |
25335c62cd9b
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
13
diff
changeset
|
3107 } |
1 | 3108 } |
3109 | |
3110 imd->in_drag = FALSE; | |
9 | 3111 |
3112 return FALSE; | |
1 | 3113 } |
3114 | |
9 | 3115 static gint image_mouse_leave_cb(GtkWidget *widget, GdkEventCrossing *event, gpointer data) |
1 | 3116 { |
3117 ImageWindow *imd = data; | |
9 | 3118 |
3119 if (imd->scroller_id != -1) | |
3120 { | |
3121 imd->scroller_xpos = imd->scroller_x; | |
3122 imd->scroller_ypos = imd->scroller_y; | |
3123 imd->scroller_xinc = 0; | |
3124 imd->scroller_yinc = 0; | |
3125 } | |
3126 | |
3127 return FALSE; | |
3128 } | |
3129 | |
3130 static gint image_scroll_cb(GtkWidget *widget, GdkEventScroll *event, gpointer data) | |
3131 { | |
3132 ImageWindow *imd = data; | |
3133 | |
3134 if (imd->func_scroll && | |
3135 event && event->type == GDK_SCROLL) | |
3136 { | |
3137 imd->func_scroll(imd, event->direction, event->time, | |
3138 event->x, event->y, event->state, imd->data_scroll); | |
3139 return TRUE; | |
3140 } | |
3141 | |
3142 return FALSE; | |
3143 } | |
3144 | |
3145 static void image_mouse_drag_cb(GtkWidget *widget, GdkDragContext *context, gpointer data) | |
3146 { | |
3147 ImageWindow *imd = data; | |
3148 | |
3149 imd->drag_moved = IMAGE_DRAG_SCROLL_THRESHHOLD; | |
1 | 3150 } |
3151 | |
3152 /* | |
9 | 3153 *------------------------------------------------------------------- |
3154 * drag and drop | |
3155 *------------------------------------------------------------------- | |
3156 */ | |
3157 | |
3158 /* | |
3159 *------------------------------------------------------------------- | |
3160 * public interface | |
3161 *------------------------------------------------------------------- | |
3162 */ | |
3163 | |
3164 void image_attach_window(ImageWindow *imd, GtkWidget *window, | |
3165 const gchar *title, const gchar *title_right, gint show_zoom) | |
1 | 3166 { |
3167 imd->top_window = window; | |
3168 g_free(imd->title); | |
9 | 3169 imd->title = g_strdup(title); |
3170 g_free(imd->title_right); | |
3171 imd->title_right = g_strdup(title_right); | |
3172 imd->title_show_zoom = show_zoom; | |
3173 | |
3174 image_update_title(imd); | |
3175 } | |
3176 | |
3177 void image_set_update_func(ImageWindow *imd, | |
3178 void (*func)(ImageWindow *imd, gpointer data), | |
3179 gpointer data) | |
3180 { | |
3181 imd->func_update = func; | |
3182 imd->data_update = data; | |
1 | 3183 } |
3184 | |
9 | 3185 void image_set_complete_func(ImageWindow *imd, |
3186 void (*func)(ImageWindow *, gint preload, gpointer), | |
3187 gpointer data) | |
1 | 3188 { |
9 | 3189 imd->func_complete = func; |
3190 imd->data_complete = data; | |
1 | 3191 } |
3192 | |
9 | 3193 void image_set_new_func(ImageWindow *imd, |
3194 void (*func)(ImageWindow *, gpointer), | |
3195 gpointer data) | |
1 | 3196 { |
9 | 3197 imd->func_new = func; |
3198 imd->data_new = data; | |
3199 } | |
3200 | |
3201 | |
3202 static void image_button_do(ImageWindow *imd, GdkEventButton *bevent) | |
3203 { | |
3204 if (imd->func_button && | |
3205 bevent && | |
3206 (bevent->type == GDK_BUTTON_PRESS || bevent->type == GDK_BUTTON_RELEASE)) | |
1 | 3207 { |
9 | 3208 imd->func_button(imd, bevent->button, bevent->time, |
3209 bevent->x, bevent->y, bevent->state, imd->data_button); | |
1 | 3210 } |
3211 } | |
3212 | |
9 | 3213 void image_set_button_func(ImageWindow *imd, |
3214 void (*func)(ImageWindow *, gint button, guint32 time, gdouble x, gdouble y, guint state, gpointer), | |
3215 gpointer data) | |
3216 { | |
3217 imd->func_button = func; | |
3218 imd->data_button = data; | |
3219 } | |
3220 | |
3221 void image_set_scroll_func(ImageWindow *imd, | |
3222 void (*func)(ImageWindow *, GdkScrollDirection direction, guint32 time, gdouble x, gdouble y, guint state, gpointer), | |
3223 gpointer data) | |
1 | 3224 { |
9 | 3225 imd->func_scroll = func; |
3226 imd->data_scroll = data; | |
1 | 3227 } |
3228 | |
12
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3229 void image_set_scroll_notify_func(ImageWindow *imd, |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3230 void (*func)(ImageWindow *imd, gint x, gint y, gint width, gint height, gpointer data), |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3231 gpointer data) |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3232 { |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3233 imd->func_scroll_notify = func; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3234 imd->data_scroll_notify = data; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3235 } |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3236 |
9 | 3237 /* path, name */ |
3238 | |
3239 const gchar *image_get_path(ImageWindow *imd) | |
3240 { | |
3241 return imd->image_path; | |
3242 } | |
3243 | |
3244 const gchar *image_get_name(ImageWindow *imd) | |
3245 { | |
3246 return imd->image_name; | |
3247 } | |
3248 | |
3249 /* merely changes path string, does not change the image! */ | |
3250 void image_set_path(ImageWindow *imd, const gchar *newpath) | |
1 | 3251 { |
3252 g_free(imd->image_path); | |
9 | 3253 imd->image_path = g_strdup(newpath); |
3254 imd->image_name = filename_from_path(imd->image_path); | |
3255 | |
3256 image_update_title(imd); | |
3257 image_new_util(imd); | |
3258 } | |
3259 | |
3260 /* load a new image */ | |
3261 | |
3262 void image_change_path(ImageWindow *imd, const gchar *path, gdouble zoom) | |
3263 { | |
3264 if (imd->image_path == path || | |
3265 (path && imd->image_path && !strcmp(path, imd->image_path)) ) return; | |
3266 | |
12
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3267 image_source_tile_unset(imd); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3268 |
9 | 3269 image_change_real(imd, path, NULL, NULL, zoom); |
3270 } | |
3271 | |
3272 void image_change_pixbuf(ImageWindow *imd, GdkPixbuf *pixbuf, gdouble zoom) | |
3273 { | |
12
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3274 image_source_tile_unset(imd); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3275 |
9 | 3276 image_set_pixbuf(imd, pixbuf, zoom, TRUE); |
3277 image_new_util(imd); | |
3278 } | |
3279 | |
3280 void image_change_from_collection(ImageWindow *imd, CollectionData *cd, CollectInfo *info, gdouble zoom) | |
3281 { | |
3282 if (!cd || !info || !g_list_find(cd->list, info)) return; | |
3283 | |
12
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3284 image_source_tile_unset(imd); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3285 |
9 | 3286 image_change_real(imd, info->path, cd, info, zoom); |
3287 } | |
3288 | |
3289 CollectionData *image_get_collection(ImageWindow *imd, CollectInfo **info) | |
3290 { | |
3291 if (collection_to_number(imd->collection) >= 0) | |
3292 { | |
3293 if (g_list_find(imd->collection->list, imd->collection_info) != NULL) | |
3294 { | |
3295 if (info) *info = imd->collection_info; | |
3296 } | |
3297 else | |
3298 { | |
3299 if (info) *info = NULL; | |
3300 } | |
3301 return imd->collection; | |
3302 } | |
3303 | |
3304 if (info) *info = NULL; | |
3305 return NULL; | |
3306 } | |
3307 | |
3308 static void image_loader_sync_data(ImageLoader *il, gpointer data) | |
3309 { | |
3310 /* change data for the callbacks directly */ | |
3311 | |
3312 il->data_area_ready = data; | |
3313 il->data_error = data; | |
3314 il->data_done = data; | |
3315 il->data_percent = data; | |
1 | 3316 } |
3317 | |
9 | 3318 /* this is more like a move function |
3319 * it moves most data from source to imd, source does keep a ref on the pixbuf | |
3320 */ | |
3321 void image_change_from_image(ImageWindow *imd, ImageWindow *source) | |
3322 { | |
3323 if (imd == source) return; | |
3324 | |
12
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3325 imd->zoom_min = source->zoom_min; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3326 imd->zoom_max = source->zoom_max; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3327 |
9 | 3328 imd->unknown = source->unknown; |
3329 | |
3330 image_set_pixbuf(imd, source->pixbuf, image_zoom_get(source), TRUE); | |
3331 | |
3332 imd->collection = source->collection; | |
3333 imd->collection_info = source->collection_info; | |
3334 imd->size = source->size; | |
3335 imd->mtime = source->mtime; | |
3336 | |
3337 image_set_path(imd, image_get_path(source)); | |
3338 | |
3339 image_loader_free(imd->il); | |
3340 imd->il = NULL; | |
3341 | |
3342 if (imd->pixbuf && source->il) | |
3343 { | |
3344 imd->il = source->il; | |
3345 source->il = NULL; | |
3346 | |
3347 image_loader_sync_data(imd->il, imd); | |
3348 | |
3349 imd->delay_alter_type = source->delay_alter_type; | |
3350 source->delay_alter_type = ALTER_NONE; | |
3351 } | |
3352 | |
3353 image_loader_free(imd->read_ahead_il); | |
3354 imd->read_ahead_il = source->read_ahead_il; | |
3355 source->read_ahead_il = NULL; | |
3356 if (imd->read_ahead_il) image_loader_sync_data(imd->read_ahead_il, imd); | |
3357 | |
3358 if (imd->read_ahead_pixbuf) g_object_unref(imd->read_ahead_pixbuf); | |
3359 imd->read_ahead_pixbuf = source->read_ahead_pixbuf; | |
3360 source->read_ahead_pixbuf = NULL; | |
3361 | |
3362 g_free(imd->read_ahead_path); | |
3363 imd->read_ahead_path = source->read_ahead_path; | |
3364 source->read_ahead_path = NULL; | |
3365 | |
3366 if (imd->prev_pixbuf) g_object_unref(imd->prev_pixbuf); | |
3367 imd->prev_pixbuf = source->prev_pixbuf; | |
3368 source->prev_pixbuf = NULL; | |
3369 | |
3370 g_free(imd->prev_path); | |
3371 imd->prev_path = source->prev_path; | |
3372 source->prev_path = NULL; | |
3373 | |
3374 imd->completed = source->completed; | |
3375 | |
3376 imd->x_scroll = source->x_scroll; | |
3377 imd->y_scroll = source->y_scroll; | |
3378 | |
12
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3379 if (imd->source_tiles_enabled) |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3380 { |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3381 image_source_tile_unset(imd); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3382 } |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3383 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3384 if (source->source_tiles_enabled) |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3385 { |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3386 imd->source_tiles_enabled = source->source_tiles_enabled; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3387 imd->source_tiles_cache_size = source->source_tiles_cache_size; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3388 imd->source_tiles = source->source_tiles; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3389 imd->source_tile_width = source->source_tile_width; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3390 imd->source_tile_height = source->source_tile_height; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3391 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3392 source->source_tiles_enabled = FALSE; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3393 source->source_tiles = NULL; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3394 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3395 imd->func_tile_request = source->func_tile_request; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3396 imd->func_tile_dispose = source->func_tile_dispose; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3397 imd->data_tile = source->data_tile; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3398 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3399 source->func_tile_request = NULL; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3400 source->func_tile_dispose = NULL; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3401 source->data_tile = NULL; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3402 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3403 imd->image_width = source->image_width; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3404 imd->image_height = source->image_height; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3405 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3406 if (image_zoom_clamp(imd, source->zoom, TRUE, TRUE)) |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3407 { |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3408 image_size_clamp(imd); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3409 image_scroll_clamp(imd); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3410 image_tile_sync(imd, imd->width, imd->height, FALSE); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3411 image_redraw(imd, FALSE); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3412 } |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3413 return; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3414 } |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3415 |
9 | 3416 image_scroll_clamp(imd); |
3417 } | |
3418 | |
3419 /* manipulation */ | |
3420 | |
3421 void image_area_changed(ImageWindow *imd, gint x, gint y, gint width, gint height) | |
3422 { | |
3423 gint sx, sy, sw, sh; | |
3424 | |
3425 sx = (gint)floor((double)x * imd->scale); | |
3426 sy = (gint)floor((double)y * imd->scale); | |
3427 sw = (gint)ceil((double)width * imd->scale); | |
3428 sh = (gint)ceil((double)height * imd->scale); | |
3429 | |
12
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3430 if (imd->source_tiles_enabled) |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3431 { |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3432 source_tile_changed(imd, x, y, width, height); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3433 } |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3434 |
9 | 3435 image_queue(imd, sx, sy, sw, sh, FALSE, TILE_RENDER_AREA, TRUE); |
3436 } | |
3437 | |
3438 void image_reload(ImageWindow *imd) | |
3439 { | |
12
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3440 if (imd->source_tiles_enabled) return; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3441 |
9 | 3442 image_change_complete(imd, imd->zoom, FALSE); |
3443 } | |
3444 | |
3445 void image_scroll(ImageWindow *imd, gint x, gint y) | |
3446 { | |
3447 image_scroll_real(imd, x, y); | |
3448 } | |
3449 | |
13
ef790149ae21
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
12
diff
changeset
|
3450 void image_scroll_to_point(ImageWindow *imd, gint x, gint y, |
ef790149ae21
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
12
diff
changeset
|
3451 gdouble x_align, gdouble y_align) |
12
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3452 { |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3453 gint px, py; |
13
ef790149ae21
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
12
diff
changeset
|
3454 gint ax, ay; |
ef790149ae21
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
12
diff
changeset
|
3455 |
ef790149ae21
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
12
diff
changeset
|
3456 x_align = CLAMP(x_align, 0.0, 1.0); |
ef790149ae21
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
12
diff
changeset
|
3457 y_align = CLAMP(y_align, 0.0, 1.0); |
ef790149ae21
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
12
diff
changeset
|
3458 |
ef790149ae21
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
12
diff
changeset
|
3459 ax = (gdouble)imd->vis_width * x_align; |
ef790149ae21
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
12
diff
changeset
|
3460 ay = (gdouble)imd->vis_height * y_align; |
ef790149ae21
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
12
diff
changeset
|
3461 |
ef790149ae21
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
12
diff
changeset
|
3462 px = (gdouble)x * imd->scale - (imd->x_scroll + ax); |
ef790149ae21
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
12
diff
changeset
|
3463 py = (gdouble)y * imd->scale - (imd->y_scroll + ay); |
12
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3464 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3465 image_scroll(imd, px, py); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3466 } |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3467 |
9 | 3468 void image_alter(ImageWindow *imd, AlterType type) |
1 | 3469 { |
12
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3470 if (imd->source_tiles_enabled) return; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3471 |
9 | 3472 if (imd->il) |
3473 { | |
3474 /* still loading, wait till done */ | |
3475 imd->delay_alter_type = type; | |
3476 return; | |
3477 } | |
3478 | |
3479 image_alter_real(imd, type, TRUE); | |
3480 } | |
3481 | |
3482 /* zoom */ | |
3483 | |
3484 static void image_zoom_adjust_real(ImageWindow *imd, gdouble increment, | |
3485 gint center_point, gint x, gint y) | |
3486 { | |
3487 gdouble zoom = imd->zoom; | |
3488 | |
3489 if (increment == 0.0) return; /* avoid possible div by zero, a no-op anyway... */ | |
3490 | |
3491 if (zoom == 0.0) | |
3492 { | |
3493 if (imd->scale < 1.0) | |
3494 { | |
3495 zoom = 0.0 - 1.0 / imd->scale; | |
3496 } | |
3497 else | |
3498 { | |
3499 zoom = imd->scale; | |
3500 } | |
3501 } | |
3502 | |
3503 if (increment < 0.0) | |
3504 { | |
3505 if (zoom >= 1.0 && zoom + increment < 1.0) | |
3506 { | |
3507 zoom = zoom + increment - 2.0; | |
3508 } | |
3509 else | |
3510 { | |
3511 zoom = zoom + increment; | |
3512 } | |
3513 } | |
3514 else | |
1 | 3515 { |
9 | 3516 if (zoom <= -1.0 && zoom + increment > -1.0) |
3517 { | |
3518 zoom = zoom + increment + 2.0; | |
3519 } | |
3520 else | |
3521 { | |
3522 zoom = zoom + increment; | |
3523 } | |
3524 } | |
3525 | |
3526 image_zoom_sync(imd, zoom, FALSE, FALSE, FALSE, center_point, x, y); | |
3527 } | |
3528 | |
3529 void image_zoom_adjust(ImageWindow *imd, gdouble increment) | |
3530 { | |
3531 image_zoom_adjust_real(imd, increment, FALSE, 0, 0); | |
3532 } | |
3533 | |
3534 void image_zoom_adjust_at_point(ImageWindow *imd, gdouble increment, gint x, gint y) | |
3535 { | |
3536 image_zoom_adjust_real(imd, increment, TRUE, x, y); | |
3537 } | |
3538 | |
12
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3539 void image_zoom_set_limits(ImageWindow *imd, gdouble min, gdouble max) |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3540 { |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3541 if (min > 1.0 || max < 1.0) return; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3542 if (min < 1.0 && min > -1.0) return; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3543 if (min < -200.0 || max > 200.0) return; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3544 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3545 imd->zoom_min = min; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3546 imd->zoom_max = max; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3547 } |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3548 |
9 | 3549 void image_zoom_set(ImageWindow *imd, gdouble zoom) |
3550 { | |
3551 image_zoom_sync(imd, zoom, FALSE, FALSE, FALSE, FALSE, 0, 0); | |
3552 } | |
3553 | |
3554 void image_zoom_set_fill_geometry(ImageWindow *imd, gint vertical) | |
3555 { | |
3556 gdouble zoom; | |
3557 | |
3558 if (!imd->pixbuf || imd->image_width < 1 || imd->image_height < 1) return; | |
3559 | |
3560 if (vertical) | |
3561 { | |
3562 zoom = (gdouble)imd->window_height / imd->image_height; | |
3563 } | |
3564 else | |
3565 { | |
3566 zoom = (gdouble)imd->window_width / imd->image_width; | |
3567 } | |
3568 | |
3569 if (zoom < 1.0) | |
3570 { | |
3571 zoom = 0.0 - 1.0 / zoom; | |
1 | 3572 } |
9 | 3573 |
3574 image_zoom_set(imd, zoom); | |
3575 } | |
3576 | |
3577 gdouble image_zoom_get(ImageWindow *imd) | |
3578 { | |
3579 return imd->zoom; | |
3580 } | |
3581 | |
3582 gdouble image_zoom_get_real(ImageWindow *imd) | |
3583 { | |
3584 return imd->scale; | |
3585 } | |
3586 | |
3587 gchar *image_zoom_get_as_text(ImageWindow *imd) | |
3588 { | |
3589 gdouble l = 1.0; | |
3590 gdouble r = 1.0; | |
3591 gint pl = 0; | |
3592 gint pr = 0; | |
3593 gchar *approx = " "; | |
3594 | |
3595 if (imd->zoom > 0.0) | |
3596 { | |
3597 l = imd->zoom; | |
3598 } | |
3599 else if (imd->zoom < 0.0) | |
1 | 3600 { |
9 | 3601 r = 0.0 - imd->zoom; |
3602 } | |
3603 else if (imd->zoom == 0.0 && imd->scale != 0.0) | |
3604 { | |
3605 if (imd->scale >= 1.0) | |
3606 { | |
3607 l = imd->scale; | |
3608 } | |
3609 else | |
3610 { | |
3611 r = 1.0 / imd->scale; | |
3612 } | |
3613 approx = " ~"; | |
3614 } | |
3615 | |
3616 if (rint(l) != l) pl = 1; | |
3617 if (rint(r) != r) pr = 1; | |
3618 | |
3619 return g_strdup_printf("%.*f :%s%.*f", pl, l, approx, pr, r); | |
3620 } | |
3621 | |
3622 gdouble image_zoom_get_default(ImageWindow *imd, gint mode) | |
3623 { | |
3624 gdouble zoom; | |
3625 | |
3626 if (mode == ZOOM_RESET_ORIGINAL) | |
3627 { | |
3628 zoom = 1.0; | |
3629 } | |
3630 else if (mode == ZOOM_RESET_FIT_WINDOW) | |
3631 { | |
3632 zoom = 0.0; | |
1 | 3633 } |
3634 else | |
3635 { | |
3636 if (imd) | |
3637 { | |
9 | 3638 zoom = image_zoom_get(imd); |
1 | 3639 } |
3640 else | |
3641 { | |
9 | 3642 zoom = 1.0; |
1 | 3643 } |
3644 } | |
3645 | |
3646 return zoom; | |
3647 } | |
3648 | |
9 | 3649 /* read ahead */ |
3650 | |
3651 void image_prebuffer_set(ImageWindow *imd, const gchar *path) | |
3652 { | |
12
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3653 if (imd->source_tiles_enabled) return; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3654 |
9 | 3655 if (path) |
3656 { | |
3657 image_read_ahead_set(imd, path); | |
3658 } | |
3659 else | |
3660 { | |
3661 image_read_ahead_cancel(imd); | |
3662 } | |
3663 } | |
3664 | |
3665 static gint image_auto_refresh_cb(gpointer data) | |
3666 { | |
3667 ImageWindow *imd = data; | |
3668 time_t newtime; | |
3669 | |
3670 if (!imd || !imd->pixbuf || | |
3671 imd->il || !imd->image_path || | |
3672 !update_on_time_change) return TRUE; | |
3673 | |
3674 newtime = filetime(imd->image_path); | |
3675 if (newtime > 0 && newtime != imd->mtime) | |
3676 { | |
3677 imd->mtime = newtime; | |
3678 image_reload(imd); | |
3679 } | |
3680 | |
3681 return TRUE; | |
3682 } | |
3683 | |
3684 /* image auto refresh on time stamp change, in 1/1000's second, -1 disables */ | |
3685 | |
3686 void image_auto_refresh(ImageWindow *imd, gint interval) | |
3687 { | |
3688 if (!imd) return; | |
12
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3689 if (imd->source_tiles_enabled) return; |
9 | 3690 |
3691 if (imd->auto_refresh_id > -1) | |
3692 { | |
3693 g_source_remove(imd->auto_refresh_id); | |
3694 imd->auto_refresh_id = -1; | |
3695 imd->auto_refresh_interval = -1; | |
3696 } | |
3697 | |
3698 if (interval < 0) return; | |
3699 | |
3700 if (interval == 0) interval = IMAGE_AUTO_REFRESH_TIME; | |
3701 | |
3702 imd->auto_refresh_id = g_timeout_add((guint32)interval, image_auto_refresh_cb, imd); | |
3703 imd->auto_refresh_interval = interval; | |
3704 } | |
3705 | |
3706 /* allow top window to be resized ? */ | |
3707 | |
3708 void image_top_window_set_sync(ImageWindow *imd, gint allow_sync) | |
3709 { | |
3710 imd->top_window_sync = allow_sync; | |
3711 } | |
3712 | |
3713 /* background colors */ | |
3714 | |
3715 void image_background_set_black(ImageWindow *imd, gint black) | |
3716 { | |
3717 GtkStyle *style; | |
3718 | |
3719 if (!imd) return; | |
3720 | |
3721 style = gtk_style_copy(gtk_widget_get_style(imd->widget)); | |
3722 g_object_ref(G_OBJECT(style)); | |
3723 | |
3724 if (black) | |
3725 { | |
3726 style->bg[GTK_STATE_NORMAL] = style->black; | |
3727 } | |
3728 | |
3729 gtk_widget_set_style(imd->image, style); | |
3730 g_object_unref(G_OBJECT(style)); | |
3731 | |
3732 if (GTK_WIDGET_VISIBLE(imd->widget)) image_border_clear(imd); | |
3733 } | |
3734 | |
3735 void image_background_set_color(ImageWindow *imd, GdkColor *color) | |
3736 { | |
3737 GtkStyle *style; | |
3738 | |
3739 if (!imd) return; | |
3740 | |
3741 style = gtk_style_copy(gtk_widget_get_style(imd->widget)); | |
3742 g_object_ref(G_OBJECT(style)); | |
3743 | |
3744 if (color) | |
3745 { | |
3746 GdkColor *slot; | |
3747 | |
3748 slot = &style->bg[GTK_STATE_NORMAL]; | |
3749 | |
3750 slot->red = color->red; | |
3751 slot->green = color->green; | |
3752 slot->blue = color->blue; | |
3753 } | |
3754 | |
3755 gtk_widget_set_style(imd->image, style); | |
3756 g_object_unref(G_OBJECT(style)); | |
3757 | |
3758 if (GTK_WIDGET_VISIBLE(imd->widget)) image_border_clear(imd); | |
3759 } | |
3760 | |
3761 void image_set_delay_flip(ImageWindow *imd, gint delay) | |
3762 { | |
3763 if (!imd || | |
3764 imd->delay_flip == delay) return; | |
3765 | |
3766 imd->delay_flip = delay; | |
3767 if (!imd->delay_flip && imd->il) | |
3768 { | |
3769 if (imd->pixbuf) g_object_unref(imd->pixbuf); | |
3770 imd->pixbuf = NULL; | |
3771 image_load_pixbuf_ready(imd); | |
3772 | |
3773 image_queue_clear(imd); | |
3774 image_queue(imd, 0, 0, imd->width, imd->height, FALSE, TILE_RENDER_AREA, TRUE); | |
3775 } | |
3776 } | |
3777 | |
3778 /* wallpaper util */ | |
3779 | |
3780 void image_to_root_window(ImageWindow *imd, gint scaled) | |
3781 { | |
3782 GdkScreen *screen; | |
3 | 3783 GdkWindow *rootwindow; |
3784 GdkPixmap *pixmap; | |
9 | 3785 GdkPixbuf *pb; |
3786 | |
3787 if (!imd || !imd->pixbuf) return; | |
3788 | |
3789 screen = gtk_widget_get_screen(imd->image); | |
3790 rootwindow = gdk_screen_get_root_window(screen); | |
3791 if (gdk_drawable_get_visual(rootwindow) != gdk_visual_get_system()) return; | |
3 | 3792 |
3793 if (scaled) | |
3794 { | |
9 | 3795 pb = gdk_pixbuf_scale_simple(imd->pixbuf, gdk_screen_width(), gdk_screen_height(), (GdkInterpType)zoom_quality); |
3 | 3796 } |
3797 else | |
3798 { | |
9 | 3799 pb = gdk_pixbuf_scale_simple(imd->pixbuf, imd->width, imd->height, (GdkInterpType)zoom_quality); |
3 | 3800 } |
3801 | |
9 | 3802 gdk_pixbuf_render_pixmap_and_mask (pb, &pixmap, NULL, 128); |
3 | 3803 gdk_window_set_back_pixmap(rootwindow, pixmap, FALSE); |
3804 gdk_window_clear(rootwindow); | |
9 | 3805 g_object_unref(pb); |
3806 g_object_unref(pixmap); | |
3 | 3807 |
3808 gdk_flush(); | |
3809 } | |
3810 | |
3811 | |
9 | 3812 /* |
3813 *------------------------------------------------------------------- | |
3814 * init / destroy | |
3815 *------------------------------------------------------------------- | |
3816 */ | |
3817 | |
3818 static void image_free(ImageWindow *imd) | |
3819 { | |
3820 image_read_ahead_cancel(imd); | |
3821 image_post_buffer_set(imd, NULL, NULL); | |
3822 image_auto_refresh(imd, -1); | |
3823 | |
3824 g_free(imd->image_path); | |
3825 g_free(imd->title); | |
3826 g_free(imd->title_right); | |
3827 | |
3828 image_reset(imd); | |
3829 image_tile_sync_count(imd, 0); | |
3830 if (imd->pixbuf) g_object_unref(imd->pixbuf); | |
3831 | |
3832 image_scroller_timer_set(imd, FALSE); | |
3833 | |
3834 image_overlay_list_clear(imd); | |
3835 | |
12
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3836 source_tile_free_all(imd); |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3837 |
9 | 3838 g_free(imd); |
3839 } | |
3840 | |
3841 static void image_destroy_cb(GtkObject *widget, gpointer data) | |
3842 { | |
3843 ImageWindow *imd = data; | |
3844 image_free(imd); | |
3845 } | |
3846 | |
3847 ImageWindow *image_new(gint frame) | |
3848 { | |
3849 ImageWindow *imd; | |
3850 | |
3851 imd = g_new0(ImageWindow, 1); | |
12
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3852 |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3853 imd->zoom_min = IMAGE_ZOOM_MIN; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3854 imd->zoom_max = IMAGE_ZOOM_MAX; |
9 | 3855 imd->zoom = 1.0; |
3856 imd->scale = 1.0; | |
3857 | |
3858 imd->draw_idle_id = -1; | |
3859 | |
3860 imd->tile_width = IMAGE_TILE_SIZE; | |
3861 imd->tile_height = IMAGE_TILE_SIZE; | |
3862 | |
3863 imd->top_window = NULL; | |
3864 imd->title = NULL; | |
3865 imd->title_right = NULL; | |
3866 imd->title_show_zoom = FALSE; | |
3867 | |
3868 imd->unknown = TRUE; | |
3869 | |
3870 imd->pixbuf = NULL; | |
3871 | |
3872 imd->has_frame = frame; | |
3873 imd->top_window_sync = FALSE; | |
3874 | |
3875 imd->tile_cache = NULL; | |
3876 imd->tile_cache_size = 0; | |
3877 | |
3878 imd->delay_alter_type = ALTER_NONE; | |
3879 | |
3880 imd->read_ahead_il = NULL; | |
3881 imd->read_ahead_pixbuf = NULL; | |
3882 imd->read_ahead_path = NULL; | |
3883 | |
3884 imd->completed = FALSE; | |
3885 | |
3886 imd->auto_refresh_id = -1; | |
3887 imd->auto_refresh_interval = -1; | |
3888 | |
3889 imd->delay_flip = FALSE; | |
3890 | |
3891 imd->func_update = NULL; | |
3892 imd->func_complete = NULL; | |
12
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3893 imd->func_tile_request = NULL; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3894 imd->func_tile_dispose = NULL; |
9 | 3895 |
3896 imd->func_button = NULL; | |
3897 imd->func_scroll = NULL; | |
3898 | |
3899 imd->scroller_id = -1; | |
3900 imd->scroller_overlay = -1; | |
3901 | |
12
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3902 imd->source_tiles_enabled = FALSE; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3903 imd->source_tiles = NULL; |
147f4c4b9025
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
3904 |
9 | 3905 imd->image = gtk_drawing_area_new(); |
3906 gtk_widget_set_double_buffered(imd->image, FALSE); | |
3907 | |
3908 if (imd->has_frame) | |
3909 { | |
3910 imd->widget = gtk_frame_new(NULL); | |
3911 gtk_frame_set_shadow_type(GTK_FRAME(imd->widget), GTK_SHADOW_IN); | |
3912 gtk_container_add(GTK_CONTAINER(imd->widget), imd->image); | |
3913 gtk_widget_show(imd->image); | |
3914 | |
3915 GTK_WIDGET_SET_FLAGS(imd->widget, GTK_CAN_FOCUS); | |
3916 g_signal_connect(G_OBJECT(imd->widget), "focus_in_event", | |
3917 G_CALLBACK(image_focus_in_cb), imd); | |
3918 g_signal_connect(G_OBJECT(imd->widget), "focus_out_event", | |
3919 G_CALLBACK(image_focus_out_cb), imd); | |
3920 | |
3921 g_signal_connect_after(G_OBJECT(imd->widget), "expose_event", | |
3922 G_CALLBACK(image_focus_expose), imd); | |
3923 } | |
3924 else | |
3925 { | |
3926 imd->widget = imd->image; | |
3927 } | |
3928 | |
3929 g_signal_connect(G_OBJECT(imd->image), "motion_notify_event", | |
3930 G_CALLBACK(image_mouse_motion_cb), imd); | |
3931 g_signal_connect(G_OBJECT(imd->image), "button_press_event", | |
3932 G_CALLBACK(image_mouse_press_cb), imd); | |
3933 g_signal_connect(G_OBJECT(imd->image), "button_release_event", | |
3934 G_CALLBACK(image_mouse_release_cb), imd); | |
3935 g_signal_connect(G_OBJECT(imd->image), "leave_notify_event", | |
3936 G_CALLBACK(image_mouse_leave_cb), imd); | |
3937 gtk_widget_set_events(imd->image, GDK_POINTER_MOTION_MASK | | |
3938 GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_PRESS_MASK | | |
3939 GDK_LEAVE_NOTIFY_MASK); | |
3940 | |
3941 g_signal_connect(G_OBJECT(imd->image), "expose_event", | |
3942 G_CALLBACK(image_expose_cb), imd); | |
3943 g_signal_connect_after(G_OBJECT(imd->image), "size_allocate", | |
3944 G_CALLBACK(image_size_cb), imd); | |
3945 | |
3946 g_signal_connect(G_OBJECT(imd->image), "drag_begin", | |
3947 G_CALLBACK(image_mouse_drag_cb), imd); | |
3948 g_signal_connect(G_OBJECT(imd->image), "scroll_event", | |
3949 G_CALLBACK(image_scroll_cb), imd); | |
3950 | |
3951 g_signal_connect(G_OBJECT(imd->widget), "destroy", | |
3952 G_CALLBACK(image_destroy_cb), imd); | |
3953 | |
3954 return imd; | |
3955 } | |
3956 |