让基于DirectFB的Mozilla支持透明图
2007-07-25 22:20
183 查看
让基于DirectFB的Mozilla支持透明图
转载时请注明出处和作者联系方式
作者联系方式:李先静 <xianjimli at hotmail dot com>
Mozilla是个庞然大物,把Mozilla移植到GTK+/DirectFB上可不是件容易的事,所幸上次从网上找到了基于GTK+/DirectFB的Mozilla,经过一段时间的努力,最终成功的编译出minimo,为我省了不少时间。之后让它支持安装功能,方便以后扩展; 又对速度做了优化,现在十秒之内就可以运行起来。不过,虽然可以用了,还是有些美中不足,问题之一就是它不支持透明图。
移植者去年曾经声明当时还不支持透明图,今天到mozilla的网站上看了一下,还是没有任何更新,看来不能指望他们了。GTK+/DirectFB对透明图的支持非常完善,为什么mozilla不能显示透明图呢?
使用1bit的alpha值的图片会触发gdkgc-directfb.c中的一个断言,不过这个断言无关紧要,直接注释掉就行了。
nsImageGTK.cpp是Mozilla和GTK关于图象处理的衔接部分,移植者修改了不少代码,里面也有对alpha通道的处理,没有发现什么线索。我开始怀疑是gfxImageFrame和nsPNGDecoder没有把alpha数据送过来,经过跟踪发现,alpha数据是正确的,也设置到GdkGC里去了,难道是GDK-DirectFB中没有使用它吗?
跟踪到gdk_directfb_draw_drawable函数,发现的确如此,values.clip_mask是正常的,但没有人使用它。本来只要修改gdk_directfb_draw_drawable函数即可,问题是DirectFB没有提供mask方式的透明处理,自己写代码进行转换吧,又可能会造成严重的性能下降。考虑到一般情况下,被mask的pixel都是0,所以我先做了个简化处理,它在大多数情况下正常的,极少情况会显示有误,以后再改进吧。修改后的代码如下:
试了几个网页,1bit的alpha值处理正常了,但又发现8bit的alpha还是不对。用gdb跟踪了一下,发现8bit的alpha是在nsImageGTK.cpp中处理的。透明部分是随机数据,花花绿绿的。又在DrawComposited16发现背景数据不对,我猜测是nsImageFrame、nsRenderingContextGTK和nsDrawingSurfaceGTK中的问题,大概是没有初始化背景图象吧,又花了几个小时去读代码和调试,结果证实这部分代码没有任何问题。
奇怪了,再回到nsImageGTK.cpp中,发现背景数据是从windowing_data中读出来的,感觉这个变量名有点怪,查了一下GDK-DirectFB的代码,从下面的代码中我们可以看到,windowing_data果然不是我们期望的:
GdkImageDirectFB结构怎么会是pixel数据呢?明显是不对的。但不是windowing_data又是哪个变量呢?从下面这个函数,我们可以确认应该使用mem而不是windowing_data:
在nsImageGTK.cpp中,把windowing_data替换成mem,编译后重新运行,界面清新多了。
~~end~~
转载时请注明出处和作者联系方式
作者联系方式:李先静 <xianjimli at hotmail dot com>
Mozilla是个庞然大物,把Mozilla移植到GTK+/DirectFB上可不是件容易的事,所幸上次从网上找到了基于GTK+/DirectFB的Mozilla,经过一段时间的努力,最终成功的编译出minimo,为我省了不少时间。之后让它支持安装功能,方便以后扩展; 又对速度做了优化,现在十秒之内就可以运行起来。不过,虽然可以用了,还是有些美中不足,问题之一就是它不支持透明图。
移植者去年曾经声明当时还不支持透明图,今天到mozilla的网站上看了一下,还是没有任何更新,看来不能指望他们了。GTK+/DirectFB对透明图的支持非常完善,为什么mozilla不能显示透明图呢?
使用1bit的alpha值的图片会触发gdkgc-directfb.c中的一个断言,不过这个断言无关紧要,直接注释掉就行了。
nsImageGTK.cpp是Mozilla和GTK关于图象处理的衔接部分,移植者修改了不少代码,里面也有对alpha通道的处理,没有发现什么线索。我开始怀疑是gfxImageFrame和nsPNGDecoder没有把alpha数据送过来,经过跟踪发现,alpha数据是正确的,也设置到GdkGC里去了,难道是GDK-DirectFB中没有使用它吗?
跟踪到gdk_directfb_draw_drawable函数,发现的确如此,values.clip_mask是正常的,但没有人使用它。本来只要修改gdk_directfb_draw_drawable函数即可,问题是DirectFB没有提供mask方式的透明处理,自己写代码进行转换吧,又可能会造成严重的性能下降。考虑到一般情况下,被mask的pixel都是0,所以我先做了个简化处理,它在大多数情况下正常的,极少情况会显示有误,以后再改进吧。修改后的代码如下:
static void gdk_directfb_draw_drawable (GdkDrawable *drawable, GdkGC *gc, GdkDrawable *src, gint xsrc, gint ysrc, gint xdest, gint ydest, gint width, gint height) { GdkDrawableImplDirectFB *impl; GdkDrawableImplDirectFB *src_impl; GdkRegion *clip; GdkRectangle dest_rect = { xdest, ydest, xdest + width, ydest + height }; GdkGCValues values = {0}; gdk_gc_get_values(gc, &values); DFBRectangle rect = { xsrc, ysrc, width, height }; gint i; impl = GDK_DRAWABLE_IMPL_DIRECTFB (drawable); if (!impl->surface) return; if (GDK_IS_PIXMAP (src)) src_impl = GDK_DRAWABLE_IMPL_DIRECTFB (GDK_PIXMAP_OBJECT (src)->impl); else if (GDK_IS_WINDOW (src)) src_impl = GDK_DRAWABLE_IMPL_DIRECTFB (GDK_WINDOW_OBJECT (src)->impl); else if (GDK_IS_DRAWABLE_IMPL_DIRECTFB (src)) src_impl = GDK_DRAWABLE_IMPL_DIRECTFB (src); else return; clip = gdk_directfb_clip_region (drawable, gc, &dest_rect); for (i = 0; i < clip->numRects; i++) { DFBRegion reg = { clip->rects[i].x1, clip->rects[i].y1, clip->rects[i].x2 - 1, clip->rects[i].y2 - 1 }; impl->surface->SetClip (impl->surface, ®); if(values.clip_mask != NULL) { GdkDrawableImplDirectFB* mask = GDK_DRAWABLE_IMPL_DIRECTFB(values.clip_mask); impl->surface->SetBlittingFlags(impl->surface, DSBLIT_SRC_COLORKEY); impl->surface->SetSrcColorKey(impl->surface, 0, 0, 0); impl->surface->Blit (impl->surface, src_impl->surface, &rect, xdest, ydest); } else { impl->surface->Blit (impl->surface, src_impl->surface, &rect, xdest, ydest); } } impl->surface->SetClip (impl->surface, NULL); gdk_directfb_update_region (impl, clip); gdk_region_destroy (clip); } |
奇怪了,再回到nsImageGTK.cpp中,发现背景数据是从windowing_data中读出来的,感觉这个变量名有点怪,查了一下GDK-DirectFB的代码,从下面的代码中我们可以看到,windowing_data果然不是我们期望的:
nsImageGTK.cpp: windowing_data->mem static void gdk_image_init (GdkImage *image) { image->windowing_data = g_new0 (GdkImageDirectFB, 1); image->mem = NULL; image_list = g_list_prepend (image_list, image); } |
guint32 gdk_image_get_pixel (GdkImage *image, gint x, gint y) { guint32 pixel = 0; g_return_val_if_fail (GDK_IS_IMAGE (image), 0); if (!(x >= 0 && x < image->width && y >= 0 && y < image->height)) return 0; if (image->depth == 1) pixel = (((guchar *) image->mem)[y * image->bpl + (x >> 3)] & (1 << (7 - (x & 0x7)))) != 0; else { guchar *pixelp = (guchar *) image->mem + y * image->bpl + x * image->bpp; switch (image->bpp) { case 1: pixel = *pixelp; break; case 2: pixel = pixelp[0] | (pixelp[1] << 8); break; case 3: pixel = pixelp[0] | (pixelp[1] << 8) | (pixelp[2] << 16); break; case 4: pixel = pixelp[0] | (pixelp[1] << 8) | (pixelp[2] << 16); break; } } return pixel; } |
~~end~~
相关文章推荐
- 让基于DirectFB的Mozilla支持透明图
- 让基于DirectFB的GTK+ 支持全局剪切板
- 让基于DirectFB的GTK+ 支持全局剪切板
- 基于DirectFB1.4.12的简单编程与调试
- 在云服务器主机环境(不支持组播)基于单播模式的Tomcat Cluster集群配置
- Spring 下透明的让POJO 变为支持JMX的MBean
- 基于FPGA的CAN总线控制器(支持CANFD)
- 支持下拉刷新、上拉加载的RecyclerView,基于PullToRefresh
- 基于Spring的可扩展Schema进行开发自定义配置标签支持
- IE6支持透明PNG图片解决方案:DD_belatedPNG.js
- WINCE系统Picturebox控件支持透明方法
- 【转】基于 Mozilla 的扩展开发
- DD_belatedPNG透明,解决IE6不支持PNG绝佳方案
- 半透明界面(逐像素透明,不规则外观,支持任意控件)的完美解决方案
- 基于UNIX的操作系统内核——Mach、驱动程序支持、BSD
- CSS透明滤镜的兼容性写法,支持FF,IE6.0,IE7.0,IE8.0
- Unity ShaderLab(二) 支持透明的边缘发光Shader
- 基于Spring可扩展Schema提供自定义配置支持
- MyGUI支持透明窗口
- as3页游聊天框点击透明区域及普通文本支持寻路方案