QT分析之WebKit(九)

news/2024/7/8 4:53:24 标签: webkit, qt, layout, 图形, 浏览器, google

QT分析之WebKit(九)

程序人生 2010-03-11 10:38:21 阅读1091 评论0   字号: 订阅 http://blog.163.com/net_worm/blog/#m=0&t=1&c=fks_087069093085086069084094094095085084086068084084082066093

WebKit的显示,继续转邓侃博士的blog。
【21】WebKit,为了布局,忙并美丽着

如果没有1440年以后活字印刷术的大规模普及,或许就不会有文艺复兴运动,更不会有后来的启蒙运动。如果没有这两个运动的开展,或许就不会有世界范围的工业化。

在活字印刷术出现以前,每出版一本书,都必须先刻制一套模版,称为雕版,每套雕版上的每一个字,都是手工雕刻的。不仅制作雕版费时费力,而且有了错误不容易更改。活字印刷术的进步在于,可以预先批量生产各种样式和大小的字体,称为活字。需要出版某一本书籍时,先制作该书的页面模版,模版做好以后,只需要把这些活字摆放在模版上即可。如果出现错误,只需要调换某些活字,既省时又省力。如果某本书的模版不需要长期保存,还可以把模版中摆放的活字拆解下来,在印刷其它图书时用,节约成本。

活字印刷术没有解决的问题,1. 图像的印刷。起初不能印刷笔触丰富,层次复杂的图像,一直到1796年,石板印刷术(lithography)出现以后,才能印刷表现手段丰富的图像。 2. 灵活的布局排版。纸张大小不同,布局排版也不同,布局变了,需要重新摆放活字,而且有时候还需要改变字体和大小。

灵活的布局排版对于纸质书籍来说,或许并不太重要,但是对于电脑浏览器来说,却必须实现完全的自动化。否则,每当用户改变浏览器窗口的大小的时候,页面内容就不能正确显示。对于手机浏览器来说,布局排版的自动化尤其重要,因为不同手机的屏幕不一致,而且屏幕分辨率也不同。

但是即便是浏览器,也没有摆脱传统的排版方式。所谓传统的排版方式,基本是横平竖直的,单一的鸟瞰视角。


QT分析之WebKit(九) - net_worm - net_worm 的博客
Figure 1. Incunabulum, the end of 15'th century
Courtesy http://www.citrinitas.com/history_of_viscom/images/printing/venice-1505.jpg


QT分析之WebKit(九) - net_worm - net_worm 的博客
Figure 2. City of Words, by Vito Acconi, 1999
Courtesy http://upload.wikimedia.org/wikipedia/en/6/63/%27City_of_Words%27%2C_lithograph_by_Vito_Acconci%2C_1999.jpg

Figure 1 中显示的是1490年代的书籍,不难看出,现代书报中广泛使用的双列,边注,页码,首字母大写等等,都是继承了500多年以前的做法。而CSS规范,囊括了所有这些页面设计的要素。

在当今信息爆炸的形势下,如何安排页面的布局排版,在有限的页面面积内,承载更多内容,突出读者关注的内容,增强页面设计的视觉美感,成为不可回避的问题。例如,手机购物的UI设计,既要包含商品简介,又要包含用户意见反馈,还要包含实物照片,以及各个不同商场的标价等等。完美的页面设计,不仅要求简练而清晰,而且也不能遗漏相关内容,实在是一件困难的事情。可以说,手机购物之所以不普及,与手机购物的UI设计笨拙而丑陋是相关的。

要巧妙地 设计手机应用的UI设计,终极而言,需要突破传统的单一鸟瞰视角的方式,Figure 2 就是这方面的尝试。Webkit能不能做到这一点?原理上是可以做到的,但是必须修改源代码。但是在改造以前,我们还是先踏踏实实研究一下,Webkit 的布局排版的内部机制是什么。只有充分了解对方之长,才有可能改进对方之短。

读解Webkit排版布局与绘制的具体实现以前,首先需要明确的是,Webkit把排版布局(layout),与绘制(paint),分开处理。

Layout负责确定Render Tree中,每个叶子和中间节点的位置。每个节点在屏幕上的显示,都呈长方形格局。所谓位置,指的是这个长方形左上角起始坐标(X,Y),以及长方形的宽度和高度。每个中间节点的长方形,里面嵌套着若干小长方形,对应这个中间节点的后代节点等等。

在Layout过程结束以后,Webkit启动 Paint过程,负责把Render Tree中各个叶子节点,在相应的位置绘制出来。Webkit 把具体绘制的工作,交给第三方图形工具库(Graphics Library)去完成。常用的第三方图形工具库包括QT,GTK+,Wx,Skia,Cairo等等。

