1 //========================================================================
2 //
3 // GDKSplashOutputDev.cc
4 //
5 // Copyright 2003 Glyph & Cog, LLC
6 // Copyright 2004 Red Hat, Inc. (GDK port)
7 //
8 //========================================================================
9
10 #include <config.h>
11
12 #ifdef USE_GCC_PRAGMAS
13 #pragma implementation
14 #endif
15
16 #include <goo/gmem.h>
17 #include <splash/SplashTypes.h>
18 #include <splash/SplashBitmap.h>
19 #include "Object.h"
20 #include "SplashOutputDev.h"
21 #include "GfxState.h"
22
23 #include <gdk/gdk.h>
24
25 #include "PDFDoc.h"
26 #include "GlobalParams.h"
27 #include "ErrorCodes.h"
28 #include <gtk/gtk.h>
29
30 //------------------------------------------------------------------------
31
32 #define xOutMaxRGBCube 6 // max size of RGB color cube
33
34 //------------------------------------------------------------------------
35 // GDKSplashOutputDev
36 //------------------------------------------------------------------------
37
38 class GDKSplashOutputDev: public SplashOutputDev {
39 public:
40
41 GDKSplashOutputDev(GdkScreen *screen,
42 void (*redrawCbkA)(void *data),
43 void *redrawCbkDataA, SplashColor sc);
44
45 virtual ~GDKSplashOutputDev();
46
47 //----- initialization and control
48
49 // End a page.
50 virtual void endPage();
51
52 // Dump page contents to display.
53 virtual void dump();
54
55 //----- update text state
56 virtual void updateFont(GfxState *state);
57
58 //----- special access
59
60 // Clear out the document (used when displaying an empty window).
61 void clear();
62
63 // Copy the rectangle (srcX, srcY, width, height) to (destX, destY)
64 // in destDC.
65 void redraw(int srcX, int srcY,
66 GdkDrawable *drawable,
67 int destX, int destY,
68 int width, int height);
69
70 private:
71
72 int incrementalUpdate;
73 void (*redrawCbk)(void *data);
74 void *redrawCbkData;
75 };
76
77 //------------------------------------------------------------------------
78 // Constants and macros
79 //------------------------------------------------------------------------
80
81 #define xoutRound(x) ((int)(x + 0.5))
82
83 //------------------------------------------------------------------------
84 // GDKSplashOutputDev
85 //------------------------------------------------------------------------
86
GDKSplashOutputDev(GdkScreen * screen,void (* redrawCbkA)(void * data),void * redrawCbkDataA,SplashColor sc)87 GDKSplashOutputDev::GDKSplashOutputDev(GdkScreen *screen,
88 void (*redrawCbkA)(void *data),
89 void *redrawCbkDataA, SplashColor sc):
90 SplashOutputDev(splashModeRGB8, 4, gFalse, sc),
91 incrementalUpdate (1)
92 {
93 redrawCbk = redrawCbkA;
94 redrawCbkData = redrawCbkDataA;
95 }
96
~GDKSplashOutputDev()97 GDKSplashOutputDev::~GDKSplashOutputDev() {
98 }
99
clear()100 void GDKSplashOutputDev::clear() {
101 startDoc(NULL);
102 startPage(0, NULL);
103 }
104
endPage()105 void GDKSplashOutputDev::endPage() {
106 SplashOutputDev::endPage();
107 if (!incrementalUpdate) {
108 (*redrawCbk)(redrawCbkData);
109 }
110 }
111
dump()112 void GDKSplashOutputDev::dump() {
113 if (incrementalUpdate && redrawCbk) {
114 (*redrawCbk)(redrawCbkData);
115 }
116 }
117
updateFont(GfxState * state)118 void GDKSplashOutputDev::updateFont(GfxState *state) {
119 SplashOutputDev::updateFont(state);
120 }
121
redraw(int srcX,int srcY,GdkDrawable * drawable,int destX,int destY,int width,int height)122 void GDKSplashOutputDev::redraw(int srcX, int srcY,
123 GdkDrawable *drawable,
124 int destX, int destY,
125 int width, int height) {
126 GdkGC *gc;
127 int gdk_rowstride;
128
129 gdk_rowstride = getBitmap()->getRowSize();
130 gc = gdk_gc_new (drawable);
131
132 gdk_draw_rgb_image (drawable, gc,
133 destX, destY,
134 width, height,
135 GDK_RGB_DITHER_NORMAL,
136 getBitmap()->getDataPtr() + srcY * gdk_rowstride + srcX * 3,
137 gdk_rowstride);
138
139 g_object_unref (gc);
140 }
141
142
143 typedef struct
144 {
145 GtkWidget *window;
146 GtkWidget *sw;
147 GtkWidget *drawing_area;
148 GDKSplashOutputDev *out;
149 PDFDoc *doc;
150 } View;
151
152 static void
drawing_area_expose(GtkWidget * drawing_area,GdkEventExpose * event,void * data)153 drawing_area_expose (GtkWidget *drawing_area,
154 GdkEventExpose *event,
155 void *data)
156 {
157 View *v = (View*) data;
158 GdkRectangle document;
159 GdkRectangle draw;
160
161 gdk_window_clear (drawing_area->window);
162
163 document.x = 0;
164 document.y = 0;
165 document.width = v->out->getBitmapWidth();
166 document.height = v->out->getBitmapHeight();
167
168 if (gdk_rectangle_intersect (&document, &event->area, &draw))
169 {
170 v->out->redraw (draw.x, draw.y,
171 drawing_area->window,
172 draw.x, draw.y,
173 draw.width, draw.height);
174 }
175 }
176
177 static int
view_load(View * v,const char * filename)178 view_load (View *v,
179 const char *filename)
180 {
181 PDFDoc *newDoc;
182 int err;
183 GooString *filename_g;
184 int w, h;
185
186 filename_g = new GooString (filename);
187
188 // open the PDF file
189 newDoc = new PDFDoc(filename_g, 0, 0);
190
191 delete filename_g;
192
193 if (!newDoc->isOk())
194 {
195 err = newDoc->getErrorCode();
196 delete newDoc;
197 return err;
198 }
199
200 if (v->doc)
201 delete v->doc;
202 v->doc = newDoc;
203
204 v->out->startDoc(v->doc->getXRef());
205
206 v->doc->displayPage (v->out, 1, 72, 72, 0, gFalse, gTrue, gTrue);
207
208 w = v->out->getBitmapWidth();
209 h = v->out->getBitmapHeight();
210
211 gtk_widget_set_size_request (v->drawing_area, w, h);
212
213 return errNone;
214 }
215
216 static void
view_show(View * v)217 view_show (View *v)
218 {
219 gtk_widget_show (v->window);
220 }
221
222 static void
redraw_callback(void * data)223 redraw_callback (void *data)
224 {
225 View *v = (View*) data;
226
227 gtk_widget_queue_draw (v->drawing_area);
228 }
229
230 static View*
view_new(void)231 view_new (void)
232 {
233 View *v;
234 GtkWidget *window;
235 GtkWidget *drawing_area;
236 GtkWidget *sw;
237
238 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
239
240 drawing_area = gtk_drawing_area_new ();
241
242 sw = gtk_scrolled_window_new (NULL, NULL);
243
244 gtk_container_add (GTK_CONTAINER (window), sw);
245 gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (sw), drawing_area);
246
247 gtk_widget_show_all (sw);
248
249 v = g_new0 (View, 1);
250
251 v->window = window;
252 v->drawing_area = drawing_area;
253 v->sw = sw;
254 SplashColor sc;
255 sc[0] = 255;
256 sc[1] = 255;
257 sc[2] = 255;
258 v->out = new GDKSplashOutputDev (gtk_widget_get_screen (window),
259 redraw_callback, (void*) v, sc);
260 v->doc = 0;
261
262 g_signal_connect (drawing_area,
263 "expose_event",
264 G_CALLBACK (drawing_area_expose),
265 (void*) v);
266
267 return v;
268 }
269
270 int
main(int argc,char * argv[])271 main (int argc, char *argv [])
272 {
273 View *v;
274 int i;
275
276 gtk_init (&argc, &argv);
277
278 globalParams = new GlobalParams();
279
280 if (argc == 1)
281 {
282 fprintf (stderr, "usage: %s PDF-FILES...\n", argv[0]);
283 return -1;
284 }
285
286
287 i = 1;
288 while (i < argc)
289 {
290 int err;
291
292 v = view_new ();
293
294 err = view_load (v, argv[i]);
295
296 if (err != errNone)
297 g_printerr ("Error loading document!\n");
298
299 view_show (v);
300
301 ++i;
302 }
303
304 gtk_main ();
305
306 delete globalParams;
307
308 return 0;
309 }
310