android 4.0.1 webkit layout 过程分析

来源:互联网 发布:mac os high sierra 编辑:程序博客网 时间:2024/04/29 15:49
当RenderObject被创建并加入到RenderTree后,他们还没有获得自身的大小和位置信息。
各个具体的RenderBoxModelObject子类确定起自身的位置和大小的过程成为Layout.
layout过程执行完后,RenderTree上每个节点的位置信息和自身大小就确定下来了。
比如RenderBox的表示位置信息和自身大小的成员变量:
 IntRect m_frameRect;
int m_marginLeft;
int m_marginRight;
layout过程就是计算诸如此类的成员变量的值的过程,当这些值确定后,RenderObject就知道该如何渲染自己,然后才可以开始渲染过程。
webkit的 layout 过程是对CSS布局标准的具体实现,理清webkit layout的具体实现过程需要了解CSS的布局规范。
css中与页面元素的layout直接相关的属性有display,position,float.
display属性用来设置元素如何显示,比如当此属性值为none时,表示此元素不会被显示。
block则表示此元素将显示为块元素,inline表示此元素显示为内联元素。
html文档中display属性值设为block, list-item, table的元素为块元素。
display属性值设为inline, inline-table,inline-block的元素为内联元素。
块元素可作为容器包含其他的块元素或内联元素。
内联元素一般是基于语义级的基本元素,只能容纳文本或者其他内联元素。
HTML中的所有元素或者是块元素或者是内联元素。
html中所有可显示的元素都对应着一个或多个box 模型.layout过程就是确定这些box 的位置和大小的过程.
每一个块元素都会生成一个Principal Block-level Box。
list-item' element 除了生成一个Principal Block-level Box 外,还会生成更多的Box,这些Box的布局与Principal Block-level Box相关。
Block-level boxes 按照 block formatting context中定义的规则布局。
CSS 称布局Block-level boxes 的过程为Block-flow.
block formatting context:
block-level boxes 从一个containing block的顶端开始一个接一个垂直排列。还有更多的布局规则定义在http://www.w3.org/TR/CSS21/visuren.html#block-formatting
9.4.1 Block formatting contexts
除了 Table box 和 replaced element,所有的 block-level box 都是 block container box.
block container box 或者只含有block-level boxes 或者只含有inline-level boxes.
每一个内联元素会生成一个inline-level boxes 。inline-level boxes 按照  inline formatting context中定义的规则来布局。
inline formatting context:
inline-level boxes从一个containing block的顶端开始一个接一个水平排列。更多的布局规则定义在http://www.w3.org/TR/CSS21/visuren.html#block-formatting
9.4.2 Inline formatting contexts
CSS 称布局inline-level boxes 的过程为inline-flow.
box 的布局依据以下三种定位模式:
     1. Normal flow.
     包括block-level boxes 依据的 block formatting, inline-level boxes 依据的 inline formatting, 以及block-level boxes 和 inline-level boxes 依据的相对定位。
     2. Floats.
     box 先按照normal flow 布局,然后在从flow中提取出来,偏移到尽可能左或者尽可能右的地方。
     3.Absolute positioning.
     在这种定位模式下,box会彻底从normal flow 中移出来,box的定位由其自身相对于它的containing block的偏移量决定.

一个元素被称为in-flow,如果它的定位模式是Normal flow.
html元素的positon和float属性值决定了该元素生成的box的定位模式。
position属性的值有:
static,relative,absolute,fixed,inherit
static
  依据normal flow 模式来布局。     
relative
  box的位置信息先依据normal flow 模式来确定,再根据offset相对于normal flow模式确定下来的位置作偏移。
absolute
  box的位置信息由其自身相对于它的containing block的位置来确定。          
fixed
  box 的位置依据 absolute模式确定,但除此之外,还有一些别的参考条件。
每个元素都有一个containing block,根据元素的position 属性值的不同,它的box的containg block有不同的确定方式。
具体确定方式可参考
http://www.w3.org/TR/CSS21/visudet.html#containing-block-details  10.1 Definition of "containing block"
简单的说,可归结如下:
     1.根元素的containing block 叫做 initial containing block。(在webkit中对应RenderView)
     2.如果元素的position 属性值为relative 或者static, containing block 是最近的祖先block-level元素。   
     3.如果元素的position属性为fixed, containing block 或者由viewport 建立(在 continuous media 情况下)或者由page area 建立(在 page media 情况下)。

     4.如果元素的position属性值为absolute, containing block 是最近的非static的block-level元素。

webkit中FrameView是整个Document的Containing view,负责管理这个Render Tree的 layout.

frameview可以进行两种类型的layout.一种是对整个Render Tree进行Layout.这个情况下,Render Tree的根节点的layout方法被调用,从而触发这个render tree的layout过程。
另一种类型是只对整个RenderTree的一颗子树进行LayOut过程。
整颗Render Tree的根节点是RenderView即是html root 元素的containing block.
webviewcore.cpp中recordPictureSet()和recordPicture()会调用layoutIfNeededRecursive()。
从而调用FrameView.cpp的Layout()
webkit中与layout相关的主要方法有:
FrameView.cpp的Layout()会调用RenderView.cpp的Layout()
RenderBlock.cpp:layoutBlock()
RenderBlock::layoutBlockChild()
RenderBlock.cpp:layoutBlockChildren()
RenderBlockLineLayout.cpp:layoutInlineChildren()
RenderBlock::layoutPositionedObjects()
layout过程完成后RenderTree的各个节点才知道要如何渲染自己,才能开始渲染过程。


原创粉丝点击