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

gtkplotart.c

/* gtkplotart - wrapper for libart
 * Copyright 1999-2001  Adrian E. Feiguin <feiguin@ifir.edu.ar>
 */

#ifdef WITH_LIBART

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <ctype.h>
#include <time.h>
#include <gtk/gtk.h>

#include <gtkextra/gtkplotpc.h>
#include <gtkextra/gtkplot.h>
#include <gtkextra/gtkpsfont.h>
#include "gtkplotart.h"

static void gtk_plot_art_init                       (GtkPlotArt *pc);
static void gtk_plot_art_class_init                 (GtkPlotArtClass *klass);
static void gtk_plot_art_finalize                   (GtkObject *object);
static void gtk_plot_art_set_drawable               (GtkPlotArt *pc,
                                                     GdkDrawable *drawable);
static gboolean gtk_plot_art_real_init              (GtkPlotPC *pc);
static void gtk_plot_art_set_viewport               (GtkPlotPC *pc,
                                         gdouble w, gdouble h);
static void gtk_plot_art_leave                      (GtkPlotPC *pc);
static void gtk_plot_art_gsave                      (GtkPlotPC *pc);
static void gtk_plot_art_grestore                   (GtkPlotPC *pc);
static void gtk_plot_art_clip                       (GtkPlotPC *pc,
                                                     const GdkRectangle *area);
static void gtk_plot_art_clip_mask                  (GtkPlotPC *pc,
                                         gdouble x,
                                         gdouble y,
                                                     const GdkBitmap *mask);
static void gtk_plot_art_set_color                   (GtkPlotPC *pc,
                                                     const GdkColor *color);
static void gtk_plot_art_set_lineattr           (GtkPlotPC *pc,
                                                 gfloat line_width,
                                                 GdkLineStyle line_style,
                                                 GdkCapStyle cap_style,
                                                 GdkJoinStyle join_style);
static void gtk_plot_art_set_dash                    (GtkPlotPC *pc,
                                                     gdouble offset_,
                                                     gdouble *values,
                                                     gint num_values);
static void gtk_plot_art_draw_point                  (GtkPlotPC *pc,
                                                     gdouble x, gdouble y);
static void gtk_plot_art_draw_line                   (GtkPlotPC *pc,
                                                     gdouble x1, gdouble y1,
                                                     gdouble x2, gdouble y2);
static void gtk_plot_art_draw_lines                  (GtkPlotPC *pc,
                                                     GtkPlotPoint *points,
                                                     gint numpoints);
static void gtk_plot_art_draw_rectangle              (GtkPlotPC *pc,
                                                     gint filled,
                                                     gdouble x, gdouble y,
                                                     gdouble width, 
                                                     gdouble height);
static void gtk_plot_art_draw_polygon                (GtkPlotPC *pc,
                                                     gint filled,
                                                     GtkPlotPoint *points,
                                                     gint numpoints);
static void gtk_plot_art_draw_circle                 (GtkPlotPC *pc,
                                                     gint filled,
                                                     gdouble x, gdouble y,
                                                     gdouble size);
static void gtk_plot_art_draw_ellipse                (GtkPlotPC *pc,
                                                     gint filled,
                                                     gdouble x, gdouble y,
                                                     gdouble width, 
                                                     gdouble height);
static void gtk_plot_art_set_font                    (GtkPlotPC *pc,
                                         GtkPSFont *psfont,
                                                     gint height);
