/* gtkplotgnome - gnome-print driver
* Copyright 1999-2001 Adrian E. Feiguin <feiguin@ifir.edu.ar>
*/
#ifdef WITH_GNOME_PRINT
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <ctype.h>
#include <time.h>
#include <gtk/gtk.h>
#include <wctype.h>
#include <libgnomeprint/gnome-print.h>
#include <libgnomeprint/gnome-print-preview.h>
#include <libgnomeprint/gnome-font.h>
#include <gtkextra/gtkplot.h>
#include <gtkextra/gtkpsfont.h>
#include <gtkextra/gtkplotpc.h>
#include "gtkplotgnome.h"
static void gtk_plot_gnome_class_init (GtkPlotGnomeClass *klass);
static void gtk_plot_gnome_init (GtkPlotGnome *ps);
static void gtk_plot_gnome_finalize (GtkObject *object);
static void gtk_plot_gnome_set_size (GtkPlotGnome *ps,
gint units,
gdouble width,
gdouble height);
/*********************************************************************/
/* Postscript specific functions */
static gboolean init (GtkPlotPC *pc);
static void setviewport (GtkPlotPC *pc,
gdouble w, gdouble h);
static void leave (GtkPlotPC *pc);
static void gsave (GtkPlotPC *pc);
static void grestore (GtkPlotPC *pc);
static void clip (GtkPlotPC *pc,
const GdkRectangle *area);
static void clipmask (GtkPlotPC *pc,
gdouble x, gdouble y,
const GdkBitmap *mask);
static void drawlines (GtkPlotPC *pc,
GtkPlotPoint *points,
gint numpoints);
static void drawpoint (GtkPlotPC *pc,
gdouble x, gdouble y);
static void drawline (GtkPlotPC *pc,
gdouble x0, gdouble y0,
gdouble xf, gdouble yf);
static void drawpolygon (GtkPlotPC *pc,
gboolean filled,
GtkPlotPoint *points,
gint numpoints);
static void drawrectangle (GtkPlotPC *pc,
gboolean filled,
gdouble x, gdouble y,
gdouble width, gdouble height);
static void drawcircle (GtkPlotPC *pc,
gboolean filled,
gdouble x, gdouble y,
gdouble size);
static void drawellipse (GtkPlotPC *pc,
gboolean filled,
gdouble x, gdouble y,
gdouble width, gdouble height);
static void setcolor (GtkPlotPC *pc,
const GdkColor *color);
static void setlineattr (GtkPlotPC *pc,
gfloat line_width,
GdkLineStyle line_style,
GdkCapStyle cap_style,
GdkJoinStyle join_style);
static void drawstring (GtkPlotPC *pc,
gint x, gint y,
gint angle,
const GdkColor *fg,
const GdkColor *bg,
gboolean transparent,
gint border,
gint border_space,
gint border_width,
gint shadow_width,
const gchar *font,
gint height,
GtkJustification just,
const gchar *text);
static void setfont (GtkPlotPC *pc,
GtkPSFont *psfont,
gint height);
static void setdash (GtkPlotPC *pc,
gdouble offset,
gdouble *values,
gint num_values);
static void drawpixmap (GtkPlotPC *pc,
GdkPixmap *pixmap,
GdkBitmap *mask,
gint xsrc, gint ysrc,
gint xdest, gint ydest,
gint width, gint height,
gdouble sx, gdouble sy);
/*********************************************************************/
static GtkPlotPCClass *parent_class = NULL;
GtkType
gtk_plot_gnome_get_type (void)
{
static GtkType pc_type = 0;
if (!pc_type)
{
GtkTypeInfo pc_info =
{
"GtkPlotGnome",
sizeof (GtkPlotGnome),
sizeof (GtkPlotGnomeClass),
(GtkClassInitFunc) gtk_plot_gnome_class_init,
(GtkObjectInitFunc) gtk_plot_gnome_init,
/* reserved 1*/ NULL,
/* reserved 2 */ NULL,
(GtkClassInitFunc) NULL,
};
pc_type = gtk_type_unique (GTK_TYPE_PLOT_PC, &pc_info);
}
return pc_type;
}
static void
gtk_plot_gnome_init (GtkPlotGnome *ps)
{
ps->scalex = 1.0;
ps->scaley = 1.0;
ps->gsaved = FALSE;
}
static void
gtk_plot_gnome_class_init (GtkPlotGnomeClass *klass)
{
GtkObjectClass *object_class;
GtkPlotPCClass *pc_class;
parent_class = gtk_type_class (gtk_plot_pc_get_type ());
object_class = (GtkObjectClass *) klass;
pc_class = (GtkPlotPCClass *) klass;
pc_class->init = init;
pc_class->leave = leave;
pc_class->set_viewport = setviewport;
pc_class->gsave = gsave;
pc_class->grestore = grestore;
pc_class->clip = clip;
pc_class->clip_mask = clipmask;
pc_class->set_color = setcolor;
pc_class->set_dash = setdash;
pc_class->set_lineattr = setlineattr;
pc_class->draw_point = drawpoint;
pc_class->draw_line = drawline;
pc_class->draw_lines = drawlines;
pc_class->draw_rectangle = drawrectangle;
pc_class->draw_polygon = drawpolygon;
pc_class->draw_circle = drawcircle;
pc_class->draw_ellipse = drawellipse;
pc_class->set_font = setfont;
pc_class->draw_string = drawstring;
pc_class->draw_pixmap = drawpixmap;
object_class->finalize = gtk_plot_gnome_finalize;
}
static void
gtk_plot_gnome_finalize(GtkObject *object)
{
GtkPlotGnome *ps;
ps = GTK_PLOT_GNOME(object);
gnome_print_context_close(ps->ctx);
}
GtkObject *
gtk_plot_gnome_new (GnomePrinter *printer,
gint orientation,
gint page_size)
{
GtkObject *object;
GtkPlotGnome *ps;
object = gtk_type_new(gtk_plot_gnome_get_type());
ps = GTK_PLOT_GNOME(object);
gtk_plot_gnome_construct(ps, printer, orientation, page_size);
return (object);
}
void
gtk_plot_gnome_construct (GtkPlotGnome *ps,
GnomePrinter *printer,
gint orientation,
gint page_size)
{
gint width, height;
GnomePaper *paper;
gchar *paper_name[] = { "US-Letter", "Legal", "a4", "Executive" };
ps->orientation = orientation;
ps->page_size = page_size;
switch (page_size){
case GTK_PLOT_LEGAL:
width = GTK_PLOT_LEGAL_W;
height = GTK_PLOT_LEGAL_H;
break;
case GTK_PLOT_A4:
width = GTK_PLOT_A4_W;
height = GTK_PLOT_A4_H;
break;
case GTK_PLOT_EXECUTIVE:
width = GTK_PLOT_EXECUTIVE_W;
height = GTK_PLOT_EXECUTIVE_H;
break;
case GTK_PLOT_LETTER:
default:
width = GTK_PLOT_LETTER_W;
height = GTK_PLOT_LETTER_H;
}
gtk_plot_gnome_set_size(ps, GTK_PLOT_PSPOINTS, width, height);
ps->ctx = gnome_print_context_new_with_paper_size(printer, paper_name[page_size]);
}
/*
GtkObject *
gtk_plot_gnome_new_with_size (GnomePrinter *printer,
gint orientation,
gint units,
gdouble width, gdouble height)
{
GtkObject *object;
GtkPlotGnome *ps;
object = gtk_type_new(gtk_plot_gnome_get_type());
ps = GTK_PLOT_GNOME(object);
gtk_plot_gnome_construct_with_size (ps, printer, orientation, units, width, height);
return object;
}
void
gtk_plot_gnome_construct_with_size (GtkPlotGnome *ps,
GnomePrinter *printer,
gint orientation,
gint units,
gdouble width, gdouble height)
{
gtk_plot_gnome_construct(ps, printer, orientation, GTK_PLOT_CUSTOM);
gtk_plot_gnome_set_size(ps, units, width, height);
}
*/
GtkObject *
gtk_plot_gnome_preview_new (GnomeCanvas *canvas,
gint orientation,
gint page_size)
{
GtkObject *object;
GtkPlotGnome *ps;
object = gtk_type_new(gtk_plot_gnome_get_type());
ps = GTK_PLOT_GNOME(object);
gtk_plot_gnome_preview_construct(ps, canvas, orientation, page_size);
return (object);
}
void
gtk_plot_gnome_preview_construct (GtkPlotGnome *ps,
GnomeCanvas *canvas,
gint orientation,
gint page_size)
{
gint width, height;
GnomePaper *paper;
gchar *paper_name[] = { "US-Letter", "Legal", "a4", "Executive" };
ps->orientation = orientation;
ps->page_size = page_size;
switch (page_size){
case GTK_PLOT_LEGAL:
width = GTK_PLOT_LEGAL_W;
height = GTK_PLOT_LEGAL_H;
break;
case GTK_PLOT_A4:
width = GTK_PLOT_A4_W;
height = GTK_PLOT_A4_H;
break;
case GTK_PLOT_EXECUTIVE:
width = GTK_PLOT_EXECUTIVE_W;
height = GTK_PLOT_EXECUTIVE_H;
break;
case GTK_PLOT_LETTER:
default:
width = GTK_PLOT_LETTER_W;
height = GTK_PLOT_LETTER_H;
}
gtk_plot_gnome_set_size(ps, GTK_PLOT_PSPOINTS, width, height);
ps->ctx = gnome_print_preview_new(canvas, paper_name[page_size]);
}
static void
gtk_plot_gnome_set_size (GtkPlotGnome *ps,
gint units,
gdouble width,
gdouble height)
{
ps->units = units;
ps->width = width;
ps->height = height;
switch(units){
case GTK_PLOT_MM:
ps->page_width = (gdouble)width * 2.835;
ps->page_height = (gdouble)height * 2.835;
break;
case GTK_PLOT_CM:
ps->page_width = width * 28.35;
ps->page_height = height * 28.35;
break;
case GTK_PLOT_INCHES:
ps->page_width = width * 72;
ps->page_height = height * 72;
break;
case GTK_PLOT_PSPOINTS:
default:
ps->page_width = width;
ps->page_height = height;
}
gtk_plot_pc_set_viewport(GTK_PLOT_PC(ps), ps->page_width, ps->page_height);
}
void
gtk_plot_gnome_set_scale (GtkPlotGnome *ps,
gdouble sx,
gdouble sy)
{
ps->scalex = sx;
ps->scaley = sy;
}
static void
setviewport (GtkPlotPC *pc,
gdouble w, gdouble h)
{
}
static void
setlineattr (GtkPlotPC *pc,
gfloat line_width,
GdkLineStyle line_style,
GdkCapStyle cap_style,
GdkJoinStyle join_style)
{
gint art_cap, art_join;
GnomePrintContext *ctx = GTK_PLOT_GNOME(pc)->ctx;
switch (join_style) {
case GDK_JOIN_MITER:
art_join = ART_PATH_STROKE_JOIN_MITER;
break;
case GDK_JOIN_ROUND:
art_join = ART_PATH_STROKE_JOIN_ROUND;
break;
case GDK_JOIN_BEVEL:
art_join = ART_PATH_STROKE_JOIN_BEVEL;
break;
default:
art_join = ART_PATH_STROKE_JOIN_MITER;
break;
}
switch (cap_style) {
case GDK_CAP_BUTT:
case GDK_CAP_NOT_LAST:
art_cap = ART_PATH_STROKE_CAP_BUTT;
break;
case GDK_CAP_ROUND:
art_cap = ART_PATH_STROKE_CAP_ROUND;
break;
case GDK_CAP_PROJECTING:
art_cap = ART_PATH_STROKE_CAP_SQUARE;
break;
default:
art_cap = ART_PATH_STROKE_CAP_BUTT; /* shut up the compiler */
break;
}
gnome_print_setlinewidth(ctx, line_width);
gnome_print_setlinecap(ctx, art_cap);
gnome_print_setlinejoin(ctx, art_join);
}
static void
setdash(GtkPlotPC *pc,
gdouble offset,
gdouble *values,
gint num_values)
{
GnomePrintContext *ctx = GTK_PLOT_GNOME(pc)->ctx;
gnome_print_setdash(ctx, num_values, values, 0);
}
static void
leave(GtkPlotPC *pc)
{
GnomePrintContext *ctx = GTK_PLOT_GNOME(pc)->ctx;
gnome_print_showpage(ctx);
}
static gboolean
init(GtkPlotPC *pc)
{
time_t now;
GnomePrintContext *ctx;
GtkPlotGnome *ps;
now = time(NULL);
ps = GTK_PLOT_GNOME(pc);
ctx = ps->ctx;
gnome_print_beginpage(ctx, "GtkPlotGnome output");
ps->ctx = ctx;
if(ps->orientation == GTK_PLOT_PORTRAIT){
gnome_print_translate(ctx, 0, ps->page_height);
gnome_print_scale(ctx, ps->scalex, -ps->scaley);
}
if(ps->orientation == GTK_PLOT_LANDSCAPE){
gnome_print_scale(ctx, ps->scalex, -ps->scaley);
gnome_print_rotate(ctx, -90);
}
return TRUE;
}
static void
setcolor(GtkPlotPC *pc, const GdkColor *color)
{
GnomePrintContext *ctx = GTK_PLOT_GNOME(pc)->ctx;
gnome_print_setrgbcolor(ctx,
(gdouble) color->red / 65535.0,
(gdouble) color->green / 65535.0,
(gdouble) color->blue / 65535.0);
}
static void
drawpoint(GtkPlotPC *pc, gdouble x, gdouble y)
{
GnomePrintContext *ctx = GTK_PLOT_GNOME(pc)->ctx;
gnome_print_newpath(ctx);
gnome_print_moveto(ctx, x, y);
gnome_print_lineto(ctx, x, y);
gnome_print_stroke(ctx);
}
static void
drawlines(GtkPlotPC *pc, GtkPlotPoint *points, gint numpoints)
{
gint i;
GnomePrintContext *ctx = GTK_PLOT_GNOME(pc)->ctx;
gnome_print_newpath(ctx);
gnome_print_moveto(ctx, points[0].x, points[0].y);
for(i = 1; i < numpoints; i++)
gnome_print_lineto(ctx, points[i].x, points[i].y);
gnome_print_stroke(ctx);
/*
for(i = 0; i < numpoints - 1; i++){
gnome_print_newpath(ctx);
gnome_print_moveto(ctx, points[i].x, points[i].y);
gnome_print_lineto(ctx, points[i+1].x, points[i+1].y);
gnome_print_stroke(ctx);
}
*/
}
static void
drawpolygon(GtkPlotPC *pc, gboolean filled, GtkPlotPoint *points, gint numpoints)
{
gint i;
GnomePrintContext *ctx = GTK_PLOT_GNOME(pc)->ctx;
gnome_print_newpath(ctx);
gnome_print_moveto(ctx, points[0].x, points[0].y);
for(i = 1; i < numpoints; i++)
gnome_print_lineto(ctx, points[i].x, points[i].y);
if(filled)
gnome_print_fill(ctx);
else
gnome_print_closepath(ctx);
gnome_print_stroke(ctx);
}
static void
drawline(GtkPlotPC *pc, gdouble x0, gdouble y0, gdouble xf, gdouble yf)
{
GnomePrintContext *ctx = GTK_PLOT_GNOME(pc)->ctx;
gnome_print_newpath(ctx);
gnome_print_moveto(ctx, x0, y0);
gnome_print_lineto(ctx, xf, yf);
gnome_print_stroke(ctx);
}
static void
drawrectangle(GtkPlotPC *pc, gboolean filled,
gdouble x, gdouble y, gdouble width, gdouble height)
{
GtkPlotPoint point[4];
point[0].x = x;
point[0].y = y;
point[1].x = x + width;
point[1].y = y;
point[2].x = x + width;
point[2].y = y + height;
point[3].x = x;
point[3].y = y + height;
drawpolygon(pc, filled, point, 4);
}
static void
drawcircle(GtkPlotPC *pc, gboolean filled, gdouble x, gdouble y, gdouble size)
{
GtkPlotPoint *points;
gint i, npoints = 126;
points = g_new0(GtkPlotPoint, npoints);
for (i = 0; i < npoints; i++) {
double th;
th = (2 * 3.141592654 * i) / npoints;
points[i].x = x + size / 2. * cos (th);
points[i].y = y + size / 2.* sin (th);
}
drawpolygon(pc, filled, points, npoints);
g_free(points);
}
static void
drawellipse(GtkPlotPC *pc,
gboolean filled,
gdouble x, gdouble y,
gdouble width, gdouble height)
{
GtkPlotPoint *points;
gint i, npoints = 126;
points = g_new0(GtkPlotPoint, npoints);
for (i = 0; i < npoints; i++) {
double th;
th = (2 * 3.141592654 * i) / npoints;
points[i].x = x + width / 2. + width / 2. * cos (th);
points[i].y = y + height / 2. + height / 2. * sin (th);
}
drawpolygon(pc, filled, points, npoints);
g_free(points);
}
static void
drawstring (GtkPlotPC *pc,
gint x, gint y,
gint angle,
const GdkColor *fg,
const GdkColor *bg,
gboolean transparent,
gint border,
gint border_space,
gint border_width,
gint shadow_width,
const gchar *font,
gint font_height,
GtkJustification justification,
const gchar *text)
{
GnomePrintContext *ctx;
gchar *currfont;
const gchar *c;
GtkPSFont *psfont, *base_psfont, *latin_psfont = NULL;
gint curcnt = 0, offset = 0;
gint numf;
gdouble scale;
gboolean italic, bold;
gboolean special = FALSE;
GList *family;
gint twidth, theight, tdescent, tascent;
gint tx, ty, width, height;
gint i;
gchar *curstr, *lastchar = NULL, bkspchar[2], *aux, *xaux;
gchar num[4];
GnomeFont *gfont = NULL;
if (text == NULL || strlen(text) == 0) return;
ctx = GTK_PLOT_GNOME(pc)->ctx;
gtk_psfont_get_families(&family, &numf);
base_psfont = psfont = gtk_psfont_get_font(font);
italic = psfont->italic;
bold = psfont->bold;
currfont = psfont->family;
gfont = gnome_font_new_closest(psfont->family,
bold ? GNOME_FONT_BOLD : 0,
italic, font_height);
gnome_print_setfont(ctx, gfont);
gtk_plot_text_get_area(text, angle, justification, font, font_height,
&tx, &ty, &width, &height);
tx += x;
ty += y;
if(!transparent){
setcolor(pc, bg);
gtk_plot_pc_draw_rectangle(pc,
TRUE,
tx - border_space, ty - border_space,
width + 2*border_space, height + 2*border_space);
}
/* border */
setcolor(pc, fg);
setdash(pc, 0, NULL, 0);
setlineattr(pc, border_width, 0, 0, 0);
switch(border){
case GTK_PLOT_BORDER_SHADOW:
drawrectangle(pc,
TRUE,
tx - border_space + shadow_width,
ty + height + border_space,
width + 2 * border_space, shadow_width);
drawrectangle(pc,
TRUE,
tx + width + border_space,
ty - border_space + shadow_width,
shadow_width, height + 2 * border_space);
case GTK_PLOT_BORDER_LINE:
drawrectangle(pc,
FALSE,
tx - border_space, ty - border_space,
width + 2*border_space, height + 2*border_space);
case GTK_PLOT_BORDER_NONE:
default:
break;
}
gtk_plot_text_get_size(text, angle, font, font_height,
&twidth, &theight, &tascent, &tdescent);
if(angle == 90 || angle == 270) angle = 360 - angle;
gnome_print_gsave(ctx);
gnome_print_translate(ctx, x, y);
gnome_print_rotate(ctx, angle);
gnome_print_moveto(ctx, 0, 0);
gnome_print_scale(ctx, 1, -1);
if (psfont->i18n_latinfamily)
special = TRUE;
c = text;
while(c && *c != '\0' && *c != '\n') {
if(*c == '\\'){
c++;
switch(*c){
case '0': case '1': case '2': case '3':
case '4': case '5': case '6': case '7': case '9':
case '8': case'g': case 'B': case 'b': case 'x': case 'N':
case 's': case 'S': case 'i': case '-': case '+': case '^':
special = TRUE;
break;
default:
break;
}
} else {
c++;
}
}
x = y = 0;
if(special){
switch (justification) {
case GTK_JUSTIFY_LEFT:
break;
case GTK_JUSTIFY_RIGHT:
if(angle == 0 || angle == 180){
gnome_print_moveto(ctx, -twidth, 0);
x -= twidth;
} else {
gnome_print_moveto(ctx, -theight, 0);
x -= theight;
}
break;
case GTK_JUSTIFY_CENTER:
default:
if(angle == 0 || angle == 180){
gnome_print_moveto(ctx, -twidth / 2., 0);
x -= twidth / 2.;
} else {
gnome_print_moveto(ctx, -theight / 2., 0);
x -= theight / 2.;
}
break;
}
} else {
switch (justification) {
case GTK_JUSTIFY_LEFT:
break;
case GTK_JUSTIFY_RIGHT:
twidth = gnome_font_get_width_string(gfont, text);
gnome_print_moveto(ctx, -twidth, 0);
x -= twidth;
break;
case GTK_JUSTIFY_CENTER:
default:
twidth = gnome_font_get_width_string(gfont, text);
gnome_print_moveto(ctx, -twidth/2., 0);
x -= twidth/2.;
break;
}
gnome_print_show(ctx, text);
gnome_print_grestore(ctx);
return;
}
i = strlen(text) + 2;
curstr = g_malloc0(sizeof(GdkWChar) * i);
aux = (gchar *)text;
scale = font_height;
curcnt = 0;
while(aux && *aux != '\0' && *aux != '\n') {
if(*aux == '\\'){
aux++;
switch(*aux){
case '0': case '1': case '2': case '3':
case '4': case '5': case '6': case '7': case '9':
curstr[curcnt] = 0;
curcnt = 0;
gnome_print_show(ctx, curstr);
x += gnome_font_get_width_string(gfont, curstr);
gnome_print_moveto(ctx, x, y);
gfont = gnome_font_new_closest((gchar *)g_list_nth_data(family, *aux-'0'),
bold ? GNOME_FONT_BOLD : 0,
italic, scale);
gnome_print_setfont(ctx, gfont);
aux++;
break;
case '8':case 'g':
curstr[curcnt] = 0;
gnome_print_show(ctx, curstr);
x += gnome_font_get_width_string(gfont, curstr);
gnome_print_moveto(ctx, x, y);
curcnt = 0;
gfont = gnome_font_new("Symbol", scale);
gnome_print_setfont(ctx, gfont);
aux++;
break;
case 'B':
curstr[curcnt] = 0;
gnome_print_show(ctx, curstr);
x += gnome_font_get_width_string(gfont, curstr);
gnome_print_moveto(ctx, x, y);
curcnt = 0;
bold = TRUE;
gfont = gnome_font_new_closest(psfont->family,
GNOME_FONT_BOLD,
italic, scale);
gnome_print_setfont(ctx, gfont);
aux++;
break;
case 'x':
/*
xaux = aux + 1;
for (i=0; i<3; i++){
if (xaux[i] >= '0' && xaux[i] <= '9')
num[i] = xaux[i];
else
break;
}
if (i < 3){
aux++;
break;
}
num[3] = '\0';
i = atoi(num);
g_snprintf(num, 4, "%o", i % (64 * 8));
curstr[curcnt++] = '\\';
i = 0;
while (num[i]) {
curstr[curcnt++] = num[i++];
}
aux += 4;
*/
break;
case 'i':
curstr[curcnt] = 0;
gnome_print_show(ctx, curstr);
x += gnome_font_get_width_string(gfont, curstr);
gnome_print_moveto(ctx, x, y);
curcnt = 0;
italic = TRUE;
gfont = gnome_font_new_closest(psfont->family,
bold ? GNOME_FONT_BOLD : 0,
TRUE, scale);
gnome_print_setfont(ctx, gfont);
aux++;
break;
case 's':case '_':
curstr[curcnt] = 0;
gnome_print_show(ctx, curstr);
x += gnome_font_get_width_string(gfont, curstr);
curcnt = 0;
scale = 0.6 * font_height;
offset -= (gint)scale / 2;
gnome_print_moveto(ctx, x, y -(gint)scale / 2);
gfont = gnome_font_new_closest(psfont->family,
bold ? GNOME_FONT_BOLD : 0,
italic, scale);
gnome_print_setfont(ctx, gfont);
aux++;
break;
case 'S':case '^':
curstr[curcnt] = 0;
gnome_print_show(ctx, curstr);
x += gnome_font_get_width_string(gfont, curstr);
curcnt = 0;
scale = 0.6 * font_height;
offset += 0.5*font_height;
gnome_print_moveto(ctx, x, y + 0.5 * font_height);
gfont = gnome_font_new_closest(psfont->family,
bold ? GNOME_FONT_BOLD : 0,
italic, scale);
gnome_print_setfont(ctx, gfont);
aux++;
break;
case 'N':
curstr[curcnt] = 0;
gnome_print_show(ctx, curstr);
x += gnome_font_get_width_string(gfont, curstr);
curcnt = 0;
psfont = base_psfont;
italic = psfont->italic;
bold = psfont->bold;
scale = font_height;
gfont = gnome_font_new_closest(base_psfont->family,
bold ? GNOME_FONT_BOLD : 0,
italic, scale);
gnome_print_setfont(ctx, gfont);
gnome_print_moveto(ctx, x, y);
offset = 0;
aux++;
break;
case 'b':
curstr[curcnt] = '\0';
gnome_print_show(ctx, curstr);
x += gnome_font_get_width_string(gfont, curstr);
curcnt = 0;
bkspchar[1] = '\0';
if (lastchar) {
bkspchar[0] = *lastchar;
lastchar--;
} else {
bkspchar[0] = 'X';
lastchar = NULL;
}
x -= gnome_font_get_width_string(gfont, bkspchar);
gnome_print_moveto(ctx, x, y);
aux++;
break;
case '-':
curstr[curcnt] = 0;
gnome_print_show(ctx, curstr);
x += gnome_font_get_width_string(gfont, curstr);
gnome_print_moveto(ctx, x, y);
curcnt = 0;
scale -= 3;
if (scale < 6) {
scale = 6;
}
aux++;
break;
case '+':
curstr[curcnt] = 0;
gnome_print_show(ctx, curstr);
x += gnome_font_get_width_string(gfont, curstr);
gnome_print_moveto(ctx, x, y);
curcnt = 0;
scale += 3;
aux++;
break;
default:
if(aux && *aux != '\0' && *aux != '\n'){
curstr[curcnt++] = *aux;
aux++;
}
break;
}
} else {
if(aux && *aux != '\0' && *aux != '\n'){
curstr[curcnt++] = *aux;
lastchar = aux;
aux++;
}
}
}
curstr[curcnt] = 0;
gnome_print_show(ctx, curstr);
gnome_print_grestore(ctx);
g_free(curstr);
}
static void
setfont(GtkPlotPC *pc, GtkPSFont *psfont, gint height)
{
GnomePrintContext *ctx = GTK_PLOT_GNOME(pc)->ctx;
GnomeFont *font;
font = gnome_font_new(psfont->psname, height);
if(!font)
font = gnome_font_new("Courier", height);
gnome_print_setfont(ctx, font);
gtk_object_unref(GTK_OBJECT(font));
}
static void
gsave(GtkPlotPC *pc)
{
GtkPlotGnome *ps;
GnomePrintContext *ctx;
ps = GTK_PLOT_GNOME(pc);
ctx = ps->ctx;
gnome_print_gsave(ctx);
ps->gsaved = TRUE;
}
static void
grestore(GtkPlotPC *pc)
{
GtkPlotGnome *ps;
GnomePrintContext *ctx;
ps = GTK_PLOT_GNOME(pc);
ctx = ps->ctx;
if(!ps->gsaved) return;
gnome_print_grestore(ctx);
ps->gsaved = FALSE;
}
static void
clipmask(GtkPlotPC *pc, gdouble x, gdouble y, const GdkBitmap *mask)
{
GnomePrintContext *ctx = GTK_PLOT_GNOME(pc)->ctx;
gint width, height;
gint px, py;
gint npoints = 0;
gint i;
GtkPlotVector *points;
GdkImage *image;
if(!mask){
grestore(pc);
return;
}
gdk_window_get_size((GdkWindow *)mask, &width, &height);
image = gdk_image_get((GdkWindow *)mask, 0, 0, width, height);
points = (GtkPlotVector *)g_malloc(width*height*sizeof(GtkPlotVector));
for(px = 0; px < width; px++){
for(py = 0; py < height; py++){
if(gdk_image_get_pixel(image, px, py)){
points[npoints].x = px;
points[npoints].y = py;
npoints++;
break;
}
}
}
for(py = points[npoints-1].y; py < height; py++){
for(px = width - 1; px >= 0; px--){
if(gdk_image_get_pixel(image, px, py)){
points[npoints].x = px;
points[npoints].y = py;
npoints++;
break;
}
}
}
for(px = points[npoints-1].x; px >= 0; px--){
for(py = height - 1; py >= 0; py--){
if(gdk_image_get_pixel(image, px, py)){
points[npoints].x = px;
points[npoints].y = py;
npoints++;
break;
}
}
}
for(py = points[npoints-1].y; py >= 0; py--){
for(px = 0; px < width; px++){
if(gdk_image_get_pixel(image, px, py)){
points[npoints].x = px;
points[npoints].y = py;
npoints++;
break;
}
}
}
gnome_print_gsave(ctx);
gnome_print_newpath(ctx);
gnome_print_moveto(ctx, points[0].x, points[0].y);
for(i = 1; i < npoints; i++)
gnome_print_lineto(ctx, points[i].x, points[i].y);
gnome_print_closepath(ctx);
gnome_print_clip(ctx);
g_free(points);
gdk_image_destroy(image);
}
static void
clip(GtkPlotPC *pc, const GdkRectangle *clip)
{
GnomePrintContext *ctx = GTK_PLOT_GNOME(pc)->ctx;
if(!clip){
gnome_print_grestore(ctx);
return;
}
gnome_print_gsave(ctx);
gnome_print_newpath(ctx);
gnome_print_moveto(ctx, clip->x, clip->y);
gnome_print_lineto(ctx, clip->x + clip->width, clip->y);
gnome_print_lineto(ctx, clip->x + clip->width, clip->y + clip->height);
gnome_print_lineto(ctx, clip->x, clip->y + clip->height);
gnome_print_closepath(ctx);
gnome_print_clip(ctx);
}
static void
drawpixmap (GtkPlotPC *pc,
GdkPixmap *pixmap,
GdkBitmap *mask,
gint xsrc, gint ysrc,
gint xdest, gint ydest,
gint width, gint height,
gdouble scale_x, gdouble scale_y)
{
GnomePrintContext *ctx = GTK_PLOT_GNOME(pc)->ctx;
GdkColormap *colormap;
GdkColorContext *cc;
GdkVisual *visual;
guchar *rgb_image, *line;
GdkImage *image;
GdkImage *mask_image = NULL;
gint x, y;
if(!pixmap) return;
colormap = gdk_colormap_get_system ();
visual = gdk_visual_get_system ();
cc = gdk_color_context_new(visual, colormap);
image = gdk_image_get(pixmap,
xsrc, ysrc,
width, height);
if(mask)
mask_image = gdk_image_get(mask,
xsrc, ysrc,
width, height);
gnome_print_gsave(ctx);
gnome_print_translate(ctx, xdest, ydest);
gnome_print_scale(ctx, width * scale_x, height * scale_y);
rgb_image = g_new0(guchar, width * height * 3);
line = rgb_image;
for(y = height - 1; y >= 0; y--){
for(x = 0; x < width; x++){
GdkColor color;
color.pixel = gdk_image_get_pixel(image, x, y);
gdk_color_context_query_color(cc, &color);
line[x * 3] = color.red/256;
line[x * 3 + 1] = color.green/256;
line[x * 3 + 2] = color.blue/256;
if(mask_image){
gulong pixel;
pixel = gdk_image_get_pixel(mask_image, x, y);
if(pixel != 0){
line[x * 3] = 255;
line[x * 3 + 1] = 255;
line[x * 3 + 2] = 255;
}
}
}
line += width * 3;
}
gnome_print_rgbimage(ctx, rgb_image, width, height, width * 3);
gnome_print_grestore(ctx);
gdk_image_destroy(image);
if(mask_image) gdk_image_destroy(mask_image);
g_free(rgb_image);
gdk_color_context_free(cc);
}
#endif /* WITH_GNOME_PRINT */
syntax highlighted by Code2HTML, v. 0.9.1