Пример #1
0
static void
gtk_plot_gdk_grestore                                  (GtkPlotPC *pc)
{
  if(GTK_PLOT_GDK(pc)->gc) gdk_gc_unref(GTK_PLOT_GDK(pc)->gc);

  GTK_PLOT_GDK(pc)->ref_count--;
  if(GTK_PLOT_GDK(pc)->ref_count == 0) GTK_PLOT_GDK(pc)->gc = NULL;
}
Пример #2
0
static void
gtk_plot_gdk_finalize (GtkObject *object)
{
  gdk_window_unref(GTK_PLOT_GDK(object)->window);

  if(GTK_PLOT_GDK(object)->ref_count > 0 && GTK_PLOT_GDK(object)->gc)
          gdk_gc_destroy(GTK_PLOT_GDK(object)->gc);
}
Пример #3
0
static void
gtk_plot_gdk_draw_point                              (GtkPlotPC *pc,
                                                     gdouble x, gdouble y)
{
  if(!GTK_PLOT_GDK(pc)->gc) return;
  if(!GTK_PLOT_GDK(pc)->drawable) return;

  gdk_draw_point(GTK_PLOT_GDK(pc)->drawable, GTK_PLOT_GDK(pc)->gc,
                 roundint(x), roundint(y));
}
Пример #4
0
static void
gtk_plot_gdk_draw_line                               (GtkPlotPC *pc,
                                                     gdouble x1, gdouble y1,
                                                     gdouble x2, gdouble y2)
{
  if(!GTK_PLOT_GDK(pc)->gc) return;
  if(!GTK_PLOT_GDK(pc)->drawable) return;

  gdk_draw_line(GTK_PLOT_GDK(pc)->drawable, GTK_PLOT_GDK(pc)->gc,
                roundint(x1), roundint(y1), roundint(x2), roundint(y2));
}
Пример #5
0
static void 
gtk_plot_gdk_gsave                                  (GtkPlotPC *pc)
{
  if(GTK_PLOT_GDK(pc)->gc) 
    gdk_gc_ref(GTK_PLOT_GDK(pc)->gc);
  else{
    GTK_PLOT_GDK(pc)->gc = gdk_gc_new(GTK_PLOT_GDK(pc)->window);
  }

  GTK_PLOT_GDK(pc)->ref_count++;
}
Пример #6
0
static void
gtk_plot_gdk_set_color                               (GtkPlotPC *pc,
                                                     const GdkColor *color)
{
  GdkColor new_color;

  if(!GTK_PLOT_GDK(pc)->gc) return;

  new_color = *color;
  gdk_color_alloc(gdk_colormap_get_system(), &new_color);
  gdk_gc_set_foreground(GTK_PLOT_GDK(pc)->gc, &new_color);
}
Пример #7
0
static void
gtk_plot_gdk_clip                                   (GtkPlotPC *pc,
                                                     const GdkRectangle *area)
{
  if(!GTK_PLOT_GDK(pc)->gc) return;

  /* discard GdkRectangle* const:
   * gdk_gc_set_clip_rectangle should have a const arg.
   * I've checked the code and it doesn't change it or keep it. murrayc.
   */

  gdk_gc_set_clip_rectangle(GTK_PLOT_GDK(pc)->gc, (GdkRectangle*)area);
}
Пример #8
0
static void
gtk_plot_gdk_clip_mask                              (GtkPlotPC *pc,
						     gdouble x,
						     gdouble y,
                                                     const GdkBitmap *mask)
{
  if(!GTK_PLOT_GDK(pc)->gc) return;

  if(x >= 0 && y >= 0)
    gdk_gc_set_clip_origin(GTK_PLOT_GDK(pc)->gc, x, y);

  gdk_gc_set_clip_mask(GTK_PLOT_GDK(pc)->gc, (GdkBitmap*)mask);
}
Пример #9
0
static void
gtk_plot_gdk_draw_ellipse                            (GtkPlotPC *pc,
                                                     gint filled,
                                                     gdouble x, gdouble y,
                                                     gdouble width, gdouble height)
{
  if(!GTK_PLOT_GDK(pc)->gc) return;
  if(!GTK_PLOT_GDK(pc)->drawable) return;

  gdk_draw_arc (GTK_PLOT_GDK(pc)->drawable, GTK_PLOT_GDK(pc)->gc,
                filled,
                roundint(x), roundint(y),
                roundint(width), roundint(height), 0, 25000);
}
Пример #10
0
static void gtk_plot_gdk_set_lineattr           (GtkPlotPC *pc,
                                                 gfloat line_width,
                                                 GdkLineStyle line_style,
                                                 GdkCapStyle cap_style,
                                                 GdkJoinStyle join_style)
{
  if(!GTK_PLOT_GDK(pc)->gc) return;

  gdk_gc_set_line_attributes(GTK_PLOT_GDK(pc)->gc,
                             roundint(line_width),
                             line_style,
                             cap_style,
                             join_style);
}
Пример #11
0
static void
gtk_plot_gdk_draw_circle                             (GtkPlotPC *pc,
                                                     gint filled,
                                                     gdouble x, gdouble y,
                                                     gdouble size)
{
  if(!GTK_PLOT_GDK(pc)->gc) return;
  if(!GTK_PLOT_GDK(pc)->drawable) return;

  gdk_draw_arc (GTK_PLOT_GDK(pc)->drawable, GTK_PLOT_GDK(pc)->gc,
                filled,
                roundint(x-size/2.0), roundint(y-size/2.0),
                roundint(size), roundint(size), 0, 25000);

}
Пример #12
0
static void gtk_plot_gdk_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)
{
  GdkGC *gc;
  GdkPixmap *new_pixmap;
  GdkBitmap *new_mask = NULL;

  if(!GTK_PLOT_GDK(pc)->drawable) return;
  if(!GTK_PLOT_GDK(pc)->window) return;
  if(!GTK_PLOT_GDK(pc)->gc) return;

  gc = GTK_PLOT_GDK(pc)->gc;

  if(!gc) return;

  new_pixmap = scale_pixmap(GTK_PLOT_GDK(pc)->window, pixmap, scale_x, scale_y);
  
  if(mask)
    new_mask = scale_bitmap(GTK_PLOT_GDK(pc)->window, mask, scale_x, scale_y);

  gtk_plot_pc_clip_mask(pc, xdest, ydest, new_mask);
  gdk_draw_pixmap(GTK_PLOT_GDK(pc)->drawable, gc, new_pixmap,
                  xsrc, ysrc, xdest, ydest, width*scale_x, height*scale_y);
  gtk_plot_pc_clip_mask(pc, xdest, ydest, NULL);

  if(new_mask) gdk_bitmap_unref(new_mask);
  gdk_pixmap_unref(new_pixmap);
}
Пример #13
0
GtkObject *
gtk_plot_gdk_new                                (GtkWidget *widget)
{
  GtkObject *object;

  object = gtk_type_new(gtk_plot_gdk_get_type());

  gtk_plot_gdk_construct(GTK_PLOT_GDK(object), widget);

  return (object);
}
Пример #14
0
GtkObject *
gtk_plot_gdk_new                                (GdkDrawable *drawable)
{
  GtkObject *object;

  object = gtk_type_new(gtk_plot_gdk_get_type());

  gtk_plot_gdk_construct(GTK_PLOT_GDK(object), drawable);

  return (object);
}
Пример #15
0
static void
gtk_plot_gdk_draw_lines                              (GtkPlotPC *pc,
                                                     GtkPlotPoint *points,
                                                     gint numpoints)
{
  GdkPoint *p = NULL;
  gint i;

  if(!GTK_PLOT_GDK(pc)->gc) return;
  if(!GTK_PLOT_GDK(pc)->drawable) return;

  p = (GdkPoint *)g_malloc(numpoints * sizeof(GdkPoint));
  for(i = 0; i < numpoints; i++){
    p[i].x = roundint(points[i].x);
    p[i].y = roundint(points[i].y);
  }

  gdk_draw_lines(GTK_PLOT_GDK(pc)->drawable, GTK_PLOT_GDK(pc)->gc, p, numpoints);

  g_free(p);
}
Пример #16
0
static void
gtk_plot_gdk_set_dash                               (GtkPlotPC *pc,
                                                    gdouble offset,
                                                    gdouble *values,
                                                    gint num_values)
{
  gchar list[] = {'\0','\1','\2','\3','\4','\5','\6','\7'};
  gchar dash[1000] = "";
  gint i;

  if(!GTK_PLOT_GDK(pc)->gc) return;

  if(num_values == 0){
    return;
  }

  for(i = 0; i < num_values; i++){
     gint value;
     value = values[i];
     dash[i] = list[value];
  }

  gdk_gc_set_dashes(GTK_PLOT_GDK(pc)->gc, 0, dash, num_values);
}
Пример #17
0
/* subfunction of gtk_plot_gdk_draw_string(). */
static gint
drawstring(GtkPlotPC *pc,
	   GdkDrawable *drawable,
	   GdkGC *gc,
           gint angle,
	   gint dx, gint dy,
	   GtkPSFont *psfont, gint height,
	   const gchar *text)
{
  PangoFontDescription *font;
  PangoRectangle rect;
  const gchar *aux = text;
  gint ret_value;

  if(!text || strlen(text) == 0) return 0;
  font = gtk_psfont_get_font_description(psfont, height);
  pango_layout_set_font_description(GTK_PLOT_GDK(pc)->layout, font);

  pango_layout_set_text(GTK_PLOT_GDK(pc)->layout, text, strlen(text));
  pango_layout_get_extents(GTK_PLOT_GDK(pc)->layout, NULL, &rect);

  if (psfont->i18n_latinfamily && psfont->vertical) {
    /* vertical-writing CJK postscript fonts. */
    return rect.height;
  }
  else
  {
    /* horizontal writing */
    if(angle == 90)
      gdk_draw_layout (drawable, gc, dx, dy-PANGO_PIXELS(rect.width), GTK_PLOT_GDK(pc)->layout);
    else if(angle == 180)
      gdk_draw_layout (drawable, gc, dx-PANGO_PIXELS(rect.width), dy, GTK_PLOT_GDK(pc)->layout);
    else
      gdk_draw_layout (drawable, gc, dx, dy, GTK_PLOT_GDK(pc)->layout);

/*
    gdk_draw_layout (GTK_PLOT_GDK(pc)->drawable, gc, dx, dy, GTK_PLOT_GDK(pc)->layout);
*/

  }
  pango_font_description_free(font);
  ret_value = (angle == 0 || angle == 180) ? rect.width : rect.height;
  return PANGO_PIXELS(rect.width);
}
Пример #18
0
static void
gtk_plot_gdk_finalize (GObject *object)
{
  GtkPlotGdk *pc = GTK_PLOT_GDK(object);

  GTK_PLOT_GDK(object)->window = NULL;

  if(GTK_PLOT_GDK(object)->ref_count > 0 && GTK_PLOT_GDK(object)->gc){
          gdk_gc_destroy(GTK_PLOT_GDK(object)->gc);
          GTK_PLOT_GDK(object)->gc = NULL;
  }

  if(pc->layout)
    g_object_unref(G_OBJECT(pc->layout));
  pc->layout = NULL;

  if(pc->context)
    g_object_unref(G_OBJECT(pc->context));
  pc->context = NULL;
}
Пример #19
0
static void
gtk_plot_gdk_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)
{
  GdkGC *gc;
  GList *family = NULL;
  gint x0, y0;
  gint old_width, old_height;
  gboolean bold, italic;
  gint fontsize;
  gint ascent, descent;
  gint numf;
  gint width, height;
  gint x, y;
  gint i;
  PangoFontDescription *font = NULL, *latin_font = NULL;
  GtkPSFont *psfont, *base_psfont, *latin_psfont;
  gchar subs[2], insert_char;
  const gchar *aux = text;
  const gchar *lastchar = text;
  const gchar *wtext = text;
  const gchar *xaux = text;
  gchar new_text[strlen(text)+1];
  gchar num[4];
  PangoRectangle rect;
  PangoFontMetrics *metrics = NULL;
  PangoLayout *layout = NULL;
  gint real_x, real_y, real_width, real_height;
  GdkColor real_fg = *fg;
  GdkColor real_bg = *bg;
  PangoMatrix matrix = PANGO_MATRIX_INIT;
  PangoContext *context = GTK_PLOT_GDK(pc)->context;
  GdkDrawable *drawable = GTK_PLOT_GDK(pc)->drawable;
  gint sign_x = 1, sign_y = 0;

  if(!GTK_PLOT_GDK(pc)->drawable) return;
  if(!GTK_PLOT_GDK(pc)->gc) return;
  if(!text || strlen(text) == 0) return;

  gc = GTK_PLOT_GDK(pc)->gc;
  layout = GTK_PLOT_GDK(pc)->layout;

  if(!gc) return;

  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;
    }
  switch(angle){
    case 90:
      sign_x = 0;
      sign_y = -1;
      break;
    case 180:
      sign_x = -1;
      sign_y = 0;
      break;
    case 270:
      sign_x = 0;
      sign_y = 1;
      break;
    case 0:
    default:
      sign_x = 1;
      sign_y = 0;
      break;
  }

  switch(just){
    case GTK_JUSTIFY_LEFT:
      switch(angle){
        case 0:
            ty -= ascent;
            break;
        case 90:
            ty -= height;
            tx -= ascent;
            break;
        case 180:
            tx -= width;
            ty -= descent;
            break;
        case 270:
            tx -= descent;
            break;
      }
      break;
    case GTK_JUSTIFY_RIGHT:
      switch(angle){
        case 0:
            tx -= width;
            ty -= ascent;
            break;
        case 90:
            tx -= ascent;
            ty += height;
            break;
        case 180:
            tx += width;
            ty -= descent;
            break;
        case 270:
            tx -= descent;
            break;
      }
      break;
    case GTK_JUSTIFY_CENTER:
    default:
      switch(angle){
        case 0:
            tx -= width / 2.;
            ty -= ascent;
            break;
        case 90:
            tx -= ascent;
            ty += height / 2.;
            break;
        case 180:
            tx += width / 2.;
            ty -= descent;
            break;
        case 270:
            tx -= descent;
            ty -= height / 2.;
            break;
      }
  }

  real_x = tx;
  real_y = ty;
  real_width = width;
  real_height = height;

  pango_matrix_rotate (&matrix, angle);
  pango_context_set_matrix (context, &matrix);
  pango_layout_context_changed (layout);

  if(!transparent){
    gdk_gc_set_foreground(gc, &real_bg);
    gdk_draw_rectangle(drawable, gc, TRUE, tx, ty, old_width, old_height);
  }

