关于Windows TextOut输出文字时的一些难看的“方块”

什么是绘制实心矩形最好的方式

老一辈的程序员可能会告诉你”ExtTextOut”,性能最优。

TextOut在输出文字时,为什么有些难看的方块?

IMLangFontLink2::GetStrCodePages方法将字符串分解成许多”块“(chunk),并且在每个块中的所有字符都可以用相同的字体来显示,此外还可以通过IMLangFontLink2::MapFont来创建字体。

#include <mlang.h>

HRESULT TextOutFL(HDC hdc, int x, int y, LPCWSTR psz, int cch)
{
  ...
  while (cch > 0) {
    DWORD dwActualCodePages;
    long cchActual;
    pfl->GetStrCodePages(psz, cch, 0, &dwActualCodePages, &cchActual);
    HFONT hfLinked;
    pfl->MapFont(hdc, dwActualCodePages, 0, &hfLinked);
    HFONT hfOrig = SelectFont(hdc, hfLinked);
    TextOut(hdc, ?, ?, psz, cchActual);
    SelectFont(hdc, hfOrig);
    pfl->ReleaseFont(hfLinked);
    psz += cchActual;
    cch -= cchActual;
  }
  ...
}

下一步,应该确定每次TextOut的位置

SetTextAlign(hdc, GetTextAlign(hdc) | TA_UPDATECP);
MoveToEx(hdc, x, y, NULL);

最后,在处理从右到左(right-to-left)的语言时,IMLangFontLink2接口来将字符串分解为块,将会失败。

以下代码应该是windows文本输出的终极方案

#inlucde <usp10.h>

HRESULT TextOutUniscribe(HDC hdc, int x, int y, LPCWSTR psz, int cch)
{
  if (cch == 0) return S_OK;
  SCRIPT_STRING_ANALYSIS ssa;
  HRESULT hr = ScriptStringAnalyse(hdc, psz, cch, 0, -1, SSA_FALLBACK | SSA_GLYPHS, MAXLONG, NULL, NULL, NULL, NULL, NULL, &ssa);
  if (SUCCESS(hr))
  {
    hr = ScriptString(ssa, x, y, 0, NULL, 0, 0, FALSE);
    ScriptStringFree(&ssa);
  }
  return hr;
}