Windows 在Win7中,某些字体不';不能像在Win2K/XP中那样工作
我的问题是如何更改字体处理,以便在Windows7下正常工作。我确信我对一些以前有效但现在不再有效的东西做出了假设。但我甚至不知道从哪里开始找!我祈祷有人能帮忙!以下是我对他们的理解(我也在Microsoft Windows开发者论坛上发布了这个问题,但他们没有回答): 是的,我落后于时代(见鬼,我仍然用纯C编写WIN32代码!)我有一个10年前编写的DLL,它在窗口的客户端区域模仿更旧的DOS屏幕I/O库。不用说,它只允许使用固定宽度的字体。当一些使用DLL的程序被移动到Windows 7时,当使用固定宽度的TRUE TYPE字体时会出现奇怪的闪烁(位图字体仍然可以很好地工作)。我们已经跟踪到了这个问题,即使用Windows 在Win7中,某些字体不';不能像在Win2K/XP中那样工作,windows,fonts,font-size,truetype,Windows,Fonts,Font Size,Truetype,我的问题是如何更改字体处理,以便在Windows7下正常工作。我确信我对一些以前有效但现在不再有效的东西做出了假设。但我甚至不知道从哪里开始找!我祈祷有人能帮忙!以下是我对他们的理解(我也在Microsoft Windows开发者论坛上发布了这个问题,但他们没有回答): 是的,我落后于时代(见鬼,我仍然用纯C编写WIN32代码!)我有一个10年前编写的DLL,它在窗口的客户端区域模仿更旧的DOS屏幕I/O库。不用说,它只允许使用固定宽度的字体。当一些使用DLL的程序被移动到Windows 7时,
ExtTextOut
编写的单个字符比它应该的宽。我用三种不同的方法检查了度量值(对132个字符的字符串使用GetTextExtentPoint32
除以132,调用GetTextMetrics
甚至对所有256个字符使用GetCharABCWidths
),它们都同意字体的宽度相同。但是ExtTextOut
正在渲染比字体宽度宽一到两个像素的背景矩形。或者它开始在参数中给出的位置左侧渲染一到两个像素的背景[我这样称呼它:ExtTextOut(hdc,r.left,r.top,ETO_不透明,&r,&ch,1,NULL)
。]记住,这段代码在Windows 2000、Windows XP和,在Windows 7上使用位图字体,但在Windows 7下使用固定宽度的true type字体时,它不再正常工作
对于那些不明白我需要做什么的人:试着想象一下在一张方格纸上写一个字符。每个正方形使用相同的字体,但可能有不同的前景和/或背景色。我使用TA|u TOP | TA|u LEFT
文本对齐,因为它是最简单的,任何一致应用的对齐方式都应该适用于固定宽度的字体
我看到的是ExtTextOut发出的背景矩形比我在RECT*
参数中指定的要大。因为我提供的矩形是根据报告的字体大小创建的,所以这种情况永远不会发生——在Windows XP和更早版本上也不会发生,在Windows 7下的位图(即..FON)字体上也不会发生。但在Windows7下,固定宽度的TrueType字体总是会出现这种情况。这与Windows 2000、Windows XP和Windows 7(32&64)上运行的可执行文件完全相同。虽然我想简单地说Windows 7有一个bug,但我更倾向于相信,我对Windows下字体处理所做的一些基本假设不再正确(在为Windows编写软件20年之后)
但我不知道如何或在哪里发现那可能是什么!请,请帮帮我
---弹药---
对于任何感兴趣的人来说,我已经设法解决了我所考虑的一个bug——直到我找到了与之相反的文档。我的解决方案包括对我的库的两个更改:
GetTextExtentPoint32()
返回的大小
来自TEXTMETRICS
的数据量ExtTextOut()
调用中包括ETO\u剪裁
标志tmHeight+tmExternalLeading
表示连续文本行顶部之间的像素数,如文档所示。我发现从GetTextExtentPoint32(
)返回的size.cy值不一样,似乎更准确。我发现的最糟糕的例子是OCRB true type字体。以下是我在调试程序中看到的我创建的OCRB字体(使用系统字体选择对话框):
因此,出于我尚未发现的某些原因,Windows忽略了为OCRB字体定义的外部前导值。使用size值而不是TM可以生成漂亮、整洁、紧凑的文本,这正是我想要的
ETO_CLIPPING
标志对我来说应该是不必要的,因为我将矩形设置为一个字符的精确尺寸,并使用ETO_OPAQUE
填充背景(并覆盖以前的单元格内容)。但是如果没有剪裁标志,一个字符的宽度将超过大小、文本度量和,或者ABC宽度表示——至少,根据我到目前为止找到的所有文档,这是正确的
我相信高度问题已经存在很长一段时间了,但是在我们在Windows7下运行我们的软件之前,其余的都是不必要的。我把这个附加在我的问题后面,看看是否有人能解释我显然不懂的东西
--附件2--
1:我能找到的所有文档都说tmHeight+tmexternalreading
应该产生单行间距的文本。时期但这并不总是正确的,我找不到说明Windows如何确定不同值的文档,这些值有时由GetTextExtentPoint32()
返回
2:在Win7(可能是Vista)下,ExtTextOut
开始填充稍微多一些的背景(通过在右侧添加两个额外的像素),但仅当选择了true type字体时。即使矩形是字符的预期大小(在两个维度上)的两倍,它也会这样做。DPI/缩放可能是一个因素,但由于我的系统设置为100%,Windows似乎在1:1缩放因子方面遇到问题,这似乎是一个错误。它只影响真实类型而不影响位图(.FON)字体这一事实似乎也排除了缩放的可能性(除非存在缺陷)
ocrbtm.tmHeight = 11
ocrbtm.tmExternalLeading = 7
ocrbsize.cy = 11
CreateFontIndirect
SelectFont
GetTextMetrics
if( (tmPitchAndFamily & TMPF_TRUETYPE) && Win6.x or above )
if( SystemParametersInfo( SPI_GETCLEARTYPE ) )
lfQuality = NONANTIALIASED_QUALITY
DeleteObject( font )
CreateFontIndirect
// Draw the sample text with an opaque background.
assert(::GetMapMode(ps.hdc) == MM_TEXT);
assert(::GetBkMode(ps.hdc) == OPAQUE);
assert(::GetTextAlign(ps.hdc) == TA_TOP);
COLORREF rgbOld = ::SetBkColor(ps.hdc, RGB(0xC0, 0xFF, 0xC0));
::TextOutW(ps.hdc, x, y, pszText, cchText);
::SetBkColor(ps.hdc, rgbOld);
// This vertical line at the right side of the text shows that opaque
// background is exactly the height returned by GetTextExtentPoint32.
SIZE size = {0};
if (::GetTextExtentPoint32W(ps.hdc, pszText, cchText, &size)) {
::MoveToEx(ps.hdc, x + size.cx, y, NULL);
::LineTo(ps.hdc, x + size.cx, y + size.cy);
}
// These horizontal lines show the normal line spacing, taking into
// account tmExternalLeading.
assert(tm.tmExternalLeading > 0); // ensure it's an interesting case
::MoveToEx(ps.hdc, x, y, NULL);
::LineTo(ps.hdc, x + size.cx, y); // top of this line
const int yNext = y + tm.tmHeight + tm.tmExternalLeading;
::MoveToEx(ps.hdc, x, yNext, NULL);
::LineTo(ps.hdc, x + size.cx, yNext); // top of next line