使用 GDI 每像素 8 位 CMY 掩码模式

在 Microsoft Windows 2000 中, HT_Get8BPPMaskPalette 函数返回 8 位每像素单色或 CMY 调色板。 在 Windows XP 及更高版本中,此函数已修改,以便在 Use8BPPMaskPal 参数设置为 TRUE 时,它还返回反索引 CMY 调色板。 返回的调色板的类型取决于调用 HT_Get8BPPMaskPalette 时存储在 pPaletteEntry[0] 中的值。 如果 pPaletteEntry[0] 设置为“RGB0”,则返回反索引调色板。 如果 pPaletteEntry[0] 设置为 0,则返回正常的 CMY 调色板。

HT_Get8BPPMaskPalette行为发生此更改的原因是,当 Windows GDI 使用基于调色板中的索引而不是调色板颜色的 RP 时,它假定调色板的索引 0 始终为黑色,最后一个索引始终为白色。 GDI 不检查调色板条目。 HT_Get8BPPMaskPalette 中的此更改可确保正确的 ROP 输出,而不是反转的结果。

为了纠正 GDI ROP 行为,Windows XP 及更高版本中的 GDI 支持一种特殊的 CMY 调色板组合格式,即 CMY 掩码板条目从索引 255 开始 (白色) ,并向下工作到索引 0 (黑色) ,而不是从索引 0 (白色) 开始,最多为索引 255 (黑色) 。 CMY 反转模式还会将所有 CMY 掩码颜色条目移动到完整的 256 个输入调色板的中间,调色板的开头和结尾填充了相等数量的黑白条目。

注意 在随后的讨论中,术语 CMY 模式 是指 HT_Get8BPPMaskPalette 的先前实现中支持的模式。 术语 CMY_INVERTED模式 是指仅在 Windows XP 和更高版本的 GDI 上支持的模式,当 pPaletteEntry[0] 设置为“RGB0”时,此函数将反转位掩码索引。

