Commit 4ce480dd authored by Carlos Garcia Campos's avatar Carlos Garcia Campos Committed by Carlos Garcia Campos

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
parent 489459b1
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.
2007-06-14 Carlos Garcia Campos <carlosgc@gnome.org> 2007-06-14 Carlos Garcia Campos <carlosgc@gnome.org>
* shell/ev-view.c: (draw_one_page): * shell/ev-view.c: (draw_one_page):
......
...@@ -11,8 +11,8 @@ noinst_LTLIBRARIES = libgtkdvi.la ...@@ -11,8 +11,8 @@ noinst_LTLIBRARIES = libgtkdvi.la
libgtkdvi_la_SOURCES = \ libgtkdvi_la_SOURCES = \
dvi-document.c \ dvi-document.c \
dvi-document.h \ dvi-document.h \
pixbuf-device.c \ cairo-device.c \
pixbuf-device.h \ cairo-device.h \
fonts.c \ fonts.c \
fonts.h fonts.h
......
/*
* 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;
}
/*
* 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 */
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
#include "mdvi.h" #include "mdvi.h"
#include "fonts.h" #include "fonts.h"
#include "pixbuf-device.h" #include "cairo-device.h"
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include <glib/gi18n.h> #include <glib/gi18n.h>
...@@ -49,7 +49,6 @@ struct _DviDocument ...@@ -49,7 +49,6 @@ struct _DviDocument
DviParams *params; DviParams *params;
/* To let document scale we should remember width and height */ /* To let document scale we should remember width and height */
double base_width; double base_width;
double base_height; double base_height;
...@@ -58,13 +57,15 @@ struct _DviDocument ...@@ -58,13 +57,15 @@ struct _DviDocument
typedef struct _DviDocumentClass DviDocumentClass; 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_document_thumbnails_iface_init (EvDocumentThumbnailsIface *iface);
static void dvi_document_get_page_size (EvDocument *document, static void dvi_document_get_page_size (EvDocument *document,
int page, int page,
double *width, double *width,
double *height); double *height);
static void dvi_document_do_color_special (DviContext *dvi,
const char *prefix,
const char *arg);
G_DEFINE_TYPE_WITH_CODE G_DEFINE_TYPE_WITH_CODE
(DviDocument, dvi_document, G_TYPE_OBJECT, (DviDocument, dvi_document, G_TYPE_OBJECT,
...@@ -75,49 +76,50 @@ G_DEFINE_TYPE_WITH_CODE ...@@ -75,49 +76,50 @@ G_DEFINE_TYPE_WITH_CODE
static gboolean static gboolean
dvi_document_load (EvDocument *document, dvi_document_load (EvDocument *document,
const char *uri, const char *uri,
GError **error) GError **error)
{ {
gchar *filename; gchar *filename;
DviDocument *dvi_document = DVI_DOCUMENT(document); DviDocument *dvi_document = DVI_DOCUMENT(document);
filename = g_filename_from_uri (uri, NULL, error); filename = g_filename_from_uri (uri, NULL, error);
if (!filename) { if (!filename) {
g_set_error (error, g_set_error (error,
EV_DOCUMENT_ERROR, EV_DOCUMENT_ERROR,
EV_DOCUMENT_ERROR_INVALID, EV_DOCUMENT_ERROR_INVALID,
_("File not available")); _("File not available"));
return FALSE; return FALSE;
} }
g_mutex_lock (dvi_context_mutex); g_mutex_lock (dvi_context_mutex);
if (dvi_document->context) if (dvi_document->context)
mdvi_destroy_context (dvi_document->context); mdvi_destroy_context (dvi_document->context);
dvi_document->context = mdvi_init_context(dvi_document->params, dvi_document->spec, filename); dvi_document->context = mdvi_init_context(dvi_document->params, dvi_document->spec, filename);
g_mutex_unlock (dvi_context_mutex); g_mutex_unlock (dvi_context_mutex);
if (!dvi_document->context) { if (!dvi_document->context) {
g_set_error (error, g_set_error (error,
EV_DOCUMENT_ERROR, EV_DOCUMENT_ERROR,
EV_DOCUMENT_ERROR_INVALID, EV_DOCUMENT_ERROR_INVALID,
_("DVI document has incorrect format")); _("DVI document has incorrect format"));
return FALSE; return FALSE;
} }
mdvi_pixbuf_device_init (&dvi_document->context->device); mdvi_cairo_device_init (&dvi_document->context->device);
dvi_document->base_width = dvi_document->context->dvi_page_w * dvi_document->context->params.conv
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; + 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; + 2 * unit2pix(dvi_document->params->vdpi, MDVI_VMARGIN) / dvi_document->params->vshrink;
g_free (dvi_document->uri); g_free (dvi_document->uri);
dvi_document->uri = g_strdup (uri); dvi_document->uri = g_strdup (uri);
return TRUE; return TRUE;
} }
...@@ -132,31 +134,29 @@ dvi_document_save (EvDocument *document, ...@@ -132,31 +134,29 @@ dvi_document_save (EvDocument *document,
} }
static int static int
dvi_document_get_n_pages (EvDocument *document) dvi_document_get_n_pages (EvDocument *document)
{ {
DviDocument *dvi_document = DVI_DOCUMENT (document); DviDocument *dvi_document = DVI_DOCUMENT (document);
return dvi_document->context->npages;
return dvi_document->context->npages;
} }
static void static void
dvi_document_get_page_size (EvDocument *document, dvi_document_get_page_size (EvDocument *document,
int page, int page,
double *width, double *width,
double *height) double *height)
{ {
DviDocument * dvi_document = DVI_DOCUMENT (document); DviDocument *dvi_document = DVI_DOCUMENT (document);
*width = dvi_document->base_width; *width = dvi_document->base_width;
*height = dvi_document->base_height;; *height = dvi_document->base_height;;
return;
} }
static cairo_surface_t * static cairo_surface_t *
dvi_document_render (EvDocument *document, dvi_document_render (EvDocument *document,
EvRenderContext *rc) EvRenderContext *rc)
{ {
GdkPixbuf *pixbuf;
cairo_surface_t *surface; cairo_surface_t *surface;
cairo_surface_t *rotated_surface; cairo_surface_t *rotated_surface;
DviDocument *dvi_document = DVI_DOCUMENT(document); DviDocument *dvi_document = DVI_DOCUMENT(document);
...@@ -170,7 +170,7 @@ dvi_document_render (EvDocument *document, ...@@ -170,7 +170,7 @@ dvi_document_render (EvDocument *document,
*/ */
g_mutex_lock (dvi_context_mutex); 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, mdvi_set_shrink (dvi_document->context,
(int)((dvi_document->params->hshrink - 1) / rc->scale) + 1, (int)((dvi_document->params->hshrink - 1) / rc->scale) + 1,
...@@ -186,24 +186,19 @@ dvi_document_render (EvDocument *document, ...@@ -186,24 +186,19 @@ dvi_document_render (EvDocument *document,
if (required_height >= proposed_height) if (required_height >= proposed_height)
ymargin = (required_height - proposed_height) / 2; ymargin = (required_height - proposed_height) / 2;
mdvi_pixbuf_device_set_margins (&dvi_document->context->device, xmargin, ymargin); mdvi_cairo_device_set_margins (&dvi_document->context->device, xmargin, ymargin);
mdvi_cairo_device_set_scale (&dvi_document->context->device, rc->scale);
mdvi_pixbuf_device_render (dvi_document->context); mdvi_cairo_device_render (dvi_document->context);
surface = mdvi_cairo_device_get_surface (&dvi_document->context->device);
pixbuf = mdvi_pixbuf_device_get_pixbuf (&dvi_document->context->device);
g_mutex_unlock (dvi_context_mutex); 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, rotated_surface = ev_document_misc_surface_rotate_and_scale (surface,
required_width, required_width,
required_height, required_height,
rc->rotation); rc->rotation);
cairo_surface_destroy (surface); cairo_surface_destroy (surface);
return rotated_surface; return rotated_surface;
} }
...@@ -214,7 +209,7 @@ dvi_document_finalize (GObject *object) ...@@ -214,7 +209,7 @@ dvi_document_finalize (GObject *object)
g_mutex_lock (dvi_context_mutex); g_mutex_lock (dvi_context_mutex);
if (dvi_document->context) { 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); mdvi_destroy_context (dvi_document->context);
} }
g_mutex_unlock (dvi_context_mutex); g_mutex_unlock (dvi_context_mutex);
...@@ -235,7 +230,7 @@ dvi_document_class_init (DviDocumentClass *klass) ...@@ -235,7 +230,7 @@ dvi_document_class_init (DviDocumentClass *klass)
gobject_class->finalize = dvi_document_finalize; 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"