像素精确字符串测量

时间:2017-12-01 09:40:09

标签: windows winapi gdi device-context

我尝试计算给定文本的确切像素大小(例如,计算到InvalidateRect或稍后创建足够大小的位图)。我在测量时没有设备上下文,所以我不得不求助于内存设备上下文。

我发现带有DT_CALCRECT的{​​{3}}显然会返回“提前宽度”,而不是绘制时像素占用的实际宽度。使用DrawText对此进行补偿(有关ABC宽度的说明,请参阅GetCharABCWidths)至多是另一种近似值,例如如果第一个字形非常狭窄,那么第二个字形的ABC宽度可能是决定性的(即使它对于我的例子情况它“似乎给出了好的结果”),更不用说字体平滑了。

因此,我尝试使用here / SetBoundsRect

auto MeasureTest = [](int x, int y) {
    auto dc = CreateCompatibleDC(nullptr);
    SetBoundsRect(dc, nullptr, DCB_ENABLE | DCB_RESET);
    auto const text = L"Test";
    RECT rect{x, y, x, y};
    DrawText(dc, text, 4, &rect, DT_NOCLIP);
    GetBoundsRect(dc, &rect, 0);
    return rect;
};

(请忽略内存泄漏。我确认所有这些函数都会返回我在MSDN中读到的内容。)

使用此例程,我得到以下结果:

MeasureTest(0, 0);       // returns (0,0)-(1,1); reasonable (dc holds a 1x1 bitmap)

如上所述,这似乎是合理的,因为dc最初包含1x1位图。但是,以下两个调用表明至少已完成一些测量:

MeasureTest(-100, -100); // returns (0,0)-(-72,-84), i.e. an empty rect
MeasureTest(100, 100);   // returns (100,100)-(1,1), i.e. an empty rect

我尝试在绘图之前在设备上下文中选择一个足够大的位图(1000x1000像素),这显然给出了正确的结果。但是,当然,这引出了最初的问题:字符串占用了多少像素?

是否有可靠的方法来确定字符串的精确像素大小?

0 个答案:

没有答案