对于使用 Windows GDI 半色调每像素 8 位 CMY 掩码模式的所有 Windows XP 和更高版本的驱动程序,需要执行以下步骤。 如果要开发适用于 Windows 2000 的驱动程序,则应将驱动程序的使用限制为每像素 8 位单色调色板。

  1. GDIINFO 结构的 flHTFlags 成员设置为 HT_FLAG_INVERT_8BPP_BITMASK_IDX,以便 GDI 将以CMY_INVERTED模式之一呈现图像。

  2. 在调用 HT_Get8BPPMaskPalette 之前,按如下所示设置 pPaletteEntry[0] :

    pPaletteEntry[0].peRed   = 'R';
    pPaletteEntry[0].peGreen = 'G';
    pPaletteEntry[0].peBlue  = 'B';
    pPaletteEntry[0].peFlags = '0';
    

    为此,调用方应使用 winddi.h) 中定义的 HT_SET_BITMASKPAL2RGB 宏 (。 下面是一个示例,演示了此宏的用法:

    HT_SET_BITMASKPAL2RGB(pPaletteEntry)
    

    此处 ,pPaletteEntry 是指向在调用 HT_Get8BPPMaskPalette 函数时传递的 PALETTEENTRY 的指针。 当此宏完成执行时, pPaletteEntry[0] 将包含字符串“RGB0”。

  3. 使用 winddi.h 中定义的 HT_IS_BITMASKPALRGB 宏检查从调用HT_Get8BPPMaskPalette返回的 pPaletteEntry 参数。 以下示例演示了此宏的用法。

    InvCMYSupported = HT_IS_BITMASKPALRGB(pPaletteEntry)
    

    在此表达式中, pPaletteEntry 是指向传递给 HT_Get8BPPMaskPalette 函数的 PALETTEENTRY 的指针。 如果此宏返回 TRUE,则 GDI 确实 支持反转 CMY 8 位每像素位掩码模式。 调用方必须使用转换表将调色板索引转换为墨迹级别。 有关生成此转换表的函数示例,请参阅 将每像素 8 位半色调索引转换为墨迹级别

    如果此宏返回 FALSE,则表示当前版本的 GDI 不支持 反转 CMY 8 位/像素位掩码模式。 在这种情况下,GDI 仅支持较旧的 CMY 非反转模式。

对于支持每像素 8 位CMY_INVERTED模式的 GDI 版本,传递给 HT_Get8BPPMaskPalette 函数的 CMYMask 参数值的含义已更改。 下表概述了这些更改:

CMYMask
CMY 模式索引
(pPaletteEntry[0] != 'RGB0')
CMY_INVERTED模式索引
(pPaletteEntry[0] == 'RGB0')

0

0:白色

1 到 254:浅灰色 --> 深灰色
255:黑色

0 - 黑色

1 到 254:深灰色 --> 浅灰色
255: 白色

1

0:白色

1 到 123:123 5x5x5 颜色
124 到 255:黑色

0 到 65:黑色

66 到 189:123 5x5x5 颜色加上一个重复颜色。 索引 127 处的条目将复制到索引 128。
190 到 255:白色
索引 127 和 128 处的值会重复,以确保 XOR ROP 正常工作。

2

0:白色

1 到 214:214 6x6x6 颜色
215 到 255:黑色

0 到 20:黑色

21 到 234:214 6x6x6 颜色
235 到 255:白色

3 到 255

0:白色

1 到 254:CxMxY 颜色位掩码
255:黑色
在上述产品中,C、M 和 Y 分别表示青色、洋红色和黄色的级别数。
注意:对于这些模式,有效组合不得有任何青色、洋红色或黄色墨迹级别等于零。 对于此类组合, HT_Get8BPPMaskPalette 通过在其 pPaletteEntry 参数中返回零计数调色板来指示错误条件。

0:黑色

1 到 254:居中 CxMxY 颜色,开头填充黑色,末尾填充白色
如果 CxMxY 是奇数,则索引 128 处的条目是索引 127 处的条目的副本。
255: 白色
在上述产品中,C、M 和 Y 分别表示青色、洋红色和黄色的级别数。
注意: (C x M x Y) 索引在 256 个条目的调色板中居中。 也就是说,填充调色板的低端的黑色条目和填充高端的白色条目数量相等。
注意:对于这些模式,有效组合不得有任何青色、洋红色或黄色墨迹级别等于零。 对于此类组合, HT_Get8BPPMaskPalette 通过在其 pPaletteEntry 参数中返回零计数调色板来指示错误条件。
  • 对于 CMYMask 值为 0 (灰度) ,调用方可以处理 CMY 模式或CMY_INVERTED模式。 但请注意,GDI RP 仅在CMY_INVERTED模式下正确处理。

    CMY 模式:索引 0 到 255 表示从白色到黑色的灰度。

    CMY_INVERTED模式:索引 0 到 255 表示从黑色到白色的灰度。

  • 对于 CMYMask 从 1 到 255 的任何有效值,调用方应使用将 每像素 8 位半色调索引转换为墨迹级别 中显示的示例函数,以将索引转换为墨迹级别。

  • 对于 CMYMask 从 1 到 255 的任何有效值,CMY_INVERTED模式在调色板中填充数组开头的黑色条目,在数组末尾填充相同数量的白色条目。 数组的中间用其他颜色填充。 这可确保所有 256 个调色板条目都对称分布,以便 GDI RP(基于索引而不是基于颜色)正常工作。 当索引 N 处的颜色是索引 (256 - N) 时,颜色是对称分布的。 当颜色及其逆向打印在一起时,结果为黑色。 换句话说,对于给定颜色及其反转,两个青色墨迹级别将添加到最大青色墨迹级别,两个洋红色墨迹级别和两个黄色墨迹级别也一样。 生成的墨迹级别对应于黑色。

    例如:具有青色、洋红色和黄色三个级别的 CMY 调色板共有 27 (3 x 3 x 3) 颜色索引,包括黑色和白色。 由于 27 是奇数,并且 GDI 要求使用相同数量的黑白条目填充CMY_INVERTED模式调色板,因此 GDI 复制中间索引处的条目 (索引 13 中的 27 种颜色) 。 索引 13 和 14 处的条目现在相同,调色板现在将具有 28 种颜色。 为了填充调色板,GDI 在调色板的开头放置 114 个黑色条目, (索引为 0 到 113) ,将 28 个颜色放置在索引 114 (黑色) 到 141 (白色) ,并使用白色 (索引 142 到 255) 填充其余 114 个条目。 这使得总共 256 个条目 (114 + 28 + 114 = 256 个条目) 。 索引的这种布局可确保正确呈现所有 IOPS。 将 8 位每像素半色调索引转换为墨迹级别 中的示例函数演示如何生成墨迹级别以及 Windows 2000 CMY332 索引转换表。

    下表列出了上一段中讨论的 3 x 3 x 3 调色板的青色、洋红色和黄色级别。 28 种颜色 (27 种原始调色板颜色外加一个重复) 嵌入在 256 色调色板的中间,开头有同等量的黑色填充,末尾有白色填充。 调色板是对称的,这意味着如果将索引 N 处的墨迹级别添加到索引 (256 - N) 处,则结果将为黑色 (青色、洋红色和黄色级别 = 2) 。

    调色板索引 (3x3x3 索引) 青色级别 0 到 2 洋红色级别 0 到 2 黄色级别 0 到 2

    0 到 113

    黑色

    2

    2

    2

    114 (0)

    黑色

    2

    2

    2

    115 (1)

    2

    2

    1

    116 (2)

    2

    2

    0

    117 (3)

    2

    1

    2

    118 (4)

    2

    1

    1

    119 (5)

    2

    1

    0

    120 (6)

    2

    0

    2

    121 (7)

    2

    0

    1

    122 (8)

    2

    0

    0

    123 (9)

    1

    2

    2

    124 (10)

    1

    2

    1

    125 (11)

    1

    2

    0

    126 (12)

    1

    1

    2

    127 (13)

    复制到索引 128

    1

    1

    1

    128 (14)

    索引 127 处条目的副本

    1

    1

    1

    129 (15)

    1

    1

    0

    130 (16)

    1

    0

    2

    131 (17)

    1

    0

    1

    132 (18)

    1

    0

    0

    133 (19)

    0

    2

    2

    134 (20)

    0

    2

    1

    135 (21)

    0

    2

    0

    136 (22)

    0

    1

    2

    137 (23)

    0

    1

    1

    138 (24)

    0

    1

    0

    139 (25)

    0

    0

    2

    140 (26)

    0

    0

    1

    141 (27)

    White

    0

    0

    0

    142 到 255

    White

    0

    0

    0

  • 如果请求的调色板是 CMY 模式调色板 (不是CMY_INVERTED模式调色板) ,则对于 CMYMask 的值(从 3 到 255),则呈现的每像素 8 位字节索引位具有以下含义。 在本例中,位模式表示可以直接使用的墨迹级别,而无需翻译。 当使用转换表的 CMY332Idx 成员将CMY_INVERTED模式字节索引映射到 CMY 模式时,这同样适用。 有关详细信息 ,请参阅将每像素 8 位半色调索引转换为墨迹级别
  Bit     7 6 5 4 3 2 1 0
          |   | |   | | |
          +---+ +---+ +-+
            |     |    |
            |     |    +-- Yellow 0-3 (Max. 4 levels)
            |     |
            |     +-- Magenta 0-7 (Max. 8 levels)
            |
            +-- Cyan 0-7 (Max. 8 levels)