12月17, 2013

[译]CSS在WebKit和Blink下的区域绘制

由安德烈·布库尔发表于2013年10月28日

CSS 2.1规范定义了一个盒模型用来显示页面文档里面的内容。WebKit和Blink引擎遵守本规范并且予以实现,那么,假设显示文档布局时每个元素都是一个单独的盒子,文档片段越来越多,就会出现一个盒子里还有多个盒子的情况。这意味着,引擎必须做一些判断和处理来正确渲染它们。关于Fragment实现方面在我之前的文章 “CSS Fragmentation In WebKit”中有详细介绍。所以在这篇文章中,我们专注于CSS区域绘制是如何实现的。

图片1

图1

     考虑这样一个文档流RenderFlowThread,它包含3个指定宽高的区域。渲染之初,布局中只有body元素的内容,所以会先计算页面主区域(RenderRegion对象)的大小和位置。然后再展现RenderFlowThread对象中的内容。正如你所看到的,各区域宽度不同,这也将影响线框(line box)的大小。图1可以看到布局后的RenderFlowThread草图,我们以不同的颜色来区分这些片段,之后好方便看该区域将被定位的地方。严格地说,文档流的宽度应为其内容中最宽区域的宽度(在这个例子中是RenderRegion3)。根据存储在RenderBoxRegionInfo类型对象中的宽度值,每个区域block的宽度决定了线框的宽度。各区域间的空白是有分页支柱标识的(在图1中为灰色箭头表示),看起来自然些。因为RenderFlowThread的高度是其所有区域高度的总和,如果内容太多,可能会溢出(见图1中RenderFlowThread的底部)。

图片2

图2

随后,在绘图时候内容片段才真正被渲染。当一个区域将要被绘制时,它会先调整图形上下文的位置,然后在正确的位置上绘制RenderFlowThread层内的该区域盒内容。再次根据RenderBoxRegionInfo对象来调整它的宽度,一切看起来都像在区域内部的一样(例如边框和阴影等)。其他区域的部分并不在预期之内,会被裁剪掉(如图2的灰色部分)。在最后一个区域,你可以看到底部溢出的区域没有被裁剪。这是因为裁剪的是RenderFlowThread的可视化部分,它包括所有的内容,直到再没有自绘制的层为止。就这样,RenderFlowThread的内容(包括溢出)被分散了,每个区域绘制的仅仅是它的一部分。在绘制过程的最后,RenderFlowThread看起来像如下图3,每个区域只包括其一部分,最后一个区域的溢出是可见的。

图片3

图3

目前我们正在研究的以上流程的一个重要改进。就是如何把对RenderFlowThread的绘制委派给区域层自身去处理,而不是目前执行的区域渲染。这能使我们以树形结构更好的绘制RenderFlowThread,并且修复一些bug(例如:相对定位溢出区域的裁剪错误)。

本文链接:https://75team.com/post/css在webkit和blink下的区域绘制.html

-- EOF --

Comments

评论加载中...

注:如果长时间无法加载,请针对 disq.us | disquscdn.com | disqus.com 启用代理。