Don't change the font, dammit!

by Michael S. Kaplan, published on 2006/02/13 15:01 -05:00, original URI:

I'll be the first person to say at a party that the NULL GLYPH (􏿿) is not going to engender the most intuitive user experience when it is displayed in a user interface.

(It might in fact be why I am not invited to more parties!)

But even I will admit that there are times when it does not matter whether you call it font fallback, font substitution, font linking, or font Magic 8-Ball. It is simply not what you want in every single situation.

(I suspect this will not cause more party invitations to be forthcoming!)

I ran across just such a situation the other day when Drew Bliss (a dev on the Windows team) asked:

When adding text to a richedit control they appear to use and/or interpret certain characters as formatting control characters.  For example, if I have an ANSI string with a 0xe1 character in it the richedit control will switch fonts after hitting the 0xe1 character.

Is there a way to avoid this and add text to the richedit without it scanning for special characters?  It was suggested to me that EM_STREAMIN using SF_TEXT would get raw text into the richedit without interpretation, but some quick tests don't appear to support that theory.

I have no idea what richedit is doing internally, I was just guessing that it had something to do with special formatting characters.  That could be completely wrong.

The font I've used to repro the problem was Terminal.  After the e1 character the font changes from Terminal back to what appears to be one the default system fonts.

My question could be rephrased as "how can I avoid undesired font changes in richedit when putting arbitrary text into a richedit control?"

The particular feature Drew is referring to is the way RichEdit will, if the currently selected font will not display a character, find a font that will support it using its own internal understanding of where to look for the characters.

(His evalutaion that EM_STREAMIN will not help here was correct!)

In this particular case, Terminal is a bitmap font that does not have the character -- so all it can do is switch the font. Arguably RichEdit should be smart enough to know when to switch back, but it has a good faith basis to believe that there will be more that does not fit -- and there would be performance implications to attempting to do so.

There are basically four possible solutions:

In this particular case, where the need to have text properly lined up in a fixed width font was the most important one (even if other RichEdit features like color were needed), the last option was the proper solution.

Hon-Wah Chan, one of the awesome developers on RichEdit who I met a few years ago at a Unicode Conference (we were both speaking there), made that last suggestion, and even gave a code sample to accomplish it, using the EM_GETLANGOPTIONS/EM_SETLANGOPTIONS messages:

If you always setup the font correctly and don't want Richedit to switch font on you, you could turn off the auto font feature as follow:

LRESULT lres = SendMessage(hRE, EM_GETLANGOPTIONS, 0, 0);
lres &= ~IMF_AUTOFONT;
SendMessage(hRE, EM_SETLANGOPTIONS, 0, lres);

As the notes for these very useful messages point out:

The EM_SETLANGOPTIONS message controls the following:

The IMF_AUTOFONT flag is set by default. The IMF_AUTOKEYBOARD and IMF_IMECANCELCOMPLETE flags are clear by default.

As Hon-Wah suggests, the IMF_AUTOFONT does something a bit different than the docs claim here, since it is not really the keyboard behavior that it controls -- it is the font switching behavior based on the actual text.

It is actually fascinating to consider the interaction between IMF_AUTOFONT (which is turned on by default) and IMF_AUTOKEYBOARD (which is not), since the latter affects you more when you are typing and the former affects you more when text is loaded into the control later.

(People who work at Microsoft may have seen this interaction if they enter characters of other scripts like Han ideographs into their Product Studio bug reports -- pasting or typing the text in does not change the font of later text, while reloading the bug later will show all of the text after such an insertion to be changed!)

Now I don't want to call the general feature here a bad one. I mean, if this whole post looked like 􏿿􏿿􏿿􏿿􏿿􏿿􏿿􏿿􏿿􏿿􏿿􏿿􏿿􏿿􏿿􏿿 and so on, I hope people would be less happy with the change in quality of the blog.

But that does not mean you always want it to work that way. When you have a good reason to want to turn it off, you can use Hon-Wah's code to make it possible. :-)


This post brought to you by "𐒅" (U+10485, a.k.a. OSMANYA LETTER KHA)

# Michael Dunn_ on 13 Feb 2006 5:25 PM:

Great tip! But you've got a typo in the code, it should be &= not ^=

# Michael S. Kaplan on 13 Feb 2006 6:08 PM:

Typo? What typo? I don't see any typo in the code, Mike.

Don't mind Mike Dunn everyone, he is s regular reader and a classy guy. But sometimes he sees stuff that's not there....

[any more]


# Ben Cooke on 14 Feb 2006 3:27 AM:

Hmm. I would expect the default behavior to be to change the font *for display* but not to insert commands into the RTF markup to change it. Why? Because another system is likely to have a different set of fonts with different character coverage, so it should be up to the RTE to figure out at display time what font to use, much like web browsers do when confronted by a codepoint they can't render with the preferred font.

I'm guessing efficiency reasons are the excuse for this, though.

# Michael S. Kaplan on 14 Feb 2006 3:33 AM:

Actually, as far as I know, nothing is inserted there. Were you seeing anything inserted? Isn't it just what the control does when it is displaying?

# Ben Cooke on 14 Feb 2006 1:50 PM:

I didn't actually test it. I guess I just misunderstood what you were saying. :)


# Michael S. Kaplan on 14 Feb 2006 3:03 PM:

Whew! :-)

Seki on 8 Aug 2008 5:59 AM:

It's working, many, many thanks!

haithink on 19 Dec 2010 6:47 PM:

It's working, many, many thanks!

referenced by

2007/12/16 How best to keep the font switcheroo from happening?

2006/02/17 What's the latest on the MS front?

go to newer or older post, or back to index or month or day