您的位置:首页 > Web前端 > CSS

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

2011-01-04 19:30 627 查看
webkit源码分析系列-css盒模型和元素绘制

2010年8月25日联系商易上海电子商务网站建设,了解更多
webkit源码分析系列-css盒模型和元素绘制

一、什么是css盒模型?
  W3C组织就建议把所有网页上的对象都放在一个盒(box)中,设计师可以通过创建定义来控制这个盒的属性,这些对像包括段落、列表、标题、图片以及层。盒模型主要定义四个区域:内容(content)、边框距(padding)、边界(border)和边距(margin)。margin,background-color,background-image,padding,content,border之间的层次、关系和相互影响。盒模型的示意图。





  这些属性我们可以把它转移到我们日常生活中的盒子(箱子)上来理解,日常生活中所见的盒子也具有这些属性,所以叫它盒子模式。那么内容(content)就是盒子里装的东西;而填充(padding)就是怕盒子里装的东西(贵重的)损坏而添加的泡沫或者其它抗震的辅料;边框(border)就是盒子本身了;至于边界(margin)则说明盒子摆放的时候的不能全部堆在一起,要留一定空隙保持通风,同时也为了方便取出嘛。在网页设计上,内容常指文字、图片等元素,但是也可以是小盒子(DIV嵌套),与现实生活中盒子不同的是,现实生活中的东西一般不能大于盒子,否则盒子会被撑坏的,而CSS盒子具有弹性,里面的东西大过盒子本身最多把它撑大,但它不会损坏的。填充和边界只有宽度属性,可以理解为生活中盒子里的抗震辅料厚度,而边框有大小和颜色之分,可以对每一条边框定义不同的样式。我们又可以理解为生活中所见盒子的厚度以及这个盒子是用什么颜色材料做成的,边界就是该盒子与其它东西要保留多大距离。
  需要注意到是:width和height定义的是Content部分的宽度和高度而不是整个盒子的高度,padding border margin的宽度依次加在外面。背景会填充padding和content部分。但是由于浏览器设计上的问题,不同浏览器显示效果会有些不同。左右Margin加倍的问题当box为float时,IE6中box左右的margin会加倍。
  W3C定义的平面盒模式如下:



二、webkit元素绘制

1.RenderBoxModelObject

(1)在RenderBoxModelObject::styleDidChange()函数里,会根据requiresLayer()函数的返回值,来决定是否
创建一个RenderLayer。requiresLayer()函数的定义为:
virtual bool requiresLayer() const { return isRoot() || isPositioned() || isRelPositioned() || isTransparent() || hasOverflowClip() ||
hasTransform() || hasMask() || hasReflection(); }
在其定义中:
isRoot()判断是否为根节点;
isPositioned()判断是否为absolute定位方式,或者fixed定位方式;
isRelPositioned()判断是否为relative定位方式;
isTransparent()对应于css属性的opacity(透明度),只有当opacity小于1.0时,返回值才为真。
后面几个条件为内部的条件,与css属性无关。
如果要创建一个RenderLayer,就需要上面的requiresLayer()返回为真,所以能够触发创建一个RenderLayer的css属性为:
position:absolute,relative,fixed(static不能,它为无特殊定位,对象遵循HTML定位规则);opacity:小于1 (大于1,isTransparent()
函数返回假,不会创建RenderLayer;小于0的时候,该函数也返回真,会创建RenderLayer)。
创建RenderLayer代码:m_layer = new (renderArena()) RenderLayer(this);

(2)在RenderBoxModelObject::styleDidChange()函数里,创建RenderLayer之后,必须调用setHasLayer(true)函数,否则该RenderLayer
不会被渲染,即被视为没有RenderLayer。

(3)在RenderBoxModelObject::styleDidChange()函数里将新创建的RenderLayer插入RenderLayer树中去。
代码: m_layer->insertOnlyThisLayer();
2.RenderLayer

