How to draw raster console fonts in GDI?

716 Views Asked by At

How do I draw the raster fonts used by the Windows console in a GDI application? For instance, the 8x8 fixed font as shown in this screenshot.Command Prompt Properties - raster fonts

Can these fonts be used via the CreateFont() API, or is there some special way that Windows loads these fonts?

2

There are 2 best solutions below

3
On

The console uses "fixed width fonts", such as "Courier New" (available in all Windows version) or "Consolas" (available since Vista).

Fixed width fonts are not necessarily raster. To use raster fonts, enumerate fonts to find a raster font such as "Terminal" or "Fixedsys". You have to use the right size (example, 18 for "Terminal" font) otherwise Windows may substitute a different font and resize. There are also issues with DPI settings. If program is not DPI aware then magnification will occur if work station has high DPI settings.

case WM_PAINT: 
{
    PAINTSTRUCT ps;
    auto hdc = BeginPaint(hwnd, &ps);
    auto hfont = CreateFont(-18, 0, 0, 0, 0, 0, 0, 0,
        ANSI_CHARSET,
        OUT_DEVICE_PRECIS,
        CLIP_DEFAULT_PRECIS,
        DEFAULT_QUALITY,
        DEFAULT_PITCH,
        L"Terminal");

    auto oldfont = SelectObject(hdc, hfont);

    RECT rc = { 0,0,100,300 };
    DrawText(hdc, L"Test 123", -1, &rc, DT_LEFT | DT_TOP);

    SelectObject(hdc, oldfont);
    DeleteObject(hfont);

    EndPaint(hwnd, &ps);
    return 0;
}
0
On

The answer was similar to Barmak's answer, with the difference that both width and height are specified, so to create a font for the 8x8 raster font I use the following code:

hfont = CreateFont(-8, -8, 0, 0, 0, 0, 0, 0, OEM_CHARSET, OUT_DEVICE_PRECIS,
        CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, _T("Terminal"));

Specifically, both the height and width must be specified, and the OEM_CHARSET charset must be specified, in order to select one of the Raster Fonts.

My intent is to render to a DirectDraw surface (IDirectDrawSurface7::GetDC()) then subsequently paint that surface to the primary, as shown here:
enter image description here
With a bit of trickery involving multiple passes I added a bit of a shadow effect to the text, however that is outside the scope of my original question.