1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; c-indent-level: 8 -*- */
3
* Copyright (C) 2005, Jonathan Blandford <jrb@gnome.org>
4
* Copyright (C) 2005, Bastien Nocera <hadess@hadess.net>
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2, or (at your option)
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24
#include "impress-document.h"
25
#include "ev-document-thumbnails.h"
26
#include "ev-document-misc.h"
28
struct _ImpressDocumentClass
30
GObjectClass parent_class;
33
struct _ImpressDocument
35
GObject parent_instance;
43
PangoContext *pango_ctx;
45
/* Only used while rendering inside the mainloop */
51
#define PAGE_WIDTH 1024
52
#define PAGE_HEIGHT 768
54
typedef struct _ImpressDocumentClass ImpressDocumentClass;
56
static void impress_document_document_iface_init (EvDocumentIface *iface);
57
static void impress_document_document_thumbnails_iface_init (EvDocumentThumbnailsIface *iface);
59
G_DEFINE_TYPE_WITH_CODE (ImpressDocument, impress_document, G_TYPE_OBJECT,
60
{ G_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT,
61
impress_document_document_iface_init);
62
G_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT_THUMBNAILS,
63
impress_document_document_thumbnails_iface_init);
68
imp_render_draw_bezier_real (GdkDrawable *d, GdkGC *gc, int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3)
71
int ax, bx, cx, ay, by, cy;
78
bx = 3 * (x2 - x1) - cx;
79
ax = x3 - x0 - cx - bx;
81
by = 3 * (y2 - y1) - cy;
82
ay = y3 - y0 - cy - by;
84
for (t = 0; t < 1; t += 0.01) {
87
nx = ax * t3 + bx * t2 + cx * t + x0;
88
ny = ay * t3 + by * t2 + cy * t + y0;
89
gdk_draw_line (d, gc, x, y, nx, ny);
96
imp_render_get_size(void *drw_data, int *w, int *h)
98
ImpressDocument *impress_document = IMPRESS_DOCUMENT (drw_data);
100
gdk_drawable_get_size(impress_document->pixmap, w, h);
104
imp_render_set_fg_color(void *drw_data, ImpColor *color)
106
ImpressDocument *impress_document = IMPRESS_DOCUMENT (drw_data);
110
c.green = color->green;
111
c.blue = color->blue;
112
gdk_gc_set_rgb_fg_color(impress_document->gc, &c);
116
imp_render_draw_line(void *drw_data, int x1, int y1, int x2, int y2)
118
ImpressDocument *impress_document = IMPRESS_DOCUMENT (drw_data);
120
gdk_draw_line(impress_document->pixmap, impress_document->gc, x1, y1, x2, y2);
124
imp_render_draw_rect(void *drw_data, int fill, int x, int y, int w, int h)
126
ImpressDocument *impress_document = IMPRESS_DOCUMENT (drw_data);
128
gdk_draw_rectangle(impress_document->pixmap, impress_document->gc, fill, x, y, w, h);
132
imp_render_draw_polygon(void *drw_data, int fill, ImpPoint *pts, int nr_pts)
134
ImpressDocument *impress_document = IMPRESS_DOCUMENT (drw_data);
136
gdk_draw_polygon(impress_document->pixmap, impress_document->gc, fill, (GdkPoint *)pts, nr_pts);
140
imp_render_draw_arc(void *drw_data, int fill, int x, int y, int w, int h, int sa, int ea)
142
ImpressDocument *impress_document = IMPRESS_DOCUMENT (drw_data);
144
gdk_draw_arc(impress_document->pixmap, impress_document->gc, fill, x, y, w, h, sa * 64, ea * 64);
148
imp_render_draw_bezier(void *drw_data, int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3)
150
ImpressDocument *impress_document = IMPRESS_DOCUMENT (drw_data);
152
imp_render_draw_bezier_real (impress_document->pixmap, impress_document->gc, x0, y0, x1, y1, x2, y2, x3, y3);
156
imp_render_open_image(void *drw_data, const unsigned char *pix, size_t size)
158
GdkPixbufLoader *gpl;
161
gpl = gdk_pixbuf_loader_new();
162
gdk_pixbuf_loader_write(gpl, pix, size, NULL);
163
gdk_pixbuf_loader_close(gpl, NULL);
164
pb = gdk_pixbuf_loader_get_pixbuf(gpl);
169
imp_render_get_image_size(void *drw_data, void *img_data, int *w, int *h)
171
GdkPixbuf *pb = (GdkPixbuf *) img_data;
173
*w = gdk_pixbuf_get_width(pb);
174
*h = gdk_pixbuf_get_height(pb);
178
imp_render_scale_image(void *drw_data, void *img_data, int w, int h)
180
GdkPixbuf *pb = (GdkPixbuf *) img_data;
182
return gdk_pixbuf_scale_simple(pb, w, h, GDK_INTERP_BILINEAR);
186
imp_render_draw_image(void *drw_data, void *img_data, int x, int y, int w, int h)
188
ImpressDocument *impress_document = IMPRESS_DOCUMENT (drw_data);
189
GdkPixbuf *pb = (GdkPixbuf *) img_data;
191
gdk_draw_pixbuf(impress_document->pixmap, impress_document->gc, pb, 0, 0, x, y, w, h, GDK_RGB_DITHER_NONE, 0, 0);
195
imp_render_close_image(void *drw_data, void *img_data)
197
GdkPixbuf *pb = (GdkPixbuf *) img_data;
199
g_object_unref(G_OBJECT(pb));
203
imp_render_markup(const char *text, size_t len, int styles, int size)
205
double scr_mm, scr_px, dpi;
210
scr_mm = gdk_screen_get_height_mm(gdk_screen_get_default());
211
scr_px = gdk_screen_get_height(gdk_screen_get_default());
212
dpi = (scr_px / scr_mm) * 25.4;
213
sz = (int) ((double) size * 72.0 * PANGO_SCALE / dpi);
214
esc = g_markup_escape_text(text, len);
215
ret = g_strdup_printf("<span size ='%d'>%s</span>", sz, esc);
221
imp_render_get_text_size(void *drw_data, const char *text, size_t len, int size, int styles, int *w, int *h)
223
ImpressDocument *impress_document = IMPRESS_DOCUMENT (drw_data);
228
g_return_if_fail (impress_document->pango_ctx != NULL);
230
lay = pango_layout_new(impress_document->pango_ctx);
231
m = imp_render_markup(text, len, styles, size);
232
pango_layout_set_markup(lay, m, strlen(m));
233
pango_layout_get_size(lay, &pw, &ph);
236
*w = pw / PANGO_SCALE;
237
*h = ph / PANGO_SCALE;
241
imp_render_draw_text(void *drw_data, int x, int y, const char *text, size_t len, int size, int styles)
243
ImpressDocument *impress_document = IMPRESS_DOCUMENT (drw_data);
247
g_return_if_fail (impress_document->pango_ctx != NULL);
249
lay = pango_layout_new(impress_document->pango_ctx);
250
m = imp_render_markup(text, len, styles, size);
251
pango_layout_set_markup(lay, m, strlen(m));
252
gdk_draw_layout(impress_document->pixmap, impress_document->gc, x, y, lay);
257
static const ImpDrawer imp_render_functions = {
259
imp_render_set_fg_color,
260
imp_render_draw_line,
261
imp_render_draw_rect,
262
imp_render_draw_polygon,
264
imp_render_draw_bezier,
265
imp_render_open_image,
266
imp_render_get_image_size,
267
imp_render_scale_image,
268
imp_render_draw_image,
269
imp_render_close_image,
270
imp_render_get_text_size,
274
/* Document interface */
276
impress_document_load (EvDocument *document,
280
ImpressDocument *impress_document = IMPRESS_DOCUMENT (document);
285
/* FIXME: Could we actually load uris ? */
286
filename = g_filename_from_uri (uri, NULL, error);
294
imp = imp_open (filename, &err);
298
//FIXME translate the err, set error
302
impress_document->imp = imp;
308
impress_document_save (EvDocument *document,
316
impress_document_get_n_pages (EvDocument *document)
318
ImpressDocument *impress_document = IMPRESS_DOCUMENT (document);
320
g_return_val_if_fail (IMPRESS_IS_DOCUMENT (document), 0);
321
g_return_val_if_fail (impress_document->imp != NULL, 0);
323
return imp_nr_pages (impress_document->imp);
327
impress_document_get_page_size (EvDocument *document,
332
ImpressDocument *impress_document = IMPRESS_DOCUMENT (document);
334
g_return_if_fail (IMPRESS_IS_DOCUMENT (document));
335
g_return_if_fail (impress_document->imp != NULL);
339
*height = PAGE_HEIGHT;
343
imp_render_get_from_drawable (ImpressDocument *impress_document)
347
page = imp_get_page (impress_document->imp, impress_document->pagenum);
349
g_return_val_if_fail (page != NULL, FALSE);
351
imp_context_set_page (impress_document->ctx, page);
352
imp_render (impress_document->ctx, impress_document);
354
impress_document->pixbuf = gdk_pixbuf_get_from_drawable (NULL,
355
GDK_DRAWABLE (impress_document->pixmap),
359
PAGE_WIDTH, PAGE_HEIGHT);
360
g_cond_broadcast (impress_document->cond);
365
impress_document_render_pixbuf (EvDocument *document,
368
ImpressDocument *impress_document = IMPRESS_DOCUMENT (document);
369
GdkPixbuf *scaled_pixbuf;
371
g_return_val_if_fail (IMPRESS_IS_DOCUMENT (document), 0);
372
g_return_val_if_fail (impress_document->imp != NULL, 0);
374
impress_document->pagenum = rc->page;
376
g_mutex_lock (impress_document->mutex);
377
impress_document->cond = g_cond_new ();
379
g_idle_add ((GSourceFunc) imp_render_get_from_drawable, impress_document);
381
g_cond_wait (impress_document->cond, impress_document->mutex);
382
g_cond_free (impress_document->cond);
383
g_mutex_unlock (impress_document->mutex);
385
scaled_pixbuf = gdk_pixbuf_scale_simple (impress_document->pixbuf,
386
PAGE_WIDTH * rc->scale,
387
PAGE_HEIGHT * rc->scale,
388
GDK_INTERP_BILINEAR);
389
gdk_pixbuf_unref (impress_document->pixbuf);
390
impress_document->pixbuf = NULL;
392
return scaled_pixbuf;
396
impress_document_finalize (GObject *object)
398
ImpressDocument *impress_document = IMPRESS_DOCUMENT (object);
400
g_mutex_free (impress_document->mutex);
402
imp_close (impress_document->imp);
403
imp_delete_context (impress_document->ctx);
404
g_free (impress_document->pango_ctx);
405
g_object_unref (G_OBJECT (impress_document->pixmap));
406
g_object_unref (impress_document->gc);
408
G_OBJECT_CLASS (impress_document_parent_class)->finalize (object);
412
impress_document_class_init (ImpressDocumentClass *klass)
414
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
416
gobject_class->finalize = impress_document_finalize;
420
impress_document_can_get_text (EvDocument *document)
425
static EvDocumentInfo *
426
impress_document_get_info (EvDocument *document)
428
EvDocumentInfo *info;
430
info = g_new0 (EvDocumentInfo, 1);
431
info->fields_mask = 0;
437
impress_document_document_iface_init (EvDocumentIface *iface)
439
iface->load = impress_document_load;
440
iface->save = impress_document_save;
441
iface->can_get_text = impress_document_can_get_text;
442
iface->get_n_pages = impress_document_get_n_pages;
443
iface->get_page_size = impress_document_get_page_size;
444
iface->render_pixbuf = impress_document_render_pixbuf;
445
iface->get_info = impress_document_get_info;
449
impress_document_thumbnails_get_thumbnail (EvDocumentThumbnails *document,
455
GdkPixbuf *pixbuf = NULL;
459
impress_document_get_page_size (EV_DOCUMENT (document),
463
rc = ev_render_context_new (rotation, page, size/w);
464
pixbuf = impress_document_render_pixbuf (EV_DOCUMENT (document), rc);
465
g_object_unref (G_OBJECT (rc));
469
GdkPixbuf *tmp_pixbuf = pixbuf;
470
pixbuf = ev_document_misc_get_thumbnail_frame (-1, -1, 0, tmp_pixbuf);
471
g_object_unref (tmp_pixbuf);
478
impress_document_thumbnails_get_dimensions (EvDocumentThumbnails *document,
480
gint suggested_width,
487
impress_document_get_page_size (EV_DOCUMENT (document),
490
g_return_if_fail (w > 0);
492
*width = suggested_width;
493
*height = (gint) (suggested_width * page_ratio);
497
impress_document_document_thumbnails_iface_init (EvDocumentThumbnailsIface *iface)
499
iface->get_thumbnail = impress_document_thumbnails_get_thumbnail;
500
iface->get_dimensions = impress_document_thumbnails_get_dimensions;
504
impress_document_init (ImpressDocument *impress_document)
508
impress_document->mutex = g_mutex_new ();
509
impress_document->ctx = imp_create_context(&imp_render_functions);
511
window = gdk_screen_get_root_window (gdk_screen_get_default ());
513
impress_document->pixmap = gdk_pixmap_new (window,
514
PAGE_WIDTH, PAGE_HEIGHT, -1);
515
impress_document->gc = gdk_gc_new (impress_document->pixmap);
516
impress_document->pango_ctx = gdk_pango_context_get ();
520
* vim: sw=2 ts=8 cindent noai bs=2