(1)在RenderLayer::updateZOrderLists()函数里,通过一个for循环,把RenderBoxModelObject::styleDidChange()函数里,插入进来的
所有RenderLayer加入到m_posZOrderList。
m_posZOrderList的定义为:Vector<RenderLayer*>* m_posZOrderList;
这个函数的调用过程如下:
#0 0x42a61f40 in kill () from /lib/libc.so.0
#1 0x42052f14 in pthread_kill () from /lib/libpthread.so.0
#2 0x420534c8 in raise () from /lib/libpthread.so.0
#3 0x4167d438 in QWSSignalHandler::handleSignal () from /opt/lib/libQtGui.so.4
#4 <signal handler called>
#5 0x40e1fc78 in WebCore::RenderLayer::updateZOrderLists () from /opt/lib/libQtWebKit.so.4
#6 0x40e1fe7c in WebCore::RenderLayer::updateLayerListsIfNeeded () from /opt/lib/libQtWebKit.so.4
#7 0x40e1ff3c in WebCore::RenderLayer::hitTestLayer () from /opt/lib/libQtWebKit.so.4
#8 0x40e2043c in WebCore::RenderLayer::hitTestLayer () from /opt/lib/libQtWebKit.so.4
#9 0x40e2115c in WebCore::RenderLayer::hitTest () from /opt/lib/libQtWebKit.so.4
#10 0x408437c0 in WebCore::Document::prepareMouseEvent () from /opt/lib/libQtWebKit.so.4
#11 0x40c8b3e0 in WebCore::EventHandler::prepareMouseEvent () from /opt/lib/libQtWebKit.so.4
#12 0x40c96580 in WebCore::EventHandler::handleMouseMoveEvent () from /opt/lib/libQtWebKit.so.4
#13 0x40c96c0c in WebCore::EventHandler::mouseMoved () from /opt/lib/libQtWebKit.so.4
#14 0x40f4cf38 in WebCore::FrameLoaderClientQt::postProgressFinishedNotification () from /opt/lib/libQtWebKit.so.4
#15 0x40c16808 in WebCore::ProgressTracker::finalProgressComplete () from /opt/lib/libQtWebKit.so.4
#16 0x40c16954 in WebCore::ProgressTracker::progressCompleted () from /opt/lib/libQtWebKit.so.4
#17 0x40bb3518 in WebCore::FrameLoader::checkLoadCompleteForThisFrame () from /opt/lib/libQtWebKit.so.4
#18 0x40bbb008 in WebCore::FrameLoader::recursiveCheckLoadComplete () from /opt/lib/libQtWebKit.so.4
#19 0x40b9f57c in WebCore::DocumentLoader::removeSubresourceLoader () from /opt/lib/libQtWebKit.so.4
#20 0x40c2d51c in WebCore::SubresourceLoader::didFinishLoading () from /opt/lib/libQtWebKit.so.4
#21 0x40c23498 in WebCore::ResourceLoader::didFinishLoading () from /opt/lib/libQtWebKit.so.4
#22 0x40f0bb4c in WebCore::QNetworkReplyHandler::finish () from /opt/lib/libQtWebKit.so.4
#23 0x40f0c7f0 in WebCore::QNetworkReplyHandler::qt_metacall () from /opt/lib/libQtWebKit.so.4
#24 0x41f03374 in QMetaCallEvent::placeMetaCall () from /opt/lib/libQtCore.so.4
#25 0x41f061ac in QObject::event () from /opt/lib/libQtCore.so.4
#26 0x41697c30 in QApplicationPrivate::notify_helper () from /opt/lib/libQtGui.so.4
#27 0x41698b8c in QApplication::notify () from /opt/lib/libQtGui.so.4
#28 0x41eef1b4 in QCoreApplication::notifyInternal () from /opt/lib/libQtCore.so.4
#29 0x41ef42d0 in QCoreApplicationPrivate::sendPostedEvents () from /opt/lib/libQtCore.so.4
#30 0x00000000 in ?? ()

(2)在RenderLayer::paintLayer()函数里,会通过判断m_posZOrderList是否为空,来决定是否继续进行渲染。
代码:
if (m_posZOrderList)
for (Vector<RenderLayer*>::iterator it = m_posZOrderList->begin(); it != m_posZOrderList->end(); ++it)
it[0]->paintLayer(rootLayer, p, paintDirtyRect, paintRestriction, paintingRoot, overlapTestRequests, localPaintFlags);
通过这段代码,将m_posZOrderList里面所有的RenderLayer都渲染,它递归地回调到了paintLayer()函数。