static void gtk_plot_art_draw_string                (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 gtk_plot_art_draw_pixmap                (GtkPlotPC *pc,
                                                     GdkPixmap *pixmap,
                                                     GdkBitmap *mask,
                                                     gint xsrc, gint ysrc,
                                                     gint xdest, gint ydest,
                                                     gint width, gint height,
                                                     gdouble scale_x, 
                                                     gdouble scale_y);
static ArtSVP * gtk_plot_art_stroke           (GtkPlotArt *art,
                                         ArtVpath *path);

static GtkPlotGdkClass *parent_class = NULL;

GtkType
gtk_plot_art_get_type (void)
{
  static GtkType pc_type = 0;

  if (!pc_type)
    {
      GtkTypeInfo pc_info =
      {
        "GtkPlotArt",
        sizeof (GtkPlotArt),
        sizeof (GtkPlotArtClass),
        (GtkClassInitFunc) gtk_plot_art_class_init,
        (GtkObjectInitFunc) gtk_plot_art_init,
        /* reserved 1*/ NULL,
        /* reserved 2 */ NULL,
        (GtkClassInitFunc) NULL,
      };

      pc_type = gtk_type_unique (GTK_TYPE_PLOT_GDK, &pc_info);
    }
  return pc_type;
}

static void
gtk_plot_art_init (GtkPlotArt *pc)
{
  GdkWindowAttr attributes;
  gint attributes_mask;

  attributes.window_type = GDK_WINDOW_CHILD;
  attributes.title = NULL;
  attributes.wclass = GDK_INPUT_OUTPUT;
  attributes.visual = gdk_visual_get_system ();
  attributes.colormap = gdk_colormap_get_system ();
  attributes.event_mask = 0;
  attributes_mask = GDK_WA_VISUAL | GDK_WA_COLORMAP;

  GTK_PLOT_GDK(pc)->drawable = NULL;

  GTK_PLOT_GDK(pc)->window = gdk_window_new (NULL, &attributes, attributes_mask);
  GTK_PLOT_GDK(pc)->gc = gdk_gc_new(GTK_PLOT_GDK(pc)->window);

  pc->line_width = 0.25;
  pc->line_style = GDK_LINE_SOLID;
  pc->cap_style = 0;
  pc->join_style = 0;
  pc->dash.offset = 0;
  pc->dash.n_dash = 0;
  pc->dash.dash = NULL;
}


static void
gtk_plot_art_class_init (GtkPlotArtClass *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;

  object_class->finalize = gtk_plot_art_finalize;

  pc_class->init = gtk_plot_art_real_init;
  pc_class->leave = gtk_plot_art_leave;
  pc_class->set_viewport = gtk_plot_art_set_viewport;
  pc_class->gsave = gtk_plot_art_gsave;
  pc_class->grestore = gtk_plot_art_grestore;
  pc_class->clip = gtk_plot_art_clip;
  pc_class->clip_mask = gtk_plot_art_clip_mask;
  pc_class->set_color = gtk_plot_art_set_color;
  pc_class->set_dash = gtk_plot_art_set_dash;
  pc_class->set_lineattr = gtk_plot_art_set_lineattr;
  pc_class->draw_point = gtk_plot_art_draw_point;
  pc_class->draw_line = gtk_plot_art_draw_line;
  pc_class->draw_lines = gtk_plot_art_draw_lines;
  pc_class->draw_rectangle = gtk_plot_art_draw_rectangle;
  pc_class->draw_polygon = gtk_plot_art_draw_polygon;
  pc_class->draw_circle = gtk_plot_art_draw_circle;
  pc_class->draw_ellipse = gtk_plot_art_draw_ellipse;
  pc_class->set_font = gtk_plot_art_set_font;
  pc_class->draw_string = gtk_plot_art_draw_string;
  pc_class->draw_pixmap = gtk_plot_art_draw_pixmap;
}


GtkObject *
gtk_plot_art_new (GdkDrawable *drawable)
{
  GtkObject *object;

  object = gtk_type_new(gtk_plot_art_get_type());

  gdk_rgb_init();

  return (object);
}


static void
gtk_plot_art_finalize (GtkObject *object)
{
  gdk_window_unref(GTK_PLOT_GDK(object)->window);
}

static void
gtk_plot_art_set_drawable(GtkPlotArt *pc, GdkDrawable *drawable)
{
  GTK_PLOT_GDK(pc)->drawable = drawable;
}

static gboolean 
gtk_plot_art_real_init (GtkPlotPC *pc)
{
  return TRUE;
}

static void
gtk_plot_art_leave (GtkPlotPC *pc)
{
  GdkGC *gc;

  gc = gdk_gc_new(GTK_PLOT_GDK(pc)->drawable);
  gdk_gc_set_foreground(gc, &pc->color);

  gdk_draw_rgb_image(GTK_PLOT_GDK(pc)->drawable, gc, 
                     0, 0, pc->width, pc->height,
                 GDK_RGB_DITHER_NONE,
                 (guchar *)GTK_PLOT_ART(pc)->buf, pc->width * 3); 

  gdk_gc_unref(gc);
}

static void 
gtk_plot_art_set_viewport               (GtkPlotPC *pc, gdouble w, gdouble h)
{
  GtkPlotArt *art;

  art = GTK_PLOT_ART(pc);

  if(art->buf)
    art_free(art->buf);

  art->buf = art_new(art_u8, w*h*3);
  art_rgb_run_alpha(art->buf, 0xFF, 0xFF, 0xFF, 0xFF, w * h);
}

static void 
gtk_plot_art_gsave                                  (GtkPlotPC *pc)
{
}

static void 
gtk_plot_art_grestore                                  (GtkPlotPC *pc)
{
}

static void 
gtk_plot_art_clip                                   (GtkPlotPC *pc,
                                                     const GdkRectangle *area)
{
/*
  g_warning ("Clipping has not been implemented with antialiasing.");
*/
}

static void 
gtk_plot_art_clip_mask                              (GtkPlotPC *pc,
                                         gdouble x,
                                         gdouble y,
                                                     const GdkBitmap *mask)
{
}

static void 
gtk_plot_art_set_color                               (GtkPlotPC *pc,
                                                     const GdkColor *color)
{
  GdkColor new_color;

  new_color = *color;
  gdk_color_alloc(gdk_colormap_get_system(), &new_color);

  pc->color = new_color;
}

static void 
gtk_plot_art_set_dash                               (GtkPlotPC *pc,
                                                    gdouble offset,
                                                    gdouble *values,
                                                    gint num_values)
{
  GtkPlotArt *art = GTK_PLOT_ART(pc);
  gint i;

  if(num_values == 0){
    if(art->dash.dash) g_free(art->dash.dash);
    art->dash.n_dash = 0;
    art->dash.dash = NULL;
    return;
  }

  art->dash.offset = 0;
  art->dash.n_dash = num_values;
  if(art->dash.dash) g_free(art->dash.dash);
  art->dash.dash = g_new0(gdouble, num_values);

  for(i = 0; i < num_values; i++){
     art->dash.dash[i] = values[i];
  }  

}

static void gtk_plot_art_set_lineattr           (GtkPlotPC *pc,
                                                 gfloat line_width,
                                                 GdkLineStyle line_style,
                                                 GdkCapStyle cap_style,
                                                 GdkJoinStyle join_style)
{
  gint art_join;
  gint art_cap;

  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;
  }

  GTK_PLOT_ART(pc)->line_style = line_style;
  GTK_PLOT_ART(pc)->join_style = art_join;
  GTK_PLOT_ART(pc)->cap_style = art_cap;
  GTK_PLOT_ART(pc)->line_width = MAX(line_width, 0.25);

  if(line_style == GDK_LINE_SOLID)
     gtk_plot_art_set_dash(pc, 0, NULL, 0);

}

