/* gtkplotart - wrapper for libart * Copyright 1999-2001 Adrian E. Feiguin */ #ifdef WITH_LIBART #include #include #include #include #include #include #include #include #include #include #include "gtkplotart.h" static void gtk_plot_art_init (GtkPlotArt *pc); static void gtk_plot_art_class_init (GtkPlotArtClass *klass); static void gtk_plot_art_finalize (GtkObject *object); static void gtk_plot_art_set_drawable (GtkPlotArt *pc, GdkDrawable *drawable); static gboolean gtk_plot_art_real_init (GtkPlotPC *pc); static void gtk_plot_art_set_viewport (GtkPlotPC *pc, gdouble w, gdouble h); static void gtk_plot_art_leave (GtkPlotPC *pc); static void gtk_plot_art_gsave (GtkPlotPC *pc); static void gtk_plot_art_grestore (GtkPlotPC *pc); static void gtk_plot_art_clip (GtkPlotPC *pc, const GdkRectangle *area); static void gtk_plot_art_clip_mask (GtkPlotPC *pc, gdouble x, gdouble y, const GdkBitmap *mask); static void gtk_plot_art_set_color (GtkPlotPC *pc, const GdkColor *color); static void gtk_plot_art_set_lineattr (GtkPlotPC *pc, gfloat line_width, GdkLineStyle line_style, GdkCapStyle cap_style, GdkJoinStyle join_style); static void gtk_plot_art_set_dash (GtkPlotPC *pc, gdouble offset_, gdouble *values, gint num_values); static void gtk_plot_art_draw_point (GtkPlotPC *pc, gdouble x, gdouble y); static void gtk_plot_art_draw_line (GtkPlotPC *pc, gdouble x1, gdouble y1, gdouble x2, gdouble y2); static void gtk_plot_art_draw_lines (GtkPlotPC *pc, GtkPlotPoint *points, gint numpoints); static void gtk_plot_art_draw_rectangle (GtkPlotPC *pc, gint filled, gdouble x, gdouble y, gdouble width, gdouble height); static void gtk_plot_art_draw_polygon (GtkPlotPC *pc, gint filled, GtkPlotPoint *points, gint numpoints); static void gtk_plot_art_draw_circle (GtkPlotPC *pc, gint filled, gdouble x, gdouble y, gdouble size); static void gtk_plot_art_draw_ellipse (GtkPlotPC *pc, gint filled, gdouble x, gdouble y, gdouble width, gdouble height); static void gtk_plot_art_set_font (GtkPlotPC *pc, GtkPSFont *psfont, gint height); static void gtk_plot_art_draw_string (GtkPlotPC *pc, gint x, gint y, gint angle, const GdkColor *fg, const GdkColor *bg, gboolean transparent, gint border, gint border_space, gint border_width, gint shadow_width, const gchar *font, gint height, GtkJustification just, const gchar *text); static void gtk_plot_art_draw_pixmap (GtkPlotPC *pc, GdkPixmap *pixmap, GdkBitmap *mask, gint xsrc, gint ysrc, gint xdest, gint ydest, gint width, gint height, gdouble scale_x, gdouble scale_y); static ArtSVP * gtk_plot_art_stroke (GtkPlotArt *art, ArtVpath *path); static GtkPlotGdkClass *parent_class = NULL; GtkType gtk_plot_art_get_type (void) { static GtkType pc_type = 0; if (!pc_type) { GtkTypeInfo pc_info = { "GtkPlotArt", sizeof (GtkPlotArt), sizeof (GtkPlotArtClass), (GtkClassInitFunc) gtk_plot_art_class_init, (GtkObjectInitFunc) gtk_plot_art_init, /* reserved 1*/ NULL, /* reserved 2 */ NULL, (GtkClassInitFunc) NULL, }; pc_type = gtk_type_unique (GTK_TYPE_PLOT_GDK, &pc_info); } return pc_type; } static void gtk_plot_art_init (GtkPlotArt *pc) { GdkWindowAttr attributes; gint attributes_mask; attributes.window_type = GDK_WINDOW_CHILD; attributes.title = NULL; attributes.wclass = GDK_INPUT_OUTPUT; attributes.visual = gdk_visual_get_system (); attributes.colormap = gdk_colormap_get_system (); attributes.event_mask = 0; attributes_mask = GDK_WA_VISUAL | GDK_WA_COLORMAP; GTK_PLOT_GDK(pc)->drawable = NULL; GTK_PLOT_GDK(pc)->window = gdk_window_new (NULL, &attributes, attributes_mask); GTK_PLOT_GDK(pc)->gc = gdk_gc_new(GTK_PLOT_GDK(pc)->window); pc->line_width = 0.25; pc->line_style = GDK_LINE_SOLID; pc->cap_style = 0; pc->join_style = 0; pc->dash.offset = 0; pc->dash.n_dash = 0; pc->dash.dash = NULL; } static void gtk_plot_art_class_init (GtkPlotArtClass *klass) { GtkObjectClass *object_class; GtkPlotPCClass *pc_class; parent_class = gtk_type_class (gtk_plot_pc_get_type ()); object_class = (GtkObjectClass *) klass; pc_class = (GtkPlotPCClass *) klass; object_class->finalize = gtk_plot_art_finalize; pc_class->init = gtk_plot_art_real_init; pc_class->leave = gtk_plot_art_leave; pc_class->set_viewport = gtk_plot_art_set_viewport; pc_class->gsave = gtk_plot_art_gsave; pc_class->grestore = gtk_plot_art_grestore; pc_class->clip = gtk_plot_art_clip; pc_class->clip_mask = gtk_plot_art_clip_mask; pc_class->set_color = gtk_plot_art_set_color; pc_class->set_dash = gtk_plot_art_set_dash; pc_class->set_lineattr = gtk_plot_art_set_lineattr; pc_class->draw_point = gtk_plot_art_draw_point; pc_class->draw_line = gtk_plot_art_draw_line; pc_class->draw_lines = gtk_plot_art_draw_lines; pc_class->draw_rectangle = gtk_plot_art_draw_rectangle; pc_class->draw_polygon = gtk_plot_art_draw_polygon; pc_class->draw_circle = gtk_plot_art_draw_circle; pc_class->draw_ellipse = gtk_plot_art_draw_ellipse; pc_class->set_font = gtk_plot_art_set_font; pc_class->draw_string = gtk_plot_art_draw_string; pc_class->draw_pixmap = gtk_plot_art_draw_pixmap; } GtkObject * gtk_plot_art_new (GdkDrawable *drawable) { GtkObject *object; object = gtk_type_new(gtk_plot_art_get_type()); gdk_rgb_init(); return (object); } static void gtk_plot_art_finalize (GtkObject *object) { gdk_window_unref(GTK_PLOT_GDK(object)->window); } static void gtk_plot_art_set_drawable(GtkPlotArt *pc, GdkDrawable *drawable) { GTK_PLOT_GDK(pc)->drawable = drawable; } static gboolean gtk_plot_art_real_init (GtkPlotPC *pc) { return TRUE; } static void gtk_plot_art_leave (GtkPlotPC *pc) { GdkGC *gc; gc = gdk_gc_new(GTK_PLOT_GDK(pc)->drawable); gdk_gc_set_foreground(gc, &pc->color); gdk_draw_rgb_image(GTK_PLOT_GDK(pc)->drawable, gc, 0, 0, pc->width, pc->height, GDK_RGB_DITHER_NONE, (guchar *)GTK_PLOT_ART(pc)->buf, pc->width * 3); gdk_gc_unref(gc); } static void gtk_plot_art_set_viewport (GtkPlotPC *pc, gdouble w, gdouble h) { GtkPlotArt *art; art = GTK_PLOT_ART(pc); if(art->buf) art_free(art->buf); art->buf = art_new(art_u8, w*h*3); art_rgb_run_alpha(art->buf, 0xFF, 0xFF, 0xFF, 0xFF, w * h); } static void gtk_plot_art_gsave (GtkPlotPC *pc) { } static void gtk_plot_art_grestore (GtkPlotPC *pc) { } static void gtk_plot_art_clip (GtkPlotPC *pc, const GdkRectangle *area) { /* g_warning ("Clipping has not been implemented with antialiasing."); */ } static void gtk_plot_art_clip_mask (GtkPlotPC *pc, gdouble x, gdouble y, const GdkBitmap *mask) { } static void gtk_plot_art_set_color (GtkPlotPC *pc, const GdkColor *color) { GdkColor new_color; new_color = *color; gdk_color_alloc(gdk_colormap_get_system(), &new_color); pc->color = new_color; } static void gtk_plot_art_set_dash (GtkPlotPC *pc, gdouble offset, gdouble *values, gint num_values) { GtkPlotArt *art = GTK_PLOT_ART(pc); gint i; if(num_values == 0){ if(art->dash.dash) g_free(art->dash.dash); art->dash.n_dash = 0; art->dash.dash = NULL; return; } art->dash.offset = 0; art->dash.n_dash = num_values; if(art->dash.dash) g_free(art->dash.dash); art->dash.dash = g_new0(gdouble, num_values); for(i = 0; i < num_values; i++){ art->dash.dash[i] = values[i]; } } static void gtk_plot_art_set_lineattr (GtkPlotPC *pc, gfloat line_width, GdkLineStyle line_style, GdkCapStyle cap_style, GdkJoinStyle join_style) { gint art_join; gint art_cap; switch (join_style) { case GDK_JOIN_MITER: art_join = ART_PATH_STROKE_JOIN_MITER; break; case GDK_JOIN_ROUND: art_join = ART_PATH_STROKE_JOIN_ROUND; break; case GDK_JOIN_BEVEL: art_join = ART_PATH_STROKE_JOIN_BEVEL; break; default: art_join = ART_PATH_STROKE_JOIN_MITER; break; } switch (cap_style) { case GDK_CAP_BUTT: case GDK_CAP_NOT_LAST: art_cap = ART_PATH_STROKE_CAP_BUTT; break; case GDK_CAP_ROUND: art_cap = ART_PATH_STROKE_CAP_ROUND; break; case GDK_CAP_PROJECTING: art_cap = ART_PATH_STROKE_CAP_SQUARE; break; default: art_cap = ART_PATH_STROKE_CAP_BUTT; /* shut up the compiler */ break; } GTK_PLOT_ART(pc)->line_style = line_style; GTK_PLOT_ART(pc)->join_style = art_join; GTK_PLOT_ART(pc)->cap_style = art_cap; GTK_PLOT_ART(pc)->line_width = MAX(line_width, 0.25); if(line_style == GDK_LINE_SOLID) gtk_plot_art_set_dash(pc, 0, NULL, 0); } static void gtk_plot_art_draw_point (GtkPlotPC *pc, gdouble x, gdouble y) { gtk_plot_art_draw_line(pc, x, y, x, y); } static void gtk_plot_art_draw_line (GtkPlotPC *pc, gdouble x1, gdouble y1, gdouble x2, gdouble y2) { GtkPlotArt *art = GTK_PLOT_ART(pc); ArtVpath *vec = NULL; ArtSVP *svp = NULL; art_u32 color; color = (pc->color.red/256 << 16) | (pc->color.green/256 << 8) | (pc->color.blue/256); vec = art_new(ArtVpath, 3); vec[0].code = ART_MOVETO; vec[0].x = x1; vec[0].y = y1; vec[1].code = ART_LINETO; vec[1].x = x2; vec[1].y = y2; vec[2].code = ART_END; vec[2].x = x2; vec[2].y = y2; svp = gtk_plot_art_stroke(art, vec); art_rgb_svp_alpha(svp, 0, 0, pc->width - 1, pc->height - 1, (color << 8) + 0xFF, GTK_PLOT_ART(pc)->buf, pc->width * 3, NULL); } static void gtk_plot_art_draw_lines (GtkPlotPC *pc, GtkPlotPoint *points, gint numpoints) { GtkPlotArt *art = GTK_PLOT_ART(pc); ArtVpath *vec = NULL; ArtSVP *svp = NULL; gint i; art_u32 color; color = (pc->color.red/256 << 16) | (pc->color.green/256 << 8) | (pc->color.blue/256); vec = art_new(ArtVpath, numpoints + 1); vec[0].code = ART_MOVETO; vec[0].x = points[0].x; vec[0].y = points[0].y; for(i = 1; i < numpoints; i++){ vec[i].code = ART_LINETO; vec[i].x = points[i].x; vec[i].y = points[i].y; } vec[numpoints].code = ART_END; vec[numpoints].x = points[numpoints - 1].x; vec[numpoints].y = points[numpoints - 1].y; svp = gtk_plot_art_stroke(art, vec); art_rgb_svp_alpha(svp, 0, 0, pc->width - 1, pc->height - 1, (color << 8) + 0xFF, GTK_PLOT_ART(pc)->buf, pc->width * 3, NULL); } static void gtk_plot_art_draw_rectangle (GtkPlotPC *pc, gint filled, gdouble x, gdouble y, gdouble width, gdouble height) { GtkPlotArt *art = GTK_PLOT_ART(pc); ArtVpath *vec = NULL; ArtSVP *svp = NULL; art_u32 color; color = (pc->color.red/256 << 16) | (pc->color.green/256 << 8) | (pc->color.blue/256); vec = art_new(ArtVpath, 6); vec[0].code = ART_MOVETO; vec[0].x = x; vec[0].y = y; vec[1].code = ART_LINETO; vec[1].x = x+width; vec[1].y = y; vec[2].code = ART_LINETO; vec[2].x = x+width; vec[2].y = y+height; vec[3].code = ART_LINETO; vec[3].x = x; vec[3].y = y+height; vec[4].code = ART_LINETO; vec[4].x = x; vec[4].y = y; vec[5].code = ART_END; if(filled) svp = art_svp_from_vpath(vec); else svp = gtk_plot_art_stroke(art, vec); art_rgb_svp_alpha(svp, 0, 0, pc->width - 1, pc->height - 1, (color << 8) + 0xFF, GTK_PLOT_ART(pc)->buf, pc->width * 3, NULL); } static void gtk_plot_art_draw_polygon (GtkPlotPC *pc, gint filled, GtkPlotPoint *points, gint numpoints) { GtkPlotArt *art = GTK_PLOT_ART(pc); ArtVpath *vec = NULL; ArtSVP *svp = NULL; gint i; art_u32 color; color = (pc->color.red/256 << 16) | (pc->color.green/256 << 8) | (pc->color.blue/256); vec = art_new(ArtVpath, numpoints + 2); vec[0].code = ART_MOVETO; vec[0].x = points[0].x; vec[0].y = points[0].y; for(i = 1; i < numpoints; i++){ vec[i].code = ART_LINETO; vec[i].x = points[i].x; vec[i].y = points[i].y; } vec[numpoints].code = ART_LINETO; vec[numpoints].x = points[0].x; vec[numpoints].y = points[0].y; vec[numpoints+1].code = ART_END; if(filled) svp = art_svp_from_vpath(vec); else svp = gtk_plot_art_stroke(art, vec); art_rgb_svp_alpha(svp, 0, 0, pc->width - 1, pc->height - 1, (color << 8) + 0xFF, GTK_PLOT_ART(pc)->buf, pc->width * 3, NULL); } static void gtk_plot_art_draw_circle (GtkPlotPC *pc, gint filled, gdouble x, gdouble y, gdouble size) { GtkPlotPoint *points; gint i, npoints = 126; points = g_new0(GtkPlotPoint, npoints); for (i = 0; i < npoints; i++) { double th; th = (2 * 3.141592654 * i) / npoints; points[i].x = x + size / 2. * cos (th); points[i].y = y + size / 2.* sin (th); } gtk_plot_art_draw_polygon(pc, filled, points, npoints); g_free(points); } static void gtk_plot_art_draw_ellipse (GtkPlotPC *pc, gint filled, gdouble x, gdouble y, gdouble width, gdouble height) { GtkPlotPoint *points; gint i, npoints = 126; points = g_new0(GtkPlotPoint, npoints); for (i = 0; i < npoints; i++) { double th; th = (2 * 3.141592654 * i) / npoints; points[i].x = x + width / 2. + width / 2. * cos (th); points[i].y = y + height / 2. + height / 2. * sin (th); } gtk_plot_art_draw_polygon(pc, filled, points, npoints); g_free(points); } static void gtk_plot_art_set_font (GtkPlotPC *pc, GtkPSFont *psfont, gint height) { } /* subfunction of gtk_plot_art_draw_string(). */ static gint drawstring(GtkPlotPC *pc, GdkBitmap *dest, GdkGC *gc, GdkColor *black, GdkColor *white, gint dx, gint dy, GtkPSFont *psfont, GdkFont *font, GdkFont *latin_font, GdkWChar wc) { GdkBitmap *tmp; GdkFont *dfont; GdkImage *image; gint w, h, a, d, x, y, d2; guint32 pixel; if (psfont->i18n_latinfamily && psfont->vertical && (0 > wc || wc > 0x7f)) { /* vertical-writing CJK postscript fonts. */ dfont = font; w = gdk_char_width_wc(dfont, wc); a = dfont->ascent; d = dfont->descent; h = a + d; d2 = w * d / h; tmp = gdk_pixmap_new(GTK_PLOT_GDK(pc)->window, w, h, 1); gdk_gc_set_foreground(gc, white); gdk_draw_rectangle(tmp, gc, TRUE, 0, 0, -1, -1); gdk_gc_set_foreground(gc, black); gdk_draw_text_wc(tmp, dfont, gc, 0, a, &wc, 1); image = gdk_image_get(tmp, 0, 0, w, h); for (y = 0; y < h; y++) { for (x = 0; x < w; x++) { pixel = gdk_image_get_pixel(image, x, y); if (pixel == black->pixel) gdk_draw_point(dest, gc, dx + y, dy + d2 - x); } } gdk_image_destroy(image); gdk_pixmap_unref(tmp); return h; } else { /* horizontal writing */ if (psfont->i18n_latinfamily && 0 <= wc && wc <= 0x7f) dfont = latin_font; else dfont = font; gdk_draw_text_wc(dest, dfont, gc, dx, dy, &wc, 1); w = gdk_char_width_wc(dfont, wc); return w; } } static void gtk_plot_art_draw_string (GtkPlotPC *pc, gint tx, gint ty, gint angle, const GdkColor *fg, const GdkColor *bg, gboolean transparent, gint border, gint border_space, gint border_width, gint shadow_width, const gchar *font_name, gint font_height, GtkJustification just, const gchar *text) { GdkBitmap *text_bitmap; guchar *text_art, *line; GdkImage *image; GdkGC *gc, *bitmap_gc; GdkColormap *colormap; GdkColor white, black; GList *family = NULL; gint y0; gint old_width, old_height; gint bitmap_width, bitmap_height; gboolean bold, italic; gint fontsize; gint ascent, descent; gint numf; gint width, height; gint x, y; gint i; GdkFont *font, *latin_font, *dfont; GtkPSFont *psfont, *base_psfont, *latin_psfont; gchar subs[2], insert_char; GdkWChar *aux, *wtext, *lastchar = NULL, *xaux; gchar num[4]; gdouble affine[6], rotate[6], translate[6]; art_u32 color; if(!text || strlen(text) == 0) return; colormap = gdk_colormap_get_system (); gc = GTK_PLOT_GDK(pc)->gc; gtk_plot_text_get_size(text, angle, font_name, font_height, &width, &height, &ascent, &descent); if(height == 0 || width == 0) return; old_width = width; old_height = height; if(angle == 90 || angle == 270) { old_width = height; old_height = width; } gtk_psfont_get_families(&family, &numf); font = gtk_psfont_get_gdkfont(font_name, font_height); base_psfont = psfont = gtk_psfont_get_font(font_name); italic = psfont->italic; bold = psfont->bold; fontsize = font_height; x = 0; y0 = y = ascent; if (psfont->i18n_latinfamily) { latin_psfont = gtk_psfont_find_by_family(psfont->i18n_latinfamily, italic, bold); latin_font = gtk_psfont_get_gdkfont(latin_psfont->psname, fontsize); } else { latin_psfont = NULL; latin_font = NULL; } i = strlen(text) + 2; aux = wtext = g_malloc0(sizeof(GdkWChar) * i); gdk_mbstowcs(wtext, text, i - 1); /* initializing text bitmap - ajd */ text_bitmap = gdk_pixmap_new(GTK_PLOT_GDK(pc)->window, old_width, old_height, 1); bitmap_gc = gdk_gc_new(text_bitmap); gdk_color_white (colormap, &white); gdk_gc_set_foreground(bitmap_gc, &white); gdk_draw_rectangle(text_bitmap, bitmap_gc, TRUE, 0, 0, -1, -1); gdk_color_black (colormap, &black); gdk_gc_set_foreground(bitmap_gc, &black); while(aux && *aux != '\0' && *aux != '\n'){ if(*aux == '\\'){ aux++; switch(*aux){ case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '9': psfont = gtk_psfont_find_by_family((gchar *)g_list_nth_data(family, *aux-'0'), italic, bold); gdk_font_unref(font); font = gtk_psfont_get_gdkfont(psfont->psname, fontsize); if (latin_font) { gdk_font_unref(latin_font); latin_font = NULL; } aux++; break; case '8': case 'g': psfont = gtk_psfont_find_by_family("Symbol", italic, bold); gdk_font_unref(font); font = gtk_psfont_get_gdkfont(psfont->psname, fontsize); if (latin_font) { gdk_font_unref(latin_font); latin_font = NULL; } aux++; break; case 'B': bold = TRUE; psfont = gtk_psfont_find_by_family(psfont->family, italic, bold); gdk_font_unref(font); font = gtk_psfont_get_gdkfont(psfont->psname, fontsize); if (latin_font) { gdk_font_unref(latin_font); latin_font = NULL; } if (psfont->i18n_latinfamily) { latin_psfont = gtk_psfont_find_by_family(psfont->i18n_latinfamily, italic, bold); latin_font = gtk_psfont_get_gdkfont(latin_psfont->psname, fontsize); } aux++; break; case 'x': xaux = aux + 1; for (i=0; i<3; i++){ if (xaux[i] >= '0' && xaux[i] <= '9') num[i] = xaux[i]; else break; } if (i < 3){ aux++; break; } num[3] = '\0'; insert_char = (gchar)atoi(num); subs[0] = insert_char; subs[1] = '\0'; /* \xNNN is always outputted with latin fonts. */ dfont = (psfont->i18n_latinfamily != NULL) ? latin_font : font; gdk_draw_string (text_bitmap, dfont, bitmap_gc, x, y, subs); x += gdk_char_width(font, insert_char); aux += 4; lastchar = aux - 1; break; case 'i': italic = TRUE; psfont = gtk_psfont_find_by_family(psfont->family, italic, bold); gdk_font_unref(font); font = gtk_psfont_get_gdkfont(psfont->psname, fontsize); if (latin_font) { gdk_font_unref(latin_font); latin_font = NULL; } if (psfont->i18n_latinfamily) { latin_psfont = gtk_psfont_find_by_family(psfont->i18n_latinfamily, italic, bold); latin_font = gtk_psfont_get_gdkfont(latin_psfont->psname, fontsize); } aux++; break; case 'S': case '^': fontsize = (int)((gdouble)fontsize * 0.6 + 0.5); gdk_font_unref(font); font = gtk_psfont_get_gdkfont(psfont->psname, fontsize); y -= font->ascent; if (latin_font) { gdk_font_unref(latin_font); latin_font = NULL; } if (psfont->i18n_latinfamily) { latin_psfont = gtk_psfont_find_by_family(psfont->i18n_latinfamily, italic, bold); latin_font = gtk_psfont_get_gdkfont(latin_psfont->psname, fontsize); } aux++; break; case 's': case '_': fontsize = (int)((gdouble)fontsize * 0.6 + 0.5); gdk_font_unref(font); font = gtk_psfont_get_gdkfont(psfont->psname, fontsize); y += font->descent; if (latin_font) { gdk_font_unref(latin_font); latin_font = NULL; } if (psfont->i18n_latinfamily) { latin_psfont = gtk_psfont_find_by_family(psfont->i18n_latinfamily, italic, bold); latin_font = gtk_psfont_get_gdkfont(latin_psfont->psname, fontsize); } aux++; break; case '+': fontsize += 3; gdk_font_unref(font); font = gtk_psfont_get_gdkfont(psfont->psname, fontsize); if (latin_font) { gdk_font_unref(latin_font); latin_font = NULL; } if (psfont->i18n_latinfamily) { latin_psfont = gtk_psfont_find_by_family(psfont->i18n_latinfamily, italic, bold); latin_font = gtk_psfont_get_gdkfont(latin_psfont->psname, fontsize); } aux++; break; case '-': fontsize -= 3; gdk_font_unref(font); font = gtk_psfont_get_gdkfont(psfont->psname, fontsize); if (latin_font) { gdk_font_unref(latin_font); latin_font = NULL; } if (psfont->i18n_latinfamily) { latin_psfont = gtk_psfont_find_by_family(psfont->i18n_latinfamily, italic, bold); latin_font = gtk_psfont_get_gdkfont(latin_psfont->psname, fontsize); } aux++; break; case 'N': psfont = base_psfont; gdk_font_unref(font); fontsize = font_height; font = gtk_psfont_get_gdkfont(psfont->psname, fontsize); y = y0; italic = psfont->italic; bold = psfont->bold; if (latin_font) { gdk_font_unref(latin_font); latin_font = NULL; } if (psfont->i18n_latinfamily) { latin_psfont = gtk_psfont_find_by_family(psfont->i18n_latinfamily, italic, bold); latin_font = gtk_psfont_get_gdkfont(latin_psfont->psname, fontsize); } aux++; break; case 'b': if (lastchar) { gtk_psfont_get_char_size(psfont, font, latin_font, *lastchar, &i, NULL, NULL); x -= i; if (lastchar == wtext) lastchar = NULL; else lastchar--; } else { gtk_psfont_get_char_size(psfont, font, latin_font, 'X', &i, NULL, NULL); x -= i; } aux++; break; default: if(aux && *aux != '\0' && *aux !='\n'){ x += drawstring(pc, text_bitmap, bitmap_gc, &black, &white, x, y, psfont, font, latin_font, *aux); lastchar = aux; aux++; } break; } } else { if(aux && *aux != '\0' && *aux !='\n'){ x += drawstring(pc, text_bitmap, bitmap_gc, &black, &white, x, y, psfont, font, latin_font, *aux); lastchar = aux; aux++; } } } g_free(wtext); /* performing text rotation and saving it onto clip mask bitmap - ajd */ gtk_plot_text_get_area(text, angle, just, font_name, font_height, &x, &y, &width, &height); tx += x; ty += y; art_affine_rotate(rotate, (gdouble) -angle); switch(angle){ case 0: art_affine_translate(translate, tx, ty); break; case 90: art_affine_translate(translate, tx, ty + old_width); break; case 180: art_affine_translate(translate, tx + old_width , ty + old_height); break; case 270: art_affine_translate(translate, tx + old_height, ty); break; } art_affine_multiply(affine, rotate, translate); bitmap_height = old_height; bitmap_width = (old_width + 31) & -32; image = gdk_image_get(text_bitmap, 0, 0, old_width, old_height); text_art = g_malloc0 ((bitmap_width >> 3) * bitmap_height); line = text_art; for(y = 0; y < bitmap_height; y++){ for(x = 0; x < bitmap_width; x++) { if( black.pixel == gdk_image_get_pixel(image, x, y) ){ line[x >> 3] |= 128 >> (x & 7); } } line += bitmap_width >> 3; } gdk_image_destroy(image); if(!transparent){ gtk_plot_pc_set_color(pc, (GdkColor *) bg); gtk_plot_pc_draw_rectangle(pc, TRUE, tx - border_space, ty - border_space, width + 2*border_space, height + 2*border_space); } gtk_plot_pc_set_color(pc, (GdkColor *)fg); color = (pc->color.red/256 << 24) | (pc->color.green/256 << 16) | (pc->color.blue/256 << 8) | 0xFF; art_rgb_bitmap_affine ( GTK_PLOT_ART(pc)->buf, 0, 0, pc->width - 1, pc->height - 1, pc->width * 3, text_art, old_width, old_height, bitmap_width >> 3, color, affine, ART_FILTER_NEAREST, NULL); g_free(text_art); gdk_font_unref(font); if (latin_font) gdk_font_unref(latin_font); gdk_gc_unref(bitmap_gc); gdk_pixmap_unref(text_bitmap); /* border */ gtk_plot_pc_set_dash(pc, 0, NULL, 0); gtk_plot_pc_set_lineattr(pc, border_width, 0, 0, 0); switch(border){ case GTK_PLOT_BORDER_SHADOW: gtk_plot_pc_draw_rectangle(pc, TRUE, tx - border_space + shadow_width, ty + height + border_space, width + 2 * border_space, shadow_width); gtk_plot_pc_draw_rectangle(pc, TRUE, tx + width + border_space, ty - border_space + shadow_width, shadow_width, height + 2 * border_space); case GTK_PLOT_BORDER_LINE: gtk_plot_pc_draw_rectangle(pc, FALSE, tx - border_space, ty - border_space, width + 2*border_space, height + 2*border_space); case GTK_PLOT_BORDER_NONE: default: break; } return; } static void gtk_plot_art_draw_pixmap (GtkPlotPC *pc, GdkPixmap *pixmap, GdkBitmap *mask, gint xsrc, gint ysrc, gint xdest, gint ydest, gint width, gint height, gdouble scale_x, gdouble scale_y) { GdkColormap *colormap; GdkColorContext *cc; GdkVisual *visual; art_u8 *pixels = NULL, *pixel; ArtPixBuf *pixbuf; gdouble affine[6], scale[6], translate[6]; GdkImage *image; GdkImage *mask_image = NULL; gint x, y; if(!pixmap){ gtk_plot_pc_draw_rectangle(pc, FALSE, xdest, ydest, width * scale_x, height * scale_y); return; } colormap = gdk_colormap_get_system (); visual = gdk_visual_get_system (); cc = gdk_color_context_new(visual, colormap); image = gdk_image_get(pixmap, xsrc, ysrc, width, height); if(mask) mask_image = gdk_image_get(mask, xsrc, ysrc, width, height); pixels = art_new(art_u8, width * 4 * height); pixel = pixels; for(y = 0; y < height; y++){ for(x = 0; x < width; x++){ GdkColor color; color.pixel = gdk_image_get_pixel(image, x, y); gdk_color_context_query_color(cc, &color); pixel[0] = color.red/256; pixel[1] = color.green/256; pixel[2] = color.blue/256; pixel[3] = 0xFF; if(mask_image){ gulong mask_pixel; mask_pixel = gdk_image_get_pixel(mask_image, x, y); if(mask_pixel == 0) pixel[3] = 0; } pixel += 4; } } gdk_image_destroy(image); if(mask_image) gdk_image_destroy(mask_image); gdk_color_context_free(cc); pixbuf = art_pixbuf_new_rgba (pixels, width, height, width*4); art_affine_translate(translate, xdest, ydest); art_affine_scale(scale, scale_x, scale_y); art_affine_multiply(affine, scale, translate); art_rgb_pixbuf_affine (GTK_PLOT_ART(pc)->buf, 0, 0, pc->width - 1, pc->height - 1, pc->width * 3, pixbuf, affine, ART_FILTER_NEAREST, NULL); art_free(pixels); } static ArtSVP * gtk_plot_art_stroke (GtkPlotArt *art, ArtVpath *path) { ArtSVP *svp = NULL; if(art->dash.n_dash != 0){ ArtVpath *dash_path = NULL; dash_path = art_vpath_dash(path, &art->dash); art_free(path); path = dash_path; } svp = art_svp_vpath_stroke (path, art->join_style, art->cap_style, art->line_width, 4, 0.25); return (svp); } #endif /* WITH_LIBART */