(3)对于每个RenderLayer,会通过下面代码,进入到RenderObject里面,进行具体的渲染。
if (!selectionOnly) {
paintInfo.phase = PaintPhaseFloat;
renderer()->paint(paintInfo, tx, ty);
paintInfo.phase = PaintPhaseForeground;
paintInfo.overlapTestRequests = overlapTestRequests;
renderer()->paint(paintInfo, tx, ty); //为浏览器内容绘制的入口,很重要
paintInfo.phase = PaintPhaseChildOutlines;
renderer()->paint(paintInfo, tx, ty);
}
3.RenderBlock

(1)在RenderBlock::paint()函数里,调用RenderBlock::paintObject()函数,进入RenderObject的绘制。

(2)在RenderBlock::paintObject()函数里,会完成各个阶段的绘制,先从背景,再到内容,浮动,边框等。

(3)在绘制内容时,调用RenderBlock::paintContents()函数,它又会调用RenderBlock::paintChildren()来绘制其子元素。在绘制
子元素函数里面,通过child->paint()回调到RenderBlock::paint()函数。这样就形成了递归调用,直到把所有需要绘制的元素都绘制
完。从这里也可以看出,是从下层往上层绘制,因为paintContents()是在RenderBlock::paintObject()的第二阶段,只有它完成了,
才会绘制其他部分。

函数调用关系:
#0 0x42a60f40 in kill () from /lib/libc.so.0
#1 0x42051f14 in pthread_kill () from /lib/libpthread.so.0
#2 0x420524c8 in raise () from /lib/libpthread.so.0
#3 0x4167c438 in QWSSignalHandler::handleSignal () from /opt/lib/libQtGui.so.4
#4 <signal handler called>
#5 0x40db3c98 in WebCore::RenderBlock::paint () from /opt/lib/libQtWebKit.so.4
#6 0x40db3fdc in WebCore::RenderBlock::paintChildren () from /opt/lib/libQtWebKit.so.4
#7 0x40dc8b2c in WebCore::RenderBlock::paintObject () from /opt/lib/libQtWebKit.so.4
#8 0x40db3c04 in WebCore::RenderBlock::paint () from /opt/lib/libQtWebKit.so.4 重要点,从8到5递归调用。绘制需要重新绘制的元素。
#9 0x40e22ec0 in WebCore::RenderLayer::paintLayer () from /opt/lib/libQtWebKit.so.4
#10 0x40e22760 in WebCore::RenderLayer::paintLayer () from /opt/lib/libQtWebKit.so.4
#11 0x40e23430 in WebCore::RenderLayer::paint () from /opt/lib/libQtWebKit.so.4
#12 0x40cb3fa0 in WebCore::FrameView::paintContents () from /opt/lib/libQtWebKit.so.4
#13 0x40f60000 in QWebFramePrivate::renderPrivate () from /opt/lib/libQtWebKit.so.4
#14 0x40f90360 in QWebView::paintEvent () from /opt/lib/libQtWebKit.so.4
#15 0x416da7fc in QWidget::event () from /opt/lib/libQtGui.so.4
#16 0x40f8ff78 in QWebView::event () from /opt/lib/libQtWebKit.so.4
#17 0x41696c30 in QApplicationPrivate::notify_helper () from /opt/lib/libQtGui.so.4
#18 0x41697b8c in QApplication::notify () from /opt/lib/libQtGui.so.4
#19 0x41eee1b4 in QCoreApplication::notifyInternal () from /opt/lib/libQtCore.so.4
#20 0x416d83b0 in QWidgetPrivate::drawWidget () from /opt/lib/libQtGui.so.4
#21 0x41850394 in QWidgetBackingStore::sync () from /opt/lib/libQtGui.so.4
#22 0xbef9c790 in ?? ()
4.表单输入控件(input)

每个表单输入控件会在RenderBoxModelObject::styleDidChange()函数里,创建一个RenderLayer (因为我们在css默认样式里面,对input使用了opacity属性)。

(1).对于表单输入控件,其绘制不是通过RenderBlock::paintObject ()函数里面第二阶段(2. paint contents)的paintContents(paintInfo, tx, ty)
函数调用来绘制的,而是通过第一阶段(1. paint background, borders etc)的paintBoxDecorations(paintInfo, tx, ty)函数调用来绘制。