static void 
gtk_plot_art_draw_point                              (GtkPlotPC *pc,
                                                     gdouble x, gdouble y)
{
  gtk_plot_art_draw_line(pc, x, y, x, y);
}

static void 
gtk_plot_art_draw_line                               (GtkPlotPC *pc,
                                                     gdouble x1, gdouble y1,
                                                     gdouble x2, gdouble y2)
{
  GtkPlotArt *art = GTK_PLOT_ART(pc);
  ArtVpath *vec = NULL;
  ArtSVP *svp = NULL;
  art_u32 color;

  color = (pc->color.red/256 << 16) | (pc->color.green/256 << 8) | (pc->color.blue/256);

  vec = art_new(ArtVpath, 3);
  vec[0].code = ART_MOVETO;
  vec[0].x = x1;
  vec[0].y = y1;
  vec[1].code = ART_LINETO;
  vec[1].x = x2;
  vec[1].y = y2;
  vec[2].code = ART_END;
  vec[2].x = x2;
  vec[2].y = y2;

  svp = gtk_plot_art_stroke(art, vec);

  art_rgb_svp_alpha(svp, 0, 0, pc->width - 1, pc->height - 1, 
                    (color << 8) + 0xFF,  
                    GTK_PLOT_ART(pc)->buf, pc->width * 3, NULL);

}

