TextOutW在屏幕与打印机上的显示方式不同

时间:2018-06-05 14:57:53

标签: winapi printing vb6 dpi

我们有一个用于打印的VB6应用程序,目前我们无法在.NET中重写。 :)我们要解决的问题是打印文本与UI预览完全不匹配。我们有一个自定义文本框控件,分别使用ExtTextOut和TextOut处理绘制和打印。它们的输出应该相同,但是,如果字体相同,则屏幕或打印机上的文字可能会更大。高度是完美的,只是间距和字符宽度不同。我还不确定这是一个字体字距调整问题,但差异确实取决于间距和字符宽度的打印机DPI。 DPI越高,差异越大。 4000 DPI会产生细微的字符。但我可以确信我们在某处处理DPI是错误的。

以下代码来自打印方面,用于设置字体并打印一些文本。

fntHeight = MulDiv(m_Font.SIZE, GetDeviceCaps(printerDC, LOGPIXELSY), 72)

fnt = CreateFont(-fntHeight, 0, escapement, escapement, FW_BOLD, Font.Italic, Font.Underline, _
Font.Strikethrough, Font.Charset, 0, CLIP_LH_ANGLES, FontQuality, 0, Font.Name)

SelectObject(printerDC, fnt)

TextOutW(printerDC, x, y, StrPtr(strOutputText), Len(strOutputText))

UI的绘图代码非常相似。用户看到的问题:UI不是一个很好的衡量标准,因为如果文本字段的大小太小,因为如果打印机DC上的文本比屏幕DC略宽,那么最后一个字符,例如句点,被切断了。

这种差异因字体大小而异,在28处差异为0.它可以在+14和-14之间轻松变化,打印或绘制的文本宽度更大。到目前为止,我还无法找出导致TextOut,ExtTextOut和GetTextExtentPoint32提供不同结果的原因。

此代码计算差异,并由paint事件用于尝试调整间距以说明它,但如果我们能够找到为什么首先存在差异,那就更好了,因为它可以& #39; t考虑字符宽度差异。 GetTextExtentPoints32隐藏在对TextWidthU的调用之后。

' Call GetTextExtentPoint32W(hdc, StrPtr(strText), Len(strText), textSize)
printerTextWidth = TextWidthU(printerDC, strOutputText) * (screenXdpi / printerXdpi)
screenTextWidth = TextWidthU(UserControl.hdc, strOutputText)
totalDifference = printerTextWidth - screenTextWidth

1 个答案:

答案 0 :(得分:2)

文本光栅化器对齐像素边界上的所有字符。例如,字母'i'对于96 DPI可以具有3个像素宽度,但对于192 DPI可以具有5,6或7个宽度。如果要匹配屏幕和打印机宽度,则应根据打印机分辨率计算宽度并适当调整屏幕位置。

您可以按原样调整单个字母,整个单词的位置或保留屏幕布局,但可以根据打印机文本大小剪切或延伸右边距。

MS Word调整字母位置(观察字母之间的空格):

enter image description here

有趣的起点: http://www.antigrain.com/research/font_rasterization/index.html#FONT_RASTERIZATION