谷歌浏览器的源码分析 34

通过上一次的分析,我们看到所有网页数据经过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是怎么样显示的呢?这个会比上面的过程更加复杂,后面再仔细地分析它。下一次,主要仔细地看看这些过程里的一些类功能。

再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow

原文地址:https://www.cnblogs.com/skiwnchh/p/10346616.html

时间: 2024-11-01 18:51:07

谷歌浏览器的源码分析 34的相关文章

谷歌浏览器的源码分析 21

分享一下我老师大神的人工智能教程吧.零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!http://www.captainbed.net 上一次说到类RenderThread和类RenderView把消息处理,那么这两个类是怎么样处理消息的呢?又是怎么样处理浏览的消息呢?现在就带着这两个问题去分析它的源码,理解它处理消息的方法.类RenderThread处理消息的代码如下:<?xml:namespace prefix = o ns = "urn:schemas-

谷歌浏览器的源码分析 4

关于对话框,主要实现了让用户查看当前软件的版本.软件信息和检查升级的功能.因此这个类主要继续ChromeViews::View类.ChromeViews::DialogDelegate和GoogleUpdateStatusListener.其中ChromeViews::View实现窗口的布局和显示问题,ChromeViews::DialogDelegate实现了事件响应,或者窗口某时是否可以显示按钮的问题,GoogleUpdateStatusListener是用来实现接收更新程序状态信息. 这个

谷歌浏览器的源码分析 6

前面已经介绍了这么引人的输入自动完成功能,并且可以在输入超级连接框里直接通过GOOGLE搜索所有的内容,这是比较大的创新,不但可以节省界面的占用面积,还很方便大家查询的需要,比如记不住的连接,根本不需要去记了,只要你记住需要的内容就行了.这样既不需要到什么门户网站去找连接,也不需要去记住众多的网站,这个功能是非常方便的. 这个输入框的自动完成的功能,是比较智能化的.因为它会根据以往的输入自动完成,或者智能提示所需要的连接或者内容. 下面就来先看这个类的定义: #001  // Provides

谷歌浏览器的源码分析 7

当我们键入字母或者文字开始时,那么类AutocompleteEdit就会从窗口消息里获取到相应的字母或者文字,然后根据输入的信息到本地或者网络上保存的信息库里查找相应的输入提示,这就是自动完成的实现.下面就来先分析输入的函数:<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /> #001  void AutocompleteEdit::OnChar(TCHAR ch, UIN

谷歌浏览器的源码分析 9

为了处理字符消息实现自动完成的功能,这是怎么样实现的呢?其实是先记录字符消息响应前的字符串以及选中状态,接着再处理消息,最后才查询可能的输入,做出智能提示.<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /> #001  void AutocompleteEdit::OnBeforePossibleChange() { #002    // Record our state.

谷歌浏览器的源码分析 13

分享一下我老师大神的人工智能教程吧.零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!http://www.captainbed.net 上一次说到调用函数OpenURL来打开网络连接,这仅是网络浏览的开始,现在再来分析它怎么样去下载网页数据,然后再显示出来.<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /> #001  void Autocom

谷歌浏览器的源码分析 29

分享一下我老师大神的人工智能教程吧.零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!http://www.captainbed.net 上一次说到通过WinHTTP来接收网络数据,但没有具体介绍怎么样接收,现在就来分析这方面的代码.首先是通过函数WinHttpQueryHeaders来查询HTTP协议头的大小,接着还是通过函数WinHttpQueryHeaders把数据接收到缓冲区里.下面这段代码,就是做这样的事情:<?xml:namespace prefix =

jQuery源码分析系列(34) : Ajax - 预处理jsonp

上一章大概讲了前置过滤器和请求分发器的作用,这一章主要是具体分析每种对应的处理方式 $.ajax()调用不同类型的响应,被传递到成功处理函数之前,会经过不同种类的预处理(prefilters). 预处理的类型取决于由更加接近默认的Content-Type响应,但可以明确使用dataType选项进行设置.如果提供了dataType选项, 响应的Content-Type头信息将被忽略. 有效的数据类型是text, html, xml, json,jsonp,和 script. dataType:预期

Solr4.8.0源码分析(22)之 SolrCloud的Recovery策略(三)

Solr4.8.0源码分析(22)之 SolrCloud的Recovery策略(三) 本文是SolrCloud的Recovery策略系列的第三篇文章,前面两篇主要介绍了Recovery的总体流程,以及PeerSync策略.本文以及后续的文章将重点介绍Replication策略.Replication策略不但可以在SolrCloud中起到leader到replica的数据同步,也可以在用多个单独的Solr来实现主从同步.本文先介绍在SolrCloud的leader到replica的数据同步,下一篇