CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 13 of 13
  1. #1
    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. #2
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,395

    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.
    Victor Nijegorodov

  3. #3
    Join Date
    Oct 2015
    Posts
    6

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

    Quote Originally Posted by VictorN View Post
    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. #4
    Join Date
    Nov 2003
    Posts
    1,902

  5. #5
    Join Date
    Oct 2015
    Posts
    6

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

    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. #6
    Join Date
    Nov 2003
    Posts
    1,902

    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. #7
    Join Date
    Oct 2015
    Posts
    6

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

    Quote Originally Posted by Codeplug View Post
    >> 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. #8
    Join Date
    Nov 2003
    Posts
    1,902

    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. #9
    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. #10
    Join Date
    Oct 2015
    Posts
    6

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

    Quote Originally Posted by Codeplug View Post
    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. #11
    Join Date
    Oct 2015
    Posts
    6

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

    Quote Originally Posted by OReubens View Post
    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. #12
    Join Date
    Nov 2003
    Posts
    1,902

    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

  13. #13
    Join Date
    Feb 2021
    Posts
    1

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

    Quote Originally Posted by interactii View Post
    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!
    I recently had the same problem.
    You have to extract the average width and multiply this with the desired aspect ratio

    LogFont.lfHeight = -(int)height;
    LogFont.lfWidth = 0;
    font = CreateFontIndirectW(&LogFont);
    SetTextAlign(PrHDC, TA_BASELINE );
    SelectObject(PrHDC, font);
    GetTextMetrics(PrHDC, &tm);
    DeleteObject(font);
    LogFont.lfWidth = (tm.tmAveCharWidth + tm.tmOverhang) * aspect_ratio;
    font = CreateFontIndirectW(&LogFont);

    I know this is a really old question but a solution is hard to find.

Posting Permissions

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





Click Here to Expand Forum to Full Width

Featured