Chinaunix首页 | 论坛 | 博客
  • 博客访问: 192556
  • 博文数量: 111
  • 博客积分: 3010
  • 博客等级: 中校
  • 技术积分: 1240
  • 用 户 组: 普通用户
  • 注册时间: 2009-08-07 07:46
文章分类

全部博文(111)

文章存档

2015年(2)

2014年(1)

2011年(1)

2010年(7)

2009年(100)

我的朋友

分类: LINUX

2009-08-07 11:02:07


转载时请注明出处和作者联系方式
文章出处:http://www.limodev.cn/blog
作者联系方式:李先静

绘 图操作是在mutable image上进行的,也就是画在GdkPixmap上的,由于GdkPixmap没有画圆和椭圆的函数,我选择用cairo来实现。大部分函数的实现很直 观,调用cairo相应的函数就行了,gxpport_draw_arc比较麻烦一点,因为gxpport_draw_arc支持画椭圆,而cairo没 有函数直接对应,我们可以通过cairo的变换函数来实现:

void gxpport_draw_arc(
jint pixel, const jshort *clip,
gxpport_mutableimage_native_handle dst,
int dotted, int x, int y, int width, int height,
int startAngle, int arcAngle)
{
cairo_t* cr = gxpport_get_dst_cairo(dst);
double start = ANGLE_FROM_DEGREE(startAngle);
double arc = ANGLE_FROM_DEGREE(arcAngle);
 
cairo_init_style(cr, pixel, clip, dotted);
cairo_save (cr);
cairo_translate (cr, x + width / 2.0, y + height / 2.0);
cairo_scale (cr, width / 2.0, height / 2.0);
cairo_arc(cr, 0.0, 0.0, 1., start, arc);
cairo_restore (cr);
cairo_stroke (cr);
 
return;
}

其它函数的实现类似,这里不再重复了。另外有两个问题值得一提:

o 目标pixmap可能为空,这时要画在当前的窗口上,我们调用自己实现的lfpport_get_active_screen来获得当前窗口。

o其次是与GTK的绘制机制有关。要往GdkWinow上绘制东西,只能在expose消息里做,在expose之前GTK会clear窗口上的内 容,之后才把绘制的内容刷新到屏幕上。而JAVA的绘制操作显然不是在expose消息里执行的。为了解决这个问题,我们需要建立另外一个 pixmap,JAVA先绘制到这个pixmap上,而在expose消息里从这个pixmap拷过去。

我们这样处理窗口的expose事件:

static gboolean frame_on_expose_event                 (GtkWidget       *widget,
GdkEventExpose *event,
gpointer user_data)
{
int w = 0;
int h = 0;
(void)event;
(void)user_data;
 
GdkDrawable* drawable = GDK_DRAWABLE(widget->window);
GdkDrawable* back_buffer = g_object_get_data(G_OBJECT(drawable), "back_buffer");
GdkGC* gc = gdk_gc_new(drawable);
 
if(back_buffer != NULL)
{
gdk_drawable_get_size(drawable, &w, &h);
gdk_draw_drawable(drawable, gc, back_buffer, 0, 0, 0, 0, w, h);
}
g_object_unref(G_OBJECT(gc));
 
return TRUE;
}
Category: KVM hack notes
阅读(472) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~