我有一个只需要 HDC 的绘图函数。但我需要展示将打印的内容的精确缩放版本。

因此,目前,我将CreateCompatibledc()与打印机HDC和CreateCompatibleBitMap()与打印机的HDC一起使用。

我认为这样 DC 将具有打印机的精确宽度和高度。当我在 HDC 中选择字体时,文本将按照打印机的方式精确缩放。

不幸的是,我无法使用 StretchBlt() 将此 HDC 的像素复制到控件的 HDC,因为我猜它们属于不同的 HDC 类型。

如果我从与打印机页面相同的W,H的窗口HDC创建“内存帆布”,则字体是少年的,因为它们会缩放为屏幕,而不是页面...

我应该从窗口的dc和createCompatibleBitMap()中创建consteCompatibledc(),而不是打印机的直流电或其他东西?

如果有人可以解释执行此操作的正确方法。(并且仍然有一些看起来与打印机上完全相同的东西)...

嗯,我会很感激!

...史蒂夫

有帮助吗?

解决方案

根据您想要的准确程度,这可能会变得很困难。

有很多方法。听起来您正在尝试绘制打印机大小的位图,然后将其缩小。执行此操作的步骤是:

  1. 为打印机创建一个 DC(或者更好的是 IC——信息上下文)。
  2. 查询打印机DC以找出分辨率、页面尺寸、物理偏移量等。
  3. 为窗口/屏幕创建一个 DC。
  4. 创建兼容的 DC(内存 DC)。
  5. 为窗口/屏幕创建兼容的位图,但大小应为打印机页面的像素大小。(这种方法的问题是,这是一个巨大的位图,并且可能会失败。)
  6. 选择兼容的位图到内存DC中。
  7. 使用与绘制到实际打印机时使用的坐标相同的坐标绘制到内存 DC。(选择字体时,请确保将它们缩放到打印机的逻辑英寸,而不是屏幕的逻辑英寸。)
  8. StretchBlt 内存 DC 到窗口,这将缩小整个图像。您可能想要尝试拉伸模式,看看哪种模式最适合您要显示的图像类型。
  9. 释放所有资源。

但在朝这个方向前进之前,请考虑一下其他选择。这种方法涉及分配一个巨大的屏幕外位图。这在资源匮乏的计算机上可能会失败。即使没有,您也可能会耗尽其他应用程序的资源。

另一个答案中给出的图元文件方法对于许多应用程序来说是一个不错的选择。我想从这个开始。

另一种方法是计算出某些虚构的高分辨率单元中的所有尺寸。例如,假设一切都以千分之一英寸为单位。然后,您的绘图例程会将这个虚数单位缩放为目标设备使用的实际 dpi。

最后一种方法(也可能是图元文件)的问题是 GDI 字体不能完美地线性缩放。各个字符的宽度根据目标分辨率进行调整。在高分辨率设备(如 300+ dpi 激光打印机)上,这种调整是最小的。但在 96 dpi 的屏幕上,这些调整可能会导致线条长度出现显着误差。因此,预览窗口中的文本可能会比打印页面上的文本不成比例(通常更宽)。

因此,核心方法是在打印机上下文中测量文本,然后在屏幕上下文中再次测量,并调整差异。例如(使用虚构的数字),您可以测量打印机上下文中某些文本的宽度,结果为 900 个打印机像素。假设打印机像素与屏幕像素的比例为 3:1。您预计屏幕上的相同文本宽度为 300 屏幕像素。但是您在屏幕上下文中进行测量,您会得到一个类似于 325 屏幕像素的值。当您绘制到屏幕上时,您必须以某种方式使文本变窄 25 像素。您可以将字符拉近,或者选择稍小的字体,然后将它们拉伸。

硬核方法涉及更多复杂性。例如,您可以尝试检测打印机驱动程序进行的字体替换,并尽可能将它们与可用的屏幕字体进行匹配。

我很幸运地结合了大位图和硬核方法。我没有为整个页面制作一个巨大的位图,而是为一行文本制作一个足够大的位图。然后我以打印机尺寸绘制到屏幕外位图上并 StretchBlt 它缩小到屏幕尺寸。这消除了在字体质量略有下降的情况下处理大小差异的情况。它适合实际的打印预览,但您不会想构建这样的所见即所得编辑器。一行位图足够小,足以使其实用。

好消息是只有文字很难。所有其他绘图都是坐标和尺寸的简单缩放。

我很少使用 GDI+,但我认为它消除了非线性字体缩放。因此,如果您使用 GDI+,则只需缩放坐标即可。缺点是我认为 GDI+ 上的字体质量没有那么好。

最后,如果您是 Vista 或更高版本上的本机应用程序,请确保您已将进程标记为“DPI 感知”。否则,如果用户使用高 DPI 屏幕,Windows 会欺骗您并声称分辨率只有 96 dpi,然后对您绘制的任何内容进行模糊放大。这会降低视觉质量,并使打印预览的调试变得更加复杂。由于许多程序不能很好地适应更高 DPI 的屏幕,微软从 Vista 开始默认添加了“高 DPI 缩放”。

编辑添加

另一个警告:如果您使用打印机大小的位图将 HFONT 选择到内存 DC 中,则它是 可能的 您得到的字体与在实际打印机 DC 中选择相同的 HFONT 时得到的字体不同。这是因为某些打印机驱动程序会将常见字体替换为内存中的字体。例如,某些 PostScript 打印机会用内部 PostScript 字体替换某些常见的 TrueType 字体。

您可以先将 HFONT 选择到打印机 IC 中,然后使用 GDI 功能,例如 GetTextFace, GetTextMetrics, , 有可能 GetOutlineTextMetrics 了解所选的实际字体。然后,您可以创建一个新的 LOGFONT 以尝试更紧密地匹配打印机将使用的内容,将其转换为 HFONT,并将其选择到内存 DC 中。这是真正良好实施的标志。

其他提示

一两件事,可能是值得尝试的是建立一个增强型图元DC,绘制到它正常的,然后用打印机标准扩展此图元文件。这是由 WTL BmpView例程所使用的方法 - 我不知道如何准确,这将是但它可能是值得考虑的(它应该很容易移植相关的类Win32的,但WTL是Win32编程所以可能是值得利用巨大的替代品。)

那么它不会看起来是一样的,因为你必须在打印机DC更高的分辨率,所以你必须写各种各样的转换功能。我会去与你有工作的方法,但文字太小,只是由打印机窗口宽度除以源窗口的宽度乘以每个位置/字体大小。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top