#001
class RenderWidgetHost;
#002
class WebMouseEvent;
#003
class WebCursor;
#004
#005
typedef CWinTraits<WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 0>
#006
RenderWidgetHostHWNDTraits;
#007
#008
static const wchar_t* const kRenderWidgetHostHWNDClass =
#
可看到这个窗口类名称是定义在这里,再跟着
kRenderWidgetHostHWNDClass
来查找,就会找到显示窗口,如下:
#001
class RenderWidgetHostHWND :
#002
public CWindowImpl<RenderWidgetHostHWND,
#003
CWindow,
#004
RenderWidgetHostHWNDTraits>,
#005
public RenderWidgetHostView {
#006
public:
#007
RenderWidgetHostHWND(RenderWidgetHost* render_widget_host);
#008
virtual ~RenderWidgetHostHWND();
#009
#010
void set_close_on_deactivate(bool close_on_deactivate) {
#011
close_on_deactivate_ = close_on_deactivate;
#012
}
#013
#014
void set_parent_hwnd(HWND parent) { parent_hwnd_ = parent; }
#015
#016
DECLARE_WND_CLASS_EX(kRenderWidgetHostHWNDClass, CS_DBLCLKS, 0);
通过上面的分析,就可以找到显示网页的窗口类
RenderWidgetHostHWND
,在这个类里,主要显示的位置是在
void RenderWidgetHostHWND::OnPaint(HDC dc)
函数里面,它的代码如下:
#001
void RenderWidgetHostHWND::OnPaint(HDC dc) {
#002
DCHECK(render_widget_host_->process()->channel());
#003
#004
CPaintDC paint_dc(m_hWnd);
#005
HBRUSH white_brush = reinterpret_cast<HBRUSH>(GetStockObject(WHITE_BRUSH));
#006
#007
RenderWidgetHost::BackingStore* backing_store =
#008
render_widget_host_->GetBackingStore()
;
#009
#010
if (backing_store) {
#011
gfx::Rect damaged_rect(paint_dc.m_ps.rcPaint);
#012
#013
gfx::Rect bitmap_rect(
#014
0, 0, backing_store->size().width(), backing_store->size().height());
#015
#016
gfx::Rect paint_rect = bitmap_rect.Intersect(damaged_rect);
#017
if (!paint_rect.IsEmpty()) {
#018
BitBlt(paint_dc.m_hDC,
#019
paint_rect.x(),
#020
paint_rect.y(),
#021
paint_rect.width(),
#022
paint_rect.height(),
#023
backing_store->dc(),
#024
paint_rect.x(),
#025
paint_rect.y(),
#026
SRCCOPY);
#027
}
......
#058
}
其实这个函数是通过如下发送消息给另一个进程进行渲染成
BMP
的图片,
Send(new ViewMsg_Repaint(routing_id_, view_size));
那么谁来接收
ViewMsg_Repaint
消息呢?继续细心地查找,就到在如下类函数里处理:
void RenderWidget::OnMsgRepaint(const gfx::Size& size_to_paint)
在这个函数,并不是最终的结果,它又会调用其它线程来处理渲染,以便达到异步的结果。它的调用过程如下:
1)
RenderWidget::DoDeferredPaint()
线程里开始渲染网页显示
2)
RenderWidget::PaintRect()
窗口里开始进行显示
3)
WebViewImpl::Paint() web
视类开始显示。
4)
WebFrameImpl::Paint() web
框架类开始显示。
5)
WebCore::ScrollView::paint()
滚动窗口显示。
6)
WebCore::Frame::paint() WebCore
里的框架显示。
7)
WebCore::RenderLayer::paint()
分层显示。
8)
WebCore::RenderLayer::paintLayer()
9)
WebCore::RenderBlock::paint()
在每一层里显示每一块区域。
10)
WebCore::RenderBlock::paintObject()
显示这一区域的对象。
11)
WebCore::RenderBlock::paintContents()
显示需要显示的内容。
12)
WebCore::RenderFlow::paintLines()
这里需要显示文字。
13)
WebCore::RootInlineBox::paint()
开始显示一行文字。
14)
WebCore::InlineFlowBox::paint()
进行一行文字排列。
15)
WebCore::InlineTextBox::paint()
16)
WebCore::GraphicsContext::drawText()
进行一个一个文字显示。
17)
WebCore::Font::drawText()
这里调用字体类来把文字的编码变成位图。
18)
WebCore::Font::drawSimpleText()
这里把位图显示到界面内存里。
通过上面的分析,可以看到显示一串文字的过程是如此复杂的过程。其它图片显示的过程也是一样,都把它们变成位图,然后再分层显示出来。那么
JavaScript
是怎么样显示的呢?这个会比上面的过程更加复杂,后面再仔细地分析它。下一次,主要仔细地看看这些过程里的一些类功能。