Windows的GDI映射方式,逻辑坐标,设备坐标的理解
最近在学win32的编程,看的是《windows程序设计第5版》一书,这本书是*人翻译的,有些译法和大陆不一样,书中还有一些错误的地方,很多时候需要中英文对照阅读,下载请点击
https://download.csdn.net/download/u013238941/10611720
好了,下面开始正文:
在看到gdi(gdi graphic device interface图形设备接口)映射方式这一节的时候,书中又是逻辑坐标,又是设备坐标,又是视口,窗口,又是视埠什么的,搞得人头都大了。虽然我现在还没有完全读懂,但是我感觉我已经抓住了理解这些东西的主线,下面的东西就当作我的笔记吧:
1.逻辑坐标和设备坐标
首先,逻辑坐标这个名词就让很多人望而却步,确实,不能“望文生义”地理解的翻译就不是好翻译 ------鲁迅。哈哈,开个玩笑,我们要理解这两个东西,首先要想到如果你要用win32要绘制一个东西,该怎么做呢?比如绘制一个矩形,假设我们调用的是rectangle(hdc,30,20,50,80),(这个函数的用法是rectangle(hdc,left,top,right,bottom),我叫雷锋,不用谢我)。可以看到,跟很多gdi函数一样,这个函数里面使用了很多数字,坐标。让我们回忆一下小学知识,绘制一个东西,不仅应当搞清楚他的长度,还应该搞清楚他的单位,那么这里的30,20,50,80的单位是什么呢?很多人会说,是像素!这个答案是对的,但是又不全对。事实上,windows默认的映射方式(mapping mode,简称就是mm)是mm_text,在mm_text映射方式(text实际上跟文字没有多大关系,是这种映射方式下的坐标方向,从左到右,从上到下,跟文字阅读方式一样)下,这个单位确实是像素。实际上,逻辑坐标和设备坐标的区别就在于他们的单位不一样!
下面我们拿出一个公式
要讲上面的公式,就要先说一下视口(viewport *译作视埠)和窗口(window *译作视窗)
首先,不要被这两个名字迷惑了,这两个坐标是跟映射有关的,跟屏幕坐标系,窗口坐标系,客户端坐标系是相对独立的两个知识。
其实公式拿出来,学数学的小伙伴是不是就懂了大半了,这个公式非常重要,理解了这个公式,后面的很多东西就能理解,首先,公式中的window,winorg,winext,就是带了win的东西,就是使用的逻辑坐标的值,就跟gdi函数中的一样,逻辑坐标的单位可能是像素(mm_text映射)、毫米(单位是0.1mm,在mm_lometric映射下)等等等等(看下图).
就是说我们在调用win32函数绘图的时候,要知道自己使用的单位(根据映射模式确定的)。因为绘图函数里的数值,使用的就是这些单位,虽然默认的mm_text映射模式使用的单位就是像素,但是很多时候其他单位也很有用,比如你要做一个屏幕尺子的时候,你要用尺子量一下物体有几厘米。尺子上的刻度就可以用其他的映射模式来画。但是屏幕在显示的时候却不能只知道逻辑坐标几厘米啊,屏幕得知道具体的像素位置才行啊!那这个时候,就需要用到上面的公式转换了。讲到这里,公式里的viewext/winext是什么意思就很明显了。那就是在当前逻辑坐标系下(比如几厘米,打比方哈),实际上是上面映射模式表格里的单位)对应的设备坐标应该是多少个像素!这样转换过后,得到实际的viewport,就是该逻辑点在屏幕上的位置。
所以说视口和窗口实际上是表示的同一块区域,只不过是因为单位和原点的不同,需要进行映射,逻辑单位就是窗口,就是window,就是像素,毫米,英寸,就是给人用的单位,就是设备无关的单位,设备单位就是视口,就是viewport,就只能是像素,就是给设备用的单位,确定的一厘米,在不同的设备上的像素数可能会有区别,所以是设备相关的单位。
要注意的是在上述的5映射模式下,viewext/winext的比例都是已经确定了,不能更改的,如果要更改两个值,只能在mm_isotropic和mm_anisotropic映射模式下使用setviewportextex()和setwindowextex()更改。而且这两个函数在上面5种映射方式下无效。
最后,这些映射模式,视口原点(vieworg),窗口原点(winorg)等,都是设备内容(dc device context,又译作装置内容、设备上下文等)的属性,设备内容其实就是你绘制的区域。有三种beginpaint(在wm_paint时绘制无效区域),getdc是客户端区域(在更新时绘制整个客户区域),getwindowsdc是整个窗口区域(可以绘制包括窗口标题栏,菜单栏区域)。这些知识细讲的话又是另一篇博客了
所以只要牢记开头的公式,得到正确的对应的参数,就可以画出需要的图形。