static void 
gtk_plot_art_draw_lines                              (GtkPlotPC *pc,
                                                     GtkPlotPoint *points,
                                                     gint numpoints)
{
  GtkPlotArt *art = GTK_PLOT_ART(pc);
  ArtVpath *vec = NULL;
  ArtSVP *svp = NULL;
  gint i;
  art_u32 color;

  color = (pc->color.red/256 << 16) | (pc->color.green/256 << 8) | (pc->color.blue/256);

  vec = art_new(ArtVpath, numpoints + 1);
  vec[0].code = ART_MOVETO;
  vec[0].x = points[0].x;
  vec[0].y = points[0].y;

  for(i = 1; i < numpoints; i++){
    vec[i].code = ART_LINETO;
    vec[i].x = points[i].x;
    vec[i].y = points[i].y;
  }

  vec[numpoints].code = ART_END;
  vec[numpoints].x = points[numpoints - 1].x;
  vec[numpoints].y = points[numpoints - 1].y;

  svp = gtk_plot_art_stroke(art, vec);

  art_rgb_svp_alpha(svp, 0, 0, pc->width - 1, pc->height - 1, 
                    (color << 8) + 0xFF,  
                    GTK_PLOT_ART(pc)->buf, pc->width * 3, NULL);
}

static void 
gtk_plot_art_draw_rectangle                          (GtkPlotPC *pc,
                                                     gint filled,
                                                     gdouble x, gdouble y,
                                                     gdouble width, gdouble height)
{
  GtkPlotArt *art = GTK_PLOT_ART(pc);
  ArtVpath *vec = NULL;
  ArtSVP *svp = NULL;
  art_u32 color;

  color = (pc->color.red/256 << 16) | (pc->color.green/256 << 8) | (pc->color.blue/256);

  vec = art_new(ArtVpath, 6);
  vec[0].code = ART_MOVETO;
  vec[0].x = x;
  vec[0].y = y;
  vec[1].code = ART_LINETO;
  vec[1].x = x+width;
  vec[1].y = y;
  vec[2].code = ART_LINETO;
  vec[2].x = x+width;
  vec[2].y = y+height;
  vec[3].code = ART_LINETO;
  vec[3].x = x;
  vec[3].y = y+height;
  vec[4].code = ART_LINETO;
  vec[4].x = x;
  vec[4].y = y;
  vec[5].code = ART_END;


  if(filled)
    svp = art_svp_from_vpath(vec);
  else
    svp = gtk_plot_art_stroke(art, vec);

  art_rgb_svp_alpha(svp, 0, 0, pc->width - 1, pc->height - 1, 
                    (color << 8) + 0xFF,  
                    GTK_PLOT_ART(pc)->buf, pc->width * 3, NULL);
}

static void 
gtk_plot_art_draw_polygon                            (GtkPlotPC *pc,
                                                     gint filled,
                                                     GtkPlotPoint *points,
                                                     gint numpoints)
{
  GtkPlotArt *art = GTK_PLOT_ART(pc);
  ArtVpath *vec = NULL;
  ArtSVP *svp = NULL;
  gint i;
  art_u32 color;

  color = (pc->color.red/256 << 16) | (pc->color.green/256 << 8) | (pc->color.blue/256);

  vec = art_new(ArtVpath, numpoints + 2);
  vec[0].code = ART_MOVETO;
  vec[0].x = points[0].x;
  vec[0].y = points[0].y;

  for(i = 1; i < numpoints; i++){
    vec[i].code = ART_LINETO;
    vec[i].x = points[i].x;
    vec[i].y = points[i].y;
  }

  vec[numpoints].code = ART_LINETO;
  vec[numpoints].x = points[0].x;
  vec[numpoints].y = points[0].y;
  vec[numpoints+1].code = ART_END;

  if(filled)
    svp = art_svp_from_vpath(vec);
  else
    svp = gtk_plot_art_stroke(art, vec);

  art_rgb_svp_alpha(svp, 0, 0, pc->width - 1, pc->height - 1, 
                    (color << 8) + 0xFF,  
                    GTK_PLOT_ART(pc)->buf, pc->width * 3, NULL);
}

static void 
gtk_plot_art_draw_circle                             (GtkPlotPC *pc,
                                                     gint 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);
  }

  gtk_plot_art_draw_polygon(pc, filled, points, npoints);
  g_free(points);
}

static void 
gtk_plot_art_draw_ellipse                            (GtkPlotPC *pc,
                                                     gint 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);
  }

  gtk_plot_art_draw_polygon(pc, filled, points, npoints);
  g_free(points);
}

static void 
gtk_plot_art_set_font                                (GtkPlotPC *pc,
                                         GtkPSFont *psfont,
                                                     gint height)
{

}

