读书笔记(7)

GDI对象的用户模式数据结构

 

每个GDI对象在全局GDI对象句柄表中都有入口,这个表有个pUser的指针。对于大多数GDI对象来说,pUser是NULL(空)指针。但对于

 

画刷、区域、字体和设备上下文GDI对象,GDI对象表中相应的pUser字段不空。它们确实指向一些用户模式地址空间的数据结构。

 

(1)用户模式画刷数据:纯色画刷优化:

对于纯色画刷pUser指向一个24字节的块,其中前12字节是LOGBRUSH结构的拷贝。如果画刷是纯色画刷,唯一重要的信息是画刷的颜

 

色。对其他类型的画刷,pUser是空指针。

typedef struct

{

    LOGBRUSH logbrush;

    DWORD    dwUnused[3];

}USerData_SolidBrush;

纯色画刷很特别,因为它们量多,但生存期很短。实现渐进填充、阴影或光线效果时,会生成成百上千的纯色画刷,使用一次或者几

 

次来绘制图片的切片,然后立该删除。因为它们的需要量很大,应用程序不能把它们保存到下一次需要的时候。否则很容易超过GDI

 

对象表的限制。所以大多数纯色画刷在使用一次后不久就被销毁,并在需要的时候再创建。

通过在用户模式保存一份LOGBRUSH的拷贝,GDI也许能对大量创建、使用和删除纯色画刷的序列模式进行优化。第一个纯色画刷删除

 

之后,GDI可以把它保存在内部,而不是释放分配好的数据结构。需要新纯色画刷时,GDI能够通过改变颜色创建新画刷来重用它,而

 

不必回到内核模式分配一块内存再把新画刷的信息加进去。

 

(2)用户模式区域数据:正方形区域优化:

对于由CreateRectRgn和ExtCreateRgn这样的函数创建的区域对象来说,pUser字段仅在最简单的情况——矩形区域下使用,这和纯色

 

画刷类似。由pUser指向的数据块是大小为24字节的矩形框。在数据块内部,前两个DWORD的意义未知,剩下16字节构成了RECT结构

typedef struct

{

    DWORD dwUnknown1;

    DWORD dwUnknown2;

    RECT  rcBound;

}UserData_RectRgn;

你可以用SetRectRgn通过指定的坐标把区域变成矩形区域。知道pUser字段指向的数据结构,就知道这在GDI中很容易实现的,GDI只

 

需要保证pUser字段非空,即UserData_TectRgn结构被分配,然后设置正确的内部坐标。因此作为GDI对象的区域就是可变的对象。

 

(3)用户模式字体数据:宽度表

Windows GDI为字体定义的数据结构是所有GDI对象最多的。有LOGFONT、TEXTMETERIC、PANOSE、ABC和GLYPHSET等等。但是我们在GDI

 

对象表中没有发现这些数据结构的行踪,字体句柄的用户模式数据结构非常简单:

typedef struct

{

    DWORD dwUnknown;

    void * pCharWidthData;

}UserData_Font;

UserData_Font的第一个字段总是零。第二个字段也经常是零,只有调用GetCharWidth这样的函数之后除外。GetCharWidth用于将某

 

个范围内的字符宽度来填充一个数组。调用GetCharWidth之后,pCharWidthData指向从系统堆分配的数据结构,它基本上是一个缓存

 

的字符宽度表。这里我们又看到GDI费很大力气优化性能。

 

(4)用户模式设备上下文数据:存储设置信息

 在用Windows GDI绘制之前,首先要得到设备上下文的句柄。可以自己创建这个句柄,也可以从OS中得到。也可设置并得到设备上下

 

文的24个属性,如映射模式、文本前景色、背景色、画刷、画笔和字体常用设备上下文设置,因此GDI很自然地需要一个结构存储各

 

种各样的与设备上下文有关的设置。在Windows NT/2000下,GDI对象表中的pUser字段指向这样一个设备上下文句柄结构。

通过改变设备上下文的设置,并监视二进制数据的变化这一枯燥乏味的过程后,就得到了pUser指向的设备上下文结构的粗略图景。

 

但是这些信息还是不完全、非正式的。借助微软提供的内核级GDI调试器扩展和WinDbg,这幅图就更完全、更正式了。

 

(*对于这个数据结构,DC_ATTR结构书写了很大篇幅,没太看懂,也就不写了,以免误人子弟,总之也是为了提高GDI性能也设计的*

 

 

总结一下,本节我们看了纯色画刷、矩形、区域、字体和设备上下文GDI对象的用户模式可存取数据结构,这些数据结构十分简单,

 

大部分是通过减少GDI在用户内核模式执行特权之间的切换来优化GDI性能。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值