I have font class which is a wrapper around API's that create
HFONT
.
Relevant excerpt from class:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
|
class Font
{
// ...
HFONT mhFont;
};
bool Font::GetLogFont(LOGFONT& LogFont) const noexcept
{
if (GetObjectW(mhFont, sizeof(LOGFONT), &LogFont) != 0)
return true;
return false;
}
DWRITE_FONT_WEIGHT Font::GetDWriteCompatibleWeight() const noexcept
{
LOGFONT LogFont{ };
if (GetLogFont(LogFont))
{
return static_cast<DWRITE_FONT_WEIGHT>(LogFont.lfWeight);
}
// If failed return normal weight
return DWRITE_FONT_WEIGHT::DWRITE_FONT_WEIGHT_NORMAL;
}
|
DWRITE_FONT_WEIGHT
is an enum defined as shown on the link below
https://learn.microsoft.com/en-us/windows/win32/api/dwrite/ne-dwrite-dwrite_font_weight
LOGFONG lfWeight
consists of same range of values, 0-1000, however not every value is defined for
DWRITE_FONT_WEIGHT
.
https://learn.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-createfontw
Therefore my
GetDWriteCompatibleWeight
function may return a value that in fact does not exist in the
DWRITE_FONT_WEIGHT
enum
.
However it works!
I've tried with font weight 350 which isn't defined in the enum, the return value was 350 and a function that expect the enum succeeded:
Sample code which call the converter method
1 2 3 4 5 6 7 8 9 10 11 12 13
|
Font mFont = /* ... */
hr = pWriteFactory->CreateTextFormat(
DEFAULT_FONT_TYPEFACE, // The default font constant
NULL,
// This succeeds with value of 350 or any other that is not in DWRITE_FONT_WEIGHT
mFont.GetDWriteCompatibleWeight(),
DWRITE_FONT_STYLE::DWRITE_FONT_STYLE_NORMAL,
DWRITE_FONT_STRETCH::DWRITE_FONT_STRETCH_NORMAL,
static_cast<float>(DialogBase.cy),
L"en-us",
&mpCaptionFormat);
|
My question is, why does it succeed and would it be better method to use
if else
to convert
HFONT.lfWeight
to closest match instead of casting the value directly?
For example, is it better to:
1 2 3 4 5 6
|
if (lfWeight <= 100)
return DWRITE_FONT_WEIGHT_THIN;
else if (lfWeight <= 200)
return DWRITE_FONT_WEIGHT_EXTRA_LIGHT;
// etc.. a bunch of if else statements follow for each enum
|
Is there a better method?