Example #1
0
static void
gtk_plot_bar_draw_legend(GtkPlotData *data, gint x, gint y)
{
  GtkPlotBar *bar;
  GtkPlot *plot = NULL;
  GtkPlotText legend;
  GdkRectangle area;
  gint lascent, ldescent, lheight, lwidth;
  gdouble m;

  bar = GTK_PLOT_BAR(data);

  g_return_if_fail(data->plot != NULL);
  g_return_if_fail(GTK_IS_PLOT(data->plot));
  g_return_if_fail(GTK_WIDGET_VISIBLE(data));
  g_return_if_fail(GTK_WIDGET_VISIBLE(data->plot));

  plot = data->plot;
  area.x = GTK_WIDGET(plot)->allocation.x;
  area.y = GTK_WIDGET(plot)->allocation.y;
  area.width = GTK_WIDGET(plot)->allocation.width;
  area.height = GTK_WIDGET(plot)->allocation.height;

  m = plot->magnification;
  legend = plot->legends_attr;

  if(data->legend)
    legend.text = data->legend;
  else
    legend.text = "";

  gtk_plot_text_get_size(legend.text, legend.angle, legend.font,
                         roundint(legend.height * m),
                         &lwidth, &lheight,
                         &lascent, &ldescent);


  legend.x = (gdouble)(area.x + x + roundint((plot->legends_line_width + 4) * m))
             / (gdouble)area.width;
  legend.y = (gdouble)(area.y + y + lascent) / (gdouble)area.height;

  gtk_plot_draw_text(plot, legend);


  if(data->symbol.symbol_style == GTK_PLOT_SYMBOL_OPAQUE){
    gtk_plot_pc_set_color(plot->pc, &plot->background);
    gtk_plot_pc_draw_rectangle(plot->pc, TRUE,
                               x, y,
                               roundint(plot->legends_line_width * m),
                               lascent + ldescent);
  }

  gtk_plot_pc_set_lineattr (plot->pc, data->symbol.border.line_width, 0, 0, 0);
  gtk_plot_pc_set_dash(plot->pc, 0, 0, 0);

  if(data->symbol.symbol_style == GTK_PLOT_SYMBOL_FILLED){
    gtk_plot_pc_set_color(plot->pc, &data->symbol.color);
    gtk_plot_pc_draw_rectangle(plot->pc, TRUE,
                               x, y,
                               roundint(plot->legends_line_width * m),
                               lascent + ldescent);
  }

  gtk_plot_pc_set_color(plot->pc, &data->symbol.border.color);
  gtk_plot_pc_draw_rectangle(plot->pc, FALSE,
                             x, y,
                             roundint(plot->legends_line_width * m),
                             lascent + ldescent);

}
static void
gtk_plot_candle_draw_legend(GtkPlotData *data, gint x, gint y)
{
  GtkPlotCandle *box;
  GtkPlot *plot = NULL;
  GtkPlotText legend;
  GdkRectangle area;
  gint lascent, ldescent, lheight, lwidth;
  gdouble m;

  box = GTK_PLOT_CANDLE(data);

  g_return_if_fail(data->plot != NULL);
  g_return_if_fail(GTK_IS_PLOT(data->plot));
  if(!GTK_WIDGET_REALIZED(data->plot)) return;

  plot = data->plot;
  area.x = GTK_WIDGET(plot)->allocation.x;
  area.y = GTK_WIDGET(plot)->allocation.y;
  area.width = GTK_WIDGET(plot)->allocation.width;
  area.height = GTK_WIDGET(plot)->allocation.height;

  m = plot->magnification;
  legend = plot->legends_attr;

  if(data->legend)
    legend.text = data->legend;
  else
    legend.text = "";

  gtk_plot_text_get_size(legend.text, legend.angle, legend.font,
                         roundint(legend.height * m), 
                         &lwidth, &lheight,
                         &lascent, &ldescent);


  legend.x = (gdouble)(area.x + x + roundint((plot->legends_line_width + 4) * m))
             / (gdouble)area.width;
  legend.y = (gdouble)(area.y + y + lascent) / (gdouble)area.height;

  gtk_plot_draw_text(plot, legend);

  gtk_plot_pc_set_lineattr (plot->pc, data->symbol.border.line_width, 0, 0, 0);
  gtk_plot_pc_set_dash (plot->pc, 0, 0, 0);

  gtk_plot_pc_set_color(plot->pc, &data->symbol.color);

  if(data->symbol.symbol_style == GTK_PLOT_SYMBOL_EMPTY){
    gtk_plot_pc_draw_line(plot->pc, 
                          x,  
                          y + (lascent + ldescent) / 2,
                          x + roundint(plot->legends_line_width * m), 
                          y + (lascent + ldescent) / 2); 
  } else {
    gtk_plot_pc_draw_rectangle(plot->pc, TRUE, 
                               x, y,
                               roundint(plot->legends_line_width * m), 
                               lascent + ldescent);
    gtk_plot_pc_set_color(plot->pc, &data->symbol.border.color);
    gtk_plot_pc_draw_rectangle(plot->pc, FALSE, 
                               x, y,
                               roundint(plot->legends_line_width * m), 
                               lascent + ldescent);

  }

}
Example #3
0
static void
gtk_plot_bar_draw_symbol(GtkPlotData *dataset,
                         gdouble x, gdouble y, gdouble z, gdouble a,
                         gdouble dx, gdouble dy, gdouble dz, gdouble da)
{
  GtkPlot *plot;
  GtkPlotBar *bar;
  GdkRectangle area, clip_area;
  gdouble px, py, px0, py0;
  gdouble x1 = 0.0, y1 = 0.0, width = 0.0, height = 0.0;
  gdouble ex, ey;

  bar = GTK_PLOT_BAR(dataset);
  plot = dataset->plot;

  area.x = GTK_WIDGET(plot)->allocation.x;
  area.y = GTK_WIDGET(plot)->allocation.y;
  area.width = GTK_WIDGET(plot)->allocation.width;
  area.height = GTK_WIDGET(plot)->allocation.height;

  clip_area.x = area.x + roundint(plot->x * area.width);
  clip_area.y = area.y + roundint(plot->y * area.height);
  clip_area.width = roundint(plot->width * area.width);
  clip_area.height = roundint(plot->height * area.height);

  gtk_plot_pc_clip(plot->pc, &clip_area);

  if(GTK_IS_PLOT3D(plot)){
  } else {
    switch(bar->orientation){
      case GTK_ORIENTATION_VERTICAL:
        gtk_plot_get_pixel(plot, x-bar->width, y, &px, &py);
        gtk_plot_get_pixel(plot, x+bar->width, MAX(0., plot->ymin), &px0, &py0);
        if(dataset->show_yerrbars)
          gtk_plot_get_pixel(plot, x, y + dy, &ex, &ey);
        break;
      case GTK_ORIENTATION_HORIZONTAL:
        gtk_plot_get_pixel(plot, y, x+bar->width, &px, &py);
        gtk_plot_get_pixel(plot, MAX(0., plot->xmin), x-bar->width, &px0, &py0);
        if(dataset->show_xerrbars)
          gtk_plot_get_pixel(plot, y + dy, x, &ex, &ey);
        break;
    }
    x1 = MIN(px, px0);
    y1 = MIN(py, py0);
    if(GTK_IS_PLOT_PS(plot->pc)){
      width = fabs(px - px0);
      height = fabs(py0 - py);
    }
    else
    {
      width = abs(roundint(px - px0));
      height = abs(roundint(py0 - py));
    }

    if(dataset->symbol.symbol_style == GTK_PLOT_SYMBOL_OPAQUE){
      gtk_plot_pc_set_color(plot->pc, &plot->background);
      gtk_plot_pc_draw_rectangle (plot->pc,
                                  TRUE,
                                  x1, y1, width, height);
    }

    gtk_plot_pc_set_lineattr (plot->pc, dataset->symbol.border.line_width,
                              0, 0, 0);
    gtk_plot_pc_set_dash (plot->pc, 0, 0, 0);

    if(dataset->symbol.symbol_style == GTK_PLOT_SYMBOL_FILLED){
      gtk_plot_pc_set_color(plot->pc, &dataset->symbol.color);
      gtk_plot_pc_draw_rectangle (plot->pc,
                                  TRUE,
                                  x1, y1, width, height);
    }

    gtk_plot_pc_set_color(plot->pc, &dataset->symbol.border.color);
    gtk_plot_pc_draw_rectangle (plot->pc,
                                FALSE,
                                x1, y1, width, height);

    if(dataset->show_yerrbars){
      gtk_plot_pc_draw_line(plot->pc, ex, py, ex, ey);
      gtk_plot_pc_draw_line(plot->pc, px, ey, px0, ey);
    }
    if(dataset->show_xerrbars){
      gtk_plot_pc_draw_line(plot->pc, px, ey, ex, ey);
      gtk_plot_pc_draw_line(plot->pc, ex, py, ex, py0);
    }
  }

  gtk_plot_pc_clip(plot->pc, NULL);
}
Example #4
0
static void
gtk_plot_polar_draw_circle(GtkPlotPolar *polar)
{
  GtkWidget *widget;
  GtkPlot *plot;
  GtkPlotAxis *axis, perp;
  GtkPlotText tick;
  gchar label[100];
  gdouble x, y;
  gint line_width;
  gdouble xp, yp, width, height, size;
  gint ntick;
  gdouble m;
  gdouble x_tick = 0.;
  gdouble x1, y1;
  gdouble ox, oy;
  gint text_height, text_width, ascent, descent;
  gdouble rotation;
  gboolean veto = FALSE;
  gint sign = 1;
  GtkAllocation allocation;

  widget = GTK_WIDGET(polar);
  plot = GTK_PLOT(polar);

  m = plot->magnification;
  rotation = polar->rotation;
  if(plot->reflect_y) sign = -1;

  xp = plot->internal_allocation.x;
  yp = plot->internal_allocation.y;
  width = plot->internal_allocation.width;
  height = plot->internal_allocation.height;

  ox = width / 2.;
  oy = height / 2.;

  x = xp + ox;
  y = yp + oy;

  axis = plot->bottom;

  line_width = axis->line.line_width;
  gtk_plot_pc_set_color(plot->pc, &axis->line.color);

  gtk_plot_pc_set_lineattr(plot->pc, axis->line.line_width, 0, 3, 0);

  gtk_plot_get_pixel(plot,
                     plot->ymax,
                     90.0 - rotation,
                     &x1, &size);
  size = fabs(size - y);
  gtk_plot_pc_draw_circle (plot->pc,
                          FALSE,
                          x, y,
                          2 * size);

  gtk_plot_pc_set_lineattr(plot->pc, axis->ticks_width, 0, 1, 0);

  gtk_plot_text_get_size("0", 0, axis->labels_attr.font, roundint(axis->labels_attr.height * m), &text_width, &text_height, &ascent, &descent);

  for(ntick = 0; ntick < axis->ticks.nticks; ntick++){
    x_tick = axis->ticks.values[ntick].value;
    if(!axis->ticks.values[ntick].minor && x_tick >= axis->ticks.min){

      if(!axis->custom_labels){
        gtk_plot_axis_parse_label(axis, x_tick, axis->label_precision, axis->label_style, label);
      }
      else
      {
        g_signal_emit_by_name(GTK_OBJECT(axis), "tick_label", 
                                &x_tick, label, &veto);
        if(!veto)
          gtk_plot_axis_parse_label(axis, x_tick, axis->label_precision, axis->label_style, label);
      }

      gtk_plot_get_pixel(plot,
                         plot->ymax,
                         x_tick,
                         &x1, &y1);

      x_tick += rotation;

      if(axis->major_mask & GTK_PLOT_TICKS_IN){
         perp.direction.x = cos(x_tick * PI / 180. * sign);
         perp.direction.y = -sin(x_tick * PI / 180. * sign);
         gtk_plot_pc_draw_line(plot->pc,
                       x1,
                       y1,
                       x1 + perp.direction.x*m*axis->ticks_length,
                       y1 + perp.direction.y*m*axis->ticks_length);
      }
      if(axis->major_mask & GTK_PLOT_TICKS_OUT){
         perp.direction.x = -cos(x_tick * PI / 180. * sign);
         perp.direction.y = sin(x_tick * PI / 180. * sign);
         gtk_plot_pc_draw_line(plot->pc,
                       x1,
                       y1,
                       x1 - perp.direction.x*m*axis->ticks_length,
                       y1 - perp.direction.y*m*axis->ticks_length);
      }

      tick = axis->labels_attr;
      tick.text = label;

      if((x_tick >= 0.0 && x_tick < 90.0) || (x_tick > 270.0 && x_tick <= 360.0)) 
                                  tick.justification = GTK_JUSTIFY_LEFT;
      if(x_tick > 90.0 && x_tick < 270.0) 
                                  tick.justification = GTK_JUSTIFY_RIGHT;
      if(x_tick == 90.0 || x_tick == 270.0) 
                                  tick.justification = GTK_JUSTIFY_CENTER;
      y1 += text_height / 2;

      if((x_tick - rotation) != 360.0 && axis->label_mask != 0){
         gtk_widget_get_allocation (widget, &allocation);
         perp.direction.x = -cos(x_tick * PI / 180. * sign);
         perp.direction.y = sin(x_tick * PI / 180. * sign);
         tick.x = x1;
         tick.y = y1;
         tick.x -= roundint(perp.direction.x*axis->labels_offset * m);
         tick.y -= roundint(perp.direction.y*axis->labels_offset * m);
         tick.x = (gdouble)tick.x / (gdouble)allocation.width;
         tick.y = (gdouble)tick.y / (gdouble)allocation.height;
         gtk_plot_draw_text(plot, tick);
      }

    }
    if(axis->ticks.values[ntick].minor && x_tick >= axis->ticks.min){

      gtk_plot_get_pixel(plot,
                         plot->ymax,
                         x_tick,
                         &x1, &y1);

      x_tick += rotation;

      if(axis->minor_mask & GTK_PLOT_TICKS_IN){
         perp.direction.x = cos(x_tick * PI / 180. * sign);
         perp.direction.y = -sin(x_tick * PI / 180. * sign);
         gtk_plot_pc_draw_line(plot->pc,
                       x1,
                       y1,
                       x1 + perp.direction.x*m*axis->ticks_length/2.,
                       y1 + perp.direction.y*m*axis->ticks_length/2.);
      }
      if(axis->minor_mask & GTK_PLOT_TICKS_OUT){
         perp.direction.x = -cos(x_tick * PI / 180. * sign);
         perp.direction.y = sin(x_tick * PI / 180. * sign);
         gtk_plot_pc_draw_line(plot->pc,
                       x1,
                       y1,
                       x1 - perp.direction.x*m*axis->ticks_length/2.,
                       y1 - perp.direction.y*m*axis->ticks_length/2.);
      }
    }
  }    
}
static void
gtk_plot_candle_draw_symbol(GtkPlotData *dataset,
                         gdouble x, gdouble y, gdouble z, gdouble a,
                         gdouble dx, gdouble dy, gdouble dz, gdouble da)
{
  GtkPlot *plot;
  GtkPlotCandle *box = NULL;
  gdouble px, py, pz, ex, ey, ez;
  gdouble x1 = 0.0, y1 = 0.0, width = 0.0, height = 0.0;
  gdouble m;
  gboolean filled;
  gdouble a_scale;


  g_return_if_fail(GTK_IS_PLOT_CANDLE(dataset));

  box = GTK_PLOT_CANDLE(dataset);

  g_return_if_fail(dataset->plot != NULL);

  plot = dataset->plot;

  a_scale = gtk_plot_data_get_a_scale(dataset);
  m = plot->magnification * a_scale;

  gtk_plot_pc_set_lineattr (plot->pc, dataset->symbol.border.line_width, 
                            0, 0, 0);
  gtk_plot_pc_set_dash (plot->pc, 0, 0, 0); 

  if(x >= plot->xmin && x <= plot->xmax){
    if(GTK_IS_PLOT3D(plot)){
    }else if(dataset->show_zerrbars){
       gtk_plot_pc_set_color(plot->pc, &dataset->symbol.border.color);
       gtk_plot_get_pixel(plot, x, y, &px, &py);
       gtk_plot_get_pixel(plot, x, z, &px, &pz);
       width = m * dataset->symbol.size / 2;
       x1 = px - width;
       y1 = MIN(py, pz);
       filled = z < y;
       height = abs(py - pz);

       gtk_plot_get_pixel(plot, x, dy, &ex, &ey);
       gtk_plot_get_pixel(plot, x, dz, &ex, &ez);

       gtk_plot_pc_draw_line(plot->pc, px, py, px, ey);
       gtk_plot_pc_draw_line(plot->pc, px, pz, px, ez);

       if(!filled && dataset->symbol.symbol_style != GTK_PLOT_SYMBOL_EMPTY){
         gtk_plot_pc_set_color(plot->pc, &plot->background);
         gtk_plot_pc_draw_rectangle (plot->pc,
                                     TRUE,
                                     x1, y1, width * 2, height);
       }


       if(dataset->symbol.symbol_style == GTK_PLOT_SYMBOL_EMPTY){
         GtkPlotPoint lines[4];
         gtk_plot_pc_set_color(plot->pc, &dataset->symbol.color);
         lines[0].x = px - width;
         lines[0].y = py;
         lines[1].x = px;
         lines[1].y = py;
         lines[2].x = px;
         lines[2].y = pz;
         lines[3].x = px + width;
         lines[3].y = pz;
         gtk_plot_pc_draw_lines(plot->pc, lines, 4);
       } else {
         if(filled){
           gtk_plot_pc_set_color(plot->pc, &dataset->symbol.color);
           gtk_plot_pc_draw_rectangle (plot->pc,
                                       TRUE,
                                       x1, y1, width * 2, height);
         }
         gtk_plot_pc_set_color(plot->pc, &dataset->symbol.border.color);
         gtk_plot_pc_draw_rectangle (plot->pc,
                                     FALSE,
                                     x1, y1, width * 2, height);
       }

    }  
  }

}
Example #6
0
static void
gtk_plot_polar_draw_axis(GtkPlotPolar *polar, 
                         GtkPlotAxis *axis, GtkPlotVector tick_direction)
{
  GtkWidget *widget;
  GtkPlot *plot;
  gdouble x, y;
  gdouble xx, yy;
  gdouble x_tick;
  gdouble xp, yp, width, height, size;
  gint ntick;
  gdouble m;
  gdouble x1, y1;
  gdouble ox, oy;
  gdouble x0, y0;

  widget = GTK_WIDGET(polar);
  plot = GTK_PLOT(polar);

  m = plot->magnification;

  xp = plot->internal_allocation.x;
  yp = plot->internal_allocation.y;
  width = plot->internal_allocation.width;
  height = plot->internal_allocation.height;

  size = MIN(width, height);

  ox = width / 2.;
  oy = height / 2.;

  x = xp + ox * axis->direction.x + axis->origin.x;
  y = yp + oy * axis->direction.y + axis->origin.y;

  if(axis->direction.x == 0)
    gtk_plot_get_pixel(plot, 0, -polar->rotation+90, &x0, &y0);
  else
    gtk_plot_get_pixel(plot, 0, -polar->rotation, &y0, &x0);

  gtk_plot_draw_line(plot, axis->line, 
                x - size / 2.0 * axis->direction.x,
                y - size / 2.0 * axis->direction.y,
                x + axis->direction.x * size / 2.0,
                y + axis->direction.y * size / 2.0);
  gtk_plot_pc_set_lineattr(plot->pc, axis->ticks_width, 0, 1, 0);

  for(ntick = 0; ntick < axis->ticks.nticks; ntick++){
    x_tick = axis->ticks.values[ntick].value;
    if(axis->direction.x == 0)
      gtk_plot_get_pixel(plot, x_tick, -polar->rotation+90, &xx, &yy);
    else
      gtk_plot_get_pixel(plot, x_tick, -polar->rotation, &yy, &xx);

    yy = yy - y0;
    if(!axis->ticks.values[ntick].minor && x_tick >= axis->ticks.min){
      if(axis->major_mask & GTK_PLOT_TICKS_IN){
         x1 = x + yy * axis->direction.x;
         y1 = y + yy * axis->direction.y;
         gtk_plot_pc_draw_line(plot->pc,
                       x1,
                       y1,
                       x1 + tick_direction.x * m * axis->ticks_length,
                       y1 + tick_direction.y * m * axis->ticks_length);
         x1 = x - yy * axis->direction.x;
         y1 = y - yy * axis->direction.y;
         gtk_plot_pc_draw_line(plot->pc,
                       x1,
                       y1,
                       x1 + tick_direction.x * m * axis->ticks_length,
                       y1 + tick_direction.y * m * axis->ticks_length);
      }
      if(axis->major_mask & GTK_PLOT_TICKS_OUT){
         x1 = x + yy * axis->direction.x;
         y1 = y + yy * axis->direction.y;
         gtk_plot_pc_draw_line(plot->pc,
                       x1,
                       y1,
                       x1 - tick_direction.x * m * axis->ticks_length,
                       y1 - tick_direction.y * m * axis->ticks_length);
         x1 = x - yy * axis->direction.x;
         y1 = y - yy * axis->direction.y;
         gtk_plot_pc_draw_line(plot->pc,
                       x1,
                       y1,
                       x1 - tick_direction.x * m * axis->ticks_length,
                       y1 - tick_direction.y * m * axis->ticks_length);
      }
    }
    if(axis->ticks.values[ntick].minor && x_tick >= axis->ticks.min){
      if(axis->minor_mask & GTK_PLOT_TICKS_IN){
         x1 = x + yy * axis->direction.x;
         y1 = y + yy * axis->direction.y;
         gtk_plot_pc_draw_line(plot->pc,
                       x1,
                       y1,
                       x1 + tick_direction.x * m * axis->ticks_length/2.,
                       y1 + tick_direction.y * m * axis->ticks_length/2.);
         x1 = x - yy * axis->direction.x;
         y1 = y - yy * axis->direction.y;
         gtk_plot_pc_draw_line(plot->pc,
                       x1,
                       y1,
                       x1 + tick_direction.x * m * axis->ticks_length/2.,
                       y1 + tick_direction.y * m * axis->ticks_length/2.);
      }
      if(axis->minor_mask & GTK_PLOT_TICKS_OUT){
         x1 = x + yy * axis->direction.x;
         y1 = y + yy * axis->direction.y;
         gtk_plot_pc_draw_line(plot->pc,
                       x1,
                       y1,
                       x1 - tick_direction.x * m * axis->ticks_length/2.,
                       y1 - tick_direction.y * m * axis->ticks_length/2.);
         x1 = x - yy * axis->direction.x;
         y1 = y - yy * axis->direction.y;
         gtk_plot_pc_draw_line(plot->pc,
                       x1,
                       y1,
                       x1 - tick_direction.x * m * axis->ticks_length/2.,
                       y1 - tick_direction.y * m * axis->ticks_length/2.);
      }
    }
  }    

}
Example #7
0
static void 
gtk_plot_cairo_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)
{
  cairo_t *cairo = GTK_PLOT_CAIRO(pc)->cairo;
  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; /* Support Tiny C compiler : Original : gchar new_text[strlen(text)+1];*/
  gchar num[4];
  PangoRectangle rect;
  PangoLayout *layout = NULL;
  gint real_x, real_y, real_width, real_height;
  GdkColor real_fg = *fg;
  GdkColor real_bg = *bg;
  gint sign_x = 1, sign_y = 0;
  gint old_tx = tx, old_ty = ty;

  if (!cairo)
    return;

  layout = GTK_PLOT_CAIRO(pc)->layout;
  cairo_save(cairo);
  gtk_plot_cairo_set_color(pc, fg);
/*
  font_name = "sans";
  desc = pango_font_description_from_string(font_name);

  // Since the name does not contain the size yet... Also there is some
  // factor that I have to figure out...
  pango_font_description_set_size (desc, font_height *0.9 * PANGO_SCALE);

  pango_layout_set_font_description(layout, desc);
  pango_layout_set_text(layout, text, -1);
  cairo_save(cairo);
  cairo_translate(cairo, tx, ty);
  cairo_rotate(cairo, angle * G_PI / 180);
  gtk_plot_cairo_set_color(pc, fg);
  pango_cairo_update_layout(cairo, layout);
  PangoFontMetrics *metrics = NULL;

  metrics = pango_context_get_metrics(pango_layout_get_context(layout), desc, gtk_get_default_language());

  pango_layout_get_size (layout, &width, &height);

  ascent = pango_font_metrics_get_ascent(metrics);
  descent = pango_font_metrics_get_descent(metrics);

  if (just == GTK_JUSTIFY_RIGHT) 
    cairo_move_to(cairo, -PANGO_PIXELS(width),
                  -PANGO_PIXELS(ascent)
                  );
  else if (just == GTK_JUSTIFY_CENTER) 
    cairo_move_to(cairo, -PANGO_PIXELS(width)/2.0,
                  -PANGO_PIXELS(ascent)
                  );
  else if (just == GTK_JUSTIFY_LEFT)
    cairo_move_to(cairo, 0,
                  -PANGO_PIXELS(ascent)
                  );
  
  pango_cairo_show_layout(cairo, layout);
  cairo_restore(cairo);
*/


  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;
      }
      old_tx = tx;
      old_ty = ty;
      break;
    case GTK_JUSTIFY_RIGHT:
      switch(angle){
        case 0:
            tx -= width;
            ty -= ascent;
            old_tx -= width;
            old_ty -= ascent;
            break;
        case 90:
            tx -= ascent;
            ty += height;
            old_tx -= ascent;
            break;
        case 180:
            tx += width;
            ty -= descent;
            old_ty -= descent;
            break;
        case 270:
            tx -= descent;
            old_tx -= descent;
            old_ty -= height;
            break;
      }
      break;
    case GTK_JUSTIFY_CENTER:
    default:
      switch(angle){
        case 0:
            tx -= width / 2.;
            ty -= ascent;
            old_tx -= width / 2.;
            old_ty -= ascent;
            break;
        case 90:
            tx -= ascent;
            ty += height / 2.;
            old_tx -= ascent;
            old_ty -= height / 2.;
            break;
        case 180:
            tx += width / 2.;
            ty -= descent;
            old_tx -= width / 2.;
            old_ty -= descent;
            break;
        case 270:
            tx -= descent;
            ty -= height / 2.;
            old_tx -= descent;
            old_ty -= height / 2.;
            break;
      }
  }

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

  if(!transparent){
    gtk_plot_cairo_set_color(pc, &real_bg);
    gtk_plot_cairo_draw_rectangle(pc, TRUE, old_tx, old_ty, old_width, old_height);
  }
  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;
  }

  gtk_plot_cairo_set_color(pc, &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 (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(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, 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;

     new_text = (gchar *) g_new0(gchar , strlen(text)+1); /* Tiny C Compiler support */
     for(i = 0; i < new_len; i++) new_text[i] = *xaux++;
     new_text[new_len] = '\0';
     new_width = drawstring(pc, angle, tx+x, ty+y,
                 psfont, fontsize, new_text);
     x += sign_x * new_width;
     y += sign_y * new_width;
     lastchar = aux;

     g_free (new_text);
   }
  }

  if(latin_font) pango_font_description_free(latin_font);

/* border */

  gtk_plot_cairo_set_color(pc, &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,
                         old_tx - border_space + shadow_width,
                         old_ty + height + border_space,
                         width + 2 * border_space, shadow_width);
      gtk_plot_pc_draw_rectangle(pc,
                         TRUE,
                         old_tx + width + border_space,
                         old_ty - border_space + shadow_width,
                         shadow_width, height + 2 * border_space);
    case GTK_PLOT_BORDER_LINE:
      gtk_plot_pc_draw_rectangle(pc,
                         FALSE,
                         old_tx - border_space, old_ty - border_space,
                         width + 2*border_space, height + 2*border_space);
    case GTK_PLOT_BORDER_NONE:
    default:
        break;
  }

  cairo_restore(cairo);
  return;
}
Example #8
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;
}
Example #9
0
static void
gtk_plot_flux_draw_arrow(GtkPlotFlux *flux, gdouble x1, gdouble y1, gdouble x2, gdouble y2)
{
  GtkPlot *plot;
  GtkPlotData *data;
  GtkPlotPoint arrow[3];
  gdouble xm, ym;
  gdouble width, height;
  gdouble arrow_width;
  gdouble line_width;
  gdouble angle;
  gdouble length;
  gdouble m;

  data = GTK_PLOT_DATA(flux);
  plot = data->plot;

  m = plot->magnification;

  width = fabs(x2 - x1);
  height = fabs(y2 - y1);

  /* This is a nan */
  if (width != width || height != height) return;

  if(width == 0 && height == 0) return;
  if(width != 0)
      angle = atan2((y2 - y1), (x2 - x1));
  else
      angle = asin((y2 - y1)/height);

  length = (y2 - y1)*(y2 - y1) + (x2 - x1)*(x2 - x1);
  if (length > 0.0) length = sqrt(length);

  arrow_width = flux->arrow_width;
  line_width = data->symbol.border.line_width;
  gtk_plot_pc_set_color(plot->pc, &data->symbol.color);
  gtk_plot_pc_set_lineattr (plot->pc, line_width, 0, 0, 0);
  gtk_plot_pc_set_dash (plot->pc, 0, 0, 0);

  if(flux->centered && width != 0){
    x1 -= cos(angle) * length / 2.0;
    x2 -= cos(angle) * length / 2.0;
  }
  if(flux->centered && height != 0){
    y1 -= sin(angle) * length / 2.0;
    y2 -= sin(angle) * length / 2.0;
  }


  if(flux->arrow_style == GTK_PLOT_SYMBOL_EMPTY)
    gtk_plot_pc_draw_line(plot->pc, x1, y1, x2, y2); 
  else
    gtk_plot_pc_draw_line(plot->pc, x1, y1, 
                          x2 - flux->arrow_length * m * cos(angle) / 2., 
                          y2 - flux->arrow_length * m * sin(angle) / 2.);

  arrow[1].x = x2;
  arrow[1].y = y2;
  xm = x2 - cos(angle) * flux->arrow_length * m;
  ym = y2 - sin(angle) * flux->arrow_length * m;
  arrow[0].x = xm - sin(angle)* arrow_width * m / 2.0;
  arrow[0].y = ym + cos(angle)* arrow_width * m / 2.0;
  arrow[2].x = xm + sin(angle)* arrow_width * m / 2.0;
  arrow[2].y = ym - cos(angle)* arrow_width * m / 2.0;

  switch(flux->arrow_style){
    case GTK_PLOT_SYMBOL_EMPTY:
      gtk_plot_pc_draw_lines (plot->pc, arrow, 3);
      break;
    case GTK_PLOT_SYMBOL_OPAQUE:
      gtk_plot_pc_set_color(plot->pc, &plot->background);
      gtk_plot_pc_draw_polygon (plot->pc, TRUE, arrow, 3);
      gtk_plot_pc_set_color(plot->pc, &data->symbol.color);
      gtk_plot_pc_draw_polygon (plot->pc, FALSE, arrow, 3);
      break;
    case GTK_PLOT_SYMBOL_FILLED:
      gtk_plot_pc_draw_polygon (plot->pc, TRUE, arrow, 3);
  }
}
Example #10
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;
}