In Win7 some fonts don't work like they did in Win2K/XP

时间秒杀一切 提交于 2019-12-04 04:44:36

Make sure your code is high DPI aware, and then tell the OS that your process is DPI aware.

If you don't tell the OS that you're DPI aware, some of the measurement functions will lie and give you numbers based on the assumption that the display DPI is actually 96 dpi regardless of what it really is. Meanwhile, the drawing functions will try to scale in the other direction. For simple high-level drawing, this approach generally works (though it often leads to fuzzy text). For small measurements and precise placement of individual characters, this often results in round off problems that lead to things like inconsistent font sizes. This behavior was introduced in Windows Vista.

You can see it all the time in Visual Studio 2010+ as the syntax highlighter colors the text and words shift by a couple pixels here and there as you type. Really frickin' annoying.

Regarding the amendment:

tmExternalLeading is simply a recommendation from the font designer as to how much extra space to put between lines of text. MSDN documentation typically says, "the amount of extra leading (space) that the application adds between rows." Well, you're the application, so the "Right Thing To Do" is to add it between rows when you're drawing text yourself, but it really is up to you. (I suspect higher level functions like DrawText will use it.

It is perfectly correct for GetTextExtentPoint32 (and friends) to return a size.cy equal to tmHeight and to ignore tmExternalLeading. As the programmer, it's ultimately your choice how much leading to actually use.

You can see that this with some simply drawing code. Select a font with a non-zero tmExternalLeading (Arial works for me). Draw some text using TextOut and a unique background color. Then measure the text with GetTextExtentPoint32 and draw some lines based on the values you get back. You'll see that the background color rectangle excludes the external leading. External leading is just that: external. It's not in the bounds of the character cell.

  // 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

The gap between the bottom of the colored rectangle and the top of the next line represents the external leading, which is always outside the character cell.

OCR-B is designed for reliable optical character recognition in banking equipment. Having a large external leading (relative to the height of the actual text) may be appropriate for some OCR applications. For this particular font, it's probably not an aesthetic choice.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!