/* TEST */
/*
  gdk_draw_rectangle(text_pixmap, gc, FALSE, 0, 0, old_width-1, old_height-1);
*/

  gtk_psfont_get_families(&family, &numf);
  base_psfont = psfont = gtk_psfont_get_by_name(font_name);
  font = gtk_psfont_get_font_description(psfont, font_height);
  italic = psfont->italic;
  bold = psfont->bold;
  fontsize = font_height;
  x0 = x = 0;
  y0 = y = 0;

  if (psfont->i18n_latinfamily) {
    latin_psfont = gtk_psfont_get_by_family(psfont->i18n_latinfamily, italic,
                                             bold);
    if(latin_font) pango_font_description_free(latin_font);
    latin_font = gtk_psfont_get_font_description(latin_psfont, fontsize);
  } else {
    latin_psfont = NULL;
    latin_font = NULL;
  }

  gdk_gc_set_foreground(gc, &real_fg);
  aux = text;
  while(aux && *aux != '\0' && *aux != '\n'){
   if(*aux == '\\'){
     aux = g_utf8_next_char(aux);
     switch(*aux){
       case '0': case '1': case '2': case '3':
       case '4': case '5': case '6': case '7': case '9':
           psfont = gtk_psfont_get_by_family((gchar *)g_list_nth_data(family, *aux-'0'), italic, bold);
           pango_font_description_free(font);
           font = gtk_psfont_get_font_description(psfont, fontsize);
           aux = g_utf8_next_char(aux);
           break;
       case '8': case 'g':
           psfont = gtk_psfont_get_by_family("Symbol", italic, bold);
           pango_font_description_free(font);
           font = gtk_psfont_get_font_description(psfont, fontsize);
           aux = g_utf8_next_char(aux);
           break;
       case 'B':
           bold = TRUE;
           psfont = gtk_psfont_get_by_family(psfont->family, italic, bold);
           pango_font_description_free(font);
           font = gtk_psfont_get_font_description(psfont, fontsize);
           if(latin_font){
             latin_font = NULL;
           }
           if (psfont->i18n_latinfamily) {
             latin_psfont = gtk_psfont_get_by_family(psfont->i18n_latinfamily,
                                                      italic, bold);
             if(latin_font) pango_font_description_free(latin_font);
             latin_font = gtk_psfont_get_font_description(latin_psfont, fontsize);
           }
           aux = g_utf8_next_char(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 = g_utf8_next_char(aux);
              break;
           }
           num[3] = '\0';
           insert_char = (gchar)atoi(num);
           subs[0] = insert_char;
           subs[1] = '\0';
           pango_layout_set_font_description(layout, font);
           pango_layout_set_text(layout, subs, 1);
           pango_layout_get_extents(layout, NULL, &rect);
           x += sign_x*PANGO_PIXELS(rect.width);
           y += sign_y*PANGO_PIXELS(rect.width);
           aux += 4;
           lastchar = aux - 1;
           break;
       case 'i':
           italic = TRUE;
           psfont = gtk_psfont_get_by_family(psfont->family, italic, bold);
           pango_font_description_free(font);
           font = gtk_psfont_get_font_description(psfont, fontsize);
           if (psfont->i18n_latinfamily) {
             latin_psfont = gtk_psfont_get_by_family(psfont->i18n_latinfamily,
                                                      italic, bold);
             if(latin_font) pango_font_description_free(latin_font);
             latin_font = gtk_psfont_get_font_description(latin_psfont, fontsize);
           }
           aux = g_utf8_next_char(aux);
           break;
       case 'S': case '^':
           fontsize = (int)((gdouble)fontsize * 0.6 + 0.5);
           pango_font_description_free(font);
           font = gtk_psfont_get_font_description(psfont, fontsize);
           if(metrics) pango_font_metrics_unref(metrics);
           metrics = pango_context_get_metrics(pango_layout_get_context(layout), font, pango_context_get_language(pango_layout_get_context(layout)));
           if (psfont->i18n_latinfamily) {
             latin_font = gtk_psfont_get_font_description(latin_psfont, fontsize);
           }
           if(angle == 180)
             y = y0 + fontsize;
           else if(angle == 270)
             x = x0 + sign_y*fontsize;
           aux = g_utf8_next_char(aux);
           break;
       case 's': case '_':
           fontsize = (int)((gdouble)fontsize * 0.6 + 0.5);
           pango_font_description_free(font);
           font = gtk_psfont_get_font_description(psfont, fontsize);
           if(metrics) pango_font_metrics_unref(metrics);
           metrics = pango_context_get_metrics(pango_layout_get_context(layout), font, pango_context_get_language(pango_layout_get_context(layout)));
           if(angle == 0)
             y = y0 + fontsize;
           else if(angle == 90)
             x = x0 - sign_y*fontsize;
           if (psfont->i18n_latinfamily) {
             latin_font = gtk_psfont_get_font_description(latin_psfont, fontsize);
           }
           aux = g_utf8_next_char(aux);
           break;
       case '+':
           fontsize += 3;
           y -= sign_x*3;
           x += sign_y*3;
           pango_font_description_free(font);
           font = gtk_psfont_get_font_description(psfont, fontsize);
           if (psfont->i18n_latinfamily) {
             latin_font = gtk_psfont_get_font_description(latin_psfont, fontsize);
           }
           aux = g_utf8_next_char(aux);
           break;
       case '-':
           fontsize -= 3;
           y += sign_x*3;
           x -= sign_y*3;
           pango_font_description_free(font);
           font = gtk_psfont_get_font_description(psfont, fontsize);
           if (psfont->i18n_latinfamily) {
             latin_font = gtk_psfont_get_font_description(latin_psfont, fontsize);
           }
           aux = g_utf8_next_char(aux);
           break;
       case 'N':
	   psfont = base_psfont;
           fontsize = font_height;
           pango_font_description_free(font);
           font = gtk_psfont_get_font_description(psfont, fontsize);
           if(angle == 0 || angle == 180)
             y = y0;
           else
             x = x0;
           italic = psfont->italic;
           bold = psfont->bold;
           aux = g_utf8_next_char(aux);
           break;
       case 'b':
	   if (lastchar) {
             const gchar *aux2 = lastchar;
             gint i = g_utf8_prev_char(lastchar) != --aux2 ? 2 : 1;
             pango_layout_set_text(layout, lastchar, i);
             pango_layout_get_extents(layout, NULL, &rect);
	     x -= sign_x*PANGO_PIXELS(rect.width);
	     y -= sign_y*PANGO_PIXELS(rect.width);

	     if (lastchar == wtext)
	       lastchar = NULL;
	     else
	       lastchar = g_utf8_prev_char(lastchar);
	   } else {
             pango_layout_set_text(layout, "X", 1);
             pango_layout_get_extents(layout, NULL, &rect);
	     x -= sign_x*PANGO_PIXELS(rect.width);
	     y -= sign_y*PANGO_PIXELS(rect.width);
	   }
           aux = g_utf8_next_char(aux);
           break;
       default:
           if(aux && *aux != '\0' && *aux !='\n'){
             gint new_width = 0;
	     new_width = drawstring(pc, drawable, gc, angle, tx+x, ty+y,
			     psfont, fontsize, aux);
             x += sign_x * new_width;
             y += sign_y * new_width;
	     lastchar = aux;
	     aux = g_utf8_next_char(aux);
	   }
	   break;
     }
   } else {
     gint new_len = 0;
     gint new_width = 0;
     lastchar = aux;
     while(aux && *aux != '\0' && *aux !='\n' && *aux != '\\'){
       xaux = aux;
       new_len += g_utf8_next_char(aux) != ++xaux ? 2 : 1;
       aux = g_utf8_next_char(aux);
     }
     xaux = lastchar;
     for(i = 0; i < new_len; i++) new_text[i] = *xaux++;
     new_text[new_len] = '\0';
     new_width = drawstring(pc, drawable, gc, angle, tx+x, ty+y,
	         psfont, fontsize, new_text);
     x += sign_x * new_width;
     y += sign_y * new_width;
     lastchar = aux;
   }
  }

  pango_font_description_free(font);
  if(latin_font) pango_font_description_free(latin_font);
  if(metrics) pango_font_metrics_unref(metrics);

