diff options
author | Carlos Garcia Campos <carlosgc@gnome.org> | 2007-06-17 15:05:11 (GMT) |
---|---|---|
committer | Carlos Garcia Campos <carlosgc@src.gnome.org> | 2007-06-17 15:05:11 (GMT) |
commit | 4ce480dd80453275c10c3b99f988667c2f1bdfff (patch) | |
tree | a025495303fca4cbd3a219eeab51354001bc519d /backend/dvi | |
parent | 489459b17b659b9c51f62e12fd9ee730e85a1bfd (diff) |
Removed Added
2007-06-17 Carlos Garcia Campos <carlosgc@gnome.org>
* backend/dvi/Makefile.am:
* backend/dvi/pixbuf-device.[ch]: Removed
* backend/dvi/cairo-device.[ch]: Added
* backend/dvi/mdvi-lib/dviread.c: (draw_shrink_rule):
* backend/dvi/dvi-document.c: (dvi_document_load),
(dvi_document_render), (dvi_document_finalize),
(dvi_document_thumbnails_get_thumbnail), (parse_color),
(dvi_document_do_color_special):
* libdocument/ev-document-misc.[ch]:
(ev_document_misc_pixbuf_from_surface):
Port dvi backend to cairo and fix a problem with colors.
svn path=/trunk/; revision=2506
Diffstat (limited to 'backend/dvi')
-rw-r--r-- | backend/dvi/Makefile.am | 4 | ||||
-rw-r--r-- | backend/dvi/cairo-device.c | 295 | ||||
-rw-r--r-- | backend/dvi/cairo-device.h | 41 | ||||
-rw-r--r-- | backend/dvi/dvi-document.c | 256 | ||||
-rw-r--r-- | backend/dvi/mdvi-lib/dviread.c | 4 | ||||
-rw-r--r-- | backend/dvi/pixbuf-device.c | 220 | ||||
-rw-r--r-- | backend/dvi/pixbuf-device.h | 24 |
7 files changed, 487 insertions, 357 deletions
diff --git a/backend/dvi/Makefile.am b/backend/dvi/Makefile.am index f23a34b..be90e26 100644 --- a/backend/dvi/Makefile.am +++ b/backend/dvi/Makefile.am @@ -11,8 +11,8 @@ noinst_LTLIBRARIES = libgtkdvi.la libgtkdvi_la_SOURCES = \ dvi-document.c \ dvi-document.h \ - pixbuf-device.c \ - pixbuf-device.h \ + cairo-device.c \ + cairo-device.h \ fonts.c \ fonts.h diff --git a/backend/dvi/cairo-device.c b/backend/dvi/cairo-device.c new file mode 100644 index 0000000..19006d2 --- /dev/null +++ b/backend/dvi/cairo-device.c @@ -0,0 +1,295 @@ +/* + * Copyright (C) 2007 Carlos Garcia Campos <carlosgc@gnome.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include <gdk/gdkcolor.h> +#include "cairo-device.h" + +typedef struct { + cairo_t *cr; + + gint xmargin; + gint ymargin; + + gdouble scale; + + Ulong fg; + Ulong bg; + +} DviCairoDevice; + +static void +dvi_cairo_draw_glyph (DviContext *dvi, + DviFontChar *ch, + int x0, + int y0) +{ + DviCairoDevice *cairo_device; + int x, y, w, h; + gboolean isbox; + DviGlyph *glyph; + cairo_surface_t *surface; + + cairo_device = (DviCairoDevice *) dvi->device.device_data; + + glyph = &ch->grey; + + isbox = (glyph->data == NULL || (dvi->params.flags & MDVI_PARAM_CHARBOXES)); + + x = - glyph->x + x0 + cairo_device->xmargin; + y = - glyph->y + y0 + cairo_device->ymargin; + w = glyph->w; + h = glyph->h; + + surface = cairo_get_target (cairo_device->cr); + if (x < 0 || y < 0 + || x + w > cairo_image_surface_get_width (surface) + || y + h > cairo_image_surface_get_height (surface)) + return; + + cairo_save (cairo_device->cr); + if (isbox) { + cairo_rectangle (cairo_device->cr, + x - cairo_device->xmargin, + y - cairo_device->ymargin, + w, h); + cairo_stroke (cairo_device->cr); + } else { + cairo_translate (cairo_device->cr, x, y); + cairo_set_source_surface (cairo_device->cr, + (cairo_surface_t *) glyph->data, + 0, 0); + cairo_paint (cairo_device->cr); + } + + cairo_restore (cairo_device->cr); +} + +static void +dvi_cairo_draw_rule (DviContext *dvi, + int x, + int y, + Uint width, + Uint height, + int fill) +{ + DviCairoDevice *cairo_device; + Ulong color; + + cairo_device = (DviCairoDevice *) dvi->device.device_data; + + color = cairo_device->fg; + + cairo_save (cairo_device->cr); + + cairo_set_line_width (cairo_device->cr, + cairo_get_line_width (cairo_device->cr) * cairo_device->scale); + cairo_set_source_rgb (cairo_device->cr, + ((color >> 16) & 0xff) / 255., + ((color >> 8) & 0xff) / 255., + ((color >> 0) & 0xff) / 255.); + + cairo_rectangle (cairo_device->cr, + x + cairo_device->xmargin, + y + cairo_device->ymargin, + width, height); + if (fill == 0) { + cairo_stroke (cairo_device->cr); + } else { + cairo_fill (cairo_device->cr); + } + + cairo_restore (cairo_device->cr); +} + +static int +dvi_cairo_alloc_colors (void *device_data, + Ulong *pixels, + int npixels, + Ulong fg, + Ulong bg, + double gamma, + int density) +{ + double frac; + GdkColor color, color_fg, color_bg; + int i, n; + + color_bg.red = (bg >> 16) & 0xff; + color_bg.green = (bg >> 8) & 0xff; + color_bg.blue = (bg >> 0) & 0xff; + + color_fg.red = (fg >> 16) & 0xff; + color_fg.green = (fg >> 8) & 0xff; + color_fg.blue = (fg >> 0) & 0xff; + + n = npixels - 1; + for (i = 0; i < npixels; i++) { + frac = (gamma > 0) ? + pow ((double)i / n, 1 / gamma) : + 1 - pow ((double)(n - i) / n, -gamma); + + color.red = frac * ((double)color_fg.red - color_bg.red) + color_bg.red; + color.green = frac * ((double)color_fg.green - color_bg.green) + color_bg.green; + color.blue = frac * ((double)color_fg.blue - color_bg.blue) + color_bg.blue; + + pixels[i] = (color.red << 16) + (color.green << 8) + color.blue + 0xff000000; + } + + return npixels; +} + +static void * +dvi_cairo_create_image (void *device_data, + Uint width, + Uint height, + Uint bpp) +{ + return cairo_image_surface_create (CAIRO_FORMAT_RGB24, width, height); +} + +static void +dvi_cairo_free_image (void *ptr) +{ + cairo_surface_destroy ((cairo_surface_t *)ptr); +} + +static void +dvi_cairo_put_pixel (void *image, int x, int y, Ulong color) +{ + cairo_t *cr; + cairo_surface_t *surface; + gint rowstride; + guchar *p; + + surface = (cairo_surface_t *) image; + + rowstride = cairo_image_surface_get_stride (surface); + p = cairo_image_surface_get_data (surface) + y * rowstride + x * 4; + + p[2] = (color >> 16) & 0xff; + p[1] = (color >> 8) & 0xff; + p[0] = (color >> 0) & 0xff; +} + +static void +dvi_cairo_set_color (void *device_data, Ulong fg, Ulong bg) +{ + DviCairoDevice *cairo_device = (DviCairoDevice *) device_data; + + cairo_device->fg = fg; + cairo_device->bg = bg; +} + +/* Public methods */ +void +mdvi_cairo_device_init (DviDevice *device) +{ + device->device_data = g_new0 (DviCairoDevice, 1); + + device->draw_glyph = dvi_cairo_draw_glyph; + device->draw_rule = dvi_cairo_draw_rule; + device->alloc_colors = dvi_cairo_alloc_colors; + device->create_image = dvi_cairo_create_image; + device->free_image = dvi_cairo_free_image; + device->put_pixel = dvi_cairo_put_pixel; + device->set_color = dvi_cairo_set_color; + device->refresh = NULL; +} + +void +mdvi_cairo_device_free (DviDevice *device) +{ + DviCairoDevice *cairo_device; + + cairo_device = (DviCairoDevice *) device->device_data; + + if (cairo_device->cr) + cairo_destroy (cairo_device->cr); + + g_free (cairo_device); +} + +cairo_surface_t * +mdvi_cairo_device_get_surface (DviDevice *device) +{ + DviCairoDevice *cairo_device; + + cairo_device = (DviCairoDevice *) device->device_data; + + return cairo_surface_reference (cairo_get_target (cairo_device->cr)); +} + +void +mdvi_cairo_device_render (DviContext* dvi) +{ + DviCairoDevice *cairo_device; + gint page_width; + gint page_height; + cairo_surface_t *surface; + gchar *pixels; + gint rowstride; + static const cairo_user_data_key_t key; + + cairo_device = (DviCairoDevice *) dvi->device.device_data; + + if (cairo_device->cr) + cairo_destroy (cairo_device->cr); + + page_width = dvi->dvi_page_w * dvi->params.conv + 2 * cairo_device->xmargin; + page_height = dvi->dvi_page_h * dvi->params.vconv + 2 * cairo_device->ymargin; + + rowstride = page_width * 4; + pixels = (gchar *) g_malloc (page_height * rowstride); + memset (pixels, 0xff, page_height * rowstride); + + surface = cairo_image_surface_create_for_data (pixels, + CAIRO_FORMAT_RGB24, + page_width, page_height, + rowstride); + cairo_surface_set_user_data (surface, &key, + pixels, (cairo_destroy_func_t)g_free); + + cairo_device->cr = cairo_create (surface); + cairo_surface_destroy (surface); + + mdvi_dopage (dvi, dvi->currpage); +} + +void +mdvi_cairo_device_set_margins (DviDevice *device, + gint xmargin, + gint ymargin) +{ + DviCairoDevice *cairo_device; + + cairo_device = (DviCairoDevice *) device->device_data; + + cairo_device->xmargin = xmargin; + cairo_device->ymargin = ymargin; +} + +void +mdvi_cairo_device_set_scale (DviDevice *device, + gdouble scale) +{ + DviCairoDevice *cairo_device; + + cairo_device = (DviCairoDevice *) device->device_data; + + cairo_device->scale = scale; +} diff --git a/backend/dvi/cairo-device.h b/backend/dvi/cairo-device.h new file mode 100644 index 0000000..d5451be --- /dev/null +++ b/backend/dvi/cairo-device.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2007 Carlos Garcia Campos <carlosgc@gnome.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef MDVI_CAIRO_DEVICE +#define MDVI_CAIRO_DEVICE + +#include <glib.h> +#include <cairo.h> + +#include "mdvi.h" + +G_BEGIN_DECLS + +void mdvi_cairo_device_init (DviDevice *device); +void mdvi_cairo_device_free (DviDevice *device); +cairo_surface_t *mdvi_cairo_device_get_surface (DviDevice *device); +void mdvi_cairo_device_render (DviContext* dvi); +void mdvi_cairo_device_set_margins (DviDevice *device, + gint xmargin, + gint ymargin); +void mdvi_cairo_device_set_scale (DviDevice *device, + gdouble scale); + +G_END_DECLS + +#endif /* MDVI_CAIRO_DEVICE */ diff --git a/backend/dvi/dvi-document.c b/backend/dvi/dvi-document.c index 445c1e0..56d8bbb 100644 --- a/backend/dvi/dvi-document.c +++ b/backend/dvi/dvi-document.c @@ -23,7 +23,7 @@ #include "mdvi.h" #include "fonts.h" -#include "pixbuf-device.h" +#include "cairo-device.h" #include <gtk/gtk.h> #include <glib/gi18n.h> @@ -49,7 +49,6 @@ struct _DviDocument DviParams *params; /* To let document scale we should remember width and height */ - double base_width; double base_height; @@ -58,13 +57,15 @@ 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_iface_init (EvDocumentIface *iface); static void dvi_document_document_thumbnails_iface_init (EvDocumentThumbnailsIface *iface); -static void dvi_document_get_page_size (EvDocument *document, - int page, - double *width, - double *height); +static void dvi_document_get_page_size (EvDocument *document, + int page, + double *width, + double *height); +static void dvi_document_do_color_special (DviContext *dvi, + const char *prefix, + const char *arg); G_DEFINE_TYPE_WITH_CODE (DviDocument, dvi_document, G_TYPE_OBJECT, @@ -75,49 +76,50 @@ G_DEFINE_TYPE_WITH_CODE static gboolean dvi_document_load (EvDocument *document, - const char *uri, - GError **error) + const char *uri, + GError **error) { - gchar *filename; - DviDocument *dvi_document = DVI_DOCUMENT(document); - - filename = g_filename_from_uri (uri, NULL, error); - - if (!filename) { + gchar *filename; + DviDocument *dvi_document = DVI_DOCUMENT(document); + + filename = g_filename_from_uri (uri, NULL, error); + + if (!filename) { g_set_error (error, EV_DOCUMENT_ERROR, EV_DOCUMENT_ERROR_INVALID, _("File not available")); return FALSE; - } + } - g_mutex_lock (dvi_context_mutex); - if (dvi_document->context) - mdvi_destroy_context (dvi_document->context); - - dvi_document->context = mdvi_init_context(dvi_document->params, dvi_document->spec, filename); - g_mutex_unlock (dvi_context_mutex); - - if (!dvi_document->context) { + g_mutex_lock (dvi_context_mutex); + if (dvi_document->context) + mdvi_destroy_context (dvi_document->context); + + dvi_document->context = mdvi_init_context(dvi_document->params, dvi_document->spec, filename); + g_mutex_unlock (dvi_context_mutex); + + if (!dvi_document->context) { g_set_error (error, EV_DOCUMENT_ERROR, EV_DOCUMENT_ERROR_INVALID, _("DVI document has incorrect format")); return FALSE; - } - - mdvi_pixbuf_device_init (&dvi_document->context->device); - - dvi_document->base_width = dvi_document->context->dvi_page_w * dvi_document->context->params.conv + } + + mdvi_cairo_device_init (&dvi_document->context->device); + + + dvi_document->base_width = dvi_document->context->dvi_page_w * dvi_document->context->params.conv + 2 * unit2pix(dvi_document->params->dpi, MDVI_HMARGIN) / dvi_document->params->hshrink; - - dvi_document->base_height = dvi_document->context->dvi_page_h * dvi_document->context->params.vconv + + dvi_document->base_height = dvi_document->context->dvi_page_h * dvi_document->context->params.vconv + 2 * unit2pix(dvi_document->params->vdpi, MDVI_VMARGIN) / dvi_document->params->vshrink; - - g_free (dvi_document->uri); - dvi_document->uri = g_strdup (uri); - - return TRUE; + + g_free (dvi_document->uri); + dvi_document->uri = g_strdup (uri); + + return TRUE; } @@ -132,31 +134,29 @@ dvi_document_save (EvDocument *document, } static int -dvi_document_get_n_pages (EvDocument *document) +dvi_document_get_n_pages (EvDocument *document) { - DviDocument *dvi_document = DVI_DOCUMENT (document); - return dvi_document->context->npages; + DviDocument *dvi_document = DVI_DOCUMENT (document); + + return dvi_document->context->npages; } static void -dvi_document_get_page_size (EvDocument *document, - int page, - double *width, - double *height) +dvi_document_get_page_size (EvDocument *document, + int page, + double *width, + double *height) { - DviDocument * dvi_document = DVI_DOCUMENT (document); + DviDocument *dvi_document = DVI_DOCUMENT (document); *width = dvi_document->base_width; *height = dvi_document->base_height;; - - return; } static cairo_surface_t * dvi_document_render (EvDocument *document, EvRenderContext *rc) { - GdkPixbuf *pixbuf; cairo_surface_t *surface; cairo_surface_t *rotated_surface; DviDocument *dvi_document = DVI_DOCUMENT(document); @@ -170,7 +170,7 @@ dvi_document_render (EvDocument *document, */ g_mutex_lock (dvi_context_mutex); - mdvi_setpage(dvi_document->context, rc->page); + mdvi_setpage (dvi_document->context, rc->page); mdvi_set_shrink (dvi_document->context, (int)((dvi_document->params->hshrink - 1) / rc->scale) + 1, @@ -186,24 +186,19 @@ dvi_document_render (EvDocument *document, if (required_height >= proposed_height) ymargin = (required_height - proposed_height) / 2; - mdvi_pixbuf_device_set_margins (&dvi_document->context->device, xmargin, ymargin); - - mdvi_pixbuf_device_render (dvi_document->context); - - pixbuf = mdvi_pixbuf_device_get_pixbuf (&dvi_document->context->device); + mdvi_cairo_device_set_margins (&dvi_document->context->device, xmargin, ymargin); + mdvi_cairo_device_set_scale (&dvi_document->context->device, rc->scale); + mdvi_cairo_device_render (dvi_document->context); + surface = mdvi_cairo_device_get_surface (&dvi_document->context->device); g_mutex_unlock (dvi_context_mutex); - /* FIXME: we should write a mdvi device based on cairo */ - surface = ev_document_misc_surface_from_pixbuf (pixbuf); - g_object_unref (pixbuf); - rotated_surface = ev_document_misc_surface_rotate_and_scale (surface, required_width, - required_height, + required_height, rc->rotation); cairo_surface_destroy (surface); - + return rotated_surface; } @@ -214,7 +209,7 @@ dvi_document_finalize (GObject *object) g_mutex_lock (dvi_context_mutex); if (dvi_document->context) { - mdvi_pixbuf_device_free (&dvi_document->context->device); + mdvi_cairo_device_free (&dvi_document->context->device); mdvi_destroy_context (dvi_document->context); } g_mutex_unlock (dvi_context_mutex); @@ -235,7 +230,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_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 (); @@ -296,16 +291,16 @@ dvi_document_thumbnails_get_thumbnail (EvDocumentThumbnails *document, { DviDocument *dvi_document = DVI_DOCUMENT (document); GdkPixbuf *pixbuf; - GdkPixbuf *border_pixbuf; GdkPixbuf *rotated_pixbuf; + cairo_surface_t *surface; gint thumb_width, thumb_height; gint proposed_width, proposed_height; - + thumb_width = (gint) (dvi_document->base_width * rc->scale); thumb_height = (gint) (dvi_document->base_height * rc->scale); - - g_mutex_lock (dvi_context_mutex); + g_mutex_lock (dvi_context_mutex); + mdvi_setpage (dvi_document->context, rc->page); mdvi_set_shrink (dvi_document->context, @@ -316,29 +311,31 @@ dvi_document_thumbnails_get_thumbnail (EvDocumentThumbnails *document, proposed_height = dvi_document->context->dvi_page_h * dvi_document->context->params.vconv; if (border) { - mdvi_pixbuf_device_set_margins (&dvi_document->context->device, - MAX (thumb_width - proposed_width, 0) / 2, - MAX (thumb_height - proposed_height, 0) / 2); + mdvi_cairo_device_set_margins (&dvi_document->context->device, + MAX (thumb_width - proposed_width, 0) / 2, + MAX (thumb_height - proposed_height, 0) / 2); } else { - mdvi_pixbuf_device_set_margins (&dvi_document->context->device, - MAX (thumb_width - proposed_width - 2, 0) / 2, - MAX (thumb_height - proposed_height - 2, 0) / 2); + mdvi_cairo_device_set_margins (&dvi_document->context->device, + MAX (thumb_width - proposed_width - 2, 0) / 2, + MAX (thumb_height - proposed_height - 2, 0) / 2); } - - - mdvi_pixbuf_device_render (dvi_document->context); - pixbuf = mdvi_pixbuf_device_get_pixbuf (&dvi_document->context->device); + mdvi_cairo_device_set_scale (&dvi_document->context->device, rc->scale); + mdvi_cairo_device_render (dvi_document->context); + surface = mdvi_cairo_device_get_surface (&dvi_document->context->device); g_mutex_unlock (dvi_context_mutex); - + + pixbuf = ev_document_misc_pixbuf_from_surface (surface); + cairo_surface_destroy (surface); + rotated_pixbuf = gdk_pixbuf_rotate_simple (pixbuf, 360 - rc->rotation); g_object_unref (pixbuf); - - if (border) { - GdkPixbuf *tmp_pixbuf = rotated_pixbuf; - - rotated_pixbuf = ev_document_misc_get_thumbnail_frame (-1, -1, tmp_pixbuf); - g_object_unref (tmp_pixbuf); + + if (border) { + GdkPixbuf *tmp_pixbuf = rotated_pixbuf; + + rotated_pixbuf = ev_document_misc_get_thumbnail_frame (-1, -1, tmp_pixbuf); + g_object_unref (tmp_pixbuf); } return rotated_pixbuf; @@ -406,54 +403,95 @@ hsb2rgb (float h, float s, float v, char *red, char *green, char *blue) } static void -dvi_document_do_color_special (DviContext *dvi, const char *prefix, const char *arg) +parse_color (const gchar *ptr, + gdouble *color, + gint n_color) { - char *op, *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; + /* 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; + 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)) { - float h, s, b; - char red, green, blue; - sscanf (tmp+4, "%f %f %f", &h, &s, &b); + gdouble hsb[3]; + guchar red, green, blue; - if (hsb2rgb (h, s, b, &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)) { - double r, g, b, c, m, y, k; - - sscanf (tmp+5, "%f %f %f %f", &c, &m, &y, &k); + gdouble cmyk[4]; + double r, g, b; + guchar red, green, blue; + + parse_color (tmp + 5, cmyk, 4); - r = 1.0 - c - k; + r = 1.0 - cmyk[0] - cmyk[3]; if (r < 0.0) r = 0.0; - g = 1.0 - m - k; + g = 1.0 - cmyk[1] - cmyk[3]; if (g < 0.0) g = 0.0; - b = 1.0 - y - k; + b = 1.0 - cmyk[2] - cmyk[3]; 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); + + 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)) - mdvi_push_color (dvi, RGB2ULONG (color.red*255/65535, - color.green*255/65535, - color.blue*255/65535), 0xFFFFFFFF); + + 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); + } } } } diff --git a/backend/dvi/mdvi-lib/dviread.c b/backend/dvi/mdvi-lib/dviread.c index 8398c27..3042951 100644 --- a/backend/dvi/mdvi-lib/dviread.c +++ b/backend/dvi/mdvi-lib/dviread.c @@ -1178,8 +1178,8 @@ static void draw_shrink_rule (DviContext *dvi, int x, int y, Uint w, Uint h, int hs = dvi->params.hshrink; vs = dvi->params.vshrink; - fg = dvi->params.fg; - bg = dvi->params.bg; + fg = dvi->curr_fg; + bg = dvi->curr_bg; if (MDVI_ENABLED(dvi, MDVI_PARAM_ANTIALIASED)) { npixels = vs * hs + 1; diff --git a/backend/dvi/pixbuf-device.c b/backend/dvi/pixbuf-device.c deleted file mode 100644 index 1ef4365..0000000 --- a/backend/dvi/pixbuf-device.c +++ /dev/null @@ -1,220 +0,0 @@ -#include "pixbuf-device.h" -#include <gtk/gtk.h> - -typedef struct _DviPixbufDevice -{ - GdkPixbuf *pixbuf; - - gboolean valid; - - gint xmargin; - gint ymargin; - - Ulong fg; - Ulong bg; - -} DviPixbufDevice; - -static void dvi_pixbuf_draw_rule(DviContext *dvi, int x, int y, Uint w, Uint h, int fill); - -static void dvi_pixbuf_draw_glyph(DviContext *dvi, DviFontChar *ch, int x0, int y0) -{ - DviPixbufDevice *c_device = (DviPixbufDevice *) dvi->device.device_data; - - int x, y, w, h; - int isbox; - DviGlyph *glyph; - - glyph = &ch->grey; - - isbox = (glyph->data == NULL || (dvi->params.flags & MDVI_PARAM_CHARBOXES)); - - x = - glyph->x + x0 + c_device->xmargin; - y = - glyph->y + y0 + c_device->ymargin; - w = glyph->w; - h = glyph->h; - - if (x < 0 || y < 0 - || x + w > gdk_pixbuf_get_width (c_device->pixbuf) - || y + h > gdk_pixbuf_get_height (c_device->pixbuf)) - return; - - if (isbox) { - dvi_pixbuf_draw_rule(dvi, x - c_device->xmargin, y - c_device->ymargin, w, h, FALSE); - } - else { - gdk_pixbuf_copy_area (GDK_PIXBUF (glyph->data), - 0, 0, - w, h, - c_device->pixbuf, x, y); - } -} - -static void dvi_pixbuf_draw_rule(DviContext *dvi, int x, int y, Uint w, Uint h, int fill) -{ - DviPixbufDevice *c_device = (DviPixbufDevice *) dvi->device.device_data; - gint rowstride; - guchar *p; - gint i, j; - gint red, green, blue; - - red = (c_device->fg >> 16) & 0xff; - green = (c_device->fg >> 8) & 0xff; - blue = c_device->fg & 0xff; - - x += c_device->xmargin; y += c_device->ymargin; - - if (x < 0 || y < 0 - || x + w > gdk_pixbuf_get_width (c_device->pixbuf) - || y + h > gdk_pixbuf_get_height (c_device->pixbuf)) - return; - - rowstride = gdk_pixbuf_get_rowstride (c_device->pixbuf); - p = gdk_pixbuf_get_pixels (c_device->pixbuf) + rowstride * y + 3 * x; - - for (i = 0; i < h; i++) { - if (i == 0 || i == h - 1 || fill) { - for (j = 0; j < w; j++) { - p[j * 3] = red; - p[j * 3 + 1] = green; - p[j * 3 + 2] = blue; - } - } else { - p[0] = red; - p[1] = green; - p[2] = blue; - p[(w - 1) * 3] = red; - p[(w - 1) * 3 + 1] = green; - p[(w - 1) * 3 + 2] = blue; - } - p += rowstride; - } -} - -static int dvi_pixbuf_interpolate_colors(void *device_data, - Ulong *pixels, int nlevels, Ulong fg, Ulong bg, double g, int density) -{ - double frac; - GdkColor color, color_fg, color_bg; - int i, n; - - color_bg.red = (bg >> 16) & 0xff; - color_bg.green = (bg >> 8) & 0xff; - color_bg.blue = bg & 0xff; - - color_fg.red = fg >> 16 & 0xff; - color_fg.green = fg >> 8 & 0xff; - color_fg.blue = fg & 0xff; - - n = nlevels - 1; - for(i = 0; i < nlevels; i++) { - if(g > 0) - frac = pow((double)i / n, 1 / g); - else - frac = 1 - pow((double)(n - i) / n, -g); - color.red = frac * ((double)color_fg.red - color_bg.red) + color_bg.red; - color.green = frac * ((double)color_fg.green - color_bg.green) + color_bg.green; - color.blue = frac * ((double)color_fg.blue - color_bg.blue) + color_bg.blue; - - pixels[i] = (color.red << 16) + (color.green << 8) + color.blue + 0xff000000; - } - - return nlevels; -} - -static void *dvi_pixbuf_create_image(void *device_data, Uint w, Uint h, Uint bpp) -{ - - return gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, w, h); - - return NULL; -} - -static void dvi_pixbuf_free_image(void *ptr) -{ - g_object_unref (GDK_PIXBUF(ptr)); -} - -static void dvi_pixbuf_put_pixel(void *image, int x, int y, Ulong color) -{ - guchar *p; - - p = gdk_pixbuf_get_pixels (GDK_PIXBUF(image)) + y * gdk_pixbuf_get_rowstride(GDK_PIXBUF(image)) + x * 3; - - p[0] = (color >> 16) & 0xff; - p[1] = (color >> 8) & 0xff; - p[2] = color & 0xff; -} - -static void dvi_pixbuf_set_color(void *device_data, Ulong fg, Ulong bg) -{ - DviPixbufDevice *c_device = (DviPixbufDevice *) device_data; - - c_device->fg = fg; - - return; -} - -void mdvi_pixbuf_device_init (DviDevice *device) -{ - device->device_data = - g_new0 (DviPixbufDevice, 1); - - device->draw_glyph = dvi_pixbuf_draw_glyph; - device->draw_rule = dvi_pixbuf_draw_rule; - device->alloc_colors = dvi_pixbuf_interpolate_colors; - device->create_image = dvi_pixbuf_create_image; - device->free_image = dvi_pixbuf_free_image; - device->put_pixel = dvi_pixbuf_put_pixel; - device->set_color = dvi_pixbuf_set_color; - device->refresh = NULL; - - return; -} - -void mdvi_pixbuf_device_free (DviDevice *device) -{ - DviPixbufDevice *c_device = (DviPixbufDevice *) device->device_data; - - if (c_device->pixbuf) - g_object_unref (c_device->pixbuf); - - g_free (c_device); -} - -GdkPixbuf * -mdvi_pixbuf_device_get_pixbuf (DviDevice *device) -{ - DviPixbufDevice *c_device = (DviPixbufDevice *) device->device_data; - - return g_object_ref (c_device->pixbuf); -} - -void -mdvi_pixbuf_device_render (DviContext * dvi) -{ - DviPixbufDevice *c_device = (DviPixbufDevice *) dvi->device.device_data; - gint page_width; - gint page_height; - - if (c_device->pixbuf) - g_object_unref (c_device->pixbuf); - - page_width = dvi->dvi_page_w * dvi->params.conv + 2 * c_device->xmargin; - page_height = dvi->dvi_page_h * dvi->params.vconv + 2 * c_device->ymargin; - - c_device->pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, page_width, page_height); - gdk_pixbuf_fill (c_device->pixbuf, 0xffffffff); - - mdvi_dopage (dvi, dvi->currpage); -} - - -void -mdvi_pixbuf_device_set_margins (DviDevice *device, gint xmargin, gint ymargin) -{ - DviPixbufDevice *c_device = (DviPixbufDevice *) device->device_data; - - c_device->xmargin = xmargin; - c_device->ymargin = ymargin; -} diff --git a/backend/dvi/pixbuf-device.h b/backend/dvi/pixbuf-device.h deleted file mode 100644 index bacae4b..0000000 --- a/backend/dvi/pixbuf-device.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef MDVI_PIXBUF_DEVICE -#define MDVI_PIXBUF_DEVICE - -#include "mdvi.h" -#include <gtk/gtk.h> - -void -mdvi_pixbuf_device_init (DviDevice *device); - -void -mdvi_pixbuf_device_free (DviDevice *device); - -GdkPixbuf * -mdvi_pixbuf_device_get_pixbuf (DviDevice *device); - -void -mdvi_pixbuf_device_render (DviContext *dvi); - -void -mdvi_pixbuf_device_set_margins (DviDevice *device, gint xmargin, gint ymargin); - -#endif /* MDVI_PIXBUF_DEVICE */ - - |