+/* EvFileExporterIface */
+static void
+dvi_document_file_exporter_begin (EvFileExporter *exporter,
+ EvFileExporterContext *fc)
+{
+ DviDocument *dvi_document = DVI_DOCUMENT(exporter);
+
+ if (dvi_document->exporter_filename)
+ g_free (dvi_document->exporter_filename);
+ dvi_document->exporter_filename = g_strdup (fc->filename);
+
+ if (dvi_document->exporter_opts) {
+ g_string_free (dvi_document->exporter_opts, TRUE);
+ }
+ dvi_document->exporter_opts = g_string_new ("-s ");
+}
+
+static void
+dvi_document_file_exporter_do_page (EvFileExporter *exporter,
+ EvRenderContext *rc)
+{
+ DviDocument *dvi_document = DVI_DOCUMENT(exporter);
+
+ g_string_append_printf (dvi_document->exporter_opts, "%d,", (rc->page) + 1);
+}
+
+static void
+dvi_document_file_exporter_end (EvFileExporter *exporter)
+{
+ gchar *command_line;
+ gint exit_stat;
+ GError *err = NULL;
+ gboolean success;
+
+ DviDocument *dvi_document = DVI_DOCUMENT(exporter);
+
+ command_line = g_strdup_printf ("dvipdfm %s -o %s \"%s\"", /* dvipdfm -s 1,2,.., -o exporter_filename dvi_filename */
+ dvi_document->exporter_opts->str,
+ dvi_document->exporter_filename,
+ dvi_document->context->filename);
+
+ success = g_spawn_command_line_sync (command_line,
+ NULL,
+ NULL,
+ &exit_stat,
+ &err);
+
+ g_free (command_line);
+
+ if (success == FALSE) {
+ g_warning ("Error: %s", err->message);
+ } else if (exit_stat != 0) {
+ g_warning ("Error: dvipdfm exited with non-zero status.");
+ }
+
+ if (err)
+ g_error_free (err);
+}
+
+static EvFileExporterCapabilities
+dvi_document_file_exporter_get_capabilities (EvFileExporter *exporter)
+{
+ return EV_FILE_EXPORTER_CAN_PAGE_SET |
+ EV_FILE_EXPORTER_CAN_COPIES |
+ EV_FILE_EXPORTER_CAN_COLLATE |
+ EV_FILE_EXPORTER_CAN_REVERSE |
+ EV_FILE_EXPORTER_CAN_GENERATE_PDF;
+}
+
+static void
+dvi_document_file_exporter_iface_init (EvFileExporterIface *iface)
+{
+ iface->begin = dvi_document_file_exporter_begin;
+ iface->do_page = dvi_document_file_exporter_do_page;
+ iface->end = dvi_document_file_exporter_end;
+ iface->get_capabilities = dvi_document_file_exporter_get_capabilities;
+}
+
+#define RGB2ULONG(r,g,b) ((0xFF<<24)|(r<<16)|(g<<8)|(b))
+
+static gboolean
+hsb2rgb (float h, float s, float v, char *red, char *green, char *blue)
+{
+ float i, f, p, q, t, r, g, b;
+
+ if (h == 360)
+ h = 0;
+ else if ((h > 360) || (h < 0))
+ return FALSE;
+
+ s /= 100;
+ v /= 100;
+ h /= 60;
+ i = floor (h);
+ f = h - i;
+ p = v * (1 - s);
+ q = v * (1 - (s * f));
+ t = v * (1 - (s * (1 - f)));
+
+ if (i == 0) {
+ r = v;
+ g = t;
+ b = p;
+ } else if (i == 1) {
+ r = q;
+ g = v;
+ b = p;
+ } else if (i == 2) {
+ r = p;
+ g = v;
+ b = t;
+ } else if (i == 3) {
+ r = p;
+ g = q;
+ b = v;
+ } else if (i == 4) {
+ r = t;
+ g = p;
+ b = v;
+ } else if (i == 5) {
+ r = v;
+ g = p;
+ b = q;
+ }
+
+ (*red) = (char)floor(r * 255);
+ (*green) = (char)floor(g * 255);
+ (*blue) = (char)floor(b * 255);
+
+ return TRUE;
+}
+
+static void
+parse_color (const gchar *ptr,
+ gdouble *color,
+ gint n_color)
+{
+ gchar *p = (gchar *)ptr;
+ gint i;
+
+ for (i = 0; i < n_color; i++) {
+ while (isspace (*p)) p++;
+ color[i] = g_ascii_strtod (p, NULL);
+ while (!isspace (*p) && *p != '\0') p++;
+ if (*p == '\0')
+ break;
+ }
+}
+
+static void
+dvi_document_do_color_special (DviContext *dvi, const char *prefix, const char *arg)
+{
+ if (strncmp (arg, "pop", 3) == 0) {
+ mdvi_pop_color (dvi);
+ } else if (strncmp (arg, "push", 4) == 0) {
+ /* Find color source: Named, CMYK or RGB */
+ const char *tmp = arg + 4;
+
+ while (isspace (*tmp)) tmp++;
+
+ if (!strncmp ("rgb", tmp, 3)) {
+ gdouble rgb[3];
+ guchar red, green, blue;
+
+ parse_color (tmp + 4, rgb, 3);
+
+ red = 255 * rgb[0];
+ green = 255 * rgb[1];
+ blue = 255 * rgb[2];
+
+ mdvi_push_color (dvi, RGB2ULONG (red, green, blue), 0xFFFFFFFF);
+ } else if (!strncmp ("hsb", tmp, 4)) {
+ gdouble hsb[3];
+ guchar red, green, blue;
+
+ parse_color (tmp + 4, hsb, 3);
+
+ if (hsb2rgb (hsb[0], hsb[1], hsb[2], &red, &green, &blue))
+ mdvi_push_color (dvi, RGB2ULONG (red, green, blue), 0xFFFFFFFF);
+ } else if (!strncmp ("cmyk", tmp, 4)) {
+ gdouble cmyk[4];
+ double r, g, b;
+ guchar red, green, blue;
+
+ parse_color (tmp + 5, cmyk, 4);
+
+ r = 1.0 - cmyk[0] - cmyk[3];
+ if (r < 0.0)
+ r = 0.0;
+ g = 1.0 - cmyk[1] - cmyk[3];
+ if (g < 0.0)
+ g = 0.0;
+ b = 1.0 - cmyk[2] - cmyk[3];
+ if (b < 0.0)
+ b = 0.0;
+
+ red = r * 255 + 0.5;
+ green = g * 255 + 0.5;
+ blue = b * 255 + 0.5;
+
+ mdvi_push_color (dvi, RGB2ULONG (red, green, blue), 0xFFFFFFFF);
+ } else if (!strncmp ("gray ", tmp, 5)) {
+ gdouble gray;
+ guchar rgb;
+
+ parse_color (tmp + 5, &gray, 1);
+
+ rgb = gray * 255 + 0.5;
+
+ mdvi_push_color (dvi, RGB2ULONG (rgb, rgb, rgb), 0xFFFFFFFF);
+ } else {
+ GdkColor color;
+
+ if (gdk_color_parse (tmp, &color)) {
+ guchar red, green, blue;
+
+ red = color.red * 255 / 65535.;
+ green = color.green * 255 / 65535.;
+ blue = color.blue * 255 / 65535.;
+
+ mdvi_push_color (dvi, RGB2ULONG (red, green, blue), 0xFFFFFFFF);
+ }
+ }
+ }
+}