]> www.fi.muni.cz Git - evince.git/blob - djvu/djvu-document.c
135d81cfa144bf97e75a5f2108f85fe00070eaf5
[evince.git] / djvu / djvu-document.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; c-indent-level: 8 -*- */
2 /*
3  * Copyright (C) 2005, Nickolay V. Shmyrev <nshmyrev@yandex.ru>
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, or (at your option)
8  * 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 #include "djvu-document.h"
21 #include "ev-document-thumbnails.h"
22 #include "ev-document-misc.h"
23
24 #include <libdjvu/ddjvuapi.h>
25 #include <gtk/gtk.h>
26 #include <gdk-pixbuf/gdk-pixbuf-core.h>
27
28 #define SCALE_FACTOR 0.2
29
30 enum {
31         PROP_0,
32         PROP_TITLE
33 };
34
35 struct _DjvuDocumentClass
36 {
37         GObjectClass parent_class;
38 };
39
40 struct _DjvuDocument
41 {
42         GObject parent_instance;
43
44         ddjvu_context_t  *d_context;
45         ddjvu_document_t *d_document;
46         ddjvu_format_t   *d_format;
47         
48         gchar *uri;
49 };
50
51 typedef struct _DjvuDocumentClass DjvuDocumentClass;
52
53 static void djvu_document_document_iface_init (EvDocumentIface *iface);
54 static void djvu_document_document_thumbnails_iface_init (EvDocumentThumbnailsIface *iface);
55
56 G_DEFINE_TYPE_WITH_CODE 
57     (DjvuDocument, djvu_document, G_TYPE_OBJECT, 
58     {
59       G_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT, djvu_document_document_iface_init);    
60       G_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT_THUMBNAILS, djvu_document_document_thumbnails_iface_init)
61      });
62
63 static gboolean
64 djvu_document_load (EvDocument  *document,
65                       const char  *uri,
66                       GError     **error)
67 {
68         DjvuDocument *djvu_document = DJVU_DOCUMENT (document);
69         ddjvu_document_t *doc;
70         gchar *filename;
71
72         /* FIXME: We could actually load uris  */
73         filename = g_filename_from_uri (uri, NULL, error);
74         if (!filename)
75                 return FALSE;
76         
77         doc = ddjvu_document_create_by_filename (djvu_document->d_context, filename, TRUE);
78
79         if (!doc) return FALSE;
80
81         if (djvu_document->d_document)
82             ddjvu_document_release (djvu_document->d_document);
83
84         djvu_document->d_document = doc;
85
86         while (!ddjvu_document_decoding_done (djvu_document->d_document)) {
87                     ddjvu_message_wait (djvu_document->d_context);
88                     ddjvu_message_pop (djvu_document->d_context);       
89         }
90         g_free (djvu_document->uri);
91         djvu_document->uri = g_strdup (uri);
92
93         return TRUE;
94 }
95
96
97 static gboolean
98 djvu_document_save (EvDocument  *document,
99                       const char  *uri,
100                       GError     **error)
101 {
102         DjvuDocument *djvu_document = DJVU_DOCUMENT (document);
103
104         return ev_xfer_uri_simple (djvu_document->uri, uri, error);
105 }
106
107 static int
108 djvu_document_get_n_pages (EvDocument  *document)
109 {
110         DjvuDocument *djvu_document = DJVU_DOCUMENT (document);
111         
112         g_return_val_if_fail (djvu_document->d_document, 0);
113         
114         return ddjvu_document_get_pagenum (djvu_document->d_document);
115 }
116
117 static void
118 djvu_document_get_page_size (EvDocument   *document,
119                                int           page,
120                                double       *width,
121                                double       *height)
122 {
123         DjvuDocument *djvu_document = DJVU_DOCUMENT (document);
124         ddjvu_pageinfo_t info;
125         
126         g_return_if_fail (djvu_document->d_document);
127         
128         while (ddjvu_document_get_pageinfo(djvu_document->d_document, page, &info) < DDJVU_JOB_OK) {
129                     ddjvu_message_wait (djvu_document->d_context);
130                     ddjvu_message_pop (djvu_document->d_context);       
131         }
132
133         *width = info.width * SCALE_FACTOR; 
134         *height = info.height * SCALE_FACTOR;
135 }
136
137 static GdkPixbuf *
138 djvu_document_render_pixbuf (EvDocument  *document, 
139                              EvRenderContext *rc)
140 {
141         DjvuDocument *djvu_document = DJVU_DOCUMENT (document);
142         GdkPixbuf *pixbuf;
143         GdkPixbuf *rotated_pixbuf;
144         
145         ddjvu_rect_t rrect;
146         ddjvu_rect_t prect;
147         ddjvu_page_t *d_page;
148         
149         double page_width, page_height;
150
151         d_page = ddjvu_page_create_by_pageno (djvu_document->d_document, rc->page);
152         
153         while (!ddjvu_page_decoding_done (d_page)) {
154                     ddjvu_message_wait (djvu_document->d_context);
155                     ddjvu_message_pop (djvu_document->d_context);       
156         }
157         
158         page_width = ddjvu_page_get_width (d_page) * rc->scale * SCALE_FACTOR;
159         page_height = ddjvu_page_get_height (d_page) * rc->scale * SCALE_FACTOR;
160
161         pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, page_width, page_height);
162
163         prect.x = 0; prect.y = 0;
164         prect.w = page_width; prect.h = page_height;
165         rrect = prect;
166
167         ddjvu_page_render(d_page, DDJVU_RENDER_COLOR,
168                           &prect,
169                           &rrect,
170                           djvu_document->d_format,
171                           gdk_pixbuf_get_rowstride (pixbuf),
172                           (gchar *)gdk_pixbuf_get_pixels (pixbuf));
173         
174         rotated_pixbuf = gdk_pixbuf_rotate_simple (pixbuf, 360 - rc->rotation);
175         g_object_unref (pixbuf);
176         
177         return rotated_pixbuf;
178 }
179
180 static void
181 djvu_document_finalize (GObject *object)
182 {
183         DjvuDocument *djvu_document = DJVU_DOCUMENT (object);
184
185         if (djvu_document->d_document)
186             ddjvu_document_release (djvu_document->d_document);
187
188         ddjvu_context_release (djvu_document->d_context);
189         ddjvu_format_release (djvu_document->d_format);
190         g_free (djvu_document->uri);
191         
192         G_OBJECT_CLASS (djvu_document_parent_class)->finalize (object);
193 }
194
195 static void
196 djvu_document_class_init (DjvuDocumentClass *klass)
197 {
198         GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
199
200         gobject_class->finalize = djvu_document_finalize;
201 }
202
203 static gboolean
204 djvu_document_can_get_text (EvDocument *document)
205 {
206         return FALSE;
207 }
208
209 static EvDocumentInfo *
210 djvu_document_get_info (EvDocument *document)
211 {
212         EvDocumentInfo *info;
213
214         info = g_new0 (EvDocumentInfo, 1);
215
216         return info;
217 }
218
219 static void
220 djvu_document_document_iface_init (EvDocumentIface *iface)
221 {
222         iface->load = djvu_document_load;
223         iface->save = djvu_document_save;
224         iface->can_get_text = djvu_document_can_get_text;
225         iface->get_n_pages = djvu_document_get_n_pages;
226         iface->get_page_size = djvu_document_get_page_size;
227         iface->render_pixbuf = djvu_document_render_pixbuf;
228         iface->get_info = djvu_document_get_info;
229 }
230
231 static void
232 djvu_document_thumbnails_get_dimensions (EvDocumentThumbnails *document,
233                                            gint                  page,
234                                            gint                  suggested_width,
235                                            gint                  *width,
236                                            gint                  *height)
237 {
238         DjvuDocument *djvu_document = DJVU_DOCUMENT (document); 
239         gdouble p_width, p_height;
240         gdouble page_ratio;
241         
242         djvu_document_get_page_size (EV_DOCUMENT(djvu_document), page, &p_width, &p_height);
243
244         page_ratio = p_height / p_width;
245         *width = suggested_width;
246         *height = (gint) (suggested_width * page_ratio);
247         
248         return;
249 }
250
251 static GdkPixbuf *
252 djvu_document_thumbnails_get_thumbnail (EvDocumentThumbnails   *document,
253                                           gint                   page,
254                                           gint                   rotation,
255                                           gint                   width,
256                                           gboolean               border)
257 {
258         DjvuDocument *djvu_document = DJVU_DOCUMENT (document);
259         GdkPixbuf *pixbuf, *rotated_pixbuf;
260         gint thumb_width, thumb_height;
261
262         guchar *pixels;
263         
264         g_return_val_if_fail (djvu_document->d_document, NULL);
265         
266         djvu_document_thumbnails_get_dimensions (document, page, width, &thumb_width, &thumb_height);
267         
268         pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8,
269                                  thumb_width, thumb_height);
270         gdk_pixbuf_fill (pixbuf, 0xffffffff);
271         pixels = gdk_pixbuf_get_pixels (pixbuf);
272         
273         while (ddjvu_thumbnail_status (djvu_document->d_document, page, 1) < DDJVU_JOB_OK) {
274                     ddjvu_message_wait (djvu_document->d_context);
275                     ddjvu_message_pop (djvu_document->d_context);       
276         }
277                     
278         ddjvu_thumbnail_render (djvu_document->d_document, page, 
279                                 &thumb_width, &thumb_height,
280                                 djvu_document->d_format,
281                                 gdk_pixbuf_get_rowstride (pixbuf), 
282                                 (gchar *)pixels);
283
284         rotated_pixbuf = gdk_pixbuf_rotate_simple (pixbuf, 360 - rotation);
285         g_object_unref (pixbuf);
286
287         if (border) {
288               GdkPixbuf *tmp_pixbuf = rotated_pixbuf;
289               rotated_pixbuf = ev_document_misc_get_thumbnail_frame (-1, -1, 0, tmp_pixbuf);
290               g_object_unref (tmp_pixbuf);
291         }
292         
293         return rotated_pixbuf;
294 }
295
296 static void
297 djvu_document_document_thumbnails_iface_init (EvDocumentThumbnailsIface *iface)
298 {
299         iface->get_thumbnail = djvu_document_thumbnails_get_thumbnail;
300         iface->get_dimensions = djvu_document_thumbnails_get_dimensions;
301 }
302
303 static void
304 djvu_document_init (DjvuDocument *djvu_document)
305 {
306         djvu_document->d_context = ddjvu_context_create ("Evince");
307         djvu_document->d_format = ddjvu_format_create (DDJVU_FORMAT_RGB24, 0, 0);
308         ddjvu_format_set_row_order (djvu_document->d_format,1);
309         
310         djvu_document->d_document = NULL;
311 }
312