X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?a=blobdiff_plain;ds=sidebyside;f=backend%2Fdvi%2Fdvi-document.c;h=445c1e0cab2df14b6dd943c1a0441ff4bfa0493b;hb=217797d63b2d3b1c9a7a0511af1bbf3d99f0d482;hp=bd699709791a1000643e74fa1a98dad4c4b3af2b;hpb=1d6150237848b4c1fede94ce23baa4fd8870fd93;p=evince.git diff --git a/backend/dvi/dvi-document.c b/backend/dvi/dvi-document.c index bd699709..445c1e0c 100644 --- a/backend/dvi/dvi-document.c +++ b/backend/dvi/dvi-document.c @@ -58,6 +58,7 @@ struct _DviDocument typedef struct _DviDocumentClass DviDocumentClass; +static void dvi_document_do_color_special (DviContext *dvi, const char *prefix, const char *arg); static void dvi_document_document_iface_init (EvDocumentIface *iface); static void dvi_document_document_thumbnails_iface_init (EvDocumentThumbnailsIface *iface); static void dvi_document_get_page_size (EvDocument *document, @@ -151,15 +152,14 @@ dvi_document_get_page_size (EvDocument *document, return; } -static GdkPixbuf * -dvi_document_render_pixbuf (EvDocument *document, - EvRenderContext *rc) +static cairo_surface_t * +dvi_document_render (EvDocument *document, + EvRenderContext *rc) { GdkPixbuf *pixbuf; - GdkPixbuf *rotated_pixbuf; - + cairo_surface_t *surface; + cairo_surface_t *rotated_surface; DviDocument *dvi_document = DVI_DOCUMENT(document); - gint required_width, required_height; gint proposed_width, proposed_height; gint xmargin = 0, ymargin = 0; @@ -176,8 +176,8 @@ dvi_document_render_pixbuf (EvDocument *document, (int)((dvi_document->params->hshrink - 1) / rc->scale) + 1, (int)((dvi_document->params->vshrink - 1) / rc->scale) + 1); - required_width = dvi_document->base_width * rc->scale; - required_height = dvi_document->base_height * rc->scale; + required_width = dvi_document->base_width * rc->scale + 0.5; + required_height = dvi_document->base_height * rc->scale + 0.5; proposed_width = dvi_document->context->dvi_page_w * dvi_document->context->params.conv; proposed_height = dvi_document->context->dvi_page_h * dvi_document->context->params.vconv; @@ -194,10 +194,17 @@ dvi_document_render_pixbuf (EvDocument *document, g_mutex_unlock (dvi_context_mutex); - rotated_pixbuf = gdk_pixbuf_rotate_simple (pixbuf, 360 - rc->rotation); + /* FIXME: we should write a mdvi device based on cairo */ + surface = ev_document_misc_surface_from_pixbuf (pixbuf); g_object_unref (pixbuf); - return rotated_pixbuf; + rotated_surface = ev_document_misc_surface_rotate_and_scale (surface, + required_width, + required_height, + rc->rotation); + cairo_surface_destroy (surface); + + return rotated_surface; } static void @@ -206,11 +213,10 @@ dvi_document_finalize (GObject *object) DviDocument *dvi_document = DVI_DOCUMENT(object); g_mutex_lock (dvi_context_mutex); - if (dvi_document->context) - { + if (dvi_document->context) { mdvi_pixbuf_device_free (&dvi_document->context->device); mdvi_destroy_context (dvi_document->context); - } + } g_mutex_unlock (dvi_context_mutex); if (dvi_document->params) @@ -230,6 +236,7 @@ dvi_document_class_init (DviDocumentClass *klass) gobject_class->finalize = dvi_document_finalize; mdvi_init_kpathsea("evince", MDVI_MFMODE, MDVI_FALLBACK_FONT, MDVI_DPI); + mdvi_register_special ("Color", "color", NULL, dvi_document_do_color_special, 1); mdvi_register_fonts (); dvi_context_mutex = g_mutex_new (); @@ -259,7 +266,7 @@ dvi_document_document_iface_init (EvDocumentIface *iface) iface->can_get_text = dvi_document_can_get_text; iface->get_n_pages = dvi_document_get_n_pages; iface->get_page_size = dvi_document_get_page_size; - iface->render_pixbuf = dvi_document_render_pixbuf; + iface->render = dvi_document_render; iface->get_info = dvi_document_get_info; } @@ -344,6 +351,112 @@ dvi_document_document_thumbnails_iface_init (EvDocumentThumbnailsIface *iface) iface->get_dimensions = dvi_document_thumbnails_get_dimensions; } +#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 +dvi_document_do_color_special (DviContext *dvi, const char *prefix, const char *arg) +{ + char *op, *color; + + 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)) { + float r, g, b; + unsigned char red, green, blue; + sscanf (tmp+4, "%f %f %f", &r, &g, &b); + red = 255*r; + green = 255*g; + blue = 255*b; + mdvi_push_color (dvi, RGB2ULONG (red, green, blue), 0xFFFFFFFF); + } else if (!strncmp ("hsb", tmp, 4)) { + float h, s, b; + char red, green, blue; + sscanf (tmp+4, "%f %f %f", &h, &s, &b); + + if (hsb2rgb (h, s, b, &red, &green, &blue)) + mdvi_push_color (dvi, RGB2ULONG (red, green, blue), 0xFFFFFFFF); + } else if (!strncmp ("cmyk", tmp, 4)) { + double r, g, b, c, m, y, k; + + sscanf (tmp+5, "%f %f %f %f", &c, &m, &y, &k); + + r = 1.0 - c - k; + if (r < 0.0) + r = 0.0; + g = 1.0 - m - k; + if (g < 0.0) + g = 0.0; + b = 1.0 - y - k; + if (b < 0.0) + b = 0.0; + mdvi_push_color (dvi, RGB2ULONG ((char)(r*255+0.5), (char)(r*255+0.5), + (char)(b*255+0.5)), 0xFFFFFFFF); + } else { + GdkColor color; + if (gdk_color_parse (tmp, &color)) + mdvi_push_color (dvi, RGB2ULONG (color.red*255/65535, + color.green*255/65535, + color.blue*255/65535), 0xFFFFFFFF); + } + } +} static void dvi_document_init_params (DviDocument *dvi_document)