/* subfunction of gtk_plot_art_draw_string(). */
static gint
drawstring(GtkPlotPC *pc,
         GdkBitmap *dest,
         GdkGC *gc,
         GdkColor *black, GdkColor *white,
         gint dx, gint dy,
         GtkPSFont *psfont,
         GdkFont *font,
         GdkFont *latin_font,
         GdkWChar wc)
{
  GdkBitmap *tmp;
  GdkFont *dfont;
  GdkImage *image;
  gint w, h, a, d, x, y, d2;
  guint32 pixel;

  if (psfont->i18n_latinfamily && psfont->vertical && (0 > wc || wc > 0x7f)) {
    /* vertical-writing CJK postscript fonts. */
    dfont = font;

    w = gdk_char_width_wc(dfont, wc);
    a = dfont->ascent;
    d = dfont->descent;
    h = a + d;
    d2 = w * d / h;

    tmp = gdk_pixmap_new(GTK_PLOT_GDK(pc)->window, w, h, 1);

    gdk_gc_set_foreground(gc, white);
    gdk_draw_rectangle(tmp, gc, TRUE, 0, 0, -1, -1);
    gdk_gc_set_foreground(gc, black);

    gdk_draw_text_wc(tmp, dfont, gc, 0, a, &wc, 1);

    image = gdk_image_get(tmp, 0, 0, w, h);

    for (y = 0; y < h; y++) {
      for (x = 0; x < w; x++) {
      pixel = gdk_image_get_pixel(image, x, y);
      if (pixel == black->pixel)
        gdk_draw_point(dest, gc, dx + y, dy + d2 - x);
      }
    }

    gdk_image_destroy(image);
    gdk_pixmap_unref(tmp);

    return h;
  } else {
    /* horizontal writing */
    if (psfont->i18n_latinfamily && 0 <= wc && wc <= 0x7f)
      dfont = latin_font;
    else
      dfont = font;

    gdk_draw_text_wc(dest, dfont, gc, dx, dy, &wc, 1);
    w = gdk_char_width_wc(dfont, wc);
    
    return w;
  }
}

