今天笔者几篇文章介绍了改绘制执行的文章. 关联文章的地址
Chromium的绘制也要从WM_PAINT的开始
HWNDMessageHandler是Chromium中UI和系统消息的媒介。它来全权处理了。
好了,一个WM_PAINT消息来了。
void HWNDMessageHandler::OnPaint(HDC dc) 中,关键代码如下:
1 |
scoped_ptr<gfx::CanvasPaint> canvas( |
2 |
gfx::CanvasPaint::CreateCanvasPaint(hwnd())); |
3 |
delegate_->HandlePaint(canvas->AsCanvas()); |
此处的
gfx::CanvasPaint就是一个平台有关的画布,new一个出来,scoped住,分开这里时就会执行它的析构。
class CanvasPaintWin : public gfx::CanvasPaint, public gfx::CanvasSkiaPaint 这里的CanvasPaint实际上是CanvasPaintWin 的化身。
CanvasSkiaPaint 的析构会执行
01 |
virtual ~CanvasSkiaPaint() { |
02 |
if (!isEmpty()) { |
03 |
skia::PlatformCanvas* canvas = platform_canvas(); |
04 |
canvas->restoreToCount(1); |
05 |
// Commit the drawing to the screen |
06 |
skia::DrawToNativeContext(canvas, paint_dc_, ps_.rcPaint.left, |
07 |
ps_.rcPaint.top, NULL); |
08 |
} |
09 |
if (for_paint_) |
10 |
EndPaint(hwnd_, &ps_); |
11 |
} |
最终走到平台相关的绘制了,以后是GDI的BitBlt,GdiAlphaBlend等
看不到自动调用某些函数,而是放到某些对象中去执行,在chromium中非常常见。
好了,绘制的画布搞清楚了,那绘制过程是如何的呢。往回看这句
1 |
delegate_->HandlePaint(canvas->AsCanvas()) |
这里的delegate_申明是 HWNDMessageHandlerDelegate* delegate_;
class VIEWS_EXPORT NativeWidgetWin : public internal::NativeWidgetPrivate,
public HWNDMessageHandlerDelegate
大部分情况下是NativeWidgetWin 的化身了。
继而会走到如下里面
1 |
void NativeWidgetWin::HandlePaint(gfx::Canvas* canvas) { |
2 |
delegate_->OnNativeWidgetPaint(canvas); |
3 |
} |
这里的
delegate_申明是 internal::NativeWidgetDelegate* delegate_;
1 |
class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate, |
2 |
public FocusTraversable |
如上,会进入到
Widget 的
OnNativeWidgetPaint中
1 |
void Widget::OnNativeWidgetPaint(gfx::Canvas* canvas) { |
2 |
// On Linux Aura, we can get here during Init() because of the |
3 |
// SetInitialBounds call. |
4 |
if (native_widget_initialized_) |
5 |
GetRootView()->Paint(canvas); |
6 |
} |
终究找到了老窝,这里得到root_view就开始遍历Paint了。他们的Paint结果最后通过
canvas绘制到了屏幕上了!
文章结束给大家分享下程序员的一些笑话语录:
某程序员对书法十分感兴趣,退休后决定在这方面有所建树。花重金购买了上等的文房四宝。一日突生雅兴,一番磨墨拟纸,并点上了上好的檀香,颇有王羲之风 范,又具颜真卿气势,定神片刻,泼墨挥毫,郑重地写下一行字:hello world.