Ejemplo n.º 1
0
CAMLprim value
ml_cairo_pop_group (value cr)
{
  cairo_pattern_t *p = cairo_pop_group (cairo_t_val (cr));
  check_cairo_status (cr);
  return Val_cairo_pattern_t (p);
}
Ejemplo n.º 2
0
static void
redraw_pixmap (Monitor *m)
{
    int i;
    cairo_t *cr = cairo_create(m->pixmap);
    cairo_set_line_width (cr, 1.0);

    /* Erase pixmap */
    gdk_cairo_set_source_color(cr, &m->da->style->black);
    cairo_paint(cr);

    gdk_cairo_set_source_color(cr, &m->foreground_color);
    for (i = 0; i < m->pixmap_width; i++)
    {
        unsigned int drawing_cursor = (m->ring_cursor + i) % m->pixmap_width;

        /* Draw one bar of the graph */
        cairo_move_to(cr, i + 0.5, m->pixmap_height);
        cairo_line_to(cr, i + 0.5, (1.0 - m->stats[drawing_cursor]) * m->pixmap_height);
        cairo_stroke(cr);
    }

    check_cairo_status(cr);
    cairo_destroy(cr);
    /* Redraw pixmap */
    gtk_widget_queue_draw(m->da);
}
Ejemplo n.º 3
0
void paint_message(cairo_t *cr, const char *from, const char *content)
{
  static char from_buffer[256];
  if (strlen(from) > 0)
    snprintf(from_buffer, sizeof(from_buffer), "[%s]", from);
  else
    strncpy(from_buffer, "", sizeof(from_buffer));
  cairo_save(cr);
  
  //清空背景
  cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.0);
  cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
  cairo_paint (cr);

  //设置字体
  cairo_select_font_face (cr, font_name, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
  cairo_set_font_size (cr, font_size);

  //计算文字位置
  cairo_text_extents_t extents_from, extents_content;
  cairo_text_extents(cr, from_buffer, &extents_from);
  cairo_text_extents(cr, content, &extents_content);
  int x = (window_width - extents_from.width - extents_content.width) / 2;
  if (x < 0)
    x = 0;
  int y = window_height - 10;

  //实现昵称和消息内容
  paint_text(cr, from_buffer, x, y, 1, 2, font_color, border_color, shadow_color);
  paint_text(cr, content, x + extents_from.width + font_size / 2, y, 1, 2, font_color, border_color, shadow_color);

  cairo_restore (cr);
  check_cairo_status();
}
Ejemplo n.º 4
0
void paint_text(cairo_t *cr, const char *text, int x, int y, int border, int shadow,
  const float font_color[3], const float border_color[3], const float shadow_color[3])
{
  cairo_save(cr);

  if (shadow > 0)
    paint_text(cr, text, x + shadow, y + shadow, border, 0, shadow_color, shadow_color, shadow_color);
  if (border > 0) {
    cairo_set_source_rgb (cr, border_color[0], border_color[1], border_color[2]);
    int dx, dy;
    for (dx = -border; dx <= border; dx ++) {
      for (dy = -border; dy <= border; dy ++) {
        cairo_move_to (cr, x + dx, y + dy);
        cairo_show_text(cr, text);
      }
    }
  }

  cairo_set_source_rgb (cr, font_color[0], font_color[1], font_color[2]);
  cairo_move_to (cr, x, y);
  cairo_show_text(cr, text);

  cairo_restore (cr);
  check_cairo_status();
}
Ejemplo n.º 5
0
/* Handler for expose_event on drawing area. */
static gboolean desk_expose_event(GtkWidget * widget, GdkEventExpose * event, PagerDesk * d)
{
    GtkStyle * style = gtk_widget_get_style(widget);

    if (d->pixmap != NULL)
    {
        cairo_t *cr = gdk_cairo_create(gtk_widget_get_window(widget));
        gdk_cairo_region(cr, event->region);
        cairo_clip(cr);
        /* Recompute the pixmap if needed. */
        if (d->dirty)
        {
            d->dirty = FALSE;
            PagerPlugin * pg = d->pg;

            /* Erase the pixmap. */
            if (d->pixmap != NULL)
            {
                //GtkWidget * widget = GTK_WIDGET(d->da);
                cairo_t *cr0 = cairo_create(d->pixmap);
                gdk_cairo_set_source_color(cr0,
                    ((d->desktop_number == d->pg->current_desktop)
                        ? &style->dark[GTK_STATE_SELECTED]
                        : &style->dark[GTK_STATE_NORMAL]));
                cairo_paint(cr0);
		check_cairo_status(cr0);
                cairo_destroy(cr0);
            }

            /* Draw tasks onto the pixmap. */
            int j;
            for (j = 0; j < pg->client_count; j++)
                task_update_pixmap(pg->tasks_in_stacking_order[j], d);
        }

        /* Draw the requested part of the pixmap onto the drawing area. */
        GtkAllocation allocation;
        gtk_widget_get_allocation(GTK_WIDGET(widget), &allocation);
        gdk_cairo_set_source_color(cr,
             &style->fg[GTK_WIDGET_STATE(widget)]);
        cairo_set_source_surface(cr, d->pixmap, 0, 0);
        cairo_paint(cr);
	check_cairo_status(cr);
        cairo_destroy(cr);
    }
    return FALSE;
}
Ejemplo n.º 6
0
CAMLprim value
ml_cairo_font_extents (value cr)
{
  cairo_font_extents_t e;
  cairo_font_extents (cairo_t_val (cr), &e);
  check_cairo_status (cr);
  return Val_cairo_font_extents (&e);
}
Ejemplo n.º 7
0
CAMLprim value
ml_cairo_text_extents (value v_cr, value v_utf8)
{
  cairo_text_extents_t c_extents;
  cairo_text_extents (cairo_t_val (v_cr), String_val (v_utf8), &c_extents);
  check_cairo_status (v_cr);
  return Val_cairo_text_extents (&c_extents);
}
Ejemplo n.º 8
0
CAMLprim value
ml_cairo_in_fill (value v_cr, value p)
{
  cairo_bool_t c_ret;
  c_ret =
    cairo_in_fill (cairo_t_val (v_cr), Double_field (p, 0), Double_field (p, 1));
  check_cairo_status (v_cr);
  return Val_bool (c_ret);
}
Ejemplo n.º 9
0
void copy_surface_to_pixmap(cairo_surface_t *sf, GdkPixmap *pixmap)
{
  cairo_t *cr = gdk_cairo_create (pixmap);
  cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
  cairo_set_source_surface (cr, sf, 0, 0);
  cairo_paint (cr);
  check_cairo_status();
  cairo_destroy (cr);
}
Ejemplo n.º 10
0
CAMLprim value
ml_cairo_device_to_user_distance (value cr, value p)
{
  double x, y;
  x = Double_field (p, 0);
  y = Double_field (p, 1);
  cairo_device_to_user_distance (cairo_t_val (cr), &x, &y);
  check_cairo_status (cr);
  return ml_cairo_point (x, y);
}
Ejemplo n.º 11
0
CAMLprim value
ml_cairo_glyph_path (value v_cr, value v_glyphs)
{
  int num_glyphs;
  cairo_glyph_t *c_glyphs;
  c_glyphs = ml_convert_cairo_glypth_in (v_glyphs, &num_glyphs);
  cairo_glyph_path (cairo_t_val (v_cr), c_glyphs, num_glyphs);
  caml_stat_free (c_glyphs);
  check_cairo_status (v_cr);
  return Val_unit;
}
Ejemplo n.º 12
0
CAMLprim value
ml_cairo_glyph_extents (value v_cr, value v_glyphs)
{
  int num_glyphs;
  cairo_glyph_t *c_glyphs;
  cairo_text_extents_t c_extents;
  c_glyphs = ml_convert_cairo_glypth_in (v_glyphs, &num_glyphs);
  cairo_glyph_extents (cairo_t_val (v_cr), c_glyphs, num_glyphs, &c_extents);
  caml_stat_free (c_glyphs);
  check_cairo_status (v_cr);
  return Val_cairo_text_extents (&c_extents);
}
Ejemplo n.º 13
0
CAMLprim value
ml_cairo_set_font_matrix (value v_cr, value v_matrix)
{
#ifndef ARCH_ALIGN_DOUBLE
  cairo_set_font_matrix (cairo_t_val (v_cr), cairo_matrix_t_val (v_matrix));
#else
  cairo_matrix_t mat;
  ml_convert_cairo_matrix_in (v_matrix, &mat);
  cairo_set_font_matrix (cairo_t_val (v_cr), &mat);
#endif
  check_cairo_status (v_cr);
  return Val_unit;
}
Ejemplo n.º 14
0
CAMLprim value
ml_cairo_get_font_matrix (value v_cr)
{
#ifndef ARCH_ALIGN_DOUBLE
  CAMLparam1(v_cr);
  value v = cairo_matrix_alloc();
  cairo_get_font_matrix (cairo_t_val (v_cr), cairo_matrix_t_val (v));
  CAMLreturn(v);
#else
  cairo_matrix_t mat;
  cairo_get_font_matrix (cairo_t_val (v_cr), &mat);
  check_cairo_status (v_cr);
  return ml_convert_cairo_matrix_out (&mat);
#endif
}
Ejemplo n.º 15
0
CAMLprim value
ml_cairo_fill_extents (value v_cr)
{
  double x1, y1, x2, y2;
  cairo_fill_extents (cairo_t_val (v_cr), &x1, &y1, &x2, &y2);
  check_cairo_status (v_cr);
  {
    CAMLparam0 ();
    CAMLlocal1 (t);
    t = caml_alloc_tuple (4);
    Store_field (t, 0, caml_copy_double (x1));
    Store_field (t, 1, caml_copy_double (y1));
    Store_field (t, 2, caml_copy_double (x2));
    Store_field (t, 3, caml_copy_double (y2));
    CAMLreturn (t);
  }
}
Ejemplo n.º 16
0
CAMLprim value
ml_cairo_set_dash (value cr, value d, value off)
{
#ifndef ARCH_ALIGN_DOUBLE
  cairo_set_dash (cairo_t_val (cr), Double_array_val (d),
		  Double_array_length (d), Double_val (off));
#else
  int i, ndash = Double_array_length (d);
  double *dashes = caml_stat_alloc (ndash * sizeof (double));
  for (i = 0; i < ndash; i++)
    dashes[i] = Double_field (d, i);
  cairo_set_dash (cairo_t_val (cr), dashes, ndash, Double_val (off));
  caml_stat_free (dashes);
#endif
  check_cairo_status (cr);
  return Val_unit;
}
Ejemplo n.º 17
0
/* Handler for configure_event on drawing area. */
static gboolean desk_configure_event(GtkWidget * widget, GdkEventConfigure * event, PagerDesk * d)
{
    /* Allocate pixmap and statistics buffer without border pixels. */
#if GTK_CHECK_VERSION(2,18,0)
    GtkAllocation *allocation = g_new0 (GtkAllocation, 1);
    gtk_widget_get_allocation(GTK_WIDGET(widget), allocation);
    int new_pixmap_width = allocation->width;
    int new_pixmap_height = allocation->height;
#else
    int new_pixmap_width = widget->allocation.width;
    int new_pixmap_height = widget->allocation.height;
#endif
    if ((new_pixmap_width > 0) && (new_pixmap_height > 0))
    {
        /* Allocate a new pixmap of the allocated size. */
        if (d->pixmap != NULL)
            cairo_surface_destroy(d->pixmap);
        d->pixmap = cairo_image_surface_create(CAIRO_FORMAT_RGB24, new_pixmap_width, new_pixmap_height);
        cairo_t *cr = cairo_create(d->pixmap);
        cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
        cairo_paint(cr);
	check_cairo_status(cr);
        cairo_destroy(cr);
	check_cairo_surface_status(&d->pixmap);

        /* Compute the horizontal and vertical scale factors, and mark the desktop for redraw. */
#if GTK_CHECK_VERSION(2,18,0)
        d->scale_y = (gfloat) allocation->height / (gfloat) gdk_screen_height();
        d->scale_x = (gfloat) allocation->width  / (gfloat) gdk_screen_width();
#else
        d->scale_y = (gfloat) allocation->height / (gfloat) gdk_screen_height();
        d->scale_x = (gfloat) allocation->width  / (gfloat) gdk_screen_width();
#endif
        desk_set_dirty(d);
     }

    /* Resize to optimal size. */
    gtk_widget_set_size_request(widget,
        (d->pg->plugin->panel->icon_size - BORDER_WIDTH * 2) * d->pg->aspect_ratio,
        d->pg->plugin->panel->icon_size - BORDER_WIDTH * 2);
#if GTK_CHECK_VERSION(2,18,0)
    g_free (allocation);
#endif
    return FALSE;
}
Ejemplo n.º 18
0
static gboolean
expose_event(GtkWidget * widget, GdkEventExpose * event, Monitor *m) 
{
    /* Draw the requested part of the pixmap onto the drawing area.
     * Translate it in both x and y by the border size. */
    if (m->pixmap != NULL)
    {
        cairo_t *cr = gdk_cairo_create(widget->window);
        gdk_cairo_region(cr, event->region);
        cairo_clip(cr);
        gdk_cairo_set_source_color(cr, &m->da->style->black);
        cairo_set_source_surface(cr, m->pixmap, BORDER_SIZE, BORDER_SIZE);
        cairo_paint(cr);
        check_cairo_status(cr);
        cairo_destroy(cr);
    }
    
    return FALSE;
    
}
Ejemplo n.º 19
0
static int
gra2cairo_flush(struct objlist *obj, N_VALUE *inst, N_VALUE *rval, int argc, char **argv)
{
  struct gra2cairo_local *local;
  cairo_surface_t *surface;

  _getobj(obj, "_local", inst, &local);

  if (local->cairo == NULL)
    return -1;

  gra2cairo_draw_path(local);

  surface = cairo_get_target(local->cairo);
  if (surface) {
    cairo_surface_flush(surface);
  }


  return check_cairo_status(local->cairo);
}
Ejemplo n.º 20
0
/* Draw the representation of a task's window on the backing pixmap. */
static void task_update_pixmap(PagerTask * tk, PagerDesk * d)
{
    if ((d->pixmap != NULL) && (task_is_visible(tk)))
    {
        if ((tk->desktop == ALL_DESKTOPS) || (tk->desktop == d->desktop_number))
        {
            /* Scale the representation of the window to the drawing area. */
            gfloat x = (gfloat) tk->x * d->scale_x;
            gfloat y = (gfloat) tk->y * d->scale_y;
            gfloat w = (gfloat) tk->w * d->scale_x;
            gfloat h = ((tk->nws.shaded) ? 3 : (gfloat) tk->h * d->scale_y);
            if ((w >= 3) && (h >= 3))
            {
                /* Draw the window representation and a border. */
                GtkWidget * widget = GTK_WIDGET(d->da);
                GtkStyle * style = gtk_widget_get_style(widget);
                GdkColor * color;

                cairo_t * cr = cairo_create(d->pixmap);
                cairo_set_line_width (cr, 1.0);
		cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE);
                cairo_rectangle(cr, x + 0.5, y + 0.5, w - 0.5, h - 0.5);

                color =
                    (d->pg->focused_task == tk) ? &style->bg[GTK_STATE_SELECTED] : &style->bg[GTK_STATE_NORMAL];
                cairo_set_source_rgb(cr, (double)color->red/65535, (double)color->green/65535, (double)color->blue/65535);
                cairo_fill_preserve(cr);

                color =
                    (d->pg->focused_task == tk) ? &style->fg[GTK_STATE_SELECTED] : &style->fg[GTK_STATE_NORMAL];
                cairo_set_source_rgb(cr, (double)color->red/65535, (double)color->green/65535, (double)color->blue/65535);
                cairo_stroke(cr);

		check_cairo_status(cr);
                cairo_destroy(cr);
            }
        }
    }
}
Ejemplo n.º 21
0
void dump_graph_to_png_file(const AdjacencyList &adjacency_list,
                            const VertexList &vertex_list,
                            const char *png_filename)
{
    auto bbox = get_aabb(vertex_list);

    double width = bbox.maxx - bbox.minx;
    double height = bbox.maxy - bbox.miny;

    auto surface = std::shared_ptr<cairo_surface_t>(
        cairo_image_surface_create(CAIRO_FORMAT_RGB24, width, height),
        cairo_surface_destroy);
    check_cairo_surface_status(surface.get());

    auto cr = std::shared_ptr<cairo_t>(
        cairo_create(surface.get()),
        cairo_destroy);
    check_cairo_status(cr.get());

    cairo_set_line_width(cr.get(), 1.0);

    for (const auto &edge: adjacency_list) {
        auto u = vertex_list.find(std::get<0>(edge));

        if (u == vertex_list.end()) {
            std::cout << "[WARNING] reference to non-existing vertex "
                      << std::get<0>(edge) << std::endl;
            continue;
        }

        for (const auto &way: std::get<1>(edge)) {
            auto v = vertex_list.find(way.destination);

            if (v == vertex_list.end()) {
                std::cout << "[WARNING] reference to non-existing vertex "
                          << way.destination << std::endl;
                continue;
            }

            switch (way.type) {
            case 0:
                cairo_set_source_rgb(cr.get(), 1.0, 0.0, 0.0);
                break;

            case 1:
                cairo_set_source_rgb(cr.get(), 0.0, 1.0, 0.0);
                break;

            case 2:
                cairo_set_source_rgb(cr.get(), 0.0, 0.0, 1.0);
                break;

            default:
                std::cout << "[WARNING] Wrong type of arc" << std::endl;
            }

            cairo_move_to(cr.get(),
                          u->second.x - bbox.minx,
                          height - (u->second.y - bbox.miny));
            cairo_line_to(cr.get(),
                          v->second.x - bbox.minx,
                          height - (v->second.y - bbox.miny));
            cairo_stroke(cr.get());
        }
    }

    {
        auto status = cairo_surface_write_to_png(surface.get(), png_filename);
        cairo_status_to_exception(status);
    }
}
Ejemplo n.º 22
0
static int
gra2cairo_output(struct objlist *obj, N_VALUE *inst, N_VALUE *rval,
                 int argc, char **argv)
{
  char code, *cstr, *tmp;
  int *cpar, i, r, font_style;
  double x, y, w, h, fontsize,
    fontspace, fontdir, fontsin, fontcos, a1, a2;
  cairo_line_join_t join;
  cairo_line_cap_t cap;
  double *dashlist = NULL;
  struct gra2cairo_local *local;

  local = (struct gra2cairo_local *)argv[2];
  code = *(char *)(argv[3]);
  cpar = (int *)argv[4];
  cstr = argv[5];

  if (local->cairo == NULL)
    return -1;

  if (code != 'T') {
    gra2cairo_draw_path(local);
  }
  switch (code) {
  case 'I':
    gra2cairo_set_antialias(local, local->antialias);
    local->linetonum = 0;
    r = check_cairo_status(local->cairo);
    if (r) {
      error(obj, r);
      return 1;
    }
  case '%': case 'X':
    break;
  case 'E':
    r = check_cairo_status(local->cairo);
    if (r) {
      error(obj, r);
      return 1;
    }
    break;
  case 'V':
    local->offsetx = mxd2pw(local, cpar[1]);
    local->offsety = mxd2ph(local, cpar[2]);
    cairo_new_path(local->cairo);
    if (cpar[5]) {
      x = mxd2pw(local, cpar[1]);
      y = mxd2ph(local, cpar[2]);
      w = mxd2pw(local, cpar[3]) - x;
      h = mxd2ph(local, cpar[4]) - y;

      cairo_reset_clip(local->cairo);
      cairo_rectangle(local->cairo, x, y, w, h);
      cairo_clip(local->cairo);
    } else {
      cairo_reset_clip(local->cairo);
    }

    if (local->region) {
      gra2cairo_clip_region(local, local->region);
    }
    break;
  case 'A':
    if (cpar[1] == 0) {
      cairo_set_dash(local->cairo, NULL, 0, 0);
    } else {
      dashlist = g_malloc(sizeof(* dashlist) * cpar[1]);
      if (dashlist == NULL)
	break;
      for (i = 0; i < cpar[1]; i++) {
	dashlist[i] = mxd2pw(local, cpar[6 + i]);
        if (dashlist[i] <= 0) {
	  dashlist[i] = 1;
	}
      }
      cairo_set_dash(local->cairo, dashlist, cpar[1], 0);
      g_free(dashlist);
    }

    cairo_set_line_width(local->cairo, mxd2pw(local, cpar[2]));

    if (cpar[3] == 2) {
      cap = CAIRO_LINE_CAP_SQUARE;
    } else if (cpar[3] == 1) {
      cap = CAIRO_LINE_CAP_ROUND;
    } else {
      cap = CAIRO_LINE_CAP_BUTT;
    }
    cairo_set_line_cap(local->cairo, cap);

    if (cpar[4] == 2) {
      join = CAIRO_LINE_JOIN_BEVEL;
    } else if (cpar[4] == 1) {
      join = CAIRO_LINE_JOIN_ROUND;
    } else {
      join = CAIRO_LINE_JOIN_MITER;
    }
    cairo_set_line_join(local->cairo, join);
    break;
  case 'G':
    if (local->use_opacity && cpar[0] > 3 && cpar[4] < 255) {
      cairo_set_source_rgba(local->cairo,
			    cpar[1] / 255.0,
			    cpar[2] / 255.0,
			    cpar[3] / 255.0,
			    cpar[4] / 255.0);
    } else {
      cairo_set_source_rgb(local->cairo,
			   cpar[1] / 255.0,
			   cpar[2] / 255.0,
			   cpar[3] / 255.0);
    }
    break;
  case 'M':
    cairo_move_to(local->cairo, mxd2px(local, cpar[1]), mxd2py(local, cpar[2]));
    break;
  case 'N':
    relative_move(local->cairo, mxd2pw(local, cpar[1]), mxd2ph(local, cpar[2]));
    break;
  case 'L':
    cairo_new_path(local->cairo);
    cairo_move_to(local->cairo, mxd2px(local, cpar[1]), mxd2py(local, cpar[2]));
    cairo_line_to(local->cairo, mxd2px(local, cpar[3]), mxd2py(local, cpar[4]));
    cairo_stroke(local->cairo);
    break;
  case 'T':
    cairo_line_to(local->cairo, mxd2px(local, cpar[1]), mxd2py(local, cpar[2]));
    local->linetonum++;
    break;
  case 'C':
    x = mxd2px(local, cpar[1] - cpar[3]);
    y = mxd2py(local, cpar[2] - cpar[4]);
    w = mxd2pw(local, cpar[3]);
    h = mxd2ph(local, cpar[4]);
    a1 = cpar[5] * (M_PI / 18000.0);
    a2 = cpar[6] * (M_PI / 18000.0) + a1;

    if (w == 0 || h == 0 || a1 == a2)
      break;

    cairo_new_path(local->cairo);
    cairo_save(local->cairo);
    cairo_translate(local->cairo, x + w, y + h);
    cairo_scale(local->cairo, w, h);
    cairo_arc_negative(local->cairo, 0., 0., 1., -a1, -a2);
    cairo_restore (local->cairo);
    switch (cpar[7]) {
    case 1:
      cairo_line_to(local->cairo, x + w, y + h);
      /* fall through */
    case 2:
      cairo_close_path(local->cairo);
      cairo_fill(local->cairo);
      break;
    case 3:
      cairo_line_to(local->cairo, x + w, y + h);
      /* fall through */
    case 4:
      cairo_close_path(local->cairo);
      cairo_stroke(local->cairo);
      break;
    default:
      cairo_stroke(local->cairo);
    }
    break;
  case 'B':
    cairo_new_path(local->cairo);
    if (cpar[1] <= cpar[3]) {
      x = mxd2px(local, cpar[1]);
      w = mxd2pw(local, cpar[3] - cpar[1]);
    } else {
      x = mxd2px(local, cpar[3]);
      w = mxd2pw(local, cpar[1] - cpar[3]);
    }

    if (cpar[2] <= cpar[4]) {
      y = mxd2py(local, cpar[2]);
      h = mxd2ph(local, cpar[4] - cpar[2]);
    } else {
      y = mxd2py(local, cpar[4]);
      h = mxd2ph(local, cpar[2] - cpar[4]);
    }
    cairo_rectangle(local->cairo, x, y, w, h);
    if (cpar[5] == 0) {
      cairo_stroke(local->cairo);
    } else {
      cairo_fill(local->cairo);
    }
    break;
  case 'P':
    cairo_new_path(local->cairo);
    cairo_arc(local->cairo, mxd2px(local, cpar[1]), mxd2py(local, cpar[2]), mxd2pw(local, 1), 0, 2 * M_PI);
    cairo_fill(local->cairo);
    break;
  case 'R':
    cairo_new_path(local->cairo);
    if (cpar[1] == 0)
      break;

    for (i = 0; i < cpar[1]; i++) {
      cairo_line_to(local->cairo,
		    mxd2px(local, cpar[i * 2 + 2]),
		    mxd2py(local, cpar[i * 2 + 3]));
    }
    cairo_stroke(local->cairo);
    break;
  case 'D':
    cairo_new_path(local->cairo);

    if (cpar[1] == 0)
      break;

    for (i = 0; i < cpar[1]; i++) {
      cairo_line_to(local->cairo,
		    mxd2px(local, cpar[i * 2 + 3]),
		    mxd2py(local, cpar[i * 2 + 4]));
    }
    cairo_close_path(local->cairo);

    switch (cpar[2]) {
    case 0:
      cairo_stroke(local->cairo);
      break;
    case 1:
      cairo_set_fill_rule(local->cairo, CAIRO_FILL_RULE_EVEN_ODD);
      cairo_fill(local->cairo);
      break;
    case 2:
      cairo_set_fill_rule(local->cairo, CAIRO_FILL_RULE_WINDING);
      cairo_fill(local->cairo);
      break;
    }
    break;
  case 'F':
    g_free(local->fontalias);
    local->fontalias = g_strdup(cstr);
    break;
  case 'H':
    fontspace = cpar[2] / 72.0 * 25.4;
    local->fontspace = fontspace;
    fontsize = cpar[1] / 72.0 * 25.4;
    local->fontsize = fontsize;
    fontdir = cpar[3] * MPI / 18000.0;
    fontsin = sin(fontdir);
    fontcos = cos(fontdir);
    local->fontdir = (cpar[3] % 36000) / 100.0;
    if (local->fontdir < 0) {
      local->fontdir += 360;
    }
    local->fontsin = fontsin;
    local->fontcos = fontcos;
    font_style = (cpar[0] > 3) ? cpar[4] : -1;
    local->loadfont = loadfont(local->fontalias, font_style, &local->symbol);
    break;
  case 'S':
    if (local->loadfont == NULL)
      break;

    tmp = gra2cairo_get_utf8_str(cstr, local->symbol);
    if (tmp) {
      draw_str(local, TRUE, tmp, local->loadfont, local->fontsize, local->fontspace, NULL, NULL, NULL);
      g_free(tmp);
    }
    break;
  case 'K':
    if (local->loadfont == NULL)
      break;

    tmp = sjis_to_utf8(cstr);
    if (tmp) {
      draw_str(local, TRUE, tmp, local->loadfont, local->fontsize, local->fontspace, NULL, NULL, NULL);
      g_free(tmp);
    }
    break;
  default:
    break;
  }
  return 0;
}