static void 
gtk_plot_art_draw_string                        (GtkPlotPC *pc,
                                                gint tx, gint ty,
                                                gint angle,
                                                const GdkColor *fg,
                                                const GdkColor *bg,
                                                gboolean transparent,
                                                gint border,
                                                gint border_space,
                                                gint border_width,
                                                gint shadow_width,
                                                const gchar *font_name,
                                                gint font_height,
                                                GtkJustification just,
                                                const gchar *text)
{
  GdkBitmap *text_bitmap;
  guchar *text_art, *line;
  GdkImage *image;
  GdkGC *gc, *bitmap_gc;
  GdkColormap *colormap;
  GdkColor white, black;
  GList *family = NULL;
  gint y0;
  gint old_width, old_height;
  gint bitmap_width, bitmap_height;
  gboolean bold, italic;
  gint fontsize;
  gint ascent, descent;
  gint numf;
  gint width, height;
  gint x, y;
  gint i;
  GdkFont *font, *latin_font, *dfont;
  GtkPSFont *psfont, *base_psfont, *latin_psfont;
  gchar subs[2], insert_char;
  GdkWChar *aux, *wtext, *lastchar = NULL, *xaux;
  gchar num[4];
  gdouble affine[6], rotate[6], translate[6];
  art_u32 color;

  if(!text || strlen(text) == 0) return;

  colormap = gdk_colormap_get_system ();
  gc = GTK_PLOT_GDK(pc)->gc;

  gtk_plot_text_get_size(text, angle, font_name, font_height, &width, &height, &ascent, &descent);

  if(height == 0 || width == 0) return;

  old_width = width;
  old_height = height;
  if(angle == 90 || angle == 270)
    {
      old_width = height;
      old_height = width;
    }

  gtk_psfont_get_families(&family, &numf);
  font = gtk_psfont_get_gdkfont(font_name, font_height);
  base_psfont = psfont = gtk_psfont_get_font(font_name);
  italic = psfont->italic;
  bold = psfont->bold;
  fontsize = font_height;
  x = 0;
  y0 = y = ascent;

  if (psfont->i18n_latinfamily) {
    latin_psfont = gtk_psfont_find_by_family(psfont->i18n_latinfamily, italic,
                                   bold);
    latin_font = gtk_psfont_get_gdkfont(latin_psfont->psname, fontsize);
  } else {
    latin_psfont = NULL;
    latin_font = NULL;
  }

  i = strlen(text) + 2;
  aux = wtext = g_malloc0(sizeof(GdkWChar) * i);
  gdk_mbstowcs(wtext, text, i - 1);

  /* initializing text bitmap - ajd */
  text_bitmap = gdk_pixmap_new(GTK_PLOT_GDK(pc)->window,
                              old_width, old_height, 1);
  bitmap_gc = gdk_gc_new(text_bitmap);
  gdk_color_white (colormap, &white);
  gdk_gc_set_foreground(bitmap_gc, &white);
  gdk_draw_rectangle(text_bitmap, bitmap_gc, TRUE,
                     0, 0, -1, -1);
  gdk_color_black (colormap, &black);
  gdk_gc_set_foreground(bitmap_gc, &black);

  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':
           psfont = gtk_psfont_find_by_family((gchar *)g_list_nth_data(family, *aux-'0'), italic, bold);
           gdk_font_unref(font);
           font = gtk_psfont_get_gdkfont(psfont->psname, fontsize);
         if (latin_font) {
           gdk_font_unref(latin_font);
           latin_font = NULL;
         }
           aux++;
           break;
       case '8': case 'g':
           psfont = gtk_psfont_find_by_family("Symbol", italic, bold);
           gdk_font_unref(font);
           font = gtk_psfont_get_gdkfont(psfont->psname, fontsize);
         if (latin_font) {
           gdk_font_unref(latin_font);
           latin_font = NULL;
         }
           aux++;
           break;
       case 'B':
           bold = TRUE;
           psfont = gtk_psfont_find_by_family(psfont->family, italic, bold);
           gdk_font_unref(font);
           font = gtk_psfont_get_gdkfont(psfont->psname, fontsize);
         if (latin_font) {
           gdk_font_unref(latin_font);
           latin_font = NULL;
         }
         if (psfont->i18n_latinfamily) {
           latin_psfont = gtk_psfont_find_by_family(psfont->i18n_latinfamily,
                                          italic, bold);
           latin_font = gtk_psfont_get_gdkfont(latin_psfont->psname,
                                     fontsize);
         }
           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';
           insert_char = (gchar)atoi(num);
           subs[0] = insert_char;
           subs[1] = '\0';
         /* \xNNN is always outputted with latin fonts. */
         dfont = (psfont->i18n_latinfamily != NULL) ? latin_font : font;
           gdk_draw_string (text_bitmap, dfont,
                            bitmap_gc,
                            x, y,
                            subs);

           x += gdk_char_width(font, insert_char);
           aux += 4;
           lastchar = aux - 1;
           break;
       case 'i':
           italic = TRUE;
           psfont = gtk_psfont_find_by_family(psfont->family, italic, bold);
           gdk_font_unref(font);
           font = gtk_psfont_get_gdkfont(psfont->psname, fontsize);
         if (latin_font) {
           gdk_font_unref(latin_font);
           latin_font = NULL;
         }
         if (psfont->i18n_latinfamily) {
           latin_psfont = gtk_psfont_find_by_family(psfont->i18n_latinfamily,
                                          italic, bold);
           latin_font = gtk_psfont_get_gdkfont(latin_psfont->psname,
                                     fontsize);
         }
           aux++;
           break;
       case 'S': case '^':
           fontsize = (int)((gdouble)fontsize * 0.6 + 0.5);
           gdk_font_unref(font);
           font = gtk_psfont_get_gdkfont(psfont->psname, fontsize);
           y -= font->ascent;
         if (latin_font) {
           gdk_font_unref(latin_font);
           latin_font = NULL;
         }
         if (psfont->i18n_latinfamily) {
           latin_psfont = gtk_psfont_find_by_family(psfont->i18n_latinfamily,
                                          italic, bold);
           latin_font = gtk_psfont_get_gdkfont(latin_psfont->psname,
                                     fontsize);
         }
           aux++;
           break;
       case 's': case '_':
           fontsize = (int)((gdouble)fontsize * 0.6 + 0.5);
           gdk_font_unref(font);
           font = gtk_psfont_get_gdkfont(psfont->psname, fontsize);
           y += font->descent;
         if (latin_font) {
           gdk_font_unref(latin_font);
           latin_font = NULL;
         }
         if (psfont->i18n_latinfamily) {
           latin_psfont = gtk_psfont_find_by_family(psfont->i18n_latinfamily,
                                          italic, bold);
           latin_font = gtk_psfont_get_gdkfont(latin_psfont->psname,
                                     fontsize);
         }
           aux++;
           break;
       case '+':
           fontsize += 3;
           gdk_font_unref(font);
           font = gtk_psfont_get_gdkfont(psfont->psname, fontsize);
         if (latin_font) {
           gdk_font_unref(latin_font);
           latin_font = NULL;
         }
         if (psfont->i18n_latinfamily) {
           latin_psfont = gtk_psfont_find_by_family(psfont->i18n_latinfamily,
                                          italic, bold);
           latin_font = gtk_psfont_get_gdkfont(latin_psfont->psname,
                                     fontsize);
         }
           aux++;
           break;
       case '-':
           fontsize -= 3;
           gdk_font_unref(font);
           font = gtk_psfont_get_gdkfont(psfont->psname, fontsize);
         if (latin_font) {
           gdk_font_unref(latin_font);
           latin_font = NULL;
         }
         if (psfont->i18n_latinfamily) {
           latin_psfont = gtk_psfont_find_by_family(psfont->i18n_latinfamily,
                                          italic, bold);
           latin_font = gtk_psfont_get_gdkfont(latin_psfont->psname,
                                     fontsize);
         }
           aux++;
           break;
       case 'N':
         psfont = base_psfont;
           gdk_font_unref(font);
           fontsize = font_height;
           font = gtk_psfont_get_gdkfont(psfont->psname, fontsize);
           y = y0;
           italic = psfont->italic;
           bold = psfont->bold;
         if (latin_font) {
           gdk_font_unref(latin_font);
           latin_font = NULL;
         }
         if (psfont->i18n_latinfamily) {
           latin_psfont = gtk_psfont_find_by_family(psfont->i18n_latinfamily,
                                          italic, bold);
           latin_font = gtk_psfont_get_gdkfont(latin_psfont->psname,
                                     fontsize);
         }
           aux++;
           break;
       case 'b':
         if (lastchar) {
           gtk_psfont_get_char_size(psfont, font, latin_font, *lastchar, &i,
                            NULL, NULL);
           x -= i;

           if (lastchar == wtext)
             lastchar = NULL;
           else
             lastchar--;
         } else {
           gtk_psfont_get_char_size(psfont, font, latin_font, 'X', &i, NULL,
                            NULL);
           x -= i;
         }
           aux++;
           break;
       default:
           if(aux && *aux != '\0' && *aux !='\n'){
           x += drawstring(pc, text_bitmap, bitmap_gc, &black, &white, x, y,
                       psfont, font, latin_font, *aux);
           lastchar = aux;
           aux++;
         }
         break;
     }
   } else {
     if(aux && *aux != '\0' && *aux !='\n'){
       x += drawstring(pc, text_bitmap, bitmap_gc, &black, &white, x, y,
                   psfont, font, latin_font, *aux);
       lastchar = aux;
       aux++;
     }
   }
  }

  g_free(wtext);

  /* performing text rotation and saving it onto clip mask bitmap - ajd */

  gtk_plot_text_get_area(text, angle, just, font_name, font_height,
                         &x, &y, &width, &height);
  tx += x;
  ty += y;

  art_affine_rotate(rotate, (gdouble) -angle);
  switch(angle){
    case 0:
      art_affine_translate(translate, tx, ty);
      break;
    case 90:
      art_affine_translate(translate, tx, ty + old_width);
      break;
    case 180:
      art_affine_translate(translate, tx + old_width , ty + old_height);
      break;
    case 270:
      art_affine_translate(translate, tx + old_height, ty);
      break;
  }
  art_affine_multiply(affine, rotate, translate);
 
  bitmap_height = old_height;
  bitmap_width = (old_width + 31) & -32;
  image = gdk_image_get(text_bitmap, 0, 0, old_width, old_height);
  text_art = g_malloc0 ((bitmap_width >> 3) * bitmap_height);

  line = text_art;
  for(y = 0; y < bitmap_height; y++){
      for(x = 0; x < bitmap_width; x++) {
           if( black.pixel == gdk_image_get_pixel(image, x, y) ){
             line[x >> 3] |= 128 >> (x & 7);
           }
      }
      line += bitmap_width >> 3;
  }
  gdk_image_destroy(image);

  if(!transparent){
    gtk_plot_pc_set_color(pc, (GdkColor *) bg);
    gtk_plot_pc_draw_rectangle(pc,
                     TRUE, 
                         tx - border_space, ty - border_space, 
                         width + 2*border_space, height + 2*border_space);
  }

  gtk_plot_pc_set_color(pc, (GdkColor *)fg);
  color = (pc->color.red/256 << 24) | (pc->color.green/256 << 16) | (pc->color.blue/256 << 8) | 0xFF;

  art_rgb_bitmap_affine (
          GTK_PLOT_ART(pc)->buf,
          0, 0, 
          pc->width - 1, pc->height - 1,
          pc->width * 3,
          text_art,
          old_width,
          old_height,
          bitmap_width >> 3,
          color,
          affine,
          ART_FILTER_NEAREST, NULL);

  g_free(text_art);
  gdk_font_unref(font);
  if (latin_font) gdk_font_unref(latin_font);
  gdk_gc_unref(bitmap_gc);
  gdk_pixmap_unref(text_bitmap);

