Search code examples
c++mfcgdirectvertical-text

MFC DrawText, vertical, DT_CALCRECT with lf_escapement = 900


I'm working on a MFC project with some GDI drawings. I use DC.DrawText to draw a vertical text into a DC using a LOGFONT with lfEscapement = 900. The text is output when i use DT_NOCLIP in the desired vertical formatting. However to center this text i used a call to DC.DrawText with the DT_CALCRECT argument. I recognized that, despite the text is indeed drawn vertically, the CRect has a larger width than height. My intuition says me that a vertical drawn text should have a larger height than width. I did not include the calculation for centering the text. The question is just about what i can rely upon when i implement that vertical centering.

Does DC.DrawText with DT_CALCRECT ignore escapement?

void CMFCFontTestDlg::OnPaint()
{
  CPaintDC dc(this); // Gerätekontext zum Zeichnen

  if (IsIconic())
  {
    ...
  }
  else
  {
    CDialogEx::OnPaint();

    CRect clTextRect;
    CFont myFont;

    myFont.CreateFont(12, 0, 900, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _T("Tahoma"));

    CFont* oldFont = dc.SelectObject(&myFont);

    dc.DrawText(_T("000000"), clTextRect, DT_CALCRECT);
    clTextRect.MoveToXY(100, 100);

    dc.DrawText(_T("000000"), clTextRect, DT_NOCLIP);
    dc.SelectObject(oldFont);
  }
}

enter image description here Vertically formatted text in DC


Solution

  • I found out about it in the remarks to the DrawTextEx function https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-drawtextexa. However, please note that neither the documentation of DrawText does say anything about this nor the documentation of the DT_CALCRECT flag. This is likely to be overseen if one uses DrawText and not DrawTextEx. I informed MS about this via "Is this page helpful?" feedback possibility.

    Remarks

    The DrawTextEx function supports only fonts whose escapement and orientation are both zero.

    The text alignment mode for the device context must include the TA_LEFT, TA_TOP, and TA_NOUPDATECP flags.

    Considering this the solution is to use some trigonometric calculation starting from the size determined for escapement = 0 and then calculate the topleft and bottomright points of the rotated rect.