| File: | backend/dvi/dvi-document.c |
| Warning: | line 530, column 43 The right operand of '-' is a garbage value |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; c-indent-level: 8 -*- */ | |||
| 2 | /* | |||
| 3 | * Copyright (C) 2005, Nickolay V. Shmyrev <nshmyrev@yandex.ru> | |||
| 4 | * | |||
| 5 | * This program is free software; you can redistribute it and/or modify | |||
| 6 | * it under the terms of the GNU General Public License as published by | |||
| 7 | * the Free Software Foundation; either version 2, or (at your option) | |||
| 8 | * any later version. | |||
| 9 | * | |||
| 10 | * This program is distributed in the hope that it will be useful, | |||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| 13 | * GNU General Public License for more details. | |||
| 14 | * | |||
| 15 | * You should have received a copy of the GNU General Public License | |||
| 16 | * along with this program; if not, write to the Free Software | |||
| 17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
| 18 | */ | |||
| 19 | ||||
| 20 | #include "config.h" | |||
| 21 | ||||
| 22 | #include "dvi-document.h" | |||
| 23 | #include "ev-document-thumbnails.h" | |||
| 24 | #include "ev-document-misc.h" | |||
| 25 | #include "ev-file-exporter.h" | |||
| 26 | #include "ev-file-helpers.h" | |||
| 27 | ||||
| 28 | #include "mdvi.h" | |||
| 29 | #include "fonts.h" | |||
| 30 | #include "color.h" | |||
| 31 | #include "cairo-device.h" | |||
| 32 | ||||
| 33 | #include <glib/gi18n-lib.h> | |||
| 34 | #include <ctype.h> | |||
| 35 | #include <sys/wait.h> | |||
| 36 | #include <stdlib.h> | |||
| 37 | ||||
| 38 | GMutex dvi_context_mutex; | |||
| 39 | ||||
| 40 | enum { | |||
| 41 | PROP_0, | |||
| 42 | PROP_TITLE | |||
| 43 | }; | |||
| 44 | ||||
| 45 | struct _DviDocumentClass | |||
| 46 | { | |||
| 47 | EvDocumentClass parent_class; | |||
| 48 | }; | |||
| 49 | ||||
| 50 | struct _DviDocument | |||
| 51 | { | |||
| 52 | EvDocument parent_instance; | |||
| 53 | ||||
| 54 | DviContext *context; | |||
| 55 | DviPageSpec *spec; | |||
| 56 | DviParams *params; | |||
| 57 | ||||
| 58 | /* To let document scale we should remember width and height */ | |||
| 59 | double base_width; | |||
| 60 | double base_height; | |||
| 61 | ||||
| 62 | gchar *uri; | |||
| 63 | ||||
| 64 | /* PDF exporter */ | |||
| 65 | gchar *exporter_filename; | |||
| 66 | GString *exporter_opts; | |||
| 67 | }; | |||
| 68 | ||||
| 69 | typedef struct _DviDocumentClass DviDocumentClass; | |||
| 70 | ||||
| 71 | static void dvi_document_document_thumbnails_iface_init (EvDocumentThumbnailsInterface *iface); | |||
| 72 | static void dvi_document_file_exporter_iface_init (EvFileExporterInterface *iface); | |||
| 73 | static void dvi_document_do_color_special (DviContext *dvi, | |||
| 74 | const char *prefix, | |||
| 75 | const char *arg); | |||
| 76 | ||||
| 77 | EV_BACKEND_REGISTER_WITH_CODE (DviDocument, dvi_document,static GType g_define_type_id = 0; GType dvi_document_get_type (void) { return g_define_type_id; } static void dvi_document_init (DviDocument *self); static void dvi_document_class_init (DviDocumentClass *klass); static gpointer dvi_document_parent_class = ((void* )0); static void dvi_document_class_intern_init (gpointer klass ) { dvi_document_parent_class = g_type_class_peek_parent (klass ); dvi_document_class_init ((DviDocumentClass *) klass); } __attribute__ ((visibility("default"))) GType register_lector_backend (GTypeModule *module) { const GTypeInfo our_info = { sizeof (DviDocumentClass ), ((void*)0), ((void*)0), (GClassInitFunc) dvi_document_class_intern_init , ((void*)0), ((void*)0), sizeof (DviDocument), 0, (GInstanceInitFunc ) dvi_document_init }; bindtextdomain ("lector", "/usr/share/locale" ); bind_textdomain_codeset ("lector", "UTF-8"); g_define_type_id = g_type_module_register_type (module, (ev_document_get_type ()), "DviDocument", &our_info, (GTypeFlags)0); { { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc ) dvi_document_document_thumbnails_iface_init, ((void*)0), (( void*)0) }; g_type_module_add_interface (module, g_define_type_id , (ev_document_thumbnails_get_type ()), &g_implement_interface_info ); }; { const GInterfaceInfo g_implement_interface_info = { ( GInterfaceInitFunc) dvi_document_file_exporter_iface_init, (( void*)0), ((void*)0) }; g_type_module_add_interface (module, g_define_type_id , (ev_file_exporter_get_type ()), &g_implement_interface_info ); }; } return g_define_type_id; } | |||
| 78 | {static GType g_define_type_id = 0; GType dvi_document_get_type (void) { return g_define_type_id; } static void dvi_document_init (DviDocument *self); static void dvi_document_class_init (DviDocumentClass *klass); static gpointer dvi_document_parent_class = ((void* )0); static void dvi_document_class_intern_init (gpointer klass ) { dvi_document_parent_class = g_type_class_peek_parent (klass ); dvi_document_class_init ((DviDocumentClass *) klass); } __attribute__ ((visibility("default"))) GType register_lector_backend (GTypeModule *module) { const GTypeInfo our_info = { sizeof (DviDocumentClass ), ((void*)0), ((void*)0), (GClassInitFunc) dvi_document_class_intern_init , ((void*)0), ((void*)0), sizeof (DviDocument), 0, (GInstanceInitFunc ) dvi_document_init }; bindtextdomain ("lector", "/usr/share/locale" ); bind_textdomain_codeset ("lector", "UTF-8"); g_define_type_id = g_type_module_register_type (module, (ev_document_get_type ()), "DviDocument", &our_info, (GTypeFlags)0); { { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc ) dvi_document_document_thumbnails_iface_init, ((void*)0), (( void*)0) }; g_type_module_add_interface (module, g_define_type_id , (ev_document_thumbnails_get_type ()), &g_implement_interface_info ); }; { const GInterfaceInfo g_implement_interface_info = { ( GInterfaceInitFunc) dvi_document_file_exporter_iface_init, (( void*)0), ((void*)0) }; g_type_module_add_interface (module, g_define_type_id , (ev_file_exporter_get_type ()), &g_implement_interface_info ); }; } return g_define_type_id; } | |||
| 79 | EV_BACKEND_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT_THUMBNAILS, dvi_document_document_thumbnails_iface_init);static GType g_define_type_id = 0; GType dvi_document_get_type (void) { return g_define_type_id; } static void dvi_document_init (DviDocument *self); static void dvi_document_class_init (DviDocumentClass *klass); static gpointer dvi_document_parent_class = ((void* )0); static void dvi_document_class_intern_init (gpointer klass ) { dvi_document_parent_class = g_type_class_peek_parent (klass ); dvi_document_class_init ((DviDocumentClass *) klass); } __attribute__ ((visibility("default"))) GType register_lector_backend (GTypeModule *module) { const GTypeInfo our_info = { sizeof (DviDocumentClass ), ((void*)0), ((void*)0), (GClassInitFunc) dvi_document_class_intern_init , ((void*)0), ((void*)0), sizeof (DviDocument), 0, (GInstanceInitFunc ) dvi_document_init }; bindtextdomain ("lector", "/usr/share/locale" ); bind_textdomain_codeset ("lector", "UTF-8"); g_define_type_id = g_type_module_register_type (module, (ev_document_get_type ()), "DviDocument", &our_info, (GTypeFlags)0); { { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc ) dvi_document_document_thumbnails_iface_init, ((void*)0), (( void*)0) }; g_type_module_add_interface (module, g_define_type_id , (ev_document_thumbnails_get_type ()), &g_implement_interface_info ); }; { const GInterfaceInfo g_implement_interface_info = { ( GInterfaceInitFunc) dvi_document_file_exporter_iface_init, (( void*)0), ((void*)0) }; g_type_module_add_interface (module, g_define_type_id , (ev_file_exporter_get_type ()), &g_implement_interface_info ); }; } return g_define_type_id; } | |||
| 80 | EV_BACKEND_IMPLEMENT_INTERFACE (EV_TYPE_FILE_EXPORTER, dvi_document_file_exporter_iface_init);static GType g_define_type_id = 0; GType dvi_document_get_type (void) { return g_define_type_id; } static void dvi_document_init (DviDocument *self); static void dvi_document_class_init (DviDocumentClass *klass); static gpointer dvi_document_parent_class = ((void* )0); static void dvi_document_class_intern_init (gpointer klass ) { dvi_document_parent_class = g_type_class_peek_parent (klass ); dvi_document_class_init ((DviDocumentClass *) klass); } __attribute__ ((visibility("default"))) GType register_lector_backend (GTypeModule *module) { const GTypeInfo our_info = { sizeof (DviDocumentClass ), ((void*)0), ((void*)0), (GClassInitFunc) dvi_document_class_intern_init , ((void*)0), ((void*)0), sizeof (DviDocument), 0, (GInstanceInitFunc ) dvi_document_init }; bindtextdomain ("lector", "/usr/share/locale" ); bind_textdomain_codeset ("lector", "UTF-8"); g_define_type_id = g_type_module_register_type (module, (ev_document_get_type ()), "DviDocument", &our_info, (GTypeFlags)0); { { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc ) dvi_document_document_thumbnails_iface_init, ((void*)0), (( void*)0) }; g_type_module_add_interface (module, g_define_type_id , (ev_document_thumbnails_get_type ()), &g_implement_interface_info ); }; { const GInterfaceInfo g_implement_interface_info = { ( GInterfaceInitFunc) dvi_document_file_exporter_iface_init, (( void*)0), ((void*)0) }; g_type_module_add_interface (module, g_define_type_id , (ev_file_exporter_get_type ()), &g_implement_interface_info ); }; } return g_define_type_id; } | |||
| 81 | })static GType g_define_type_id = 0; GType dvi_document_get_type (void) { return g_define_type_id; } static void dvi_document_init (DviDocument *self); static void dvi_document_class_init (DviDocumentClass *klass); static gpointer dvi_document_parent_class = ((void* )0); static void dvi_document_class_intern_init (gpointer klass ) { dvi_document_parent_class = g_type_class_peek_parent (klass ); dvi_document_class_init ((DviDocumentClass *) klass); } __attribute__ ((visibility("default"))) GType register_lector_backend (GTypeModule *module) { const GTypeInfo our_info = { sizeof (DviDocumentClass ), ((void*)0), ((void*)0), (GClassInitFunc) dvi_document_class_intern_init , ((void*)0), ((void*)0), sizeof (DviDocument), 0, (GInstanceInitFunc ) dvi_document_init }; bindtextdomain ("lector", "/usr/share/locale" ); bind_textdomain_codeset ("lector", "UTF-8"); g_define_type_id = g_type_module_register_type (module, (ev_document_get_type ()), "DviDocument", &our_info, (GTypeFlags)0); { { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc ) dvi_document_document_thumbnails_iface_init, ((void*)0), (( void*)0) }; g_type_module_add_interface (module, g_define_type_id , (ev_document_thumbnails_get_type ()), &g_implement_interface_info ); }; { const GInterfaceInfo g_implement_interface_info = { ( GInterfaceInitFunc) dvi_document_file_exporter_iface_init, (( void*)0), ((void*)0) }; g_type_module_add_interface (module, g_define_type_id , (ev_file_exporter_get_type ()), &g_implement_interface_info ); }; } return g_define_type_id; }; | |||
| 82 | ||||
| 83 | static gboolean | |||
| 84 | dvi_document_load (EvDocument *document, | |||
| 85 | const char *uri, | |||
| 86 | GError **error) | |||
| 87 | { | |||
| 88 | gchar *filename; | |||
| 89 | DviDocument *dvi_document = DVI_DOCUMENT(document)((((DviDocument*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((document)), ((dvi_document_get_type ())))))); | |||
| 90 | ||||
| 91 | filename = g_filename_from_uri (uri, NULL((void*)0), error); | |||
| 92 | if (!filename) | |||
| 93 | return FALSE; | |||
| 94 | ||||
| 95 | g_mutex_lock (&dvi_context_mutex); | |||
| 96 | if (dvi_document->context) | |||
| 97 | mdvi_destroy_context (dvi_document->context); | |||
| 98 | ||||
| 99 | dvi_document->context = mdvi_init_context(dvi_document->params, dvi_document->spec, filename); | |||
| 100 | g_mutex_unlock (&dvi_context_mutex); | |||
| 101 | g_free (filename); | |||
| 102 | ||||
| 103 | if (!dvi_document->context) { | |||
| 104 | g_set_error_literal (error, | |||
| 105 | EV_DOCUMENT_ERRORev_document_error_quark (), | |||
| 106 | EV_DOCUMENT_ERROR_INVALID, | |||
| 107 | _("DVI document has incorrect format")((char *) g_dgettext ("lector", "DVI document has incorrect format" ))); | |||
| 108 | return FALSE; | |||
| 109 | } | |||
| 110 | ||||
| 111 | mdvi_cairo_device_init (&dvi_document->context->device); | |||
| 112 | ||||
| 113 | ||||
| 114 | dvi_document->base_width = dvi_document->context->dvi_page_w * dvi_document->context->params.conv | |||
| 115 | + 2 * unit2pix(dvi_document->params->dpi, MDVI_HMARGIN"1in") / dvi_document->params->hshrink; | |||
| 116 | ||||
| 117 | dvi_document->base_height = dvi_document->context->dvi_page_h * dvi_document->context->params.vconv | |||
| 118 | + 2 * unit2pix(dvi_document->params->vdpi, MDVI_VMARGIN"1in") / dvi_document->params->vshrink; | |||
| 119 | ||||
| 120 | g_free (dvi_document->uri); | |||
| 121 | dvi_document->uri = g_strdup (uri)g_strdup_inline (uri); | |||
| 122 | ||||
| 123 | return TRUE; | |||
| 124 | } | |||
| 125 | ||||
| 126 | ||||
| 127 | static gboolean | |||
| 128 | dvi_document_save (EvDocument *document, | |||
| 129 | const char *uri, | |||
| 130 | GError **error) | |||
| 131 | { | |||
| 132 | DviDocument *dvi_document = DVI_DOCUMENT (document)((((DviDocument*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((document)), ((dvi_document_get_type ())))))); | |||
| 133 | ||||
| 134 | return ev_xfer_uri_simple (dvi_document->uri, uri, error); | |||
| 135 | } | |||
| 136 | ||||
| 137 | static int | |||
| 138 | dvi_document_get_n_pages (EvDocument *document) | |||
| 139 | { | |||
| 140 | DviDocument *dvi_document = DVI_DOCUMENT (document)((((DviDocument*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((document)), ((dvi_document_get_type ())))))); | |||
| 141 | ||||
| 142 | return dvi_document->context->npages; | |||
| 143 | } | |||
| 144 | ||||
| 145 | static void | |||
| 146 | dvi_document_get_page_size (EvDocument *document, | |||
| 147 | EvPage *page, | |||
| 148 | double *width, | |||
| 149 | double *height) | |||
| 150 | { | |||
| 151 | DviDocument *dvi_document = DVI_DOCUMENT (document)((((DviDocument*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((document)), ((dvi_document_get_type ())))))); | |||
| 152 | ||||
| 153 | *width = dvi_document->base_width; | |||
| 154 | *height = dvi_document->base_height;; | |||
| 155 | } | |||
| 156 | ||||
| 157 | static cairo_surface_t * | |||
| 158 | dvi_document_render (EvDocument *document, | |||
| 159 | EvRenderContext *rc) | |||
| 160 | { | |||
| 161 | cairo_surface_t *surface; | |||
| 162 | cairo_surface_t *rotated_surface; | |||
| 163 | DviDocument *dvi_document = DVI_DOCUMENT(document)((((DviDocument*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((document)), ((dvi_document_get_type ())))))); | |||
| 164 | gint required_width, required_height; | |||
| 165 | gint proposed_width, proposed_height; | |||
| 166 | gint xmargin = 0, ymargin = 0; | |||
| 167 | ||||
| 168 | /* We should protect our context since it's not | |||
| 169 | * thread safe. The work to the future - | |||
| 170 | * let context render page independently | |||
| 171 | */ | |||
| 172 | g_mutex_lock (&dvi_context_mutex); | |||
| 173 | ||||
| 174 | mdvi_setpage (dvi_document->context, rc->page->index); | |||
| 175 | ||||
| 176 | mdvi_set_shrink (dvi_document->context,mdvi_configure((dvi_document->context), MDVI_SET_XSHRINK, ( (int)((dvi_document->params->hshrink - 1) / rc->scale ) + 1), MDVI_SET_YSHRINK, ((int)((dvi_document->params-> vshrink - 1) / rc->scale) + 1), MDVI_PARAM_LAST) | |||
| 177 | (int)((dvi_document->params->hshrink - 1) / rc->scale) + 1,mdvi_configure((dvi_document->context), MDVI_SET_XSHRINK, ( (int)((dvi_document->params->hshrink - 1) / rc->scale ) + 1), MDVI_SET_YSHRINK, ((int)((dvi_document->params-> vshrink - 1) / rc->scale) + 1), MDVI_PARAM_LAST) | |||
| 178 | (int)((dvi_document->params->vshrink - 1) / rc->scale) + 1)mdvi_configure((dvi_document->context), MDVI_SET_XSHRINK, ( (int)((dvi_document->params->hshrink - 1) / rc->scale ) + 1), MDVI_SET_YSHRINK, ((int)((dvi_document->params-> vshrink - 1) / rc->scale) + 1), MDVI_PARAM_LAST); | |||
| 179 | ||||
| 180 | required_width = dvi_document->base_width * rc->scale + 0.5; | |||
| 181 | required_height = dvi_document->base_height * rc->scale + 0.5; | |||
| 182 | proposed_width = dvi_document->context->dvi_page_w * dvi_document->context->params.conv; | |||
| 183 | proposed_height = dvi_document->context->dvi_page_h * dvi_document->context->params.vconv; | |||
| 184 | ||||
| 185 | if (required_width >= proposed_width) | |||
| 186 | xmargin = (required_width - proposed_width) / 2; | |||
| 187 | if (required_height >= proposed_height) | |||
| 188 | ymargin = (required_height - proposed_height) / 2; | |||
| 189 | ||||
| 190 | mdvi_cairo_device_set_margins (&dvi_document->context->device, xmargin, ymargin); | |||
| 191 | mdvi_cairo_device_set_scale (&dvi_document->context->device, rc->scale); | |||
| 192 | mdvi_cairo_device_render (dvi_document->context); | |||
| 193 | surface = mdvi_cairo_device_get_surface (&dvi_document->context->device); | |||
| 194 | ||||
| 195 | g_mutex_unlock (&dvi_context_mutex); | |||
| 196 | ||||
| 197 | rotated_surface = ev_document_misc_surface_rotate_and_scale (surface, | |||
| 198 | required_width, | |||
| 199 | required_height, | |||
| 200 | rc->rotation); | |||
| 201 | cairo_surface_destroy (surface); | |||
| 202 | ||||
| 203 | return rotated_surface; | |||
| 204 | } | |||
| 205 | ||||
| 206 | static void | |||
| 207 | dvi_document_finalize (GObject *object) | |||
| 208 | { | |||
| 209 | DviDocument *dvi_document = DVI_DOCUMENT(object)((((DviDocument*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((object)), ((dvi_document_get_type ())))))); | |||
| 210 | ||||
| 211 | g_mutex_lock (&dvi_context_mutex); | |||
| 212 | if (dvi_document->context) { | |||
| 213 | mdvi_cairo_device_free (&dvi_document->context->device); | |||
| 214 | mdvi_destroy_context (dvi_document->context); | |||
| 215 | } | |||
| 216 | g_mutex_unlock (&dvi_context_mutex); | |||
| 217 | ||||
| 218 | if (dvi_document->params) | |||
| 219 | g_free (dvi_document->params); | |||
| 220 | ||||
| 221 | if (dvi_document->exporter_filename) | |||
| 222 | g_free (dvi_document->exporter_filename); | |||
| 223 | ||||
| 224 | if (dvi_document->exporter_opts) | |||
| 225 | g_string_free (dvi_document->exporter_opts, TRUE)(__builtin_constant_p (TRUE) ? ((TRUE) ? (g_string_free) ((dvi_document ->exporter_opts), (TRUE)) : g_string_free_and_steal (dvi_document ->exporter_opts)) : (g_string_free) ((dvi_document->exporter_opts ), (TRUE))); | |||
| 226 | ||||
| 227 | g_free (dvi_document->uri); | |||
| 228 | ||||
| 229 | G_OBJECT_CLASS (dvi_document_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((dvi_document_parent_class)), (((GType) ((20) << (2 ))))))))->finalize (object); | |||
| 230 | } | |||
| 231 | ||||
| 232 | static gboolean | |||
| 233 | dvi_document_support_synctex (EvDocument *document) | |||
| 234 | { | |||
| 235 | return TRUE; | |||
| 236 | } | |||
| 237 | ||||
| 238 | static void | |||
| 239 | dvi_document_class_init (DviDocumentClass *klass) | |||
| 240 | { | |||
| 241 | GObjectClass *gobject_class = G_OBJECT_CLASS (klass)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((klass)), (((GType) ((20) << (2)))))))); | |||
| 242 | EvDocumentClass *ev_document_class = EV_DOCUMENT_CLASS (klass)((((EvDocumentClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((klass)), ((ev_document_get_type ())))))); | |||
| 243 | ||||
| 244 | gobject_class->finalize = dvi_document_finalize; | |||
| 245 | ||||
| 246 | mdvi_init_kpathsea ("lector", MDVI_MFMODE((void*)0), MDVI_FALLBACK_FONT"cmr10", MDVI_DPI600, getenv("TEXMFCNF")); | |||
| 247 | ||||
| 248 | mdvi_register_special ("Color", "color", NULL((void*)0), dvi_document_do_color_special, 1); | |||
| 249 | mdvi_register_fonts (); | |||
| 250 | ||||
| 251 | ev_document_class->load = dvi_document_load; | |||
| 252 | ev_document_class->save = dvi_document_save; | |||
| 253 | ev_document_class->get_n_pages = dvi_document_get_n_pages; | |||
| 254 | ev_document_class->get_page_size = dvi_document_get_page_size; | |||
| 255 | ev_document_class->render = dvi_document_render; | |||
| 256 | ev_document_class->support_synctex = dvi_document_support_synctex; | |||
| 257 | } | |||
| 258 | ||||
| 259 | static void | |||
| 260 | dvi_document_thumbnails_get_dimensions (EvDocumentThumbnails *document, | |||
| 261 | EvRenderContext *rc, | |||
| 262 | gint *width, | |||
| 263 | gint *height) | |||
| 264 | { | |||
| 265 | DviDocument *dvi_document = DVI_DOCUMENT (document)((((DviDocument*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((document)), ((dvi_document_get_type ())))))); | |||
| 266 | gdouble page_width = dvi_document->base_width; | |||
| 267 | gdouble page_height = dvi_document->base_height; | |||
| 268 | ||||
| 269 | if (rc->rotation == 90 || rc->rotation == 270) { | |||
| 270 | *width = (gint) (page_height * rc->scale); | |||
| 271 | *height = (gint) (page_width * rc->scale); | |||
| 272 | } else { | |||
| 273 | *width = (gint) (page_width * rc->scale); | |||
| 274 | *height = (gint) (page_height * rc->scale); | |||
| 275 | } | |||
| 276 | } | |||
| 277 | ||||
| 278 | static GdkPixbuf * | |||
| 279 | dvi_document_thumbnails_get_thumbnail (EvDocumentThumbnails *document, | |||
| 280 | EvRenderContext *rc, | |||
| 281 | gboolean border) | |||
| 282 | { | |||
| 283 | DviDocument *dvi_document = DVI_DOCUMENT (document)((((DviDocument*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((document)), ((dvi_document_get_type ())))))); | |||
| 284 | GdkPixbuf *pixbuf; | |||
| 285 | GdkPixbuf *rotated_pixbuf; | |||
| 286 | cairo_surface_t *surface; | |||
| 287 | gint thumb_width, thumb_height; | |||
| 288 | gint proposed_width, proposed_height; | |||
| 289 | ||||
| 290 | thumb_width = (gint) (dvi_document->base_width * rc->scale); | |||
| 291 | thumb_height = (gint) (dvi_document->base_height * rc->scale); | |||
| 292 | ||||
| 293 | g_mutex_lock (&dvi_context_mutex); | |||
| 294 | ||||
| 295 | mdvi_setpage (dvi_document->context, rc->page->index); | |||
| 296 | ||||
| 297 | mdvi_set_shrink (dvi_document->context,mdvi_configure((dvi_document->context), MDVI_SET_XSHRINK, ( (int)dvi_document->base_width * dvi_document->params-> hshrink / thumb_width), MDVI_SET_YSHRINK, ((int)dvi_document-> base_height * dvi_document->params->vshrink / thumb_height ), MDVI_PARAM_LAST) | |||
| 298 | (int)dvi_document->base_width * dvi_document->params->hshrink / thumb_width,mdvi_configure((dvi_document->context), MDVI_SET_XSHRINK, ( (int)dvi_document->base_width * dvi_document->params-> hshrink / thumb_width), MDVI_SET_YSHRINK, ((int)dvi_document-> base_height * dvi_document->params->vshrink / thumb_height ), MDVI_PARAM_LAST) | |||
| 299 | (int)dvi_document->base_height * dvi_document->params->vshrink / thumb_height)mdvi_configure((dvi_document->context), MDVI_SET_XSHRINK, ( (int)dvi_document->base_width * dvi_document->params-> hshrink / thumb_width), MDVI_SET_YSHRINK, ((int)dvi_document-> base_height * dvi_document->params->vshrink / thumb_height ), MDVI_PARAM_LAST); | |||
| 300 | ||||
| 301 | proposed_width = dvi_document->context->dvi_page_w * dvi_document->context->params.conv; | |||
| 302 | proposed_height = dvi_document->context->dvi_page_h * dvi_document->context->params.vconv; | |||
| 303 | ||||
| 304 | if (border) { | |||
| 305 | mdvi_cairo_device_set_margins (&dvi_document->context->device, | |||
| 306 | MAX (thumb_width - proposed_width, 0)(((thumb_width - proposed_width) > (0)) ? (thumb_width - proposed_width ) : (0)) / 2, | |||
| 307 | MAX (thumb_height - proposed_height, 0)(((thumb_height - proposed_height) > (0)) ? (thumb_height - proposed_height) : (0)) / 2); | |||
| 308 | } else { | |||
| 309 | mdvi_cairo_device_set_margins (&dvi_document->context->device, | |||
| 310 | MAX (thumb_width - proposed_width - 2, 0)(((thumb_width - proposed_width - 2) > (0)) ? (thumb_width - proposed_width - 2) : (0)) / 2, | |||
| 311 | MAX (thumb_height - proposed_height - 2, 0)(((thumb_height - proposed_height - 2) > (0)) ? (thumb_height - proposed_height - 2) : (0)) / 2); | |||
| 312 | } | |||
| 313 | ||||
| 314 | mdvi_cairo_device_set_scale (&dvi_document->context->device, rc->scale); | |||
| 315 | mdvi_cairo_device_render (dvi_document->context); | |||
| 316 | surface = mdvi_cairo_device_get_surface (&dvi_document->context->device); | |||
| 317 | g_mutex_unlock (&dvi_context_mutex); | |||
| 318 | ||||
| 319 | pixbuf = ev_document_misc_pixbuf_from_surface (surface); | |||
| 320 | cairo_surface_destroy (surface); | |||
| 321 | ||||
| 322 | rotated_pixbuf = gdk_pixbuf_rotate_simple (pixbuf, 360 - rc->rotation); | |||
| 323 | g_object_unref (pixbuf); | |||
| 324 | ||||
| 325 | if (border) { | |||
| 326 | GdkPixbuf *tmp_pixbuf = rotated_pixbuf; | |||
| 327 | ||||
| 328 | rotated_pixbuf = ev_document_misc_get_thumbnail_frame (-1, -1, tmp_pixbuf); | |||
| 329 | g_object_unref (tmp_pixbuf); | |||
| 330 | } | |||
| 331 | ||||
| 332 | return rotated_pixbuf; | |||
| 333 | } | |||
| 334 | ||||
| 335 | static void | |||
| 336 | dvi_document_document_thumbnails_iface_init (EvDocumentThumbnailsInterface *iface) | |||
| 337 | { | |||
| 338 | iface->get_thumbnail = dvi_document_thumbnails_get_thumbnail; | |||
| 339 | iface->get_dimensions = dvi_document_thumbnails_get_dimensions; | |||
| 340 | } | |||
| 341 | ||||
| 342 | /* EvFileExporterIface */ | |||
| 343 | static void | |||
| 344 | dvi_document_file_exporter_begin (EvFileExporter *exporter, | |||
| 345 | EvFileExporterContext *fc) | |||
| 346 | { | |||
| 347 | DviDocument *dvi_document = DVI_DOCUMENT(exporter)((((DviDocument*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((exporter)), ((dvi_document_get_type ())))))); | |||
| 348 | ||||
| 349 | if (dvi_document->exporter_filename) | |||
| 350 | g_free (dvi_document->exporter_filename); | |||
| 351 | dvi_document->exporter_filename = g_strdup (fc->filename)g_strdup_inline (fc->filename); | |||
| 352 | ||||
| 353 | if (dvi_document->exporter_opts) { | |||
| 354 | g_string_free (dvi_document->exporter_opts, TRUE)(__builtin_constant_p (TRUE) ? ((TRUE) ? (g_string_free) ((dvi_document ->exporter_opts), (TRUE)) : g_string_free_and_steal (dvi_document ->exporter_opts)) : (g_string_free) ((dvi_document->exporter_opts ), (TRUE))); | |||
| 355 | } | |||
| 356 | dvi_document->exporter_opts = g_string_new ("-s "); | |||
| 357 | } | |||
| 358 | ||||
| 359 | static void | |||
| 360 | dvi_document_file_exporter_do_page (EvFileExporter *exporter, | |||
| 361 | EvRenderContext *rc) | |||
| 362 | { | |||
| 363 | DviDocument *dvi_document = DVI_DOCUMENT(exporter)((((DviDocument*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((exporter)), ((dvi_document_get_type ())))))); | |||
| 364 | ||||
| 365 | g_string_append_printf (dvi_document->exporter_opts, "%d,", (rc->page->index) + 1); | |||
| 366 | } | |||
| 367 | ||||
| 368 | static void | |||
| 369 | dvi_document_file_exporter_end (EvFileExporter *exporter) | |||
| 370 | { | |||
| 371 | gchar *command_line; | |||
| 372 | gint exit_stat; | |||
| 373 | GError *err = NULL((void*)0); | |||
| 374 | gboolean success; | |||
| 375 | ||||
| 376 | DviDocument *dvi_document = DVI_DOCUMENT(exporter)((((DviDocument*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((exporter)), ((dvi_document_get_type ())))))); | |||
| 377 | gchar* quoted_filename = g_shell_quote (dvi_document->context->filename); | |||
| 378 | ||||
| 379 | command_line = g_strdup_printf ("dvipdfm %s -o %s %s", /* dvipdfm -s 1,2,.., -o exporter_filename dvi_filename */ | |||
| 380 | dvi_document->exporter_opts->str, | |||
| 381 | dvi_document->exporter_filename, | |||
| 382 | quoted_filename); | |||
| 383 | g_free (quoted_filename); | |||
| 384 | ||||
| 385 | success = g_spawn_command_line_sync (command_line, | |||
| 386 | NULL((void*)0), | |||
| 387 | NULL((void*)0), | |||
| 388 | &exit_stat, | |||
| 389 | &err); | |||
| 390 | ||||
| 391 | g_free (command_line); | |||
| 392 | ||||
| 393 | if (success == FALSE) { | |||
| 394 | g_warning ("Error: %s", err->message); | |||
| 395 | } else if (!WIFEXITED(exit_stat)(((exit_stat) & 0x7f) == 0) || WEXITSTATUS(exit_stat)(((exit_stat) & 0xff00) >> 8) != EXIT_SUCCESS0){ | |||
| 396 | g_warning ("Error: dvipdfm does not end normally or exit with a failure status."); | |||
| 397 | } | |||
| 398 | ||||
| 399 | if (err) | |||
| 400 | g_error_free (err); | |||
| 401 | } | |||
| 402 | ||||
| 403 | static EvFileExporterCapabilities | |||
| 404 | dvi_document_file_exporter_get_capabilities (EvFileExporter *exporter) | |||
| 405 | { | |||
| 406 | return EV_FILE_EXPORTER_CAN_PAGE_SET | | |||
| 407 | EV_FILE_EXPORTER_CAN_COPIES | | |||
| 408 | EV_FILE_EXPORTER_CAN_COLLATE | | |||
| 409 | EV_FILE_EXPORTER_CAN_REVERSE | | |||
| 410 | EV_FILE_EXPORTER_CAN_GENERATE_PDF; | |||
| 411 | } | |||
| 412 | ||||
| 413 | static void | |||
| 414 | dvi_document_file_exporter_iface_init (EvFileExporterInterface *iface) | |||
| 415 | { | |||
| 416 | iface->begin = dvi_document_file_exporter_begin; | |||
| 417 | iface->do_page = dvi_document_file_exporter_do_page; | |||
| 418 | iface->end = dvi_document_file_exporter_end; | |||
| 419 | iface->get_capabilities = dvi_document_file_exporter_get_capabilities; | |||
| 420 | } | |||
| 421 | ||||
| 422 | #define RGB2ULONG(r,g,b)((0xFF<<24)|(r<<16)|(g<<8)|(b)) ((0xFF<<24)|(r<<16)|(g<<8)|(b)) | |||
| 423 | ||||
| 424 | static gboolean | |||
| 425 | hsb2rgb (float h, float s, float v, guchar *red, guchar *green, guchar *blue) | |||
| 426 | { | |||
| 427 | float f, p, q, t, r, g, b; | |||
| 428 | int i; | |||
| 429 | ||||
| 430 | s /= 100; | |||
| 431 | v /= 100; | |||
| 432 | h /= 60; | |||
| 433 | i = floor (h); | |||
| 434 | if (i == 6) | |||
| 435 | i = 0; | |||
| 436 | else if ((i > 6) || (i < 0)) | |||
| 437 | return FALSE; | |||
| 438 | f = h - i; | |||
| 439 | p = v * (1 - s); | |||
| 440 | q = v * (1 - (s * f)); | |||
| 441 | t = v * (1 - (s * (1 - f))); | |||
| 442 | ||||
| 443 | if (i == 0) { | |||
| 444 | r = v; | |||
| 445 | g = t; | |||
| 446 | b = p; | |||
| 447 | } else if (i == 1) { | |||
| 448 | r = q; | |||
| 449 | g = v; | |||
| 450 | b = p; | |||
| 451 | } else if (i == 2) { | |||
| 452 | r = p; | |||
| 453 | g = v; | |||
| 454 | b = t; | |||
| 455 | } else if (i == 3) { | |||
| 456 | r = p; | |||
| 457 | g = q; | |||
| 458 | b = v; | |||
| 459 | } else if (i == 4) { | |||
| 460 | r = t; | |||
| 461 | g = p; | |||
| 462 | b = v; | |||
| 463 | } else if (i == 5) { | |||
| 464 | r = v; | |||
| 465 | g = p; | |||
| 466 | b = q; | |||
| 467 | } | |||
| 468 | ||||
| 469 | *red = (guchar)floor(r * 255.0); | |||
| 470 | *green = (guchar)floor(g * 255.0); | |||
| 471 | *blue = (guchar)floor(b * 255.0); | |||
| 472 | ||||
| 473 | return TRUE; | |||
| 474 | } | |||
| 475 | ||||
| 476 | static void | |||
| 477 | parse_color (const gchar *ptr, | |||
| 478 | gdouble *color, | |||
| 479 | gint n_color) | |||
| 480 | { | |||
| 481 | gchar *p = (gchar *)ptr; | |||
| 482 | gint i; | |||
| 483 | ||||
| 484 | for (i = 0; i < n_color; i++) { | |||
| 485 | while (isspace (*p)((*__ctype_b_loc ())[(int) ((*p))] & (unsigned short int) _ISspace)) p++; | |||
| 486 | color[i] = g_ascii_strtod (p, NULL((void*)0)); | |||
| 487 | while (!isspace (*p)((*__ctype_b_loc ())[(int) ((*p))] & (unsigned short int) _ISspace) && *p != '\0') p++; | |||
| 488 | if (*p == '\0') | |||
| 489 | break; | |||
| 490 | } | |||
| 491 | } | |||
| 492 | ||||
| 493 | static void | |||
| 494 | dvi_document_do_color_special (DviContext *dvi, const char *prefix, const char *arg) | |||
| 495 | { | |||
| 496 | if (strncmp (arg, "pop", 3) == 0) { | |||
| ||||
| 497 | mdvi_pop_color (dvi); | |||
| 498 | } else if (strncmp (arg, "push", 4) == 0) { | |||
| 499 | /* Find color source: Named, CMYK or RGB */ | |||
| 500 | const char *tmp = arg + 4; | |||
| 501 | ||||
| 502 | while (isspace (*tmp)((*__ctype_b_loc ())[(int) ((*tmp))] & (unsigned short int ) _ISspace)) tmp++; | |||
| 503 | ||||
| 504 | if (!strncmp ("rgb", tmp, 3)) { | |||
| 505 | gdouble rgb[3]; | |||
| 506 | guchar red, green, blue; | |||
| 507 | ||||
| 508 | parse_color (tmp + 4, rgb, 3); | |||
| 509 | ||||
| 510 | red = 255 * rgb[0]; | |||
| 511 | green = 255 * rgb[1]; | |||
| 512 | blue = 255 * rgb[2]; | |||
| 513 | ||||
| 514 | mdvi_push_color (dvi, RGB2ULONG (red, green, blue)((0xFF<<24)|(red<<16)|(green<<8)|(blue)), 0xFFFFFFFF); | |||
| 515 | } else if (!strncmp ("hsb", tmp, 4)) { | |||
| 516 | gdouble hsb[3]; | |||
| 517 | guchar red, green, blue; | |||
| 518 | ||||
| 519 | parse_color (tmp + 4, hsb, 3); | |||
| 520 | ||||
| 521 | if (hsb2rgb (hsb[0], hsb[1], hsb[2], &red, &green, &blue)) | |||
| 522 | mdvi_push_color (dvi, RGB2ULONG (red, green, blue)((0xFF<<24)|(red<<16)|(green<<8)|(blue)), 0xFFFFFFFF); | |||
| 523 | } else if (!strncmp ("cmyk", tmp, 4)) { | |||
| 524 | gdouble cmyk[4]; | |||
| 525 | double r, g, b; | |||
| 526 | guchar red, green, blue; | |||
| 527 | ||||
| 528 | parse_color (tmp + 5, cmyk, 4); | |||
| 529 | ||||
| 530 | r = 1.0 - cmyk[0] - cmyk[3]; | |||
| ||||
| 531 | if (r < 0.0) | |||
| 532 | r = 0.0; | |||
| 533 | g = 1.0 - cmyk[1] - cmyk[3]; | |||
| 534 | if (g < 0.0) | |||
| 535 | g = 0.0; | |||
| 536 | b = 1.0 - cmyk[2] - cmyk[3]; | |||
| 537 | if (b < 0.0) | |||
| 538 | b = 0.0; | |||
| 539 | ||||
| 540 | red = r * 255 + 0.5; | |||
| 541 | green = g * 255 + 0.5; | |||
| 542 | blue = b * 255 + 0.5; | |||
| 543 | ||||
| 544 | mdvi_push_color (dvi, RGB2ULONG (red, green, blue)((0xFF<<24)|(red<<16)|(green<<8)|(blue)), 0xFFFFFFFF); | |||
| 545 | } else if (!strncmp ("gray ", tmp, 5)) { | |||
| 546 | gdouble gray; | |||
| 547 | guchar rgb; | |||
| 548 | ||||
| 549 | parse_color (tmp + 5, &gray, 1); | |||
| 550 | ||||
| 551 | rgb = gray * 255 + 0.5; | |||
| 552 | ||||
| 553 | mdvi_push_color (dvi, RGB2ULONG (rgb, rgb, rgb)((0xFF<<24)|(rgb<<16)|(rgb<<8)|(rgb)), 0xFFFFFFFF); | |||
| 554 | } else { | |||
| 555 | CdkColor color; | |||
| 556 | ||||
| 557 | if (cdk_color_parse (tmp, &color)) { | |||
| 558 | guchar red, green, blue; | |||
| 559 | ||||
| 560 | red = color.red * 255 / 65535.; | |||
| 561 | green = color.green * 255 / 65535.; | |||
| 562 | blue = color.blue * 255 / 65535.; | |||
| 563 | ||||
| 564 | mdvi_push_color (dvi, RGB2ULONG (red, green, blue)((0xFF<<24)|(red<<16)|(green<<8)|(blue)), 0xFFFFFFFF); | |||
| 565 | } | |||
| 566 | } | |||
| 567 | } | |||
| 568 | } | |||
| 569 | ||||
| 570 | static void | |||
| 571 | dvi_document_init_params (DviDocument *dvi_document) | |||
| 572 | { | |||
| 573 | dvi_document->params = g_new0 (DviParams, 1)((DviParams *) g_malloc0_n ((1), sizeof (DviParams))); | |||
| 574 | ||||
| 575 | dvi_document->params->dpi = MDVI_DPI600; | |||
| 576 | dvi_document->params->vdpi = MDVI_VDPI600; | |||
| 577 | dvi_document->params->mag = MDVI_MAGNIFICATION1.0; | |||
| 578 | dvi_document->params->density = MDVI_DEFAULT_DENSITY50; | |||
| 579 | dvi_document->params->gamma = MDVI_DEFAULT_GAMMA1.0; | |||
| 580 | dvi_document->params->flags = MDVI_PARAM_ANTIALIASED1; | |||
| 581 | dvi_document->params->hdrift = 0; | |||
| 582 | dvi_document->params->vdrift = 0; | |||
| 583 | dvi_document->params->hshrink = MDVI_SHRINK_FROM_DPI(dvi_document->params->dpi)(((1) > ((dvi_document->params->dpi) / 75)) ? (1) : ( (dvi_document->params->dpi) / 75)); | |||
| 584 | dvi_document->params->vshrink = MDVI_SHRINK_FROM_DPI(dvi_document->params->vdpi)(((1) > ((dvi_document->params->vdpi) / 75)) ? (1) : ((dvi_document->params->vdpi) / 75)); | |||
| 585 | dvi_document->params->orientation = MDVI_ORIENT_TBLR; | |||
| 586 | ||||
| 587 | dvi_document->spec = NULL((void*)0); | |||
| 588 | ||||
| 589 | dvi_document->params->bg = 0xffffffff; | |||
| 590 | dvi_document->params->fg = 0xff000000; | |||
| 591 | } | |||
| 592 | ||||
| 593 | static void | |||
| 594 | dvi_document_init (DviDocument *dvi_document) | |||
| 595 | { | |||
| 596 | dvi_document->context = NULL((void*)0); | |||
| 597 | dvi_document_init_params (dvi_document); | |||
| 598 | ||||
| 599 | dvi_document->exporter_filename = NULL((void*)0); | |||
| 600 | dvi_document->exporter_opts = NULL((void*)0); | |||
| 601 | } |