/* border */
  gtk_plot_pc_set_dash(pc, 0, NULL, 0);
  gtk_plot_pc_set_lineattr(pc, border_width, 0, 0, 0);
  switch(border){
    case GTK_PLOT_BORDER_SHADOW: 
      gtk_plot_pc_draw_rectangle(pc,
                     TRUE, 
                         tx - border_space + shadow_width, 
                         ty + height + border_space, 
                         width + 2 * border_space, shadow_width);
      gtk_plot_pc_draw_rectangle(pc,
                     TRUE, 
                         tx + width + border_space, 
                         ty - border_space + shadow_width, 
                         shadow_width, height + 2 * border_space);
    case GTK_PLOT_BORDER_LINE: 
      gtk_plot_pc_draw_rectangle(pc,
                     FALSE, 
                         tx - border_space, ty - border_space, 
                         width + 2*border_space, height + 2*border_space);
    case GTK_PLOT_BORDER_NONE: 
    default:
      break; 
  }

  return;
}

static void gtk_plot_art_draw_pixmap                (GtkPlotPC *pc,
                                                     GdkPixmap *pixmap,
                                                     GdkBitmap *mask,
                                                     gint xsrc, gint ysrc,
                                                     gint xdest, gint ydest,
                                                     gint width,
                                                     gint height,
                                                     gdouble scale_x, 
                                                     gdouble scale_y)
{
  GdkColormap *colormap;
  GdkColorContext *cc;
  GdkVisual *visual;
  art_u8 *pixels = NULL, *pixel;
  ArtPixBuf *pixbuf;
  gdouble affine[6], scale[6], translate[6];
  GdkImage *image;
  GdkImage *mask_image = NULL;
  gint x, y;

  if(!pixmap){
    gtk_plot_pc_draw_rectangle(pc, FALSE, xdest, ydest, 
                               width * scale_x, height * scale_y);
    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);

  pixels = art_new(art_u8, width * 4 * height);
  pixel = pixels;
  for(y = 0; y < height; 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);

      pixel[0] = color.red/256;
      pixel[1] = color.green/256;
      pixel[2] = color.blue/256;
      pixel[3] = 0xFF;

      if(mask_image){
           gulong mask_pixel;

           mask_pixel = gdk_image_get_pixel(mask_image, x, y);
           if(mask_pixel == 0) pixel[3] = 0;
      }

      pixel += 4;
    }
  }

  gdk_image_destroy(image);
  if(mask_image) gdk_image_destroy(mask_image);

  gdk_color_context_free(cc);

  pixbuf = art_pixbuf_new_rgba (pixels, width, height, width*4);

  art_affine_translate(translate, xdest, ydest);
  art_affine_scale(scale, scale_x, scale_y);
  art_affine_multiply(affine, scale, translate);

  art_rgb_pixbuf_affine (GTK_PLOT_ART(pc)->buf,
                         0, 0, pc->width - 1, pc->height - 1,
                         pc->width * 3,
                         pixbuf,
                         affine,
                         ART_FILTER_NEAREST, NULL);

  art_free(pixels);
}

static ArtSVP * 
gtk_plot_art_stroke               (GtkPlotArt *art, ArtVpath *path)
{
  ArtSVP *svp = NULL;

  if(art->dash.n_dash != 0){
    ArtVpath *dash_path = NULL;

    dash_path = art_vpath_dash(path, &art->dash);

    art_free(path);
    path = dash_path;
  } 

  svp = art_svp_vpath_stroke (path,
                              art->join_style,
                              art->cap_style,
                              art->line_width,
                              4,
                              0.25);
 
  return (svp);
}

#endif /* WITH_LIBART */

Generated by  Doxygen 1.6.0   Back to index