1 /* pdfdocument.h: Implementation of EvDocument for PDF
2 * Copyright (C) 2004, Red Hat, Inc.
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)
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.
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.
19 #include "gpdf-g-switch.h"
20 #include "pdf-document.h"
21 #include "gpdf-g-switch.h"
23 #include "GlobalParams.h"
24 #include "GDKSplashOutputDev.h"
27 typedef struct _PdfDocumentClass PdfDocumentClass;
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))
33 struct _PdfDocumentClass
35 GObjectClass parent_class;
40 GObject parent_instance;
48 GDKSplashOutputDev *out;
54 static void pdf_document_document_iface_init (EvDocumentIface *iface);
56 G_DEFINE_TYPE_WITH_CODE (PdfDocument, pdf_document, G_TYPE_OBJECT,
57 { G_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT,
58 pdf_document_document_iface_init) });
61 document_validate_page (PdfDocument *pdf_document)
63 if (!pdf_document->page_valid) {
64 pdf_document->doc->displayPage (pdf_document->out, pdf_document->page,
65 72 * pdf_document->scale,
66 72 * pdf_document->scale,
69 pdf_document->page_valid = TRUE;
74 pdf_document_load (EvDocument *document,
78 PdfDocument *pdf_document = PDF_DOCUMENT (document);
85 globalParams = new GlobalParams("/etc/xpdfrc");
86 globalParams->setupBaseFonts(NULL);
89 filename = g_filename_from_uri (uri, NULL, error);
93 filename_g = new GString (filename);
96 // open the PDF file, assumes ownership of filename_g
97 newDoc = new PDFDoc(filename_g, 0, 0);
99 if (!newDoc->isOk()) {
100 err = newDoc->getErrorCode();
103 /* FIXME: Add a real error enum to EvDocument */
104 g_set_error (error, G_FILE_ERROR,
106 "Failed to load document (error %d) '%s'\n",
113 if (pdf_document->doc)
114 delete pdf_document->doc;
115 pdf_document->doc = newDoc;
117 pdf_document->page = 1;
119 if (pdf_document->out)
120 pdf_document->out->startDoc(pdf_document->doc->getXRef());
122 pdf_document->page_valid = FALSE;
128 pdf_document_get_n_pages (EvDocument *document)
130 PdfDocument *pdf_document = PDF_DOCUMENT (document);
132 if (pdf_document->doc)
133 return pdf_document->doc->getNumPages();
139 pdf_document_set_page (EvDocument *document,
142 PdfDocument *pdf_document = PDF_DOCUMENT (document);
144 page = CLAMP (page, 1, ev_document_get_n_pages (document));
146 if (page != pdf_document->page) {
147 pdf_document->page = page;
148 pdf_document->page_valid = FALSE;
154 pdf_document_get_page (EvDocument *document)
156 PdfDocument *pdf_document = PDF_DOCUMENT (document);
158 return pdf_document->page;
162 redraw_callback (void *data)
164 /* Need to hook up through a EvDocument callback? */
168 pdf_document_set_target (EvDocument *document,
171 PdfDocument *pdf_document = PDF_DOCUMENT (document);
173 if (pdf_document->target != target) {
174 if (pdf_document->target)
175 g_object_unref (pdf_document->target);
177 pdf_document->target = target;
179 if (pdf_document->target)
180 g_object_ref (pdf_document->target);
182 if (pdf_document->out) {
183 delete pdf_document->out;
184 pdf_document->out = NULL;
187 if (pdf_document->target) {
188 pdf_document->out = new GDKSplashOutputDev (gdk_drawable_get_screen (pdf_document->target),
189 redraw_callback, (void*) document);
191 if (pdf_document->doc)
192 pdf_document->out->startDoc(pdf_document->doc->getXRef());
196 pdf_document->page_valid = FALSE;
201 pdf_document_set_scale (EvDocument *document,
204 PdfDocument *pdf_document = PDF_DOCUMENT (document);
206 if (pdf_document->scale != scale) {
207 pdf_document->scale = scale;
208 pdf_document->page_valid = FALSE;
213 pdf_document_set_page_offset (EvDocument *document,
217 PdfDocument *pdf_document = PDF_DOCUMENT (document);
219 pdf_document->page_x_offset = x;
220 pdf_document->page_y_offset = y;
224 pdf_document_get_page_size (EvDocument *document,
228 PdfDocument *pdf_document = PDF_DOCUMENT (document);
230 if (document_validate_page (pdf_document)) {
232 *width = pdf_document->out->getBitmapWidth();
234 *height = pdf_document->out->getBitmapHeight();
244 pdf_document_render (EvDocument *document,
250 PdfDocument *pdf_document = PDF_DOCUMENT (document);
254 if (!document_validate_page (pdf_document) || !pdf_document->target)
257 page.x = pdf_document->page_x_offset;
258 page.y = pdf_document->page_y_offset;
259 page.width = pdf_document->out->getBitmapWidth();
260 page.height = pdf_document->out->getBitmapHeight();
264 draw.width = clip_width;
265 draw.height = clip_height;
267 if (gdk_rectangle_intersect (&page, &draw, &draw))
268 pdf_document->out->redraw (draw.x - page.x, draw.y - page.y,
269 pdf_document->target,
271 draw.width, draw.height);
275 pdf_document_finalize (GObject *object)
277 PdfDocument *pdf_document = PDF_DOCUMENT (object);
279 if (pdf_document->target)
280 g_object_unref (pdf_document->target);
282 if (pdf_document->out)
283 delete pdf_document->out;
284 if (pdf_document->doc)
285 delete pdf_document->doc;
290 pdf_document_class_init (PdfDocumentClass *klass)
292 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
294 gobject_class->finalize = pdf_document_finalize;
298 pdf_document_document_iface_init (EvDocumentIface *iface)
300 iface->load = pdf_document_load;
301 iface->get_n_pages = pdf_document_get_n_pages;
302 iface->set_page = pdf_document_set_page;
303 iface->get_page = pdf_document_get_page;
304 iface->set_scale = pdf_document_set_scale;
305 iface->set_target = pdf_document_set_target;
306 iface->set_page_offset = pdf_document_set_page_offset;
307 iface->get_page_size = pdf_document_get_page_size;
308 iface->render = pdf_document_render;
312 pdf_document_init (PdfDocument *pdf_document)
314 pdf_document->page = 1;
315 pdf_document->page_x_offset = 0;
316 pdf_document->page_y_offset = 0;
317 pdf_document->scale = 1.;
319 pdf_document->page_valid = FALSE;