(2).在RenderBox::paintBoxDecorations ()函数里,通过 bool themePainted = style()->hasAppearance() && !theme()->paint(this, paintInfo, IntRect(tx, ty, w, h));
语句,在theme()->paint(this, paintInfo, IntRect(tx, ty, w, h)中,进入RenderTheme::paint () 。

(3).在RenderTheme::paint () 函数里面,绘制各种表单输入控件。往下面就是调用QT的图像绘制函数。

表单输入控件。这里是<input type=radio value="">的函数调用:
#0 0x42a59f40 in kill () from /lib/libc.so.0
#1 0x4204af14 in pthread_kill () from /lib/libpthread.so.0
#2 0x4204b4c8 in raise () from /lib/libpthread.so.0
#3 0x41675438 in QWSSignalHandler::handleSignal () from /opt/lib/libQtGui.so.4
#4 <signal handler called>
#5 0x40e2ca74 in WebCore::RenderObject::isBody () from /opt/lib/libQtWebKit.so.4
#6 0x40f2b2c8 in WebCore::RenderThemeQt::paintButton () from /opt/lib/libQtWebKit.so.4
#7 0x40f299a4 in WebCore::RenderThemeQt::paintCheckbox () from /opt/lib/libQtWebKit.so.4
#8 0x40e6feb4 in WebCore::RenderTheme::paint () from /opt/lib/libQtWebKit.so.4
#9 0x40dd88a4 in WebCore::RenderBox::paintBoxDecorations () from /opt/lib/libQtWebKit.so.4
#10 0x40dbdb10 in WebCore::RenderBlock::paintObject () from /opt/lib/libQtWebKit.so.4
#11 0x40dac69c in WebCore::RenderBlock::paint () from /opt/lib/libQtWebKit.so.4
#12 0x40e1b28c in WebCore::RenderLayer::paintLayer () from /opt/lib/libQtWebKit.so.4
#13 0x40e1b524 in WebCore::RenderLayer::paintLayer () from /opt/lib/libQtWebKit.so.4
#14 0x40e1b524 in WebCore::RenderLayer::paintLayer () from /opt/lib/libQtWebKit.so.4
#15 0x40e1c2c0 in WebCore::RenderLayer::paint () from /opt/lib/libQtWebKit.so.4
#16 0x40caca60 in WebCore::FrameView::paintContents () from /opt/lib/libQtWebKit.so.4
#17 0x40f58ee0 in QWebFramePrivate::renderPrivate () from /opt/lib/libQtWebKit.so.4
#18 0x40f89098 in QWebView::paintEvent () from /opt/lib/libQtWebKit.so.4
#19 0x416d37fc in QWidget::event () from /opt/lib/libQtGui.so.4
#20 0x40f88ca4 in QWebView::event () from /opt/lib/libQtWebKit.so.4
#21 0x4168fc30 in QApplicationPrivate::notify_helper () from /opt/lib/libQtGui.so.4
#22 0x41690b8c in QApplication::notify () from /opt/lib/libQtGui.so.4
#23 0x41ee71b4 in QCoreApplication::notifyInternal () from /opt/lib/libQtCore.so.4
#24 0x416d13b0 in QWidgetPrivate::drawWidget () from /opt/lib/libQtGui.so.4
#25 0x41849394 in QWidgetBackingStore::sync () from /opt/lib/libQtGui.so.4
#26 0xbedb1790 in ?? ()

(4).对于password,text两种input输入控件,会在WebCore/rendering/TextControlInnerElements.cpp文件里,创建一个HTMLDivElement。
代码:
TextControlInnerElement::TextControlInnerElement(Document* doc, Node* shadowParent)
: HTMLDivElement(HTMLNames::divTag, doc)
, m_shadowParent(shadowParent)
{
}
它被绑定在对应的input上,它们之间是兄弟关系。这里创建的div,在后面会调用setHasOverflowClip()函数来设置其m_hasOverflowClip。即在RenderBoxModelObject::styleDidChange()函数里,在“if (requiresLayer())”条件里,requiresLayer()函数的第五个条件hasOverflowClip()为真,
则就会创建此div对应的RenderLayer。

创建div对应的RenderObject函数调用:
#0 0x42a5bf40 in kill () from /lib/libc.so.0
#1 0x4204cf14 in pthread_kill () from /lib/libpthread.so.0
#2 0x4204d4c8 in raise () from /lib/libpthread.so.0
#3 0x41677438 in QWSSignalHandler::handleSignal () from /opt/lib/libQtGui.so.4
#4 <signal handler called>
#5 0x40e34c98 in WebCore::RenderObject::RenderObject () from /opt/lib/libQtWebKit.so.4
#6 0x40de06a8 in WebCore::RenderBoxModelObject::RenderBoxModelObject () from /opt/lib/libQtWebKit.so.4
#7 0x40dde648 in WebCore::RenderBox::RenderBox () from /opt/lib/libQtWebKit.so.4
#8 0x40daba90 in WebCore::RenderBlock::RenderBlock () from /opt/lib/libQtWebKit.so.4
#9 0x40e840b0 in WebCore::TextControlInnerTextElement::createRenderer () from /opt/lib/libQtWebKit.so.4 ( 创建div对应的RenderObject)
#10 0x40e849c0 in WebCore::TextControlInnerElement::attachInnerElement () from /opt/lib/libQtWebKit.so.4
#11 0x40e617e8 in WebCore::RenderTextControl::createSubtreeIfNeeded () from /opt/lib/libQtWebKit.so.4 (重要点)
#12 0x40e6a958 in WebCore::RenderTextControlSingleLine::createSubtreeIfNeeded () from /opt/lib/libQtWebKit.so.4
#13 0x40e6ac40 in WebCore::RenderTextControlSingleLine::updateFromElement () from /opt/lib/libQtWebKit.so.4
#14 0x40aa3430 in WebCore::HTMLFormControlElement::attach () from /opt/lib/libQtWebKit.so.4
#15 0x40ab7974 in WebCore::HTMLInputElement::attach () from /opt/lib/libQtWebKit.so.4
#16 0x40adeb94 in WebCore::HTMLParser::insertNode () from /opt/lib/libQtWebKit.so.4
#17 0x40adfa20 in WebCore::HTMLParser::parseToken () from /opt/lib/libQtWebKit.so.4
#18 0x40b01064 in WebCore::HTMLTokenizer::processToken () from /opt/lib/libQtWebKit.so.4
#19 0x40b15bec in WebCore::HTMLTokenizer::parseTag () from /opt/lib/libQtWebKit.so.4
#20 0x40b17c0c in WebCore::HTMLTokenizer::write () from /opt/lib/libQtWebKit.so.4
#21 0x40baf6b8 in WebCore::FrameLoader::write () from /opt/lib/libQtWebKit.so.4
#22 0x40f45fb4 in WebCore::FrameLoaderClientQt::committedLoad () from /opt/lib/libQtWebKit.so.4
#23 0x40ba4b8c in WebCore::FrameLoader::committedLoad () from /opt/lib/libQtWebKit.so.4
#24 0x40b8d904 in WebCore::DocumentLoader::commitLoad () from /opt/lib/libQtWebKit.so.4
#25 0x40c1ce1c in WebCore::ResourceLoader::didReceiveData () from /opt/lib/libQtWebKit.so.4
#26 0x40bf9cb8 in WebCore::MainResourceLoader::didReceiveData () from /opt/lib/libQtWebKit.so.4
#27 0x40c1c6b4 in WebCore::ResourceLoader::didReceiveData () from /opt/lib/libQtWebKit.so.4
#28 0x40f0561c in WebCore::QNetworkReplyHandler::forwardData () from /opt/lib/libQtWebKit.so.4
#29 0x40f067f0 in WebCore::QNetworkReplyHandler::qt_metacall () from /opt/lib/libQtWebKit.so.4
#30 0x41efd374 in QMetaCallEvent::placeMetaCall () from /opt/lib/libQtCore.so.4
#31 0x41f001ac in QObject::event () from /opt/lib/libQtCore.so.4
#32 0x41691c30 in QApplicationPrivate::notify_helper () from /opt/lib/libQtGui.so.4
#33 0x41692b8c in QApplication::notify () from /opt/lib/libQtGui.so.4
#34 0x41ee91b4 in QCoreApplication::notifyInternal () from /opt/lib/libQtCore.so.4
#35 0x41eee2d0 in QCoreApplicationPrivate::sendPostedEvents () from /opt/lib/libQtCore.so.4
#36 0x000a9f60 in ?? ()

创建HTMLDivElement函数调用:
#0 0x42a5af40 in kill () from /lib/libc.so.0
#1 0x4204bf14 in pthread_kill () from /lib/libpthread.so.0
#2 0x4204c4c8 in raise () from /lib/libpthread.so.0
#3 0x41676438 in QWSSignalHandler::handleSignal () from /opt/lib/libQtGui.so.4
#4 <signal handler called>
#5 0x40e836d8 in WebCore::TextControlInnerElement::TextControlInnerElement () from /opt/lib/libQtWebKit.so.4
#6 0x40e83974 in WebCore::TextControlInnerTextElement::TextControlInnerTextElement () from /opt/lib/libQtWebKit.so.4 (构造函数里创建HTMLDivElement)
#7 0x40e60f84 in WebCore::RenderTextControl::createSubtreeIfNeeded () from /opt/lib/libQtWebKit.so.4 (重要点)
#8 0x40e6a1a0 in WebCore::RenderTextControlSingleLine::createSubtreeIfNeeded () from /opt/lib/libQtWebKit.so.4
#9 0x40e6a488 in WebCore::RenderTextControlSingleLine::updateFromElement () from /opt/lib/libQtWebKit.so.4
#10 0x40aa31e8 in WebCore::HTMLFormControlElement::attach () from /opt/lib/libQtWebKit.so.4
#11 0x40ab772c in WebCore::HTMLInputElement::attach () from /opt/lib/libQtWebKit.so.4
#12 0x40ade94c in WebCore::HTMLParser::insertNode () from /opt/lib/libQtWebKit.so.4
#13 0x40adf7d8 in WebCore::HTMLParser::parseToken () from /opt/lib/libQtWebKit.so.4
#14 0x40b00e1c in WebCore::HTMLTokenizer::processToken () from /opt/lib/libQtWebKit.so.4
#15 0x40b159a4 in WebCore::HTMLTokenizer::parseTag () from /opt/lib/libQtWebKit.so.4
#16 0x40b179c4 in WebCore::HTMLTokenizer::write () from /opt/lib/libQtWebKit.so.4
#17 0x40baf470 in WebCore::FrameLoader::write () from /opt/lib/libQtWebKit.so.4
#18 0x40f459d4 in WebCore::FrameLoaderClientQt::committedLoad () from /opt/lib/libQtWebKit.so.4
#19 0x40ba4944 in WebCore::FrameLoader::committedLoad () from /opt/lib/libQtWebKit.so.4
#20 0x40b8d6bc in WebCore::DocumentLoader::commitLoad () from /opt/lib/libQtWebKit.so.4
#21 0x40c1cbd4 in WebCore::ResourceLoader::didReceiveData () from /opt/lib/libQtWebKit.so.4
#22 0x40bf9a70 in WebCore::MainResourceLoader::didReceiveData () from /opt/lib/libQtWebKit.so.4
#23 0x40c1c46c in WebCore::ResourceLoader::didReceiveData () from /opt/lib/libQtWebKit.so.4
#24 0x40f0503c in WebCore::QNetworkReplyHandler::forwardData () from /opt/lib/libQtWebKit.so.4
#25 0x40f06210 in WebCore::QNetworkReplyHandler::qt_metacall () from /opt/lib/libQtWebKit.so.4
#26 0x41efc374 in QMetaCallEvent::placeMetaCall () from /opt/lib/libQtCore.so.4
#27 0x41eff1ac in QObject::event () from /opt/lib/libQtCore.so.4
#28 0x41690c30 in QApplicationPrivate::notify_helper () from /opt/lib/libQtGui.so.4
#29 0x41691b8c in QApplication::notify () from /opt/lib/libQtGui.so.4
#30 0x41ee81b4 in QCoreApplication::notifyInternal () from /opt/lib/libQtCore.so.4
#31 0x41eed2d0 in QCoreApplicationPrivate::sendPostedEvents () from /opt/lib/libQtCore.so.4
#32 0x000a9f60 in ?? ()
5.元素具体绘制

图片,文字,表单输入控件的绘制,都是通过从RenderBlock::paint () 开始,在RenderBlock::paintObject ()中,调用RenderBlock::paintContents ()函数,
来进行递归地绘制。在RenderBlock::paintContents ()函数里,有下面代码:
if (childrenInline())
m_lineBoxes.paint(this, paintInfo, tx, ty);
else
paintChildren(paintInfo, tx, ty);
如果是inline,则进入具体网页内容的绘制。网页上面的图片和文字,都是以inline的方式呈现。即图片和文字都必须通过”m_lineBoxes.paint(this, paintInfo, tx, ty);“
语句,才能够显示在浏览器上面,它决定了网页上面是否能够正常显示图片和文字。
注意:网页上的文字或空格都会创建一个“#text”节点。
文本绘制的函数调用:
#3 0x40d0ecb4 in WebCore::GraphicsContext::drawText () from /opt/lib/libQtWebKit.so.4 (开始绘制文字)
#4 0x40da44ac in WebCore::paintTextWithShadows () from /opt/lib/libQtWebKit.so.4
#5 0x40da7a24 in WebCore::InlineTextBox::paint ()
#6 0x40d9ea28 in WebCore::InlineBox::paint () from /opt/lib/libQtWebKit.so.4
#7 0x40da3c1c in WebCore::InlineFlowBox::paint () from /opt/lib/libQtWebKit.so.4
#8 0x40e82184 in WebCore::RootInlineBox::paint () from /opt/lib/libQtWebKit.so.4
#9 0x40e1db34 in WebCore::RenderLineBoxList::paint () from /opt/lib/libQtWebKit.so.4
#10 0x40daccec in WebCore::RenderBlock::paintContents () from /opt/lib/libQtWebKit.so.4
#11 0x40dc1698 in WebCore::RenderBlock::paintObject () from /opt/lib/libQtWebKit.so.4
#12 0x40dac78c in WebCore::RenderBlock::paint () from /opt/lib/libQtWebKit.so.4

图片绘制的函数调用:
#5 0x40d11784 in WebCore::GraphicsContext::drawImage () from /opt/lib/libQtWebKit.so.4
#6 0x40e03570 in WebCore::RenderImage::paintReplaced () from /opt/lib/libQtWebKit.so.4
#7 0x40e3fb54 in WebCore::RenderReplaced::paint () from /opt/lib/libQtWebKit.so.4
#8 0x40d9eb4c in WebCore::InlineBox::paint () from /opt/lib/libQtWebKit.so.4
#9 0x40da3c24 in WebCore::InlineFlowBox::paint () from /opt/lib/libQtWebKit.so.4
#10 0x40e82198 in WebCore::RootInlineBox::paint () from /opt/lib/libQtWebKit.so.4
#11 0x40e1db48 in WebCore::RenderLineBoxList::paint () from /opt/lib/libQtWebKit.so.4
#12 0x40daccb4 in WebCore::RenderBlock::paintContents () from /opt/lib/libQtWebKit.so.4
#13 0x40dc1660 in WebCore::RenderBlock::paintObject () from /opt/lib/libQtWebKit.so.4
#14 0x40dac754 in WebCore::RenderBlock::paint () from /opt/lib/libQtWebKit.so.4

表单输入控件绘制的函数调用:
#6 0x40f2b2c8 in WebCore::RenderThemeQt::paintButton () from /opt/lib/libQtWebKit.so.4
#7 0x40f299a4 in WebCore::RenderThemeQt::paintCheckbox () from /opt/lib/libQtWebKit.so.4
#8 0x40e6feb4 in WebCore::RenderTheme::paint () from /opt/lib/libQtWebKit.so.4 (这里判断表单输入控件的类型,然后调用该类型的绘制函数)
#9 0x40dd88a4 in WebCore::RenderBox::paintBoxDecorations () from /opt/lib/libQtWebKit.so.4
#10 0x40dbdb10 in WebCore::RenderBlock::paintObject () from /opt/lib/libQtWebKit.so.4
#11 0x40dac69c in WebCore::RenderBlock::paint () from /opt/lib/libQtWebKit.so.4
总结
元素的绘制,是由默认配置(html4.css)中的display,-webkit-appearance这些css属性来控制其具体的绘制流程。即这些css属性变化,他们的绘制也会发生相应的变化。即我们对一些浏览器问题的处理,是基于某一种css默认配置的处理。所以不要轻易改动css默认配置,尤其是与上面的两条属性有关的样式。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: