Rev 13974 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed
/** R : A Computer Langage for Statistical Data Analysis* Copyright (C) 1998-1999 Lyndon Drake* and the R Development Core Team** This program is free software; you can redistribute it and/or modify* it under the terms of the GNU General Public License as published by* the Free Software Foundation; either version 2 of the License, or* (at your option) any later version.** This program is distributed in the hope that it will be useful,* but WITHOUT ANY WARRANTY; without even the implied warranty of* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the* GNU General Public License for more details.** You should have received a copy of the GNU General Public License* along with this program; if not, write to the Free Software* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*/#include "gdkrotated.h"#include <math.h>void gdk_draw_text_rot(GdkDrawable *drawable,GdkFont *font,GdkGC *gc,int x, int y,int maxx, int maxy,const gchar *text,gint text_length,double angle){GdkColor black, white;GdkPixmap *pixmap;GdkGC *rotgc;GdkImage *image;int lbearing, rbearing, width, ascent, descent, height;int dx, dy;int i, j, mini, minj, maxi, maxj;double sintheta, costheta;/* sanity check */if((text == NULL) || (*text == '\0'))return;/* shortcut horizontal text */if(angle == 0.0) {gdk_draw_text(drawable, font, gc, x, y, text, text_length);}else {/* text metrics */gdk_text_extents(font, text, text_length,&lbearing, &rbearing,&width, &ascent, &descent);height = ascent + descent;/* draw text into pixmap */pixmap = gdk_pixmap_new(drawable, width, height, 1);rotgc = gdk_gc_new(pixmap);gdk_gc_set_font(rotgc, font);white.pixel = gdk_rgb_xpixel_from_rgb(0xffffffff);black.pixel = gdk_rgb_xpixel_from_rgb(0);gdk_gc_set_foreground(rotgc, &white);gdk_draw_rectangle (pixmap, rotgc, 1, 0, 0, width, height);gdk_gc_set_foreground(rotgc, &black);gdk_draw_text(pixmap, font, rotgc, 0, ascent, text, text_length);image = gdk_image_get(pixmap, 0, 0, width, height);/* precalc cos/sin of angle *//* the floor(x * 1000.0 + 0.5) / 1000.0 is a hack to round things off */costheta = floor(cos(angle) * 1000.0 + 0.5) / 1000.0;sintheta = floor(sin(angle) * 1000.0 + 0.5) / 1000.0;/* calculate bounding box for i and j iteration */mini = maxi = floor((double)(0 - ascent) * sintheta) + x;minj = maxj = floor((double)(0 - ascent) * costheta) + y;i = floor((double)width * costheta + (double)(height - ascent) * sintheta) + x;j = floor(- (double)width * sintheta + (double)(height - ascent) * costheta) + y;if(i < mini) mini = i;if(i > maxi) maxi = i;if(j < minj) minj = j;if(j > maxj) maxj = j;i = floor((double)(height - ascent) * sintheta) + x;j = floor((double)(height - ascent) * costheta) + y;if(i < mini) mini = i;if(i > maxi) maxi = i;if(j < minj) minj = j;if(j > maxj) maxj = j;i = floor((double)width * costheta + (double)(0 - ascent) * sintheta) + x;j = floor(- (double)width * sintheta + (double)(0 - ascent) * costheta) + y;if(i < mini) mini = i;if(i > maxi) maxi = i;if(j < minj) minj = j;if(j > maxj) maxj = j;maxi++; maxj++;if(mini < 0) mini = 0;if(maxi > maxx) maxi = maxx;if(minj < 0) minj = 0;if(maxj > maxy) maxj = maxy;/* copy pixels */for(j = minj; j < maxj; j++) {for(i = mini; i < maxi; i++) {dx = floor((double)(i - x) * costheta - (double)(j - y) * sintheta);dy = floor((double)(i - x) * sintheta + (double)(j - y) * costheta) + ascent;if((dx >= 0) && (dx < width) && (dy >= 0) && (dy < height) &&(gdk_image_get_pixel(image, dx, dy) == black.pixel)) {gdk_draw_point(drawable, gc, i, j);}}}/* clean up */gdk_pixmap_unref(pixmap);gdk_gc_unref(rotgc);}}