打个比方,图形工具库相当于活字,以及绘制图像的石板(lithography),它们负责paint。而从严格意义上来说,Webkit的主要工作是layout,也就是排版布局,相当于版面模版。

关于图形库,台湾的开源高手,黄敬群(Jim Huang / jserv),写过一篇介绍Google Skia 图形库的文章(http://blog.linux.org.tw/~jserv/archives/002095.html)。文中谈到,

Google 为了搭建Android平台,于2005年8月并购了Android公司。同年11月份,Google还收购了Skia公司。2007年11 月,Google发布Android,并公开部分源代码。当人们热衷于探究Android Dalvik VM的奥秘的时候,忽略了Skia的意义。

2008年9月,Google发布了以改良的Webkit为核心的Chrome PC浏览器。当人们热衷于探究V8 JavaScript引擎等等功能模块时,再次忽略了Skia的意义。

Skia是一个2D图形工具库,该产品的特色在于,能够在手机等等移动设备中,以较低的内存和CPU消耗,呈现高品质的2D图形

Skia 的创办人,Mike Reed,是图形技术方面的顶尖人物。Mike早年任职于Apple,参与QuickDraw GX项目,处理字型和图像显示。后来他跳槽到OpenWave,开发手机浏览器。在OpenWave工作期间,与Benoit Schillings合作,在50-300KB的内存空间内,提供图层之间alpha blended方式的预览,以及全功能向量矩阵转换等等,真可谓螺丝壳里做道场。后来Benoit Schillings离开OpenWave,去Trolltech任职CTO。Trolltech的主打产品是大名鼎鼎的QT。再后来Trolltech 被Nokia并购,Benoit随之加入Nokia。Benoit Schillings离开OpenWave不久,Mike Reed也离开了OpenWave,去创建Skia公司。


QT分析之WebKit(九) - net_worm - net_worm 的博客
Figure 3. Layout implementation in Webkit
Courtesy http://www.flickr.com/photos/87209438%40N00/3609632247/sizes/l/

QT分析之WebKit(九) - net_worm - net_worm 的博客
Figure 4. Paint implementation in Webkit
Courtesy http://www.flickr.com/photos/87209438%40N00/3609632249/sizes/l/


Figure 3 和 Figure 4,分别显示了Webkit执行排版布局(layout),以及绘制(paint)的两个过程。仔细查看这两张sequence diagrams,会发现以下特点,

1. Layout 和 Paint 这两个过程完全分开。开始执行Paint过程以前,必然预先执行过Layout,否则图形库就不知道在哪里写字以及显示图像。但是这并不意味着,Layout执行结束后,随即就立刻执行Paint。实际上,Layout执行结束后,触发一个事件,这个事件启动Paint过程。但是Paint过程也可以被其它事件触发,譬如屏幕内容的切换,以及把隐藏的浏览器窗口复原等等。

2. Layout 涵盖了所有CSS规定的布局要素。包括页面边缘与内容之间的空白,文字对插入图像的避让(floating),单列与多列,上下层覆盖(z-index)等等。

3. 图像,视频播放器插件,Applet等等,在 Layout 被称作 Replaced Render Object。这些 Replaced 元素的宽度和高度可以由CSS规定。如果CSS没有规定,就解析这些元素的数据流,譬如一个JPG照片的metadata里,规定了这幅照片原件的宽度和高度。如果元素自己也没有规定宽度高度,就使用Webkit提供的缺省值。

4. 文字的宽度根据页面的排版来确定。譬如一页中包含多列文字,则每列文字宽度相等。每列文字的宽度,乘以列数,加上列与列之间的夹缝,加上页面边缘空白等等,应当等于页面总的宽度。假设页面总的宽度已知,边缘空白,和列与列之间的夹缝的宽度也已知,就可以反推文字的宽度。

5. Render Tree中每个节点在屏幕上的显示,都呈长方形格局。前面第3点和第4点,描述了宽度的确定。而高度的确定,取决于这个中间节点的所有后代节点的高度的总和。对于 Replaced 元素来说,它的高度相对比较容易确定,而文字段落的高度,需要根据字数,字型,以及字体大小计算得出。

6. 在 Layout 过程中,反复出现以 Repaint 为开头的子过程,例如 repaintAfterLayoutIfNeed
ed()。这些子过程的意义在于,当确定了某个节点的高度和宽度以后,需要对其前辈节点,和左右兄弟节点的位置,做适当调整。严格意义上来讲,这不是repaint,而是relayout

7. 相对于 Layout 过程,Paint 过程的逻辑要简单得多。Paint的过程,大致按照深度优先的顺序,遍历整棵RenderTree。也就是说,从最左边的叶子节点开始,从左向右逐个绘制 RenderTree所有可以显示的叶子节点。所谓“可以显示的叶子节点”,是因为CSS中可以规定,不显示某些叶子。


反复研究以上Layout和Paint的过程,我们有以下看法。

1. Layout 是一个计算量很繁重的过程。之所以繁重,主要体现在估算完每个RenderTree节点的宽度尤其是高度以后,需要相应调整这个节点的前辈节点以及左邻右舍兄弟节点的位置。对于文字段落而言,它的高度有赖于字数,字体和大小,所以估算不容易准确。

有没有可能把Layout 过程,与第一遍 Paint 过程合二为一?只要遍历一次RenderTree的所有叶子节点,绘制图像并码字。Paint过程结束后,各个叶子节点对应的长方形的起始位置的(X,Y)坐标,以及宽度和高度都自然迎刃而解。然后再由叶子节点开始,逐步确定RenderTree中,各个中间节点的起始位置和宽度高度。这样做的好处是,可以大大降低 Layout 过程的成本。

2. Layout 过程假设每个RenderTree 的节点都对应一个长方形屏幕区域。受限于这个规定,类似于Figure 2的效果,就显示不出来。有没有可能取消这个限制?SVG不仅提供了强大的绘图能力,而且也提供了强大的排版布局能力。能不能把CSS当着SVG格式的一个子集来看待?


http://www.niftyadmin.cn/n/1748310.html

相关文章

Hashtable源码分析_JDK1.8版本

Hashtable简介 声明 文章均为本人技术笔记&#xff0c;转载请注明出处https://segmentfault.com/u/yzwall Hashtable声明 public class Hashtable<K,V> extends Dictionary<K,V> implements Map<K,V>, Cloneable, java.io.SerializableHashtable和HashMap一样…

webkit源码分析系列-css盒模型和元素绘制

webkit源码分析系列-css盒模型和元素绘制2010年8月25日联系商易上海电子商务网站建设&#xff0c;了解更多 webkit源码分析系列-css盒模型和元素绘制 一、什么是css盒模型&#xff1f;  W3C组织就建议把所有网页上的对象都放在一个盒(box)中&#xff0c;设计师可以通过创建…

haproxy访问控制与动静分离

acl 语法&#xff1a;acl <acl_name> <criterion> [flags] [operator] <value>acl_name&#xff1a;自定义的acl名称&#xff0c;区分大小写&#xff0c;只能包含、字母、数字、"-"、 "_" 、":" 、 "."criterio…

JSP自定义不带属性和标签体的简单标签

1. 新建HelloTag类2. 添加额外的Jar包(1). 右键项目 -> Build Path -> Configure Build Path -> Libraries -> Add External JARs (2). 定位到tomcat安装目录的lib文件夹下&#xff08;我的是&#xff1a;C:\Program Files\Apache Software Foundation\Tomcat 9.0…

[webkit] htmlparser 部分

[webkit] htmlparser 部分 作者:hustyiyuan 2009-09-11 00:54 星期五 晴获取一个网页数据之后会调用 HTMLTokenizer::write这个函数&#xff0c; 传入的str即为 html 文档数据。HTMLTokenizer::write主要是解析html 文档&#xff0c;并构建对应的dom tree[node tree]&#xf…

ActiveMQ(05):JMS的API结构、开发步骤与Topic

一、JMS的API结构二、一个JMS应用的基本步骤1&#xff1a;创建一个JMS connection factory2&#xff1a;通过connection factory来创建JMS connection3&#xff1a;启动JMS connection4&#xff1a;通过connection创建JMS session5&#xff1a;创建JMS destination6&#xff1a…

WebKit介绍及总结(二)

WebKit介绍及总结&#xff08;二&#xff09; 五 . 调用过程 知道了 WebKit 的大体结构&#xff0c;我们就可以深究下去&#xff0c;看看这个浏览器引擎具体是怎么工作的。首先介绍几个基本且重要的类&#xff1a; Page &#xff1a;打开 page.h 头文件&#xff0c;我们似…

WebKit介绍及总结(三)

WebKit介绍及总结&#xff08;三&#xff09; 六 . 编译与调试 在 ubuntu-10.04 上编译 Webkit &#xff0c;所用的版本 r60742 &#xff0c;基于 Qt &#xff1a; 安装 sudo apt-get install libxslt-dev gperf bison libsqlite3-dev flex libqt4-dev build-essential s…