]> www.fi.muni.cz Git - evince.git/blob - pdf/xpdf/pdf-document.cc
6078f96297ebb81a9cd4ac6585d0a45b5b02d0e1
[evince.git] / pdf / xpdf / pdf-document.cc
1 /* pdfdocument.h: Implementation of EvDocument for PDF
2  * Copyright (C) 2004, Red Hat, Inc.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2, or (at your option)
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17  */
18
19 #include "gpdf-g-switch.h"
20 #include "pdf-document.h"
21 #include "gpdf-g-switch.h"
22
23 #include "GlobalParams.h"
24 #include "GDKSplashOutputDev.h"
25 #include "PDFDoc.h"
26
27 typedef struct _PdfDocumentClass PdfDocumentClass;
28
29 #define PDF_DOCUMENT_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), PDF_TYPE_DOCUMENT, PdfDocumentClass))
30 #define PDF_IS_DOCUMENT_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), PDF_TYPE_DOCUMENT))
31 #define PDF_DOCUMENT_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), PDF_TYPE_DOCUMENT, PdfDocumentClass))
32
33 struct _PdfDocumentClass
34 {
35         GObjectClass parent_class;
36 };
37
38 struct _PdfDocument
39 {
40         GObject parent_instance;
41
42         int page;
43         GdkRectangle page_rect;
44         GdkDrawable *target;
45
46         GDKSplashOutputDev *out;
47         PDFDoc *doc;
48         
49 };
50
51 static void pdf_document_document_iface_init (EvDocumentIface *iface);
52
53 G_DEFINE_TYPE_WITH_CODE (PdfDocument, pdf_document, G_TYPE_OBJECT,
54                          { G_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT,
55                                                   pdf_document_document_iface_init) });
56
57
58 static gboolean
59 pdf_document_load (EvDocument  *document,
60                    const char  *uri,
61                    GError     **error)
62 {
63         PdfDocument *pdf_document = PDF_DOCUMENT (document);
64         PDFDoc *newDoc;
65         int err;
66         char *filename;
67         GString *filename_g;
68         
69         if (!globalParams) {
70                 globalParams = new GlobalParams("/etc/xpdfrc");
71                 globalParams->setupBaseFonts(NULL);
72         }
73
74         filename = g_filename_from_uri (uri, NULL, error);
75         if (!filename)
76                 return FALSE;
77
78         filename_g = new GString (filename);
79         g_free (filename);
80
81         // open the PDF file
82         newDoc = new PDFDoc(filename_g, 0, 0);
83
84         delete filename_g;
85   
86         if (!newDoc->isOk()) {
87                 err = newDoc->getErrorCode();
88                 delete newDoc;
89
90                 /* FIXME: Add a real error enum to EvDocument */
91                 g_set_error (error, G_FILE_ERROR,
92                              G_FILE_ERROR_FAILED,
93                              "Failed to load document (error %d) '%s'\n",
94                              err,
95                              uri);
96                 
97                 return FALSE;
98         }
99
100         if (pdf_document->doc)
101                 delete pdf_document->doc;
102         pdf_document->doc = newDoc;
103
104         if (pdf_document->out) {
105                 pdf_document->out->startDoc(pdf_document->doc->getXRef());
106                 pdf_document->doc->displayPage (pdf_document->out, 1, 72, 72, 0, gTrue, gTrue);
107         }
108         
109         return TRUE;
110 }
111
112 static int
113 pdf_document_get_n_pages (EvDocument  *document)
114 {
115         PdfDocument *pdf_document = PDF_DOCUMENT (document);
116
117         if (pdf_document->doc)
118                 return pdf_document->doc->getNumPages();
119         else
120                 return 1;
121 }
122
123 static void
124 pdf_document_set_page (EvDocument  *document,
125                        int          page)
126 {
127         PdfDocument *pdf_document = PDF_DOCUMENT (document);
128
129         pdf_document->page = page;
130 }
131
132 static void
133 redraw_callback (void *data)
134 {
135         /* Need to hook up through a EvDocument callback? */
136 }
137
138 static void
139 pdf_document_set_target (EvDocument  *document,
140                          GdkDrawable *target)
141 {
142         PdfDocument *pdf_document = PDF_DOCUMENT (document);
143         
144         if (pdf_document->target != target) {
145                 if (pdf_document->target)
146                         g_object_unref (pdf_document->target);
147                 
148                 pdf_document->target = target;
149
150                 if (pdf_document->target)
151                         g_object_ref (pdf_document->target);
152
153                 if (pdf_document->out)
154                         delete pdf_document->out;
155
156                 if (pdf_document->target) {
157                         pdf_document->out = new GDKSplashOutputDev (gdk_drawable_get_screen (pdf_document->target),
158                                                          redraw_callback, (void*) document);
159
160                         if (pdf_document->doc) {
161                                 pdf_document->out->startDoc(pdf_document->doc->getXRef());
162                                 pdf_document->doc->displayPage (pdf_document->out, 1, 72, 72, 0, gTrue, gTrue);
163                         }
164                 }
165         }
166 }
167
168 static void
169 pdf_document_set_page_rect (EvDocument  *document,
170                             int          x,
171                             int          y,
172                             int          width,
173                             int          height)
174 {
175         PdfDocument *pdf_document = PDF_DOCUMENT (document);
176         
177         pdf_document->page_rect.x = x;
178         pdf_document->page_rect.y = y;
179         pdf_document->page_rect.width = width;
180         pdf_document->page_rect.height = height;
181 }
182
183 static void
184 pdf_document_render (EvDocument  *document,
185                      int          clip_x,
186                      int          clip_y,
187                      int          clip_width,
188                      int          clip_height)
189 {
190         PdfDocument *pdf_document = PDF_DOCUMENT (document);
191         GdkRectangle page;
192         GdkRectangle draw;
193
194         if (!pdf_document->target)
195                 return;
196         
197         page.x = 0;
198         page.y = 0;
199         page.width = pdf_document->out->getBitmapWidth();
200         page.height = pdf_document->out->getBitmapHeight();
201
202         draw.x = clip_x;
203         draw.y = clip_y;
204         draw.width = clip_width;
205         draw.height = clip_height;
206         
207         if (gdk_rectangle_intersect (&page, &draw, &draw))
208                 pdf_document->out->redraw (draw.x, draw.y,
209                                            pdf_document->target,
210                                            draw.x, draw.y,
211                                            draw.width, draw.height);
212 }
213
214 static void
215 pdf_document_finalize (GObject *object)
216 {
217         PdfDocument *pdf_document = PDF_DOCUMENT (object);
218
219         if (pdf_document->target)
220                 g_object_unref (pdf_document->target);
221
222         if (pdf_document->out)
223                 delete pdf_document->out;
224         if (pdf_document->doc)
225                 delete pdf_document->doc;
226
227 }
228
229 static void
230 pdf_document_class_init (PdfDocumentClass *klass)
231 {
232         GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
233   
234         gobject_class->finalize = pdf_document_finalize;
235 }
236
237 static void
238 pdf_document_document_iface_init (EvDocumentIface *iface)
239 {
240         iface->load = pdf_document_load;
241         iface->get_n_pages = pdf_document_get_n_pages;
242         iface->set_page = pdf_document_set_page;
243         iface->set_target = pdf_document_set_target;
244         iface->set_page_rect = pdf_document_set_page_rect;
245         iface->render = pdf_document_render;
246 }
247
248 static void
249 pdf_document_init (PdfDocument *document)
250 {
251 }
252