热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

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

通过上一次的分析,我们看到所有网页数据经过HTML分析器之后,都会变成一个一个RenderObject对象,那么这些RenderObject对象又是怎么样显示到界面上面的呢?现在就带着这个疑问来
通过上一次的分析,我们看到所有网页数据经过HTML分析器之后,都会变成一个一个RenderObject对象,那么这些RenderObject对象又是怎么样显示到界面上面的呢?现在就带着这个疑问来分析下面的代码,这样肯定会找到解决方法的。怎么样找到入口呢?其实可以先从界面显示的类开始,可以看到显示界面的窗口类名称叫做Chrome_RenderWidgetHostHWND,有了这个类名称,就可以到代码里查看它在那里了。

#001  class RenderWidgetHost;

#002  class WebMouseEvent;

#003  class WebCursor;

#004 

#005  typedefCWinTraits

#006     RenderWidgetHostHWNDTraits;

#007 

#008  static const wchar_t* cOnstkRenderWidgetHostHWNDClass=

#009      L"Chrome_RenderWidgetHostHWND";

 

可看到这个窗口类名称是定义在这里,再跟着kRenderWidgetHostHWNDClass来查找,就会找到显示窗口,如下:

#001  class RenderWidgetHostHWND :

#002    publicCWindowImpl

#003                      CWindow,

#004                      RenderWidgetHostHWNDTraits>,

#005    publicRenderWidgetHostView {

#006   public:

#007   RenderWidgetHostHWND(RenderWidgetHost* render_widget_host);

#008    virtual~RenderWidgetHostHWND();

#009 

#010    void set_close_on_deactivate(boolclose_on_deactivate) {

#011      close_on_deactivate_ =close_on_deactivate;

#012    }

#013 

#014    void set_parent_hwnd(HWNDparent) { parent_hwnd_ = parent; }

#015 

#016   DECLARE_WND_CLASS_EX(kRenderWidgetHostHWNDClass, CS_DBLCLKS, 0);

 

通过上面的分析,就可以找到显示网页的窗口类RenderWidgetHostHWND,在这个类里,主要显示的位置是在void RenderWidgetHostHWND::OnPaint(HDC dc)函数里面,它的代码如下:

#001  voidRenderWidgetHostHWND::OnPaint(HDC dc) {

#002   DCHECK(render_widget_host_->process()->channel());

#003 

#004    CPaintDC paint_dc(m_hWnd);

#005    HBRUSH white_brush =reinterpret_cast(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是怎么样显示的呢?这个会比上面的过程更加复杂,后面再仔细地分析它。下一次,主要仔细地看看这些过程里的一些类功能。


推荐阅读
  • 如何在HTML中获取鼠标的当前位置
    本文介绍了在HTML中获取鼠标当前位置的三种方法,分别是相对于屏幕的位置、相对于窗口的位置以及考虑了页面滚动因素的位置。通过这些方法可以准确获取鼠标的坐标信息。 ... [详细]
  • [翻译]PyCairo指南裁剪和masking
    裁剪和masking在PyCairo指南的这个部分,我么将讨论裁剪和masking操作。裁剪裁剪就是将图形的绘制限定在一定的区域内。这样做有一些效率的因素࿰ ... [详细]
  • fileuploadJS@sectionscripts{<scriptsrc~Contentjsfileuploadvendorjquery.ui.widget.js ... [详细]
  • 十六.增加一个项目协作留言板功能(二)----- 建立一个任务管理的列表页面
    我们设计一个页面来展示正在处理的任务,该表格可以参照之前基础信息的增删改查。用户通过这个页面对任务进行相应操作。1.在views. ... [详细]
  • 使用PyQt5 for Python gui开发笔记:实现可滚动标签
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了使用PyQt5forPythongui的可滚动标签相关的知识,希望对你有一定的参考价值。 ... [详细]
  • android图片浏览器(二)——实现显示图片的标题
    上一篇文章http:blog.csdn.netbadboy1110articledetails6879236只是单纯的显示一个图片,虽然我改进了,但是在 ... [详细]
  • 资源:吊炸天!74款APP完整源码!android界面中点击输入框时弹出输入法如果输入框在底部会出现输入法遮挡输入内容的问题解决办法设置activity的windowsoftinpu ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 本文介绍了在MFC下利用C++和MFC的特性动态创建窗口的方法,包括继承现有的MFC类并加以改造、插入工具栏和状态栏对象的声明等。同时还提到了窗口销毁的处理方法。本文详细介绍了实现方法并给出了相关注意事项。 ... [详细]
  • JavaScript和HTML之间的交互是经由过程事宜完成的。事宜:文档或浏览器窗口中发作的一些特定的交互霎时。能够运用侦听器(或处置惩罚递次来预订事宜),以便事宜发作时实行相应的 ... [详细]
  • 使用eclipse创建一个Java项目的步骤
    本文介绍了使用eclipse创建一个Java项目的步骤,包括启动eclipse、选择New Project命令、在对话框中输入项目名称等。同时还介绍了Java Settings对话框中的一些选项,以及如何修改Java程序的输出目录。 ... [详细]
  • 本文介绍了pack布局管理器在Perl/Tk中的使用方法及注意事项。通过调用pack()方法,可以控制部件在显示窗口中的位置和大小。同时,本文还提到了在使用pack布局管理器时,应注意将部件分组以便在水平和垂直方向上进行堆放。此外,还介绍了使用Frame部件或Toplevel部件来组织部件在窗口内的方法。最后,本文强调了在使用pack布局管理器时,应避免在中间切换到grid布局管理器,以免造成混乱。 ... [详细]
  • 用Vue实现的Demo商品管理效果图及实现代码
    本文介绍了一个使用Vue实现的Demo商品管理的效果图及实现代码。 ... [详细]
  • 本文整理了常用的CSS属性及用法,包括背景属性、边框属性、尺寸属性、可伸缩框属性、字体属性和文本属性等,方便开发者查阅和使用。 ... [详细]
author-avatar
mobiledu2502853587
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有