谷歌浏览器的源码分析(34)

系统 2389 0
通过上一次的分析,我们看到所有网页数据经过 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 =

# 009       L "Chrome_RenderWidgetHostHWND";

 

可看到这个窗口类名称是定义在这里,再跟着 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 是怎么样显示的呢?这个会比上面的过程更加复杂,后面再仔细地分析它。下一次,主要仔细地看看这些过程里的一些类功能。

谷歌浏览器的源码分析(34)


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论