Logo Search packages:      
Sourcecode: scigraphica version File versions  Download package

gtkplotgnome.c

/* 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 */

Generated by  Doxygen 1.6.0   Back to index