]> www.fi.muni.cz Git - evince.git/blob - pdf/xpdf/bonobo-image-x-pdf.cc
Compiles at least :)
[evince.git] / pdf / xpdf / bonobo-image-x-pdf.cc
1 /*
2  * image/x-pdf BonoboObject.
3  *
4  * Author:
5  *   Michael Meeks <michael@imaginator.com>
6  *
7  */
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <stddef.h>
11 #include <string.h>
12 #include <config.h>
13 extern "C" {
14 #define GString G_String
15 #include <gnome.h>
16 #include <libgnorba/gnorba.h>
17 #include <bonobo/gnome-bonobo.h>
18 #undef  GString 
19 }
20 #include "gtypes.h"
21 #include "GString.h"
22 #include "parseargs.h"
23 #include "gfile.h"
24 #include "gmem.h"
25 #include "Object.h"
26 #include "Stream.h"
27 #include "Array.h"
28 #include "Dict.h"
29 #include "XRef.h"
30 #include "Catalog.h"
31 #include "Page.h"
32 #include "Link.h"
33 #include "PDFDoc.h"
34 #include "GOutputDev.h"
35 #include "PSOutputDev.h"
36 #include "TextOutputDev.h"
37 #include "Params.h"
38 #include "Error.h"
39 #include "config.h"
40
41 GBool printCommands = gFalse;
42
43 CORBA_Environment ev;
44 CORBA_ORB orb;
45
46 /*
47  * BonoboObject data
48  */
49 typedef struct {
50   GnomeEmbeddable *bonobo_object;
51
52   PDFDoc *pdf;
53
54   GList *views;
55 } bonobo_object_data_t;
56
57 /*
58  * View data
59  */
60 typedef struct {
61   double                scale;
62   bonobo_object_data_t *bonobo_object_data;
63   GtkWidget            *drawing_area;
64   GtkPixmap            *pixmap;
65   GOutputDev           *out;
66   GdkColor              paper;
67   gint                  w, h;
68   gdouble               zoom;
69   gint                  page;
70 } view_data_t;
71
72 static void
73 redraw_view (view_data_t *view_data, GdkRectangle *rect)
74 {
75   GdkPixmap *pixmap;
76   GdkBitmap *dummy;
77   gint width, height;
78   bonobo_object_data_t *bonobo_object_data = view_data->bonobo_object_data;
79
80   gtk_pixmap_get (view_data->pixmap, &pixmap, &dummy);
81
82   g_return_if_fail (pixmap != NULL);
83
84   /*
85    * Do not draw outside the region that we know how to display
86    */
87   if (rect->x > view_data->w)
88     return;
89   
90   if (rect->y > view_data->h)
91     return;
92
93   /*
94    * Clip the draw region
95    */
96   if (rect->x + rect->width > view_data->w)
97     rect->width = view_data->w - rect->x;
98   
99   if (rect->y + rect->height > view_data->h)
100     rect->height = view_data->h - rect->y;
101   
102   /*
103    * Draw the exposed region.
104    */
105   gdk_draw_pixmap (view_data->drawing_area->window,
106                    view_data->drawing_area->style->white_gc,
107                    pixmap,
108                    rect->x, rect->y,
109                    rect->width,
110                    rect->height,
111                    rect->x, rect->y);
112 }
113
114 static void
115 configure_size (view_data_t *view_data, GdkRectangle *rect)
116 {
117 /*      ArtPixBuf *pixbuf;
118         
119         if (view_data->scaled)
120                 pixbuf = view_data->scaled;
121         else
122                 pixbuf = view_data->bonobo_object_data->image;
123
124         gtk_widget_set_usize (
125                 view_data->drawing_area,
126                 pixbuf->width,
127                 pixbuf->height);
128
129         rect->x = 0;
130         rect->y = 0;
131         rect->width = pixbuf->width;
132         rect->height = pixbuf->height;*/
133   g_warning ("Ahhh run away... scaling !");
134 }
135
136 static void
137 redraw_all (bonobo_object_data_t *bonobo_object_data)
138 {
139         GList *l;
140         
141         for (l = bonobo_object_data->views; l; l = l->next){
142                 GdkRectangle rect;
143                 view_data_t *view_data = (view_data_t *)l->data;
144
145                 configure_size (view_data, &rect);
146                 
147                 redraw_view (view_data, &rect);
148         }
149 }
150
151 static int
152 save_image (GnomePersistStream *ps, GNOME_Stream stream, void *data)
153 {
154   g_warning ("Unimplemented");
155   return -1;
156 }
157
158 /*
159  * Loads a PDF from a GNOME_Stream
160  */
161 static int
162 load_image_from_stream (GnomePersistStream *ps, GNOME_Stream stream, void *data)
163 {
164         bonobo_object_data_t *bonobo_object_data = (bonobo_object_data_t *)data;
165         CORBA_Environment ev;
166         CORBA_long length;
167         GNOME_Stream_iobuf *buffer;
168         FILE *hack;
169         char *name;
170
171         buffer = GNOME_Stream_iobuf__alloc ();
172
173         length = GNOME_Stream_length (stream, &ev);
174         GNOME_Stream_read (stream, length, &buffer, &ev);
175
176         name = tempnam (NULL, "xpdf-hack");
177         if (!name)
178           return -1;
179         hack = fopen (name, "w+");
180         if (!hack)
181           return -1;
182
183         fwrite (buffer->_buffer, 1, buffer->_length, hack);
184
185         CORBA_free (buffer);
186
187         bonobo_object_data->pdf = new PDFDoc (new GString (name));
188
189         redraw_all (bonobo_object_data);
190         return 0;
191 }
192
193 static void
194 destroy_view (GnomeView *view, view_data_t *view_data)
195 {
196         view_data->bonobo_object_data->views = g_list_remove (view_data->bonobo_object_data->views, view_data);
197         gtk_object_unref (GTK_OBJECT (view_data->drawing_area));
198
199         g_free (view_data);
200 }
201
202 static int
203 drawing_area_exposed (GtkWidget *widget, GdkEventExpose *event, view_data_t *view_data)
204 {
205 /*      if (!view_data->bonobo_object_data->image)
206         return TRUE;*/
207         
208         redraw_view (view_data, &event->area);
209
210         return TRUE;
211 }
212
213
214 static GtkPixmap *
215 setup_pixmap (bonobo_object_data_t *doc, view_data_t *view, GdkWindow *window)
216 {
217   GdkGCValues  gcValues;
218   GdkGC       *strokeGC;
219   PDFDoc      *pdf = doc->pdf;
220   int          w, h;
221   GdkPixmap   *pixmap = NULL;
222
223   w = view->w = (int)((pdf->getPageWidth  (view->page) * view->zoom) / 72.0);
224   h = view->h = (int)((pdf->getPageHeight (view->page) * view->zoom) / 72.0);
225
226   pixmap = gdk_pixmap_new (window, w, h, -1);
227
228   gdk_color_white (gtk_widget_get_default_colormap(), &view->paper);
229   view->out    = new GOutputDev (pixmap, view->paper, window);
230
231   gdk_color_white (gtk_widget_get_default_colormap (), &gcValues.foreground);
232   gdk_color_black (gtk_widget_get_default_colormap (), &gcValues.background);
233   gcValues.line_width = 1;
234   gcValues.line_style = GDK_LINE_SOLID;
235   strokeGC = gdk_gc_new_with_values (
236     pixmap, &gcValues, 
237     (enum GdkGCValuesMask)(GDK_GC_FOREGROUND | GDK_GC_BACKGROUND | GDK_GC_LINE_WIDTH | GDK_GC_LINE_STYLE));
238   
239   gdk_draw_rectangle (pixmap, strokeGC,
240                       TRUE, 0, 0,
241                       w, h);
242
243   return GTK_PIXMAP (gtk_pixmap_new (pixmap, NULL));
244 }
245
246 static GnomeView *
247 view_factory (GnomeEmbeddable *bonobo_object,
248               const GNOME_ViewFrame view_frame,
249               void *data)
250 {
251         GnomeView *view;
252         bonobo_object_data_t *bonobo_object_data = (bonobo_object_data_t *)data;
253         view_data_t *view_data = g_new (view_data_t, 1);
254
255         view_data->scale = 1.0;
256         view_data->bonobo_object_data = bonobo_object_data;
257         view_data->drawing_area = gtk_drawing_area_new ();
258         view_data->page = 1;
259         view_data->zoom = 86.0;
260
261         GdkWindow *win = gtk_widget_get_parent_window (GTK_WIDGET (view_data->drawing_area));
262         view_data->pixmap = setup_pixmap (bonobo_object_data, view_data, win);
263                                           
264
265         gtk_signal_connect (
266                 GTK_OBJECT (view_data->drawing_area),
267                 "expose_event",
268                 GTK_SIGNAL_FUNC (drawing_area_exposed), view_data);
269
270         gtk_widget_show (view_data->drawing_area);
271         view = gnome_view_new (view_data->drawing_area);
272
273         gtk_signal_connect (
274                 GTK_OBJECT (view), "destroy",
275                 GTK_SIGNAL_FUNC (destroy_view), view_data);
276
277         bonobo_object_data->views = g_list_prepend (bonobo_object_data->views,
278                                                 view_data);
279
280         return view;
281 }
282
283 static GnomeObject *
284 bonobo_object_factory (GnomeEmbeddableFactory *This, void *data)
285 {
286         GnomeEmbeddable *bonobo_object;
287         GnomePersistStream *stream;
288         bonobo_object_data_t *bonobo_object_data = (bonobo_object_data_t *)data;
289
290         bonobo_object_data = g_new0 (bonobo_object_data_t, 1);
291         if (!bonobo_object_data)
292                 return NULL;
293
294         /*
295          * Creates the BonoboObject server
296          */
297         bonobo_object = gnome_embeddable_new (view_factory, bonobo_object_data);
298         if (bonobo_object == NULL){
299                 g_free (bonobo_object_data);
300                 return NULL;
301         }
302
303         /* Does the pdf init stuff */
304         initParams (xpdfConfigFile); /* Init font path */
305         bonobo_object_data->pdf = NULL;
306
307         /*
308          * Interface GNOME::PersistStream 
309          */
310         stream = gnome_persist_stream_new ("bonobo-object:image-x-pdf",
311                                            load_image_from_stream,
312                                            save_image,
313                                            bonobo_object_data);
314         if (stream == NULL){
315                 gtk_object_unref (GTK_OBJECT (bonobo_object));
316                 g_free (bonobo_object_data);
317                 return NULL;
318         }
319
320         bonobo_object_data->bonobo_object = bonobo_object;
321
322         /*
323          * Bind the interfaces
324          */
325         gnome_object_add_interface (GNOME_OBJECT (bonobo_object),
326                                     GNOME_OBJECT (stream));
327         return (GnomeObject *) bonobo_object;
328 }
329
330 static void
331 init_bonobo_image_x_png_factory (void)
332 {
333         GnomeEmbeddableFactory *factory;
334         
335         factory = gnome_embeddable_factory_new (
336                 "bonobo-object-factory:image-x-pdf",
337                 bonobo_object_factory, NULL);
338 }
339
340 static void
341 init_server_factory (int argc, char **argv)
342 {
343         gnome_CORBA_init_with_popt_table (
344                 "bonobo-image-x-pdf", "1.0",
345                 &argc, argv, NULL, 0, NULL, GNORBA_INIT_SERVER_FUNC, &ev);
346
347         if (bonobo_init (CORBA_OBJECT_NIL, CORBA_OBJECT_NIL, CORBA_OBJECT_NIL) == FALSE)
348                 g_error (_("I could not initialize Bonobo"));
349 }
350
351 int
352 main (int argc, char *argv [])
353 {
354         CORBA_exception_init (&ev);
355
356         init_server_factory (argc, argv);
357         init_bonobo_image_x_png_factory ();
358
359         gtk_widget_set_default_colormap (gdk_rgb_get_cmap ());
360         gtk_widget_set_default_visual (gdk_rgb_get_visual ());
361         gtk_main ();
362         
363         CORBA_exception_free (&ev);
364
365         return 0;
366 }
367