locked
Font Rendering with Glypn information RRS feed

  • Question

  • I call "GetCharABCWidthsFloatW" to get the width information for a character. With this I will get the leftside bearing, right side bearing and the advanced width.
    • Edited by exoity Friday, February 4, 2011 8:56 PM
    Thursday, December 23, 2010 10:37 PM

All replies

  • What are you trying to do with the typeface?

     


    Elected! Your votes and support have got me my 2010 MVP!

    Developer | Windows IT | Chess | Economics | Hardcore Games | Vegan Advocate | PC Reviews

    Thursday, December 23, 2010 10:47 PM
  • Sorry about that.

     

    Basically, I am rendering a character sheet of 256 values to a bitmap. I am then trying to render the individual characters seperately, considering the fact that I will store each characters x/y information in to a different binary file.

     

    I am doing this to implement more advance rendering techniques with these font sheets, such as alpha distance fields. This part I understand, it is correctly rendering the actual characters from the font sheet that prove to be difficult for me.

    Thursday, December 23, 2010 10:58 PM
  • Is this also available for Visual Studio 2010? I do not have VS2008 (the trial ran out).
    Thursday, December 23, 2010 11:31 PM
  • Basically, I am rendering a character sheet of 256 values to a bitmap. I am then trying to render the individual characters seperately, considering the fact that I will store each characters x/y information in to a different
    binary file.

    I am doing this to implement more advance rendering techniques with these
    font sheets, such as alpha distance fields. This part I understand, it is
    correctly rendering the actual characters from the font sheet that prove to be
    difficult for me.

    You must realize that this will completely fail for multy-byte languages
    (like Chinese/Japanese/Korean) and for any scripts that require complex
    shaping (ie. Arabic, Thai, most Indic scripts).
    Even some features for English will break (for instance the "fi" and "fl"
    ligatures).

    You might try to take a look at Uniscribe, it allows you to
    customize the positioning of the glyphs, while still being aware of
    advanced typographical features and international scripts.


    Mihai Nita [Microsoft MVP, Visual C++]
    http://www.mihai-nita.net
    ------------------------------------------
    Replace year with _ to get the real email

    Friday, December 31, 2010 10:45 AM
  • Even a classic windows like the one I use for development can show any character easily. No need for rendering anything. I simply use textout()

    and

    move on. If course I could add buttons and others as easily.

    Not sure I understand your comment.

    Yes, TextOut works fine.
    But what 'exoity' wants/does is something else:
    ===========
    Basically, I am rendering a character sheet of 256 values to a bitmap. I am then trying to render the individual characters seperately, considering the fact that I will store each characters x/y information in to a different binary file.
    ===========
    If he render the characters separately, then scripts with compelex shaping
    will not be ok (because rendering "X" then rendering "Y" looks different
    than rendering "XY" (where X and Y are non-Latin characters))
    And for right-to-left languages he will have to be able to calculate the position of Y after rendering X, not trivial.


    Mihai Nita [Microsoft MVP, Visual C++]
    http://www.mihai-nita.net
    ------------------------------------------
    Replace year with _ to get the real email

    Saturday, January 1, 2011 10:46 AM
  • OK with the default font that is used by Textout you are using the default whatever that is.

    ...

    You'll see shortly how you can be very specific about the typeface and
    size that you want.

    Although interesting as a stand-alone article, I don't think it has anything
    to do with the initial question.

    He wants to get the with of each character in the string, then position them
    individually with an offset. Sounds like the description of some advanced
    text rendering that controls the spacing between characters.

    That is not possible with any GDI API, regardless the font.
    And by implementing it's own thing he will break complex scripts rendering.

    The only chance (I did not try it) is probably Uniscribe
    (something like ScriptApplyLogicalWidth or ScriptPositionSingleGlyph).


    Mihai Nita [Microsoft MVP, Visual C++]
    http://www.mihai-nita.net
    ------------------------------------------
    Replace year with _ to get the real email

    Wednesday, January 5, 2011 8:36 AM
  • As Mihai has said, Uniscribe is probably a better choice for this. One not so obvious reason is that not all fonts follow the OpenFont specification, there are at least three types of fonts covered by this (Bitmapped fonts, TrueType fonts and OpenFonts.). Another is that font behavior is the product of Windows and the hardware device manufacturers. (Raster and vector devices.)

    Not all of the GDI font functions work consistently for all fonts. (Which is probably the font, or on the other side of the HAL...in the device driver.) I do not think that looking backwards (to GDI and a C reachable API.) is practiced universally across the board. (By MS, the producer of the font and the manufacturer of the hardware.)

    When Windows was first developed, the fonts were more tied to specific hardware...usually, the hardware manufacturer provided them. The DOS print model leaves the fonts in the printer, for example, or as a canned set of data on the machine, but...not really subject to much manipulation by the user.

    The best guy to ask for this, in my opinion is...Michael Kaplan...

    http://blogs.msdn.com/b/michkap/archive/2010/04/07/9989346.aspx

     

    TextOut has no "default font", it uses whatever font is selected into the device context. Is that from Petzold's Programming Windows?

    I would be hesitant to use such a large block quote from a book that the author readily admits has become a bit of an anachronism. (I still refer to it myself, but I always consider the intervening dozen years or so of development that has occurred since it was published.)

    ...besides, I've seen Charles' chop *here* on occasion.

    Wednesday, January 5, 2011 4:43 PM
  • ...has it occurred to you that device contexts have a default font selected into them?

    For the record, you are showing what is pretty much boilerplate code. I have about 300 sets of that code...its standard MS code generated by a wizard.

    Read your Petzold again...why do you think TextOut takes a DC as its first parameter, anyway? I am certain that I remember Mr. Petzold telling me that the Font belongs to the Device Context.

    Wednesday, January 5, 2011 9:07 PM
  • The OP is wanting to circumvent that in favor of placing glyphs directly. While there are functions for that in the Win32 API (GDI), they are not likely mentioned in Programming Windows...because OpenFonts came long after that book's lifecycle.

    Which is why Mihai suggested Uniscribe, I think. (Apologies if that is not the case.)

    ...to that end, I want to impart that I ran into trouble using the GDI function ExtTextOut, iirc. Bitmapped fonts and TrueType (I think) use a single glyph for a character, however...OpenFont uses multiple glyphs to support Unicode better in cases like Chinese, where the "character" is actually composed of several distinct glyph units.

    I write to GDI alot for text and graphics output. I work for an address label and rubber stamp manufacturer, and I did not ultimately need to place glyphs individually (Thankfully! Like I said, fonts are not at all consistent in their behavior. Script fonts in italic are a particularly inconsistent lot!) I have spent a lot of time working with device contexts, fonts and graphics....both win32 and .NET...I still think that Mr. Kaplan, or perhaps even Raymond Chen....are great choices for plying MLANG. I decided it was not worth the effort -- things like RTL, kerning and ligatures are covered when you use XP and above...OpenFonts and MLANG. It looks a mess to me, and .NET is too hard to control on all users' machines if you are looking for exactly the same output.

    We use Font Logos because our company started in the computing DarkAges. (Before Unicode) In that case, we use a letter for a shape and color, and build them all up by placing the characters using positions that we provide. For example, we started with college logos, which we still have and use. They scale better than GDI scales images. (GDI+ has obviated the need for Font Logos, but...when saved to JPGs, they look horrible by way of comparison!)

    Wednesday, January 5, 2011 10:12 PM
  • The OP is wanting to circumvent that in favor of placing glyphs directly.

    Which is why Mihai suggested Uniscribe, I think. (Apologies if that is not the case.)

    Actually, it is possible to display glyphs and not characters even with GDI,
    by using ExtTextOut with ETO_GLYPH_INDEX
    (http://msdn.microsoft.com/en-us/library/dd162713%28v=vs.85%29.aspx )

    Might even be possible to call GetCharacterPlacement first, to get
    glyphs from characters, then mess with the individual glyph positions
    (stored in the lpDx member of the LPGCP_RESULTS)

    It might even be enough for what OP wants.
    And it might work because all APIs are called on full text runs
    (expressed in characters or glyphs, does not matter).

    But his initial solution was to render the characters individually
    (in bitmaps), then put the bitmaps on screen at custom calculated
    offsets. That will not work for the reasons I have explained earlier:

      PutStringOnScreen(x,y,"abc"
    );

    does not lead to the same results as:

      PutStringOnScreen(x,y,"a"
    );
      x += width("a"
    );
      PutStringOnScreen(x,y,"b"
    );
      x += width("b"
    );
      PutStringOnScreen(x,y,"c"
    );

    This is not even true for English (because of ligatures and kerning).
    And totaly breaks for complex and right-to-left scripts.
    Not to mention that for Chinese/Japanese/Korean he will have to
    pre-render tens of thousands of bitmaps, not 255.

    It might help if OP explains what he wants to achieve.
    What is the end-result, on screen, from user perspective.
    The bitmaps idea is half of a (probably bad) solution.

    It happens quite often:
     - people have a problem (let's call it 'X')
     - come with some kind of wrong solution
     - half the way thru the implementation they get stuck in
       a sub-problem (let's call it 'x')
     - ask how to solve 'x'

    The real issue is the the main "solution" is wrong.
    You have to track back, explain the initial problem, and attack
    it in a different way (and it is often easier than the initial idea).


    Mihai Nita [Microsoft MVP, Visual C++]
    http://www.mihai-nita.net
    ------------------------------------------
    Replace year with _ to get the real email

    Thursday, January 6, 2011 6:20 AM
  • Then the OP might want to use bitmaps and place them on the
    display as desired.

    The old school API is done this way and I have never seen a reference
    for other ways to change the text in a standard old school window.

    That is wrong, leads to low quality results for English,
    and to disastrous results for more complex scripts.

    To get a grasp of the complexities try taking a look at some of the articles
    here: http://www.microsoft.com/typography/SpecificationsOverview.mspx
    (the "Script-specific Development" section)

    You will see that even for Latin scripts you have to deal with
      * Character composition (and decomposition)
      * Standard ligatures
      * Contextual ligatures
      * Kerning
      * Mark to base positioning
      * Mark to mark positioning
    (http://www.microsoft.com/typography/otfntdev/standot/features.aspx)
    All of the above bullets can't work right if the processing is done
    character by character (or glyph by glyph).

    Then take a look at Arabic and Indic scripts :-)

    Now in C# its not a problem as the .NET has all kinds of helpful
    functions to make text anyway desired.

    The problems are exactly the same (or worse) in C#.


    Mihai Nita [Microsoft MVP, Visual C++]
    http://www.mihai-nita.net
    ------------------------------------------
    Replace year with _ to get the real email

    Thursday, January 6, 2011 6:30 AM