CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com

# Thread: Calculating the real lfWidth value of LOGFONT when lfWidth = 0

1. Junior Member
Join Date
Oct 2015
Posts
6

## Calculating the real lfWidth value of LOGFONT when lfWidth = 0

Hi, I'm wondering how to calculate what the real value of lfWidth in the LOGFONT structure when it is set to 0.

MSDN says that if the value is zero, the digitization aspect ratio is used to determine the width. I had hoped this meant the tmDigitizedAspectX and tmDigitizedAspectY members of TEXTMETRIC, but they always seem to be 96 and 96, regardless of font selected.

If I create a new LOGFONT with lfWidth = lfHeight, the aspect ratio of the font is often wrong - clearly fonts have aspect ratio data somewhere, for example if I do this with @Meriyo, it works almost perfectly the same as if lfWidth=0, if I do it with @Meriyo UI, it's clearly about 2x wide.

Any help would be greatly appreciated!

2. ## Re: Calculating the real lfWidth value of LOGFONT when lfWidth = 0

From MSDN:
lfWidth
The average width, in logical units, of characters in the font. If lfWidth is zero, the aspect ratio of the device is matched against the digitization aspect ratio of the available fonts to find the closest match, determined by the absolute value of the difference.

3. Junior Member
Join Date
Oct 2015
Posts
6

## Re: Calculating the real lfWidth value of LOGFONT when lfWidth = 0

Originally Posted by VictorN
From MSDN:
Yes! I saw this, but how do I get this information? As I said in my post, the TEXTMETRIC always has 96,96 for the two digitization aspect ratios regardless of font.

Thanks!

JH

4. ## Re: Calculating the real lfWidth value of LOGFONT when lfWidth = 0

5. Junior Member
Join Date
Oct 2015
Posts
6

## Re: Calculating the real lfWidth value of LOGFONT when lfWidth = 0

Originally Posted by Codeplug
Believe me, I've been through that documentation, and there's no discussion of the digitization ratios except in TEXTMETRIC that I can find. If you've found something in there that I've do tell!

I know how to get the width of a string, but that's not what I need. I need to calculate the text ratio, so that why my user says they want text at 138% width and 74% height, I know what values to plug into the LOGFONT. lfHeight is easy, lfWidth is what I'm struggling with. I know there are work arounds, such as just setting the height, getting the ABC size, bliting a character that's the larger of the two multiples, then scaling it to the correct metric, but it would be much more elegant to calculate the correct lfWidth, especially for this application.

Measuring the string after the fact won't help. As I said above, Meriyo and Meriyo UI have very different digitization aspect ratios despite looking nearly identical.

6. ## Re: Calculating the real lfWidth value of LOGFONT when lfWidth = 0

>> so that why my user says they want text at 138% width and 74% height, I know what values to plug into the LOGFONT.
I see. My first thought would be to scale via point size and normal GDI[+] scaling. I wonder how smooth the scaling would be by just using the LOGFONT members ...
Not sure how that's done.

gg

7. Junior Member
Join Date
Oct 2015
Posts
6

## Re: Calculating the real lfWidth value of LOGFONT when lfWidth = 0

Originally Posted by Codeplug
>> so that why my user says they want text at 138% width and 74% height, I know what values to plug into the LOGFONT.
I see. My first thought would be to scale via point size and normal GDI[+] scaling. I wonder how smooth the scaling would be by just using the LOGFONT members ...
Not sure how that's done.

gg
It's actually perfectly smooth for Open and TrueType fonts just using those fields in LOGFONT. Bitmap fonts are scaled correctly as well. It does work if I just set lfWidth to a non-zero value, the units are just an arbitrary ratio to the height and based on each individual font.

8. ## Re: Calculating the real lfWidth value of LOGFONT when lfWidth = 0

Other info in case it helps:
https://msdn.microsoft.com/en-us/library/bb431779.aspx

Could the "MulDiv" formula be used for the X dimension as well? Then just scale the resulting width/height appropriately? This would assume some percentage scale starting at a particular "point" height.

gg

9. Elite Member Power Poster
Join Date
Apr 2000
Location
Belgium (Europe)
Posts
4,626

## Re: Calculating the real lfWidth value of LOGFONT when lfWidth = 0

I'm getting the impression you're not quite understanding how this works.

you usually only provide the height when creating a font.
if you also supply width, then windows will create a font that as closely as possible matches what you asked it to do, it doesn't mean you'll get a font that EXACTLY matches what you're going to do.

if you want to know the metrics of a created font, then create the font, select the font into a DC, and use GetTextMetrics(). This will give you the font metrics, inlcluding an average width (usually not not Always this matches the width of digits).

if you want to know the width of an actual string of text, then use GetTextExtent(), GetTextExtentExPoint() or one of those class. This may or may not match the cumulated widths of the individual characters the string is made of. Actual string rendering can also have (advanced) kerning or non positioning characters (like the separate diacritics in unicode). Or some other rendering features that impact total string width.

10. Junior Member
Join Date
Oct 2015
Posts
6

## Re: Calculating the real lfWidth value of LOGFONT when lfWidth = 0

Originally Posted by Codeplug
Other info in case it helps:
https://msdn.microsoft.com/en-us/library/bb431779.aspx

Could the "MulDiv" formula be used for the X dimension as well? Then just scale the resulting width/height appropriately? This would assume some percentage scale starting at a particular "point" height.

gg
Yes, the MulDiv formula is used for the X dimension as well.

11. Junior Member
Join Date
Oct 2015
Posts
6

## Re: Calculating the real lfWidth value of LOGFONT when lfWidth = 0

Originally Posted by OReubens
I'm getting the impression you're not quite understanding how this works.
When they use "closest match" in the documentation, they just mean for bitmap fonts. In modern Windows, you will get output in the lfWidth\lfHeight you specify, even if the font is a bitmaped font. Windows will scale it in the background to the width and height sizes you request, based on the closest matching size (without going over it seems from my experimentation). With TTF\OTF, it really does render them in this new aspect ratio, and they look great! Give it a try!

Average width is sadly just the width of one character (X), and it can't really be used to back-calculate lfWidth. Similarly, even if you select the font into a DC with lfWidth zero, and then get it back with GetCurrentObject, it will leave lfWidth zero, so no dice there.

I do use the functions to get the text ABCs for other purposes - finding the size of the characters isn't the problem. Its knowing what size to ask for.

12. ## Re: Calculating the real lfWidth value of LOGFONT when lfWidth = 0

>> Its knowing what size to ask for.
It seems to me that you have to start with a particular point/pel size (1/72') and use that as 100% of the height, and the resulting width at that height is the width at 100%. Then scale from there. Since your working with 'points', they should scale in inches, not pixels. And 100% height and width should be at the fonts normal aspect ratio.

gg

#### Posting Permissions

• You may not post new threads
• You may not post replies
• You may not post attachments
• You may not edit your posts
•