/* border */

  gdk_gc_set_foreground(gc, &real_fg);
  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;
}
Пример #20
0
/* subfunction of gtk_plot_gdk_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;
  }
}
Пример #21
0
static void 
gtk_plot_gdk_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;
  GdkPixmap *text_pixmap;
  GdkBitmap *text_mask;
  GdkImage *image;
  GdkGC *gc, *bitmap_gc;
  GdkColormap *colormap;
  GdkColor white, black, mask_color;
  GList *family = NULL;
  gint y0;
  gint old_width, old_height;
  gboolean bold, italic;
  gint fontsize;
  gint ascent, descent;
  gint numf;
  gint xp = 0, yp = 0;
  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];

  if(!GTK_PLOT_GDK(pc)->drawable) return;
  if(!GTK_PLOT_GDK(pc)->window) return;
  if(!GTK_PLOT_GDK(pc)->gc) return;
  if(!text || strlen(text) == 0) return;

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

  if(!gc) return;

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

  /* initializing clip mask bitmap - ajd */
  text_mask = gdk_pixmap_new(GTK_PLOT_GDK(pc)->window, width, height, 1);
  mask_color = white;
  mask_color.pixel = 0;
  gdk_gc_set_foreground(bitmap_gc, &mask_color);
  gdk_draw_rectangle(text_mask, bitmap_gc, TRUE, 0, 0, -1, -1);
  mask_color = black;
  mask_color.pixel = 1;
  gdk_gc_set_foreground(bitmap_gc, &mask_color);

  /* performing text rotation and saving it onto clip mask bitmap - ajd */
  image = gdk_image_get(text_bitmap, 0, 0, old_width, old_height);
  for(y = 0; y < old_height; y++)
      for(x = 0; x < old_width; x++)
         {
           if( black.pixel == gdk_image_get_pixel(image, x, y) ){
           switch(angle){
            case 0:
                xp = x;
                yp = y;
                break;
            case 90:
                xp = y;
                yp = old_width - x;
                break;
            case 180:
                xp = old_width - x;
                yp = old_height - y;
                break;
            case 270:
                xp = old_height - y;
                yp = x;
                break;
            }
            gdk_draw_point(text_mask, bitmap_gc, xp, yp);
           }
         }
  gdk_image_destroy(image);


  /* initializing text pixmap - ajd */
  text_pixmap = gdk_pixmap_new(GTK_PLOT_GDK(pc)->window, width, height, -1);
  gdk_gc_set_foreground(gc, (GdkColor *) bg);
  gdk_draw_rectangle(text_pixmap, gc, TRUE, 0, 0, -1, -1);
  gdk_gc_set_foreground(gc, (GdkColor *) fg);

  /* copying clip mask bitmap onto text pixmap - ajd */
  gdk_gc_set_clip_mask(gc, text_mask);
  gdk_gc_set_clip_origin(gc, 0, 0);
  gdk_draw_rectangle(text_pixmap, gc, TRUE, 0, 0, -1, -1);
  gdk_gc_set_clip_mask(gc, NULL);

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

  if(transparent){
    gdk_gc_set_clip_mask (gc, text_mask);
    gdk_gc_set_clip_origin (gc, tx, ty);
  } else {
    gdk_gc_set_foreground(gc, (GdkColor *) bg);
    gtk_plot_pc_draw_rectangle(pc,
   		         TRUE, 
                         tx - border_space, ty - border_space, 
                         width + 2*border_space, height + 2*border_space);
  }

  gdk_draw_pixmap(GTK_PLOT_GDK(pc)->drawable, gc,
                  text_pixmap, 0, 0,
                  tx, ty, -1, -1);
  gdk_gc_set_clip_mask(gc, NULL);

  gdk_pixmap_unref(text_pixmap);
  gdk_bitmap_unref(text_mask);
  gdk_font_unref(font);
  if (latin_font) gdk_font_unref(latin_font);
  gdk_gc_unref(bitmap_gc);
  gdk_pixmap_unref(text_bitmap);


/* border */

  gdk_gc_set_foreground(gc, (GdkColor *) fg);
  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;
}