决定不处理它,就像在几何宽度直线中做的那样。在后一种情况中,GDI把请求分割成简单 的操作,例如,把曲线转换成近似的直线。 3.4.2绘制和填充路径 图形驱动程序把路径考虑成通过一个路径对象( PATHOBJ结构)定义的直线和/或曲线序 列。为处理闭合路径的填充,驱动程序支持 DryfillPath GDI能在设备管理的表面上调用 DryFillPath填充一个路径。GDI比较用 DEVINFO结构 中的 GCAPS BEZIERS、 GCAPS ALTERNATEFILL和 GCAPS WINDINGFILL标志填充的请求,决定 是否调用驱动程序。如果GDI调用驱动程序,驱动程序或者执行操作或者返回,通知GDI 路径或裁剪请求对由设备处理过于复杂。对后一种情况,GDI把请求分割成几个简单的操作 驱动程序也能支持可选的 DryStrokeAndFillPath函数完成路径填充的请求。这个函数 在同一时间内填充和绘制路径。许多GDI图元请求这个函数。如果绘制使用了宽线,填充区 域必须减小,以补偿路径边界宽度的增加。 当驱动程序从 DryFillPath或 DryStrokeAndfillPath函数返回 FALSE,GDI把填充路径 请求转换为一系列简单的操作并再次调用驱动程序函数。如果设备在第二次调用 DryFillPath时再返回 FALSE,GDI把路径转换成裁剪对象并调用 EngFillPath。对再次调用 Dry StrokeAndFillpath返回的 FALSE,GDI把调用转换成对 DryStrokepath和 DryFillPath 的独立的调用。 3.4.2.1填充路径模式 路径定义的两种填充模式是交孳( alternate)和旋转( winding)。两种填充模式使用 一个奇偶规则决定如何填充闭合路径。 FP_ ALTERNATEMODE如下应用奇偶均等规则:从闭合路径中的任意一个起始点向闭合路径 外的某点画一条直线。如果直线穿过奇数个路径段,起始点在闭合区域内,是填充区的一部 分。穿过偶数个路径段则意味着起始点不在填充区内。 FP WINDINGMODE不仅考虑矢量穿过路径段的次数,还考虑每个路径段的方向。路径看作 从起点向终点绘制,每个路径段的方向由指定点的顺序包含:线段的第一个顶点是“起始” 点,第二个顶点是“终”点。现在用交替模式绘制同一个任意线。从0开始,为每个直线穿 过“向前”方向的线段加1,对每个“相反的”方向的线段减1。(向前和相反取决于线段产 生的点和任意的直线。)如果计数的结果是非0,起始点在填充区内:计数值是0则意味着 点在填充区以外 图3.3显示了如何把两种规则应用到更复杂的自交叉路径的情况。在交替填充模式中, 点A在填充区中因为RAY1经过线段奇数次,而点B和C不在,因为RAY2和RAY3经过线段 偶数次。在旋转填充模式中,点A和C在填充区中,因为RAY和RAY3穿过的全部正向(正 的)和反向(负的)线段的计数值加起来都不为0,而B在填充区外,因为RAY2穿过的正 向(正的)和反向(负的)线段的计数值加起来都为0 图3.3交替和旋转模式填充
26 决定不处理它,就像在几何宽度直线中做的那样。在后一种情况中,GDI 把请求分割成简单 的操作,例如,把曲线转换成近似的直线。 3.4.2 绘制和填充路径 图形驱动程序把路径考虑成通过一个路径对象(PATHOBJ 结构)定义的直线和/或曲线序 列。为处理闭合路径的填充,驱动程序支持 DrvFillPath。 GDI 能在设备管理的表面上调用 DrvFillPath 填充一个路径。GDI 比较用 DEVINFO 结构 中的 GCAPS_BEZIERS、GCAPS_ALTERNATEFILL 和 GCAPS_WINDINGFILL 标志填充的请求,决定 是否调用驱动程序。如果 GDI 调用驱动程序,驱动程序或者执行操作或者返回,通知 GDI 路径或裁剪请求对由设备处理过于复杂。对后一种情况,GDI 把请求分割成几个简单的操作。 驱动程序也能支持可选的 DrvStrokeAndFillPath 函数完成路径填充的请求。这个函数 在同一时间内填充和绘制路径。许多 GDI 图元请求这个函数。如果绘制使用了宽线,填充区 域必须减小,以补偿路径边界宽度的增加。 当驱动程序从 DrvFillPath 或 DrvStrokeAndFillPath 函数返回 FALSE,GDI 把填充路径 请求转换为一系列简单的操作并再次调用驱动程序函数。如果设备在第二次调用 DrvFillPath 时再返回 FALSE,GDI 把路径转换成裁剪对象并调用 EngFillPath。对再次调用 DrvStrokeAndFillPath 返回的 FALSE,GDI 把调用转换成对 DrvStrokePath 和 DrvFillPath 的独立的调用。 3.4.2.1 填充路径模式 路径定义的两种填充模式是交替(alternate)和旋转(winding)。两种填充模式使用 一个奇偶规则决定如何填充闭合路径。 FP_ALTERNATEMODE 如下应用奇偶均等规则:从闭合路径中的任意一个起始点向闭合路径 外的某点画一条直线。如果直线穿过奇数个路径段,起始点在闭合区域内,是填充区的一部 分。穿过偶数个路径段则意味着起始点不在填充区内。 FP_WINDINGMODE 不仅考虑矢量穿过路径段的次数,还考虑每个路径段的方向。路径看作 从起点向终点绘制,每个路径段的方向由指定点的顺序包含:线段的第一个顶点是“起始” 点,第二个顶点是“终”点。现在用交替模式绘制同一个任意线。从 0 开始,为每个直线穿 过“向前”方向的线段加 1,对每个“相反的”方向的线段减 1。(向前和相反取决于线段产 生的点和任意的直线。)如果计数的结果是非 0,起始点在填充区内;计数值是 0 则意味着 点在填充区以外。 图 3.3 显示了如何把两种规则应用到更复杂的自交叉路径的情况。在交替填充模式中, 点 A 在填充区中因为 RAY1 经过线段奇数次,而点 B 和 C 不在,因为 RAY2 和 RAY3 经过线段 偶数次。在旋转填充模式中,点 A 和 C 在填充区中,因为 RAY1 和 RAY3 穿过的全部正向(正 的)和反向(负的)线段的计数值加起来都不为 0,而 B 在填充区外,因为 RAY2 穿过的正 向(正的)和反向(负的)线段的计数值加起来都为 0。 图 3.3 交替和旋转模式填充
3.4.2.2填充区(闭合路径) 像在直线绘制中那样,填充的像素考虑成整数坐标。区域中每条扫描线由路径线段确 定左右边界。落在左右边界之间的像素认为是在填充区域内。恰好在左边界上的像素也在区 域内,而右边界上的像素则在区域之外。如果顶边界恰好是水平线,边界上的像素都在区域 内,而底边界上的像都在区域之外。 图3.4显示了相对于区域的左右边界如何确定包括在填充区域内的像素。从数学的角 度来看,这个区域在左边界和上边界是“闭合的”,而在右边界和底边界是“开放的”。 图3.4确定像素包括在填充区内 上面有关填充区ⅹ轴的描述约定也应用于y轴,用顶边界代替左边界,用底边界代替 右边界。 3.4.3拷贝位图 驱动程序实现的位块传输( Bitblt)函数必须从一个表面向另一个拷贝位块。这些函 数包括: DryBitBlt DryStretchBlt Dry Copybits 还有一个显示器驱动程序指定的 BitBlt函数,名字为 DrySavescreen bits 如果绘制的表面是在设备管理的表面或位图上,驱动程序必须支持最小级别的位块传 输函数。如果表面是GDI管理的标准格式位图,GDI只处理没有被驱动程序挂起的操作 DryBitblt函数提供了一般的位块传输能力。如果驱动程序支持设备管理的表面或位 图,它必须实现 DrvCopy Bits函数。至少,当调用 DrvCopy Bits时,驱动程序必须进行以下 操作 和位图之间进行块传输,用驱动程序和设备表面推荐的格式 用 SRCCOPY(0 cCCC)ROP执行传输 允许任意的裁剪。 驱动程序能使用 GDI CLIPOBJ计算服务,减少对一系列裁剪矩形的裁剪。GDI向下传 递一个转换向量,Ⅻ LATEOB J结构,帮助源和目标表面的颜色索引转换。 如果设备的表面由标准格式的DIB组成,驱动程序可以仅支持简单传输。如果调用用 一个复杂的ROP进来,驱动程序通过调用 EngCopy Bits函数把块传输请求直接传回到GDI 这允许GDI把调用分割成驱动程序能够执行的简单函数 如果使用了源, DryBitblt映像一个几何源矩形到几何目标矩形,如果没有源, DryBitBlt忽略了 pprc参数。目标矩形是要修改的表面,它由两个整数端点左上角和右 下角定义,矩形是右下排斥的:矩形的右边界和下边界不是块传输的一部分。 DryBitBlt不 能由一个空的目标矩形调用。矩形的两个点总是有顺序的,即右下点的两个坐标都大于对角 左上角点的坐标 DryBitblt处理不同的ROP并能依赖设备进行一些优化。在一些情况下,如果ROP是 实色,宁可进行填充而不执行 BitBlt。对不支持所有ROP的设备,真正的所见即所得是不
27 3.4.2.2 填充区(闭合路径) 像在直线绘制中那样,填充的像素考虑成整数坐标。区域中每条扫描线由路径线段确 定左右边界。落在左右边界之间的像素认为是在填充区域内。恰好在左边界上的像素也在区 域内,而右边界上的像素则在区域之外。如果顶边界恰好是水平线,边界上的像素都在区域 内,而底边界上的像都在区域之外。 图 3.4 显示了相对于区域的左右边界如何确定包括在填充区域内的像素。从数学的角 度来看,这个区域在左边界和上边界是“闭合的”,而在右边界和底边界是“开放的”。 图 3.4 确定像素包括在填充区内 上面有关填充区 x 轴的描述约定也应用于 y 轴,用顶边界代替左边界,用底边界代替 右边界。 3.4.3 拷贝位图 驱动程序实现的位块传输(BitBlt)函数必须从一个表面向另一个拷贝位块。这些函 数包括: ▪ DrvBitBlt ▪ DrvStretchBlt ▪ DrvCopyBits 还有一个显示器驱动程序指定的 BitBlt 函数,名字为 DrvSaveScreenBits。 如果绘制的表面是在设备管理的表面或位图上,驱动程序必须支持最小级别的位块传 输函数。如果表面是 GDI 管理的标准格式位图,GDI 只处理没有被驱动程序挂起的操作。 DrvBitBlt 函数提供了一般的位块传输能力。如果驱动程序支持设备管理的表面或位 图,它必须实现 DrvCopyBits 函数。至少,当调用 DrvCopyBits 时,驱动程序必须进行以下 操作: ▪ 和位图之间进行块传输,用驱动程序和设备表面推荐的格式。 ▪ 用 SRCCOPY(0xCCCC)ROP 执行传输。 ▪ 允许任意的裁剪。 驱动程序能使用 GDI CLIPOBJ 计算服务,减少对一系列裁剪矩形的裁剪。GDI 向下传 递一个转换向量,XLATEOBJ 结构,帮助源和目标表面的颜色索引转换。 如果设备的表面由标准格式的 DIB 组成,驱动程序可以仅支持简单传输。如果调用用 一个复杂的 ROP 进来,驱动程序通过调用 EngCopyBits 函数把块传输请求直接传回到 GDI。 这允许 GDI 把调用分割成驱动程序能够执行的简单函数。 如果使用了源,DrvBitBlt 映像一个几何源矩形到几何目标矩形,如果没有源, DrvBitBlt 忽略了 pptsrc 参数。目标矩形是要修改的表面,它由两个整数端点左上角和右 下角定义,矩形是右下排斥的;矩形的右边界和下边界不是块传输的一部分。DrvBitBlt 不 能由一个空的目标矩形调用。矩形的两个点总是有顺序的,即右下点的两个坐标都大于对角 左上角点的坐标。 DrvBitBlt 处理不同的 ROP 并能依赖设备进行一些优化。在一些情况下,如果 ROP 是 实色,宁可进行填充而不执行 BitBlt。对不支持所有 ROP 的设备,真正的所见即所得是不
可能的。例如, PostScript驱动程序不支持ROP。 可选地, Drybitblt处理的位块传输能被屏蔽,包括颜色索引转换。转换矢量帮助调 色板颜色索引转换。传输可能会被显示器驱动程序任意地裁剪,使用一系列的裁剪矩形。请 求区域和信息由GDI提供。 实现 DryBitblt描述了编写光栅显示器驱动程序的一个重要的部分,它没有标准格式 的帧缓冲区。随 Windows@2000DK供应的 Microsoft vga驱动程序提供了例子代码,完 全支持平面设备的基本函数。为其他设备实现 DryBitblt的复杂性更小。 驱动程序能可选地提供 Dry StretchBlt函数,即使驱动程序支持设备管理的表面。这 个函数提供在设备管理的表面和GDI管理的表面之间延伸块传输能力。 DryStretchBlt仅支 持某些类型的延伸,如通过整数乘延伸。 DryStretchBlt也允许驱动程序在GDI位图上写,特别当驱动程序能进行中间色调处 理时。这个函数也允许同一个中间色调算法应用于GDI位图和设备表面 DryStretchBlt精确映像一个几何源矩形到一个几何目标矩形。源矩形角的坐标由给 定的整数坐标替换为(-0.5,-0.5)。函数参数中指定的点位于相应的像素中心的整数坐标 由两个这样的点定义的矩形认为是几何的,两个顶点是坐标给定的点,但每个坐标都用0.5 代替。( GDI POINTL结构使用一个速记符指定这些分数坐标顶点。)注意如何这样的矩形的 边不会有像素交叉,但提供一系列像素。矩形内的像素是通常的底边和右边排除的矩形的像 素 源矩形的点是有序的。不能给定一个空的源矩形到 DryStretchBlt。与 Drybitblt不 同, DryStretchBlt能用一个简单的裁剪矩形调用,防止在裁剪输出中的舍入错。 标矩形由两个整数点定义。这些点不是有序的,这意味着第二个点的坐标不必须比 第一个大。这些点描述的源矩形不包括底边和右边。因为矩形不是有序的, DryStretchBlt 必须不时执行两个x坐标和/或两个y坐标的倒置。(驱动程序必须尝试读出不在源表面上的 像素。) DryStretchBlt不能用一个空的目标矩形调用。 对于颜色转换, DryStretchBlt提供一个指针,pxlo,指向 XLATEOBJ结构,用于在源 和目标表面之间转换。Ⅺ LATEOBJ结构可用来查询,找到任何源索引的目标索引。对高品质 的延伸块传送, DryStretchBlt在某些情况下要求加入颜色。 DryStretchBlt也使用 COLORADJUSTMENT结构定义颜色调整值,在位被延伸之前用于源位图。 DrystretchBlt使用 iMode参数定义源像素如何组成输出。特别地, iMode提供 ALF TONE选项,允许驱动程序在输出表面使用像素组到最接近的颜色或灰度级。在下一次 用 HALFTONE的iMde调用 Dry StretchBlt后, COLORADJUSTMENT结构的改变传递到驱动程 序。另外,如果驱动程序为GDI位图请求GD处理中间色调,驱动程序可以挂起 DryStretchblt,iMde设置参数到 HALFTONE,并在 EngStretchBlt返回。 如果 DryStretchBlt挂起一个对 EngStretchBlt函数的调用,并请求了它不支持的某 些操作,它把请求返回到GDI,由相应的函数进行处理。 Drv Copy Bits函数由GDⅠ从其模拟操作调用,在设备管理的光栅表面和GDI标准格式 位图之间转换。 Drv Copy Bits为 SRCCOPY(oxC)ROP位块传输提供了一个快速路径。这 个函数为具有设备管理的位图或光栅表面的图形驱动程序请求,必须转换驱动程序表面到 (或从)任何标准格式位图。 DrvCopy Bits不会用一个空的目标举行调用,目标举行的两个 端点是有序的。这个调用和 DryBitblt有相同的请求。 DrvCopy Bits也用RLE位图(参见平台DD文档)和DDB调用。位图作为应用程序调 用几个win32GDI例程的结果提供给这个函数。可选的DDB仅由少数几个指定的驱动程序支 持
28 可能的。例如,PostScript 驱动程序不支持 ROP。 可选地,DrvBitBlt 处理的位块传输能被屏蔽,包括颜色索引转换。转换矢量帮助调 色板颜色索引转换。传输可能会被显示器驱动程序任意地裁剪,使用一系列的裁剪矩形。请 求区域和信息由 GDI 提供。 实现 DrvBitBlt 描述了编写光栅显示器驱动程序的一个重要的部分,它没有标准格式 的帧缓冲区。随 Windows 2000 DDK 供应的 Microsoft VGA 驱动程序提供了例子代码,完 全支持平面设备的基本函数。为其他设备实现 DrvBitBlt 的复杂性更小。 驱动程序能可选地提供 DrvStretchBlt 函数,即使驱动程序支持设备管理的表面。这 个函数提供在设备管理的表面和 GDI 管理的表面之间延伸块传输能力。DrvStretchBlt 仅支 持某些类型的延伸,如通过整数乘延伸。 DrvStretchBlt 也允许驱动程序在 GDI 位图上写,特别当驱动程序能进行中间色调处 理时。这个函数也允许同一个中间色调算法应用于 GDI 位图和设备表面。 DrvStretchBlt 精确映像一个几何源矩形到一个几何目标矩形。源矩形角的坐标由给 定的整数坐标替换为(-0.5,-0.5)。函数参数中指定的点位于相应的像素中心的整数坐标。 由两个这样的点定义的矩形认为是几何的,两个顶点是坐标给定的点,但每个坐标都用 0.5 代替。(GDI POINTL 结构使用一个速记符指定这些分数坐标顶点。)注意如何这样的矩形的 边不会有像素交叉,但提供一系列像素。矩形内的像素是通常的底边和右边排除的矩形的像 素。 源矩形的点是有序的。不能给定一个空的源矩形到 DrvStretchBlt。与 DrvBitBlt 不 同,DrvStretchBlt 能用一个简单的裁剪矩形调用,防止在裁剪输出中的舍入错。 目标矩形由两个整数点定义。这些点不是有序的,这意味着第二个点的坐标不必须比 第一个大。这些点描述的源矩形不包括底边和右边。因为矩形不是有序的,DrvStretchBlt 必须不时执行两个x坐标和/或两个y坐标的倒置。(驱动程序必须尝试读出不在源表面上的 像素。)DrvStretchBlt 不能用一个空的目标矩形调用。 对于颜色转换,DrvStretchBlt 提供一个指针,pxlo,指向 XLATEOBJ 结构,用于在源 和目标表面之间转换。XLATEOBJ 结构可用来查询,找到任何源索引的目标索引。对高品质 的延伸块传送,DrvStretchBlt 在某些情况下要求加入颜色。DrvStretchBlt 也使用 COLORADJUSTMENT 结构定义颜色调整值,在位被延伸之前用于源位图。 DrvStretchBlt 使用 iMode 参数定义源像素如何组成输出。特别地,iMode 提供 HALFTONE 选项,允许驱动程序在输出表面使用像素组到最接近的颜色或灰度级。在下一次 用 HALFTONE 的 iMode 调用 DrvStretchBlt 后,COLORADJUSTMENT 结构的改变传递到驱动程 序。另外,如果驱动程序为 GDI 位图请求 GDI 处理中间色调,驱动程序可以挂起 DrvStretchBlt,iMode 设置参数到 HALFTONE,并在 EngStretchBlt 返回。 如果 DrvStretchBlt 挂起一个对 EngStretchBlt 函数的调用,并请求了它不支持的某 些操作,它把请求返回到 GDI,由相应的函数进行处理。 DrvCopyBits 函数由 GDI 从其模拟操作调用,在设备管理的光栅表面和 GDI 标准格式 位图之间转换。DrvCopyBits 为 SRCCOPY(0xCCCC)ROP 位块传输提供了一个快速路径。这 个函数为具有设备管理的位图或光栅表面的图形驱动程序请求,必须转换驱动程序表面到 (或从)任何标准格式位图。DrvCopyBits 不会用一个空的目标举行调用,目标举行的两个 端点是有序的。这个调用和 DrvBitBlt 有相同的请求。 DrvCopyBits 也用 RLE 位图(参见平台 DDK 文档)和 DDB 调用。位图作为应用程序调 用几个 Win32 GDI 例程的结果提供给这个函数。可选的 DDB 仅由少数几个指定的驱动程序支 持
3.4.4过渡调色技术 传统的模拟中间色调使用相等大小的单元组成的中间色调屏幕,固定单元的距离是从 中心到中心。固定单元的距离调节墨水的浓度,当每个单元中点的大小变化时产生连续色调 的印象。 在计算机中,大多数打印或屏幕阴影也使用固定单元像素大小。为模拟点大小的变化, 一组像素的组合模拟中间色调屏幕。GDI包括过渡调色技术的默认参数,提供一个好的首次 近似。附加的设备指定的信息能加入到系统中改进输出。 驱动程序发送GDI设备相关的规范,GDI需要通过 Dry Enablepdel函数返回的 GDIINFO 结构进行过渡调色处理。驱动程序用 GDIINFO的 ulHTPatternSize成员指定模型的大小,它 定义过渡调色技术推荐的输出格式。对指定的设备,过渡调色技术与调色模型大小有关。GDI 提供许多预定义的模型尺寸,从2x2到16×16 对每个标准的模型尺寸,还有一个修改版。它通过在标准模型名上加上后缀“M”来 区分。例如,标准的6乘6的模型定义的名字是 HT PATSIZE6×6,修改的6乘6的模型定 义的名字是 HT PATSIZE6×6M。修改版给定了更多的颜色分辨率,但产生一个副作用,即 水平或垂直噪声。另外,因为每个模型的尺寸是设备分辨率相关的,相应的模型尺寸依赖于 指定的设备。 在模型尺寸(空间分辨率)和颜色分辨率之间的折中是由模型尺寸决定。一个大的过 渡调色模型产生更好的颜色分辨率,而小的模型得到更好的空间分辨率。确定最好的模型尺 寸是进行频繁地尝试和出错。更多的信息参考在线DDK中 Graphic Driver Reference的 GDLINFO GDIINFO结构中影响过渡调色技术的另一个成员是 fIHTFlags,它包含描述过渡调色 需要的设备分辨率 GDⅠ处理应用的颜色调整请求,并通过DDI把信息传递到驱动程序函数。如果应用选 择过渡调色,而且表面是标准格式的DIB,在位图发送到设备之后,GDⅠ使用其过渡调色能 力处理位图。在 PostScript驱动程序中, EngStretchBlt函数能使用 DrvCopyBits或 Drybitblt(在 SRCCOPY模式中)函数发送位图到打印机。 例如,让GDⅠ代替 PostScript打印机执行过渡调色处理,提供了更快的输出,更好 的所见即所得品质。如果打印机内嵌的过渡调色能力更好, PostScript驱动程序的接口允 许用户调整过渡色调并提供一个检查框关闭GDⅠ的过渡调色。 DryDithercolor函数能返回 DCR HALFTONE值,请求GDI使用存在的设备(过渡调色) 调色板近似一个颜色。仅当设备包含一个设备(过渡调色)调色板, DCR HALFTONE能够用 于显示器驱动程序,如VGA-16适配器卡,因为它有一个标准的固定调色板。单色驱动程序, 包括大多数光栅打印机,能使用 Dry dithercolor中 iMode的参数获得一个好的灰度效果 注意: Windows2000在24位(或更高)的设备上不支持过渡调色技术。 3.4.5图像颜色管理 在计算机监视器上显示的图像在彩色打印机上打印时经常出现不同。为解决这个问 题, Windows2000把图像颜色管理(ICM)并入到执行图像的颜色修正,这样在不同的输出 设备上颜色的出现是一致的。 有关图像颜色管理和输出设备的特别类的更多的信息,参见:第二部分第2章,显示
29 3.4.4 过渡调色技术 传统的模拟中间色调使用相等大小的单元组成的中间色调屏幕,固定单元的距离是从 中心到中心。固定单元的距离调节墨水的浓度,当每个单元中点的大小变化时产生连续色调 的印象。 在计算机中,大多数打印或屏幕阴影也使用固定单元像素大小。为模拟点大小的变化, 一组像素的组合模拟中间色调屏幕。GDI 包括过渡调色技术的默认参数,提供一个好的首次 近似。附加的设备指定的信息能加入到系统中改进输出。 驱动程序发送 GDI 设备相关的规范,GDI 需要通过 DrvEnablePDEV 函数返回的 GDIINFO 结构进行过渡调色处理。驱动程序用 GDIINFO 的 ulHTPatternSize 成员指定模型的大小,它 定义过渡调色技术推荐的输出格式。对指定的设备,过渡调色技术与调色模型大小有关。GDI 提供许多预定义的模型尺寸,从 22 到 1616。 对每个标准的模型尺寸,还有一个修改版。它通过在标准模型名上加上后缀“_M”来 区分。例如,标准的 6 乘 6 的模型定义的名字是 HT_PATSIZE_66,修改的 6 乘 6 的模型定 义的名字是 HT_PATSIZE_66_M。修改版给定了更多的颜色分辨率,但产生一个副作用,即 水平或垂直噪声。另外,因为每个模型的尺寸是设备分辨率相关的,相应的模型尺寸依赖于 指定的设备。 在模型尺寸(空间分辨率)和颜色分辨率之间的折中是由模型尺寸决定。一个大的过 渡调色模型产生更好的颜色分辨率,而小的模型得到更好的空间分辨率。确定最好的模型尺 寸是进行频繁地尝试和出错。更多的信息参考在线 DDK 中 Graphic Driver Reference 的 GDIINFO。 GDIINFO 结构中影响过渡调色技术的另一个成员是 flHTFlags,它包含描述过渡调色 需要的设备分辨率。 GDI 处理应用的颜色调整请求,并通过 DDI 把信息传递到驱动程序函数。如果应用选 择过渡调色,而且表面是标准格式的 DIB,在位图发送到设备之后,GDI 使用其过渡调色能 力处理位图。在 PostScript 驱动程序中,EngStretchBlt 函数能使用 DrvCopyBits 或 DrvBitBlt(在 SRCCOPY 模式中)函数发送位图到打印机。 例如,让 GDI 代替 PostScript 打印机执行过渡调色处理,提供了更快的输出,更好 的所见即所得品质。如果打印机内嵌的过渡调色能力更好,PostScript 驱动程序的接口允 许用户调整过渡色调并提供一个检查框关闭 GDI 的过渡调色。 DrvDitherColor 函数能返回 DCR_HALFTONE 值,请求 GDI 使用存在的设备(过渡调色) 调色板近似一个颜色。仅当设备包含一个设备(过渡调色)调色板,DCR_HALFTONE 能够用 于显示器驱动程序,如 VGA-16 适配器卡,因为它有一个标准的固定调色板。单色驱动程序, 包括大多数光栅打印机,能使用 DrvDitherColor 中 iMode 的参数获得一个好的灰度效果。 注意:Windows 2000 在 24 位(或更高)的设备上不支持过渡调色技术。 3.4.5 图像颜色管理 在计算机监视器上显示的图像在彩色打印机上打印时经常出现不同。为解决这个问 题,Windows 2000 把图像颜色管理(ICM)并入到执行图像的颜色修正,这样在不同的输出 设备上颜色的出现是一致的。 有关图像颜色管理和输出设备的特别类的更多的信息,参见:第二部分第 2 章,显示
器的颜色管理;第三部分第12章,打印机的颜色管理;或者在线DK上 Color Management for Still Image Devices 有关ICM的一般讨论,参见平台DK文档 3.5支持DD颜色和调色板函数 DDI颜色和调色板函数包括调色板管理和画刷实现函数。 3.5.1管理调色板 就像第2章对图形驱动程序的ωⅠ支持描述的,GDⅠ处理了许多调色板管理工作。当 GDⅠ调用 Dry Enablepdev函数时,驱动程序在 DEVINFO结构中必须提供其确省的调色板到 GDI。这时,驱动程序必须调用GDI的服务函数 EngCreatePalette创建确省的调色板 支持建立调色板的驱动程序也必须支持 DrySetPalette函数。这个函数是显示器驱动 程序专有的。 3.5.2实现画刷 输出直线、文本或者进行填充的图形函数至少接受一个画刷作为参数。画刷定义在指 定的表面用来绘制图形对象的模式。每个接受画刷的输出函数请求一个画刷原点。画刷原点 提供了像素在设备表面的坐标,与画刷模型左上角的像素排列在一起。画刷模型重复(平铺) 覆盖整个设备表面 驱动程序支持下列函数定义画刷 DryRealizebrush DryDithercolor 画刷总是使用混合模式,定义模型如何与设备表面上已经存在的数据混合。MIX数据 类型包括压缩到一个 ULONG值中的两个ROP2值。前景ROP在低字节。下一个字节包含背景 ROP。更多的信息参见平台DDK文档 GDⅠ保存所有的应用请求使用过的逻辑画刷。在请求驱动程序绘制之前,GDI首先发 出请求调用驱动程序的 Dry Realizebrush函数。这允许驱动程序为其自身的绘图代码计算所 请求模型的最优表示 调用 DryRealizebrush来实现由 psoPattern(画刷的模型)和 psoTarget(实现画刷 的表面)定义的画刷。实现的画刷包含驱动程序为了用模型填充一个区域而需要的信息和加 速器。这个信息只由驱动程序定义和使用。画刷的驱动程序实现写进一个缓冲区,驱动程序 通过从 DryRealizeBrush中调用GDI服务函数 BRUSHOBJ pVAllocRBrush分配这个缓冲区。 GDI缓存所有已实现的画刷;这样,它们很少需要重新计算 在 DryRealizebrush中, BRUSHOBJ使用对象表示画刷。画刷实现的表面可以是设备的 物理表面、DB或标准格式的位图。对于一个光栅设备,表面描述画刷模型表示一个位图 对于矢量设备,它总是由 Dry Enablepdev函数返回的模型表面之一。画刷使用的透明掩码是 每像素一位的位图,与模型的长度相同。掩码位为0表示像素是画刷的背景像素
30 器的颜色管理;第三部分第 12 章,打印机的颜色管理;或者在线 DDK 上 Color Management for Still Image Devices。 有关 ICM 的一般讨论,参见平台 DDK 文档。 3.5 支持 DDI 颜色和调色板函数 DDI 颜色和调色板函数包括调色板管理和画刷实现函数。 3.5.1 管理调色板 就像第 2 章对图形驱动程序的 GDI 支持描述的,GDI 处理了许多调色板管理工作。当 GDI 调用 DrvEnablePDEV 函数时,驱动程序在 DEVINFO 结构中必须提供其确省的调色板到 GDI。这时,驱动程序必须调用 GDI 的服务函数 EngCreatePalette 创建确省的 调色板。 支持建立调色板的驱动程序也必须支持 DrvSetPalette 函数。这个函数是显示器驱动 程序专有的。 3.5.2 实现画刷 输出直线、文本或者进行填充的图形函数至少接受一个画刷作为参数。画刷定义在指 定的表面用来绘制图形对象的模式。每个接受画刷的输出函数请求一个画刷原点。画刷原点 提供了像素在设备表面的坐标,与画刷模型左上角的像素排列在一起。画刷模型重复(平铺) 覆盖整个设备表面。 驱动程序支持下列函数定义画刷: DrvRealizeBrush DrvDitherColor 画刷总是使用混合模式,定义模型如何与设备表面上已经存在的数据混合。MIX 数据 类型包括压缩到一个 ULONG 值中的两个 ROP2 值。前景 ROP 在低字节。下一个字节包含背景 ROP。更多的信息参见平台 DDK 文档。 GDI 保存所有的应用请求使用过的逻辑画刷。在请求驱动程序绘制之前,GDI 首先发 出请求调用驱动程序的 DrvRealizeBrush 函数。这允许驱动程序为其自身的绘图代码计算所 请求模型的最优表示。 调用 DrvRealizeBrush 来实现由 psoPattern(画刷的模型)和 psoTarget(实现画刷 的表面)定义的画刷。实现的画刷包含驱动程序为了用模型填充一个区域而需要的信息和加 速器。这个信息只由驱动程序定义和使用。画刷的驱动程序实现写进一个缓冲区,驱动程序 通过从 DrvRealizeBrush 中调用 GDI 服务函数 BRUSHOBJ_pvAllocRBrush 分配这个缓冲区。 GDI 缓存所有已实现的画刷;这样,它们很少需要重新计算。 在 DrvRealizeBrush 中,BRUSHOBJ 使用对象表示画刷。画刷实现的表面可以是设备的 物理表面、DDB 或标准格式的位图。对于一个光栅设备,表面描述画刷模型表示一个位图; 对于矢量设备,它总是由 DrvEnablePDEV 函数返回的模型表面之一。画刷使用的透明掩码是 每像素一位的位图,与模型的长度相同。掩码位为 0 表示像素是画刷的背景像素