by Michael S. Kaplan, published on 2007/02/06 06:01 -05:00, original URI: http://blogs.msdn.com/b/michkap/archive/2007/02/06/1609072.aspx
Viktor's question not only captured the problem but it also showed that he had been digging into the problem some:
My problem:
GDI uses font linking to render CJK characters in a text box or when I call DrawText to output a mixed-script domain name. On the other hand if I use GetGlyphIndices, ScriptShape or ScriptGetCMap to query a font for missing glyphs the above mentioned functions do not take font linking into account. So I am getting missing glyphs reported, although they are correctly rendered by the GDI.
Interestingly, ScriptStringAnalyse provides SSA_FALLBACK and SSA_LINK flags to take font linking into account, but there is no interface to query the glyphs after a ScriptStringAnalyse call.
How can I find out whether GDI can render a character (string) correctly taking font linking into account?
Using MLang for font linking is inconsistent with the GDI font linking behavior, i.e. characters rendered correctly by an MLang linked font are not correctly rendered by GDI, for example.
Even ScriptStringAnalyse with SSA_FALLBACK|SSA_LINK set is not always consistent with GDI depending whether Windows support for East Asian scripts is installed or not.
I would be very grateful if you could help me solving my font linking issue or if you could write about it in a future blog post.
Thanks
Viktor
The problem here has no one stop solution -- the fact is that MLang's font linking and Uniscribe's font fallback are pretty much mutually exclusive as I pointed out in (this post), and GDI's font linking and Uniscribe's font fallback are also pretty much mutually exclusive as I pointed out in (this post).
Well, "mutually exclusive" is perhaps not the right term, since these technologies all co-exist and each has its own situation where it helps provide something useful.
But I guess what I am saying is that there is no one easy way to get the answer you might want here.
However, if you use the ScriptIsComplex function to figure out whether Uniscribe is going to be used or not (after using the IsValidLocale function to see about whether East Asian and/or complex script support is installed as I described here), then you are on your way!
You can decide whether you need to go through the Uniscribe method for figuring this out (which Viktor discusses above) or the GDI way, which involves checking the fonts in the font linking chain to see if between them all you can get support for each character in the string (in fact you can use the ScriptGetCMap function to do the specific GDI lookups for each of the fonts in the font link chain -- all you need is each character to be covered by at least one of the fonts)....
Figuring the most efficient algorithm for the above detection operation might even make an interesting interview question, with a particular eye to optimization....
(If people wanted to suggest either the algorithm or some specific optimizastions that come to mind, the comments should be open!)
Although, taking a step back, a better answer might be to reject the mixed script domain entirely as something of a phishing/security risk? :-)
This post brought to you by સ (U+0ab8, a.k.a. GUJARATI LETTER SA)
# Mike on 6 Feb 2007 12:59 PM:
I just wanted to point out that GDI *can't* apply font linking when dealing with glyph indexes directly. Glyph indexes are relative to a given font file - 'A' might be glyph #37 in one font and #983 in another.
I also wanted to pick a nit and point out that DrawText is not a GDI function - it's a USER function.
# Michael S. Kaplan on 6 Feb 2007 1:07 PM:
A User function that relies on GDI, as opposed to GDI+/WPF/MLang/Psychic HotLine, etc. :-)
For the other nit, my recommended action was to look in each font that is the chain individually and see if it HAD a glyph. It does not matter what the glyph is, since the test would just be for existence. The relativity of glyph indices is really not an issue here?
# mlippert on 6 Feb 2007 7:05 PM:
Michael,
What API function do you call to find out the GDI font-linking chain?
I've never figured out how to get that information.
# Michael S. Kaplan on 6 Feb 2007 7:08 PM:
There is no function; you have to dig into the registry for this.
# mlippert on 6 Feb 2007 7:10 PM:
Oh, and BTW this post is near and dear to my heart.
I've implemented the mlang font-linking in our app, but there were enough places it wasn't really working as I expected, eg with unicode character not in any codepage) that I had to implement a override to some other font for specific character ranges. It's possible that Uniscribe might have worked, but I never found any good documentation on it, and I didn't have the time to piece it together from code samples.
Thanks once again for your blog!