Mercurial > geeqie.yaz
annotate src/pan-item.c @ 1655:437c37d965ff
Fix two memory failures
1. if the description field for a exif information is empty the program
dumps core when trying to change this. The reason is a strcmp with a
NULL value.
The fix add the small functionality to set the field to default when
it is set empty.
2. There was a g_strdup miss in exif.c which could end in memory
corruption.
author | mow |
---|---|
date | Sun, 21 Jun 2009 22:52:08 +0000 |
parents | b106af9689db |
children |
rev | line source |
---|---|
105 | 1 /* |
196 | 2 * Geeqie |
105 | 3 * (C) 2006 John Ellis |
1284 | 4 * Copyright (C) 2008 - 2009 The Geeqie Team |
105 | 5 * |
6 * Author: John Ellis | |
7 * | |
8 * This software is released under the GNU General Public License (GNU GPL). | |
9 * Please read the included file COPYING for more information. | |
10 * This software comes with no warranty of any kind, use at your own risk! | |
11 */ | |
12 | |
13 | |
281 | 14 #include "main.h" |
105 | 15 #include "pan-types.h" |
16 | |
17 | |
18 /* | |
19 *----------------------------------------------------------------------------- | |
20 * item base functions | |
21 *----------------------------------------------------------------------------- | |
22 */ | |
23 | |
24 void pan_item_free(PanItem *pi) | |
25 { | |
26 if (!pi) return; | |
27 | |
28 if (pi->pixbuf) g_object_unref(pi->pixbuf); | |
138 | 29 if (pi->fd) file_data_unref(pi->fd); |
105 | 30 g_free(pi->text); |
31 g_free(pi->key); | |
32 g_free(pi->data); | |
33 | |
34 g_free(pi); | |
35 } | |
36 | |
37 void pan_item_set_key(PanItem *pi, const gchar *key) | |
38 { | |
39 gchar *tmp; | |
40 | |
41 if (!pi) return; | |
42 | |
43 tmp = pi->key; | |
44 pi->key = g_strdup(key); | |
45 g_free(tmp); | |
46 } | |
47 | |
48 void pan_item_added(PanWindow *pw, PanItem *pi) | |
49 { | |
50 if (!pi) return; | |
51 image_area_changed(pw->imd, pi->x, pi->y, pi->width, pi->height); | |
52 } | |
53 | |
54 void pan_item_remove(PanWindow *pw, PanItem *pi) | |
55 { | |
56 if (!pi) return; | |
57 | |
58 if (pw->click_pi == pi) pw->click_pi = NULL; | |
59 if (pw->queue_pi == pi) pw->queue_pi = NULL; | |
60 if (pw->search_pi == pi) pw->search_pi = NULL; | |
61 pw->queue = g_list_remove(pw->queue, pi); | |
62 | |
63 pw->list = g_list_remove(pw->list, pi); | |
64 image_area_changed(pw->imd, pi->x, pi->y, pi->width, pi->height); | |
65 pan_item_free(pi); | |
66 } | |
67 | |
68 void pan_item_size_by_item(PanItem *pi, PanItem *child, gint border) | |
69 { | |
70 if (!pi || !child) return; | |
71 | |
72 if (pi->x + pi->width < child->x + child->width + border) | |
73 pi->width = child->x + child->width + border - pi->x; | |
74 | |
75 if (pi->y + pi->height < child->y + child->height + border) | |
76 pi->height = child->y + child->height + border - pi->y; | |
77 } | |
78 | |
79 void pan_item_size_coordinates(PanItem *pi, gint border, gint *w, gint *h) | |
80 { | |
81 if (!pi) return; | |
82 | |
83 if (*w < pi->x + pi->width + border) *w = pi->x + pi->width + border; | |
84 if (*h < pi->y + pi->height + border) *h = pi->y + pi->height + border; | |
85 } | |
86 | |
87 | |
88 /* | |
89 *----------------------------------------------------------------------------- | |
90 * item box type | |
91 *----------------------------------------------------------------------------- | |
92 */ | |
93 | |
94 PanItem *pan_item_box_new(PanWindow *pw, FileData *fd, gint x, gint y, gint width, gint height, | |
95 gint border_size, | |
96 guint8 base_r, guint8 base_g, guint8 base_b, guint8 base_a, | |
97 guint8 bord_r, guint8 bord_g, guint8 bord_b, guint8 bord_a) | |
98 { | |
99 PanItem *pi; | |
100 | |
101 pi = g_new0(PanItem, 1); | |
102 pi->type = PAN_ITEM_BOX; | |
103 pi->fd = fd; | |
104 pi->x = x; | |
105 pi->y = y; | |
106 pi->width = width; | |
107 pi->height = height; | |
108 | |
109 pi->color_r = base_r; | |
110 pi->color_g = base_g; | |
111 pi->color_b = base_b; | |
112 pi->color_a = base_a; | |
113 | |
114 pi->color2_r = bord_r; | |
115 pi->color2_g = bord_g; | |
116 pi->color2_b = bord_b; | |
117 pi->color2_a = bord_a; | |
118 pi->border = border_size; | |
119 | |
120 pw->list = g_list_prepend(pw->list, pi); | |
121 | |
122 return pi; | |
123 } | |
124 | |
125 void pan_item_box_shadow(PanItem *pi, gint offset, gint fade) | |
126 { | |
127 gint *shadow; | |
128 | |
129 if (!pi || pi->type != PAN_ITEM_BOX) return; | |
130 | |
131 shadow = pi->data; | |
132 if (shadow) | |
133 { | |
134 pi->width -= shadow[0]; | |
135 pi->height -= shadow[0]; | |
136 } | |
137 | |
138 shadow = g_new0(gint, 2); | |
139 shadow[0] = offset; | |
140 shadow[1] = fade; | |
141 | |
142 pi->width += offset; | |
143 pi->height += offset; | |
144 | |
145 g_free(pi->data); | |
146 pi->data = shadow; | |
147 } | |
148 | |
149 gint pan_item_box_draw(PanWindow *pw, PanItem *pi, GdkPixbuf *pixbuf, PixbufRenderer *pr, | |
150 gint x, gint y, gint width, gint height) | |
151 { | |
152 gint bw, bh; | |
153 gint *shadow; | |
154 gint rx, ry, rw, rh; | |
155 | |
156 bw = pi->width; | |
157 bh = pi->height; | |
158 | |
159 shadow = pi->data; | |
160 if (shadow) | |
161 { | |
162 bw -= shadow[0]; | |
163 bh -= shadow[0]; | |
164 | |
165 if (pi->color_a > 254) | |
166 { | |
167 pixbuf_draw_shadow(pixbuf, pi->x - x + bw, pi->y - y + shadow[0], | |
168 shadow[0], bh - shadow[0], | |
169 pi->x - x + shadow[0], pi->y - y + shadow[0], bw, bh, | |
170 shadow[1], | |
171 PAN_SHADOW_COLOR, PAN_SHADOW_ALPHA); | |
172 pixbuf_draw_shadow(pixbuf, pi->x - x + shadow[0], pi->y - y + bh, | |
173 bw, shadow[0], | |
174 pi->x - x + shadow[0], pi->y - y + shadow[0], bw, bh, | |
175 shadow[1], | |
176 PAN_SHADOW_COLOR, PAN_SHADOW_ALPHA); | |
177 } | |
178 else | |
179 { | |
180 gint a; | |
181 a = pi->color_a * PAN_SHADOW_ALPHA >> 8; | |
182 pixbuf_draw_shadow(pixbuf, pi->x - x + shadow[0], pi->y - y + shadow[0], | |
183 bw, bh, | |
184 pi->x - x + shadow[0], pi->y - y + shadow[0], bw, bh, | |
185 shadow[1], | |
186 PAN_SHADOW_COLOR, a); | |
187 } | |
188 } | |
189 | |
190 if (util_clip_region(x, y, width, height, | |
191 pi->x, pi->y, bw, bh, | |
192 &rx, &ry, &rw, &rh)) | |
193 { | |
194 pixbuf_draw_rect_fill(pixbuf, | |
195 rx - x, ry - y, rw, rh, | |
196 pi->color_r, pi->color_g, pi->color_b, pi->color_a); | |
197 } | |
198 if (util_clip_region(x, y, width, height, | |
199 pi->x, pi->y, bw, pi->border, | |
200 &rx, &ry, &rw, &rh)) | |
201 { | |
202 pixbuf_draw_rect_fill(pixbuf, | |
203 rx - x, ry - y, rw, rh, | |
204 pi->color2_r, pi->color2_g, pi->color2_b, pi->color2_a); | |
205 } | |
206 if (util_clip_region(x, y, width, height, | |
207 pi->x, pi->y + pi->border, pi->border, bh - pi->border * 2, | |
208 &rx, &ry, &rw, &rh)) | |
209 { | |
210 pixbuf_draw_rect_fill(pixbuf, | |
211 rx - x, ry - y, rw, rh, | |
212 pi->color2_r, pi->color2_g, pi->color2_b, pi->color2_a); | |
213 } | |
214 if (util_clip_region(x, y, width, height, | |
215 pi->x + bw - pi->border, pi->y + pi->border, | |
216 pi->border, bh - pi->border * 2, | |
217 &rx, &ry, &rw, &rh)) | |
218 { | |
219 pixbuf_draw_rect_fill(pixbuf, | |
220 rx - x, ry - y, rw, rh, | |
221 pi->color2_r, pi->color2_g, pi->color2_b, pi->color2_a); | |
222 } | |
223 if (util_clip_region(x, y, width, height, | |
224 pi->x, pi->y + bh - pi->border, | |
225 bw, pi->border, | |
226 &rx, &ry, &rw, &rh)) | |
227 { | |
228 pixbuf_draw_rect_fill(pixbuf, | |
229 rx - x, ry - y, rw, rh, | |
230 pi->color2_r, pi->color2_g, pi->color2_b, pi->color2_a); | |
231 } | |
232 | |
233 return FALSE; | |
234 } | |
235 | |
236 | |
237 /* | |
238 *----------------------------------------------------------------------------- | |
239 * item triangle type | |
240 *----------------------------------------------------------------------------- | |
241 */ | |
242 | |
243 PanItem *pan_item_tri_new(PanWindow *pw, FileData *fd, gint x, gint y, gint width, gint height, | |
244 gint x1, gint y1, gint x2, gint y2, gint x3, gint y3, | |
245 guint8 r, guint8 g, guint8 b, guint8 a) | |
246 { | |
247 PanItem *pi; | |
248 gint *coord; | |
249 | |
250 pi = g_new0(PanItem, 1); | |
251 pi->type = PAN_ITEM_TRIANGLE; | |
252 pi->x = x; | |
253 pi->y = y; | |
254 pi->width = width; | |
255 pi->height = height; | |
256 | |
257 pi->color_r = r; | |
258 pi->color_g = g; | |
259 pi->color_b = b; | |
260 pi->color_a = a; | |
261 | |
262 coord = g_new0(gint, 6); | |
263 coord[0] = x1; | |
264 coord[1] = y1; | |
265 coord[2] = x2; | |
266 coord[3] = y2; | |
267 coord[4] = x3; | |
268 coord[5] = y3; | |
269 | |
270 pi->data = coord; | |
271 | |
272 pi->border = PAN_BORDER_NONE; | |
273 | |
274 pw->list = g_list_prepend(pw->list, pi); | |
275 | |
276 return pi; | |
277 } | |
278 | |
279 void pan_item_tri_border(PanItem *pi, gint borders, | |
280 guint8 r, guint8 g, guint8 b, guint8 a) | |
281 { | |
282 if (!pi || pi->type != PAN_ITEM_TRIANGLE) return; | |
283 | |
284 pi->border = borders; | |
285 | |
286 pi->color2_r = r; | |
287 pi->color2_g = g; | |
288 pi->color2_b = b; | |
289 pi->color2_a = a; | |
290 } | |
291 | |
292 gint pan_item_tri_draw(PanWindow *pw, PanItem *pi, GdkPixbuf *pixbuf, PixbufRenderer *pr, | |
293 gint x, gint y, gint width, gint height) | |
294 { | |
295 gint rx, ry, rw, rh; | |
296 | |
297 if (util_clip_region(x, y, width, height, | |
298 pi->x, pi->y, pi->width, pi->height, | |
299 &rx, &ry, &rw, &rh) && pi->data) | |
300 { | |
301 gint *coord = pi->data; | |
302 pixbuf_draw_triangle(pixbuf, | |
303 rx - x, ry - y, rw, rh, | |
304 coord[0] - x, coord[1] - y, | |
305 coord[2] - x, coord[3] - y, | |
306 coord[4] - x, coord[5] - y, | |
307 pi->color_r, pi->color_g, pi->color_b, pi->color_a); | |
308 | |
309 if (pi->border & PAN_BORDER_1) | |
310 { | |
311 pixbuf_draw_line(pixbuf, | |
312 rx - x, ry - y, rw, rh, | |
313 coord[0] - x, coord[1] - y, | |
314 coord[2] - x, coord[3] - y, | |
315 pi->color2_r, pi->color2_g, pi->color2_b, pi->color2_a); | |
316 } | |
317 if (pi->border & PAN_BORDER_2) | |
318 { | |
319 pixbuf_draw_line(pixbuf, | |
320 rx - x, ry - y, rw, rh, | |
321 coord[2] - x, coord[3] - y, | |
322 coord[4] - x, coord[5] - y, | |
323 pi->color2_r, pi->color2_g, pi->color2_b, pi->color2_a); | |
324 } | |
325 if (pi->border & PAN_BORDER_3) | |
326 { | |
327 pixbuf_draw_line(pixbuf, | |
328 rx - x, ry - y, rw, rh, | |
329 coord[4] - x, coord[5] - y, | |
330 coord[0] - x, coord[1] - y, | |
331 pi->color2_r, pi->color2_g, pi->color2_b, pi->color2_a); | |
332 } | |
333 } | |
334 | |
335 return FALSE; | |
336 } | |
337 | |
338 | |
339 /* | |
340 *----------------------------------------------------------------------------- | |
341 * item text type | |
342 *----------------------------------------------------------------------------- | |
343 */ | |
344 | |
345 static PangoLayout *pan_item_text_layout(PanItem *pi, GtkWidget *widget) | |
346 { | |
347 PangoLayout *layout; | |
348 | |
349 layout = gtk_widget_create_pango_layout(widget, NULL); | |
350 | |
351 if (pi->text_attr & PAN_TEXT_ATTR_MARKUP) | |
352 { | |
353 pango_layout_set_markup(layout, pi->text, -1); | |
354 return layout; | |
355 } | |
356 | |
357 if (pi->text_attr & PAN_TEXT_ATTR_BOLD || | |
358 pi->text_attr & PAN_TEXT_ATTR_HEADING) | |
359 { | |
360 PangoAttrList *pal; | |
361 PangoAttribute *pa; | |
442 | 362 |
105 | 363 pal = pango_attr_list_new(); |
364 if (pi->text_attr & PAN_TEXT_ATTR_BOLD) | |
365 { | |
366 pa = pango_attr_weight_new(PANGO_WEIGHT_BOLD); | |
367 pa->start_index = 0; | |
368 pa->end_index = G_MAXINT; | |
369 pango_attr_list_insert(pal, pa); | |
370 } | |
371 if (pi->text_attr & PAN_TEXT_ATTR_HEADING) | |
372 { | |
373 pa = pango_attr_scale_new(PANGO_SCALE_LARGE); | |
374 pa->start_index = 0; | |
375 pa->end_index = G_MAXINT; | |
376 pango_attr_list_insert(pal, pa); | |
377 } | |
378 pango_layout_set_attributes(layout, pal); | |
379 pango_attr_list_unref(pal); | |
380 } | |
381 | |
382 pango_layout_set_text(layout, pi->text, -1); | |
383 return layout; | |
384 } | |
385 | |
386 static void pan_item_text_compute_size(PanItem *pi, GtkWidget *widget) | |
387 { | |
388 PangoLayout *layout; | |
389 | |
390 if (!pi || !pi->text || !widget) return; | |
391 | |
392 layout = pan_item_text_layout(pi, widget); | |
393 pango_layout_get_pixel_size(layout, &pi->width, &pi->height); | |
394 g_object_unref(G_OBJECT(layout)); | |
395 | |
396 pi->width += pi->border * 2; | |
397 pi->height += pi->border * 2; | |
398 } | |
399 | |
400 PanItem *pan_item_text_new(PanWindow *pw, gint x, gint y, const gchar *text, | |
401 PanTextAttrType attr, PanBorderType border, | |
402 guint8 r, guint8 g, guint8 b, guint8 a) | |
403 { | |
404 PanItem *pi; | |
405 | |
406 pi = g_new0(PanItem, 1); | |
407 pi->type = PAN_ITEM_TEXT; | |
408 pi->x = x; | |
409 pi->y = y; | |
410 pi->text = g_strdup(text); | |
411 pi->text_attr = attr; | |
412 | |
413 pi->color_r = r; | |
414 pi->color_g = g; | |
415 pi->color_b = b; | |
416 pi->color_a = a; | |
417 | |
418 pi->border = border; | |
419 | |
420 pan_item_text_compute_size(pi, pw->imd->pr); | |
421 | |
422 pw->list = g_list_prepend(pw->list, pi); | |
423 | |
424 return pi; | |
425 } | |
426 | |
427 gint pan_item_text_draw(PanWindow *pw, PanItem *pi, GdkPixbuf *pixbuf, PixbufRenderer *pr, | |
428 gint x, gint y, gint width, gint height) | |
429 { | |
430 PangoLayout *layout; | |
431 | |
432 layout = pan_item_text_layout(pi, (GtkWidget *)pr); | |
433 pixbuf_draw_layout(pixbuf, layout, (GtkWidget *)pr, | |
434 pi->x - x + pi->border, pi->y - y + pi->border, | |
435 pi->color_r, pi->color_g, pi->color_b, pi->color_a); | |
436 g_object_unref(G_OBJECT(layout)); | |
437 | |
438 return FALSE; | |
439 } | |
440 | |
441 | |
442 /* | |
443 *----------------------------------------------------------------------------- | |
444 * item thumbnail type | |
445 *----------------------------------------------------------------------------- | |
446 */ | |
447 | |
448 PanItem *pan_item_thumb_new(PanWindow *pw, FileData *fd, gint x, gint y) | |
449 { | |
450 PanItem *pi; | |
451 | |
452 pi = g_new0(PanItem, 1); | |
1367
fe4da037be21
When g_new0() is used, drop redundant initializations to NULL, FALSE or 0, second pass.
zas_
parents:
1307
diff
changeset
|
453 |
105 | 454 pi->type = PAN_ITEM_THUMB; |
455 pi->fd = fd; | |
456 pi->x = x; | |
457 pi->y = y; | |
458 pi->width = PAN_THUMB_SIZE + PAN_SHADOW_OFFSET * 2; | |
459 pi->height = PAN_THUMB_SIZE + PAN_SHADOW_OFFSET * 2; | |
460 | |
461 pw->list = g_list_prepend(pw->list, pi); | |
462 | |
463 return pi; | |
464 } | |
465 | |
466 gint pan_item_thumb_draw(PanWindow *pw, PanItem *pi, GdkPixbuf *pixbuf, PixbufRenderer *pr, | |
467 gint x, gint y, gint width, gint height) | |
468 { | |
469 gint tx, ty, tw, th; | |
470 gint rx, ry, rw, rh; | |
471 | |
472 if (pi->pixbuf) | |
473 { | |
474 tw = gdk_pixbuf_get_width(pi->pixbuf); | |
475 th = gdk_pixbuf_get_height(pi->pixbuf); | |
476 | |
477 tx = pi->x + (pi->width - tw) / 2; | |
478 ty = pi->y + (pi->height - th) / 2; | |
479 | |
480 if (gdk_pixbuf_get_has_alpha(pi->pixbuf)) | |
481 { | |
482 if (util_clip_region(x, y, width, height, | |
483 tx + PAN_SHADOW_OFFSET, ty + PAN_SHADOW_OFFSET, tw, th, | |
484 &rx, &ry, &rw, &rh)) | |
485 { | |
486 pixbuf_draw_shadow(pixbuf, | |
487 rx - x, ry - y, rw, rh, | |
488 tx + PAN_SHADOW_OFFSET - x, ty + PAN_SHADOW_OFFSET - y, tw, th, | |
489 PAN_SHADOW_FADE, | |
490 PAN_SHADOW_COLOR, PAN_SHADOW_ALPHA); | |
491 } | |
492 } | |
493 else | |
494 { | |
495 if (util_clip_region(x, y, width, height, | |
496 tx + tw, ty + PAN_SHADOW_OFFSET, | |
497 PAN_SHADOW_OFFSET, th - PAN_SHADOW_OFFSET, | |
498 &rx, &ry, &rw, &rh)) | |
499 { | |
500 pixbuf_draw_shadow(pixbuf, | |
501 rx - x, ry - y, rw, rh, | |
502 tx + PAN_SHADOW_OFFSET - x, ty + PAN_SHADOW_OFFSET - y, tw, th, | |
503 PAN_SHADOW_FADE, | |
504 PAN_SHADOW_COLOR, PAN_SHADOW_ALPHA); | |
505 } | |
506 if (util_clip_region(x, y, width, height, | |
507 tx + PAN_SHADOW_OFFSET, ty + th, tw, PAN_SHADOW_OFFSET, | |
508 &rx, &ry, &rw, &rh)) | |
509 { | |
510 pixbuf_draw_shadow(pixbuf, | |
511 rx - x, ry - y, rw, rh, | |
512 tx + PAN_SHADOW_OFFSET - x, ty + PAN_SHADOW_OFFSET - y, tw, th, | |
513 PAN_SHADOW_FADE, | |
514 PAN_SHADOW_COLOR, PAN_SHADOW_ALPHA); | |
515 } | |
516 } | |
517 | |
518 if (util_clip_region(x, y, width, height, | |
519 tx, ty, tw, th, | |
520 &rx, &ry, &rw, &rh)) | |
521 { | |
522 gdk_pixbuf_composite(pi->pixbuf, pixbuf, rx - x, ry - y, rw, rh, | |
1000
4fe8f9656107
For the sake of consistency, use glib basic types everywhere.
zas_
parents:
995
diff
changeset
|
523 (gdouble) tx - x, |
4fe8f9656107
For the sake of consistency, use glib basic types everywhere.
zas_
parents:
995
diff
changeset
|
524 (gdouble) ty - y, |
105 | 525 1.0, 1.0, GDK_INTERP_NEAREST, |
526 255); | |
527 } | |
528 | |
529 if (util_clip_region(x, y, width, height, | |
530 tx, ty, tw, PAN_OUTLINE_THICKNESS, | |
531 &rx, &ry, &rw, &rh)) | |
532 { | |
533 pixbuf_draw_rect_fill(pixbuf, | |
534 rx - x, ry - y, rw, rh, | |
535 PAN_OUTLINE_COLOR_1, PAN_OUTLINE_ALPHA); | |
536 } | |
537 if (util_clip_region(x, y, width, height, | |
538 tx, ty, PAN_OUTLINE_THICKNESS, th, | |
539 &rx, &ry, &rw, &rh)) | |
540 { | |
541 pixbuf_draw_rect_fill(pixbuf, | |
542 rx - x, ry - y, rw, rh, | |
543 PAN_OUTLINE_COLOR_1, PAN_OUTLINE_ALPHA); | |
544 } | |
545 if (util_clip_region(x, y, width, height, | |
546 tx + tw - PAN_OUTLINE_THICKNESS, ty + PAN_OUTLINE_THICKNESS, | |
547 PAN_OUTLINE_THICKNESS, th - PAN_OUTLINE_THICKNESS, | |
548 &rx, &ry, &rw, &rh)) | |
549 { | |
550 pixbuf_draw_rect_fill(pixbuf, | |
551 rx - x, ry - y, rw, rh, | |
552 PAN_OUTLINE_COLOR_2, PAN_OUTLINE_ALPHA); | |
553 } | |
554 if (util_clip_region(x, y, width, height, | |
555 tx + PAN_OUTLINE_THICKNESS, ty + th - PAN_OUTLINE_THICKNESS, | |
556 tw - PAN_OUTLINE_THICKNESS * 2, PAN_OUTLINE_THICKNESS, | |
557 &rx, &ry, &rw, &rh)) | |
558 { | |
559 pixbuf_draw_rect_fill(pixbuf, | |
560 rx - x, ry - y, rw, rh, | |
561 PAN_OUTLINE_COLOR_2, PAN_OUTLINE_ALPHA); | |
562 } | |
563 } | |
564 else | |
565 { | |
566 tw = pi->width - PAN_SHADOW_OFFSET * 2; | |
567 th = pi->height - PAN_SHADOW_OFFSET * 2; | |
568 tx = pi->x + PAN_SHADOW_OFFSET; | |
569 ty = pi->y + PAN_SHADOW_OFFSET; | |
570 | |
571 if (util_clip_region(x, y, width, height, | |
572 tx, ty, tw, th, | |
573 &rx, &ry, &rw, &rh)) | |
574 { | |
575 gint d; | |
576 | |
577 d = (pw->size <= PAN_IMAGE_SIZE_THUMB_NONE) ? 2 : 8; | |
578 pixbuf_draw_rect_fill(pixbuf, | |
579 rx - x, ry - y, rw, rh, | |
580 PAN_SHADOW_COLOR, | |
581 PAN_SHADOW_ALPHA / d); | |
582 } | |
583 } | |
584 | |
585 return (pi->pixbuf == NULL); | |
586 } | |
587 | |
588 | |
589 /* | |
590 *----------------------------------------------------------------------------- | |
591 * item image type | |
592 *----------------------------------------------------------------------------- | |
593 */ | |
594 | |
595 static void pan_item_image_find_size(PanWindow *pw, PanItem *pi, gint w, gint h) | |
596 { | |
597 GList *work; | |
598 | |
599 pi->width = w; | |
600 pi->height = h; | |
601 | |
602 if (!pi->fd) return; | |
603 | |
604 work = pw->cache_list; | |
605 while (work) | |
606 { | |
607 PanCacheData *pc; | |
608 | |
609 pc = work->data; | |
610 work = work->next; | |
611 | |
612 if (pc->cd && pc->cd->dimensions && | |
138 | 613 pc->fd && pc->fd == pi->fd) |
105 | 614 { |
615 pi->width = MAX(1, pc->cd->width * pw->image_size / 100); | |
616 pi->height = MAX(1, pc->cd->height * pw->image_size / 100); | |
617 | |
618 pw->cache_list = g_list_remove(pw->cache_list, pc); | |
619 cache_sim_data_free(pc->cd); | |
138 | 620 file_data_unref(pc->fd); |
621 g_free(pc); | |
105 | 622 return; |
623 } | |
624 } | |
625 } | |
626 | |
627 PanItem *pan_item_image_new(PanWindow *pw, FileData *fd, gint x, gint y, gint w, gint h) | |
628 { | |
629 PanItem *pi; | |
630 | |
631 pi = g_new0(PanItem, 1); | |
632 pi->type = PAN_ITEM_IMAGE; | |
633 pi->fd = fd; | |
634 pi->x = x; | |
635 pi->y = y; | |
636 | |
637 pi->color_a = 255; | |
638 | |
639 pi->color2_r = 0; | |
640 pi->color2_g = 0; | |
641 pi->color2_b = 0; | |
642 pi->color2_a = PAN_SHADOW_ALPHA / 2; | |
643 | |
644 pan_item_image_find_size(pw, pi, w, h); | |
645 | |
646 pw->list = g_list_prepend(pw->list, pi); | |
647 | |
648 return pi; | |
649 } | |
650 | |
651 gint pan_item_image_draw(PanWindow *pw, PanItem *pi, GdkPixbuf *pixbuf, PixbufRenderer *pr, | |
652 gint x, gint y, gint width, gint height) | |
653 { | |
654 gint rx, ry, rw, rh; | |
655 | |
656 if (util_clip_region(x, y, width, height, | |
657 pi->x, pi->y, pi->width, pi->height, | |
658 &rx, &ry, &rw, &rh)) | |
659 { | |
660 if (pi->pixbuf) | |
661 { | |
662 gdk_pixbuf_composite(pi->pixbuf, pixbuf, rx - x, ry - y, rw, rh, | |
1000
4fe8f9656107
For the sake of consistency, use glib basic types everywhere.
zas_
parents:
995
diff
changeset
|
663 (gdouble) pi->x - x, |
4fe8f9656107
For the sake of consistency, use glib basic types everywhere.
zas_
parents:
995
diff
changeset
|
664 (gdouble) pi->y - y, |
105 | 665 1.0, 1.0, GDK_INTERP_NEAREST, |
666 pi->color_a); | |
667 } | |
668 else | |
669 { | |
670 pixbuf_draw_rect_fill(pixbuf, | |
671 rx - x, ry - y, rw, rh, | |
672 pi->color2_r, pi->color2_g, pi->color2_b, pi->color2_a); | |
673 } | |
674 } | |
675 | |
676 return (pi->pixbuf == NULL); | |
677 } | |
678 | |
679 | |
680 /* | |
681 *----------------------------------------------------------------------------- | |
682 * item lookup/search | |
683 *----------------------------------------------------------------------------- | |
684 */ | |
685 | |
686 PanItem *pan_item_find_by_key(PanWindow *pw, PanItemType type, const gchar *key) | |
687 { | |
688 GList *work; | |
689 | |
690 if (!key) return NULL; | |
691 | |
692 work = g_list_last(pw->list); | |
693 while (work) | |
694 { | |
695 PanItem *pi; | |
696 | |
697 pi = work->data; | |
698 if ((pi->type == type || type == PAN_ITEM_NONE) && | |
699 pi->key && strcmp(pi->key, key) == 0) | |
700 { | |
701 return pi; | |
702 } | |
703 work = work->prev; | |
704 } | |
705 work = g_list_last(pw->list_static); | |
706 while (work) | |
707 { | |
708 PanItem *pi; | |
709 | |
710 pi = work->data; | |
711 if ((pi->type == type || type == PAN_ITEM_NONE) && | |
712 pi->key && strcmp(pi->key, key) == 0) | |
713 { | |
714 return pi; | |
715 } | |
716 work = work->prev; | |
717 } | |
718 | |
719 return NULL; | |
720 } | |
721 | |
722 /* when ignore_case and partial are TRUE, path should be converted to lower case */ | |
723 static GList *pan_item_find_by_path_l(GList *list, GList *search_list, | |
724 PanItemType type, const gchar *path, | |
1434 | 725 gboolean ignore_case, gboolean partial) |
105 | 726 { |
727 GList *work; | |
728 | |
729 work = g_list_last(search_list); | |
730 while (work) | |
731 { | |
732 PanItem *pi; | |
733 | |
734 pi = work->data; | |
735 if ((pi->type == type || type == PAN_ITEM_NONE) && pi->fd) | |
736 { | |
1434 | 737 gboolean match = FALSE; |
105 | 738 |
726 | 739 if (path[0] == G_DIR_SEPARATOR) |
105 | 740 { |
741 if (pi->fd->path && strcmp(path, pi->fd->path) == 0) match = TRUE; | |
742 } | |
743 else if (pi->fd->name) | |
744 { | |
745 if (partial) | |
746 { | |
747 if (ignore_case) | |
748 { | |
749 gchar *haystack; | |
750 | |
751 haystack = g_utf8_strdown(pi->fd->name, -1); | |
752 match = (strstr(haystack, path) != NULL); | |
753 g_free(haystack); | |
754 } | |
755 else | |
756 { | |
757 if (strstr(pi->fd->name, path)) match = TRUE; | |
758 } | |
759 } | |
760 else if (ignore_case) | |
761 { | |
1307 | 762 if (g_ascii_strcasecmp(path, pi->fd->name) == 0) match = TRUE; |
105 | 763 } |
764 else | |
765 { | |
766 if (strcmp(path, pi->fd->name) == 0) match = TRUE; | |
767 } | |
768 } | |
769 | |
770 if (match) list = g_list_prepend(list, pi); | |
771 } | |
772 work = work->prev; | |
773 } | |
774 | |
775 return list; | |
776 } | |
777 | |
778 /* when ignore_case and partial are TRUE, path should be converted to lower case */ | |
779 GList *pan_item_find_by_path(PanWindow *pw, PanItemType type, const gchar *path, | |
1434 | 780 gboolean ignore_case, gboolean partial) |
105 | 781 { |
782 GList *list = NULL; | |
783 | |
784 if (!path) return NULL; | |
726 | 785 if (partial && path[0] == G_DIR_SEPARATOR) return NULL; |
105 | 786 |
787 list = pan_item_find_by_path_l(list, pw->list_static, type, path, ignore_case, partial); | |
788 list = pan_item_find_by_path_l(list, pw->list, type, path, ignore_case, partial); | |
789 | |
790 return g_list_reverse(list); | |
791 } | |
792 | |
783 | 793 GList *pan_item_find_by_fd(PanWindow *pw, PanItemType type, FileData *fd, |
1434 | 794 gboolean ignore_case, gboolean partial) |
783 | 795 { |
796 if (!fd) return NULL; | |
995 | 797 return pan_item_find_by_path(pw, type, fd->path, ignore_case, partial); |
783 | 798 } |
799 | |
800 | |
105 | 801 static PanItem *pan_item_find_by_coord_l(GList *list, PanItemType type, gint x, gint y, const gchar *key) |
802 { | |
803 GList *work; | |
804 | |
805 work = list; | |
806 while (work) | |
807 { | |
808 PanItem *pi; | |
809 | |
810 pi = work->data; | |
811 if ((pi->type == type || type == PAN_ITEM_NONE) && | |
812 x >= pi->x && x < pi->x + pi->width && | |
813 y >= pi->y && y < pi->y + pi->height && | |
814 (!key || (pi->key && strcmp(pi->key, key) == 0))) | |
815 { | |
816 return pi; | |
817 } | |
818 work = work->next; | |
819 } | |
820 | |
821 return NULL; | |
822 } | |
823 | |
824 PanItem *pan_item_find_by_coord(PanWindow *pw, PanItemType type, | |
825 gint x, gint y, const gchar *key) | |
826 { | |
827 PanItem *pi; | |
828 | |
829 pi = pan_item_find_by_coord_l(pw->list, type, x, y, key); | |
830 if (pi) return pi; | |
831 | |
832 return pan_item_find_by_coord_l(pw->list_static, type, x, y, key); | |
833 } | |
834 | |
835 | |
836 /* | |
837 *----------------------------------------------------------------------------- | |
838 * text alignments | |
839 *----------------------------------------------------------------------------- | |
840 */ | |
841 | |
842 PanTextAlignment *pan_text_alignment_new(PanWindow *pw, gint x, gint y, const gchar *key) | |
843 { | |
844 PanTextAlignment *ta; | |
845 | |
846 ta = g_new0(PanTextAlignment, 1); | |
847 | |
848 ta->pw = pw; | |
849 ta->x = x; | |
850 ta->y = y; | |
851 ta->key = g_strdup(key); | |
852 | |
853 return ta; | |
854 } | |
855 | |
856 void pan_text_alignment_free(PanTextAlignment *ta) | |
857 { | |
858 if (!ta) return; | |
859 | |
860 g_list_free(ta->column1); | |
861 g_list_free(ta->column2); | |
862 g_free(ta->key); | |
863 g_free(ta); | |
864 } | |
865 | |
866 PanItem *pan_text_alignment_add(PanTextAlignment *ta, const gchar *label, const gchar *text) | |
867 { | |
868 PanItem *item; | |
869 | |
870 if (label) | |
871 { | |
872 item = pan_item_text_new(ta->pw, ta->x, ta->y, label, | |
873 PAN_TEXT_ATTR_BOLD, 0, | |
874 PAN_POPUP_TEXT_COLOR, 255); | |
875 pan_item_set_key(item, ta->key); | |
876 } | |
877 else | |
878 { | |
879 item = NULL; | |
880 } | |
881 ta->column1 = g_list_append(ta->column1, item); | |
882 | |
883 if (text) | |
884 { | |
885 item = pan_item_text_new(ta->pw, ta->x, ta->y, text, | |
886 PAN_TEXT_ATTR_NONE, 0, | |
887 PAN_POPUP_TEXT_COLOR, 255); | |
888 pan_item_set_key(item, ta->key); | |
889 } | |
890 else | |
891 { | |
892 item = NULL; | |
893 } | |
894 ta->column2 = g_list_append(ta->column2, item); | |
895 | |
896 return item; | |
897 } | |
898 | |
899 void pan_text_alignment_calc(PanTextAlignment *ta, PanItem *box) | |
900 { | |
901 gint cw1, cw2; | |
902 gint x, y; | |
903 GList *work1; | |
904 GList *work2; | |
905 | |
906 cw1 = 0; | |
907 cw2 = 0; | |
908 | |
909 work1 = ta->column1; | |
910 while (work1) | |
911 { | |
912 PanItem *p; | |
913 | |
914 p = work1->data; | |
915 work1 = work1->next; | |
916 | |
917 if (p && p->width > cw1) cw1 = p->width; | |
918 } | |
919 | |
920 work2 = ta->column2; | |
921 while (work2) | |
922 { | |
923 PanItem *p; | |
924 | |
925 p = work2->data; | |
926 work2 = work2->next; | |
927 | |
928 if (p && p->width > cw2) cw2 = p->width; | |
929 } | |
930 | |
931 x = ta->x; | |
932 y = ta->y; | |
933 work1 = ta->column1; | |
934 work2 = ta->column2; | |
935 while (work1 && work2) | |
936 { | |
937 PanItem *p1; | |
938 PanItem *p2; | |
939 gint height = 0; | |
940 | |
941 p1 = work1->data; | |
942 p2 = work2->data; | |
943 work1 = work1->next; | |
944 work2 = work2->next; | |
945 | |
946 if (p1) | |
947 { | |
948 p1->x = x; | |
949 p1->y = y; | |
950 pan_item_size_by_item(box, p1, PREF_PAD_BORDER); | |
951 height = p1->height; | |
952 } | |
953 if (p2) | |
954 { | |
955 p2->x = x + cw1 + PREF_PAD_SPACE; | |
956 p2->y = y; | |
957 pan_item_size_by_item(box, p2, PREF_PAD_BORDER); | |
958 if (height < p2->height) height = p2->height; | |
959 } | |
960 | |
961 if (!p1 && !p2) height = PREF_PAD_GROUP; | |
962 | |
963 y += height; | |
964 } | |
965 } | |
1055
1646720364cf
Adding a vim modeline to all files - patch by Klaus Ethgen
nadvornik
parents:
1000
diff
changeset
|
966 /* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */ |