谷歌浏览器的源码分析(34)
2008-11-18 22:54
459 查看
通过上一次的分析,我们看到所有网页数据经过HTML分析器之后,都会变成一个一个RenderObject对象,那么这些RenderObject对象又是怎么样显示到界面上面的呢?现在就带着这个疑问来分析下面的代码,这样肯定会找到解决方法的。怎么样找到入口呢?其实可以先从界面显示的类开始,可以看到显示界面的窗口类名称叫做Chrome_RenderWidgetHostHWND,有了这个类名称,就可以到代码里查看它在那里了。
#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 =[/b]
#009 L"Chrome_RenderWidgetHostHWND";[/b]
可看到这个窗口类名称是定义在这里,再跟着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);[/b]
通过上面的分析,就可以找到显示网页的窗口类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 =[/b]
#008
render_widget_host_->GetBackingStore()[/b];
#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是怎么样显示的呢?这个会比上面的过程更加复杂,后面再仔细地分析它。下一次,主要仔细地看看这些过程里的一些类功能。
#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 =[/b]
#009 L"Chrome_RenderWidgetHostHWND";[/b]
可看到这个窗口类名称是定义在这里,再跟着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);[/b]
通过上面的分析,就可以找到显示网页的窗口类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 =[/b]
#008
render_widget_host_->GetBackingStore()[/b];
#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是怎么样显示的呢?这个会比上面的过程更加复杂,后面再仔细地分析它。下一次,主要仔细地看看这些过程里的一些类功能。
相关文章推荐
- 谷歌浏览器的源码分析(34)
- 谷歌浏览器的源码分析(34)
- 谷歌浏览器的源码分析(22)
- 谷歌浏览器的源码分析(23)
- 谷歌浏览器的源码分析(24)
- 谷歌浏览器的源码分析(6)
- 谷歌浏览器的源码分析(8)
- 谷歌浏览器的源码分析(9)
- 谷歌浏览器的源码分析(10)
- 谷歌浏览器的源码分析(15)
- 谷歌浏览器的源码分析(17)
- 谷歌浏览器的源码分析(18)
- suricata 3.1 源码分析34 (dns解析获取相关内容)
- 谷歌浏览器的源码分析(33)
- 谷歌浏览器的源码分析(22)
- 谷歌浏览器的源码分析(24)
- 谷歌浏览器的源码分析(1)
- 谷歌浏览器的源码分析(6)
- 谷歌浏览器的源码分析(7)
- 谷歌浏览器的源码分析(8)