difference when rendering horizontal line using TextOut char by char vs all at once

Viewed 96

I am writing a win32 low level gui app that emulates a console app. I use a fixed width font, my test uses Cascadia Mono, but I have the same issue with any fixed width font.

The console app is trying to draw a horizontal line using U2500 character.

I output the characters that app is passing me one by one. When I do that I get spaces between the horizontal lines, when I output in one call to textout those gaps are filled in.

I made this using the VS c++ windows app template and added this code to the WM_PAINT handling

        auto nHeight = -MulDiv(48, GetDeviceCaps(hdc, LOGPIXELSY), 72);
        auto hfont = CreateFont(
            nHeight,
            0,
            0,
            0,
            100,//200,
            0,
            0,
            0,
            DEFAULT_CHARSET,
            OUT_OUTLINE_PRECIS,
            CLIP_DEFAULT_PRECIS,
            CLEARTYPE_QUALITY,
            FIXED_PITCH,
            L"Cascadia Mono"
            );
        TEXTMETRIC tm;
        SelectObject(hdc, hfont);

        GetTextMetrics(hdc, &tm);
        auto str = L"kkkkkk─────k";
        TextOut(hdc, 0, 0, L"kkkkkk─────k", 12);
        for (int i = 0; i < 12; i++)
        {
            TextOut(hdc, i * tm.tmAveCharWidth, tm.tmHeight,  &str[i], 1);
        }

This displays

enter image description here

you can see that this is not due to me miscalculating the char cell width, the strings are exactly aligned , just there are some added pixels in the upper one, also notice some extra 'knobiness' where the joins are. V odd. Also note that the right edge of the last K before the line starts is slightly chopped off in the char by char one, but not in the all at once one.

So why am I doing it char by char, because I need to specify font weight, bg, fg for each cell.

1 Answers

Instead of using TextOut, you can use DrawText which is a bit more hi-level, like this:

for (int i = 0; i < 12; i++)
{
    RECT rc;
    rc.left = i * tm.tmAveCharWidth;
    rc.top = tm.tmHeight;
    rc.right = rc.left + 50; // todo: make sure this is ok
    rc.bottom = rc.top + 100;
    DrawText(hdc, (LPWSTR)&str[i], 1, &rc, 0);
}

And it seems to fix the "lineness" of it, although it's not 100% exactly the same (there are some pixels that show a difference):

enter image description here

Related