d3621deef99332a7e0071e9dcccd52bc189c1c73
[claws.git] / src / imageview.c
1 /*
2  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3  * Copyright (C) 1999-2002 Hiroyuki Yamamoto
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18  */
19
20 #ifdef HAVE_CONFIG_H
21 #  include "config.h"
22 #endif
23
24 #include <glib.h>
25 #include <gtk/gtkscrolledwindow.h>
26 #include <gtk/gtkpixmap.h>
27
28 #if HAVE_GDK_PIXBUF
29 #  include <gdk-pixbuf/gdk-pixbuf.h>
30 #else
31 #if HAVE_GDK_IMLIB
32 #  include <gdk_imlib.h>
33 #endif
34 #endif /* HAVE_GDK_PIXBUF */
35
36 #include "intl.h"
37 #include "mainwindow.h"
38 #include "prefs_common.h"
39 #include "procmime.h"
40 #include "imageview.h"
41 #include "utils.h"
42
43 void get_resized_size (int w, int h, int aw, int ah, int *sw, int *sh);
44
45 ImageView *imageview_create(void)
46 {
47         ImageView *imageview;
48         GtkWidget *scrolledwin;
49
50         debug_print("Creating image view...\n");
51         imageview = g_new0(ImageView, 1);
52
53         scrolledwin = gtk_scrolled_window_new(NULL, NULL);
54         gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwin),
55                                        GTK_POLICY_AUTOMATIC,
56                                        GTK_POLICY_AUTOMATIC);
57         gtk_widget_set_usize(scrolledwin, prefs_common.mainview_width, -1);
58
59         gtk_widget_show_all(scrolledwin);
60
61         imageview->scrolledwin  = scrolledwin;
62         imageview->image        = NULL;
63
64         return imageview;
65 }
66
67 void imageview_init(ImageView *imageview)
68 {
69 }
70
71 #if HAVE_GDK_PIXBUF
72 void imageview_show_image(ImageView *imageview, MimeInfo *mimeinfo,
73                           const gchar *file)
74 {
75         GdkPixbuf *pixbuf;
76         GdkPixbuf *pixbuf_scaled;
77         GdkPixmap *pixmap;
78         GdkBitmap *mask;
79         int avail_height = imageview->scrolledwin->parent->allocation.height - 10;
80         int avail_width  = imageview->scrolledwin->parent->allocation.width - 10;
81         int sized_height = -1;
82         int sized_width  = -1;
83         
84         imageview_clear(imageview);
85
86         pixbuf = gdk_pixbuf_new_from_file(file);
87
88         if (!pixbuf) {
89                 g_warning(_("Can't load the image."));  
90                 return;
91         }
92
93         if (imageview->messageview->mainwin)
94                 main_window_cursor_wait(imageview->messageview->mainwin);
95         
96         get_resized_size (gdk_pixbuf_get_width(pixbuf), gdk_pixbuf_get_height(pixbuf), 
97                           avail_width, avail_height, &sized_width, &sized_height);
98         
99         pixbuf_scaled = gdk_pixbuf_scale_simple (pixbuf, sized_width, sized_height, 0);
100         
101         gdk_pixbuf_render_pixmap_and_mask(pixbuf_scaled, &pixmap, &mask, 0);
102
103         if (!imageview->image) {
104                 imageview->image = gtk_pixmap_new(pixmap, mask);
105
106                 gtk_scrolled_window_add_with_viewport
107                         (GTK_SCROLLED_WINDOW(imageview->scrolledwin),
108                          imageview->image);
109         } else
110                 gtk_pixmap_set(GTK_PIXMAP(imageview->image), pixmap, mask);
111
112         gtk_widget_show(imageview->image);
113
114         gdk_pixbuf_unref(pixbuf);
115         gdk_pixbuf_unref(pixbuf_scaled);
116
117         if (imageview->messageview->mainwin)
118                 main_window_cursor_normal(imageview->messageview->mainwin);
119 }
120 #else
121 #if HAVE_GDK_IMLIB
122 void imageview_show_image(ImageView *imageview, MimeInfo *mimeinfo,
123                           const gchar *file)
124 {
125         GdkImlibImage *im;
126         int avail_height = imageview->scrolledwin->parent->allocation.height - 10;
127         int avail_width  = imageview->scrolledwin->parent->allocation.width - 10;
128         int sized_height = -1;
129         int sized_width  = -1;
130
131         imageview_clear(imageview);
132
133         im = gdk_imlib_load_image((gchar *)file);
134
135         if (!im) {
136                 g_warning(_("Can't load the image."));  
137                 return;
138         }
139
140         if (imageview->messageview->mainwin)
141                 main_window_cursor_wait(imageview->messageview->mainwin);
142
143         get_resized_size (im->rgb_width, im->rgb_height, 
144                           avail_width, avail_height, &sized_width, &sized_height);
145
146         gdk_imlib_render(im, sized_width, sized_height);
147
148         if (!imageview->image) {
149                 imageview->image = gtk_pixmap_new(gdk_imlib_move_image(im),
150                                                   gdk_imlib_move_mask(im));
151
152                 gtk_scrolled_window_add_with_viewport
153                         (GTK_SCROLLED_WINDOW(imageview->scrolledwin),
154                          imageview->image);
155         } else
156                 gtk_pixmap_set(GTK_PIXMAP(imageview->image),
157                                gdk_imlib_move_image(im),
158                                gdk_imlib_move_mask(im));      
159
160         gtk_widget_show(imageview->image);
161
162         gdk_imlib_destroy_image(im);
163
164         if (imageview->messageview->mainwin)
165                 main_window_cursor_normal(imageview->messageview->mainwin);
166 }
167 #else
168 void imageview_show_image(ImageView *imageview, MimeInfo *mimeinfo,
169                           const gchar *file)
170 {
171 }
172 #endif /* HAVE_GDK_IMLIB */
173 #endif /* HAVE_GDK_PIXBUF */
174
175 void imageview_clear(ImageView *imageview)
176 {
177         GtkAdjustment *hadj, *vadj;
178
179         if (imageview->image)
180                 gtk_pixmap_set(GTK_PIXMAP(imageview->image), NULL, NULL);
181         hadj = gtk_scrolled_window_get_hadjustment
182                 (GTK_SCROLLED_WINDOW(imageview->scrolledwin));
183         gtk_adjustment_set_value(hadj, 0.0);
184         vadj = gtk_scrolled_window_get_vadjustment
185                 (GTK_SCROLLED_WINDOW(imageview->scrolledwin));
186         gtk_adjustment_set_value(vadj, 0.0);
187 }
188
189 void imageview_destroy(ImageView *imageview)
190 {
191         g_free(imageview);
192 }
193
194 void get_resized_size (int w, int h, int aw, int ah, int *sw, int *sh) {
195         
196         float wratio = 1.0;
197         float hratio = 1.0;
198         float ratio  = 1.0;
199
200         if (w > aw)
201                 wratio = (float)((float)aw/(float)w);
202         if (h > ah)
203                 hratio = (float)((float)ah/(float)h);
204         
205         ratio = (wratio > hratio) ? hratio : wratio;
206
207         *sw = (int)(w * ratio);
208         *sh = (int)(h * ratio);
209         
210         /* be paranoid */
211         if (*sw <= 0 || *sh <= 0) {
212                 *sw = w;
213                 *sh = h;
214         }
215 }