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