Reputation: 307
I am reading
Programming.Windows.5th.Edition,Charles Petzold
when I was doing the Figure 4-5. SYSMETS1.C,I met the following codes:
cxCaps = (tm.tmPitchAndFamily & 1 ? 3 : 2) * cxChar / 2 ;
and there are explanations in the book,
SYSMETS1 also saves an average width of uppercase letters in the static variable cxCaps. For a fixed-pitch font, cxCaps would equal cxChar. For a variable-width font, cxCaps is set to 150 percent of cxChar. The low bit of the tmPitchAndFamily field in the TEXTMETRIC structure is 1 for a variable-width font and 0 for a fixed-pitch font. SYSMETS1 uses this bit to calculate cxCaps from cxChar.
Now that cxCaps is set to 150 percent of cxChar,I think it should be
cxCaps = (tm.tmPitchAndFamily & 1 ? 3.0 : 2.0) * cxChar / 2 ;
Can you explain it for me?Thanks!
Upvotes: 1
Views: 668
Reputation: 941635
It is trying to calculate an integer result, expressed in pixels. The effective calculation is (3 * cxChar) / 2
, not 3 * (cxChar / 2)
. Presumably the latter one is giving you pause.
It's going to get rounded down for a proportional font but will never be off by more than a single pixel. It doesn't matter since the value is only a guess anyway, the actual width is different for every glyph in a proportional font.
No points scored for readability, you could perhaps rewrite it like this:
bool proportional = tm.tmPitchAndFamily & TMPF_FIXED_PITCH;
if (proportional) cxCaps = (3 * cxChar) / 2;
else cxCaps = cxChar;
Note how the flag has the wrong name, perhaps the reason Petzold wrote it like that.
Upvotes: 0
Reputation: 18463
What are the types of cxChar
and cxCaps
? If cxChar
is float
or double
, then there is no problem, because the result of the multiplication will be converted to that type before dividing by 2, and the result would be 1.0 or 1.5. But cxCaps
should also be of a floating point type, so it can hold the floating point value.
EDIT
I checked to code of the book, and found that they are both int
. And also I found that there is no need for floating point variables.
For example assume that cxCahr
is 20. If tm.tmPitchAndFamily & 1
results in 1
, then the expression will be
cxCaps = 3 * cxChar / 2;
and cxCaps
will be 30
. And if the result is 0, 'cxCaps' will be '20'. So everything is fine. If cxChar is an odd number, then the lost value will be 0.5
, that could easily be neglected.
Upvotes: 2