Mozilla研究—图片显示
mozilla是一个以浏览器为中心的软件平台,它在我们平台中占有重要地位。我们用它来实现WEB浏览器、WAP浏览器、邮件系统、电子书和帮助阅读器等应用程序。为此,我最近花了不少时间去阅读mozilla的代码和文档,我将写一系列的BLOG作为笔记,供有需要的朋友参考。本文介绍一下图片显示。
Mozilla在解析到img tag时,先创建nsHTMLImageElement结点,接下来继续解析img tag中的属性,每解析一个属性就调用nsHTMLImageElement::SetAttr函数。在函数nsHTMLImageElement::SetAtt里,如果发现属性是src,它就会调用nsImageLoadingContent::ImageURIChanged去加载图片。
如果允许加载图片(配置决定),在nsContentUtils::LoadImage中,调用NewImageChannel创建一个Channel。并以ProxyListener对象作为参数,调用Channel的AsyncOpen函数去异步下载图片。ProxyListener实现了nsIStreamListener接口,当Channel有数据时,ProxyListener会得到通知。
当有数据可用时,ProxyListener直接把数据转发给imgRequest。在imgRequest::OnDataAvailable中,它以"@mozilla.org/image/decoder;2?type=" + mContentType生成imgDecoder的ConstractID,然后调用do_CreateInstance创建Decoder。
解码完成之后,解码器调用gfxImageFrame::SetMutable告诉gfxImageFrame解码完成了。GfxImageFrame然后调用nsIImage:: Optimize进行优化处理,对于nsImageGTK实现的nsIImage,只是对Alpha通道做些处理。
nsIImage:: Optimize完成之后,图片数据还是存放在一个buffer中的,接下来还要把它绘制到ImagePixmap上。对于nsImageGTK实现的nsIImage,是调用gdk_draw_rgb_image_dithalign去绘制的。
图片绘制到ImagePixmap上之后,这时并没有真正显示到屏幕上。只有当Layout排版布局完成之后,由PresShell::Paint来绘制所有元素时,在nsImageFrame::Paint里,才完成图片的屏幕显示。
图像解码器代码在modules/libpr0n/decoders目录下,实现了bmp gif icon jpeg png xbm等常见图像格式的解码器。
图像解码器的注册在modules/libpr0n/build/nsImageModule.cpp里完成的,每种解码器都要实现imgIDecoder接口。注册时,以”@mozilla.org/image/decoder;2?type=” + ContentType的规则生成ContractID,比如jpeg解码器注册了"@mozilla.org/image/decoder;2?type=image/jpeg"、"@mozilla.org/image/decoder;2?type=image/pjpeg"和"@mozilla.org/image/decoder;2?type=image/jpg"三个ContractID。
~~the end~~