zoukankan      html  css  js  c++  java
  • KJAVA虚拟机Hack笔记用GTK+实现绘图操作

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

    绘 图操作是在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;
    }

    欢迎到Linux mobile development上交流

  • 相关阅读:
    十进制数转换
    桶排序
    快速排序
    单词倒排
    (c++) string b; cin>>b; int i=strlen(b); 报错的原因。
    n的阶乘(1<n<10000)(结果超大……)
    2020软件工程最后一次作业
    2020软件工程第四次作业
    2020软件工程第三次作业
    2020软件工程第二次作业
  • 原文地址:https://www.cnblogs.com/zhangyunlin/p/6167580.html
Copyright © 2011-2022 走看看