emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

font selection mechanism (e.g., Japanese)


From: David Reitter
Subject: font selection mechanism (e.g., Japanese)
Date: Fri, 29 Jan 2010 10:14:07 -0500

I'm trying to understand the font selection system in order to fix problems, e.g., with the display of `han' characters in Japanese. I'd appreciate your help if you're knowledgeable with font.c.

A good example for font selection problems in Emacs 23 is Japanese, which mixes characters from different scripts. For example, we have latin characters, chinese (kanji, script: 'han'), and other scripts (hiragana, katakana).
I have four issues.

1. Selecting a better `han' font.

Finding a font to display 'han' characters is difficult for the current algorithm. What is needed is a font that is similar to the context font (the font chosen by the user for the face). In Emacs 23 (at least on the NS port with my set of fonts), han characters look very different in weight when combined with fonts common on my system, e.g. Monaco or Lucida Grande.
See a user's complaint:  
http://lists.aquamacs.org/pipermail/aquamacs-devel/2009-August/002271.html

The reason for this is that font selection prefers high coverage of the chosen font for the script; it finds some fonts on my system that have high (90%) coverage and then chooses among them, even though other fonts would have sufficient coverage and look much better. `Han' is obviously a pretty big set of characters, so only few fonts cover that many characters. At the same time, only a small portion of these is commonly used (in Japanese at least), from what I understand.

Reducing the threshold for script coverage, eg. in ns_findfonts for the NS port, addresses that - the `list' function of the font driver will return a much bigger set of fonts so that font_select_entity() can do its job.

The problem I have now is to get it to choose different fonts within the same script in cases where a low-coverage font does not provide a glyph. The above threshold change makes things work better in practice, but the HELLO file shows serious regressions.

Where in the code would one get it to choose a different font for a character if the current font can't display it? This is by-character selection, not by-script.


2. face-font-family-alternatives : broken?

face-font-family-alternatives does not work at all for me. In font_find_for_lface(), "val" seems to empty; printing SDATA (attrs[LFACE_FAMILY_INDEX]) shows something better, like "Lucida_Grande". But that's not what the alist is queried for.

3. font driver specific matching

As an observation: The matching provided by the font driver (as a backup to listing the entities) is not usually called, at least in the NS port. This is because font_find_for_lface() usually seems to widen the search so much (pretty much looking for all fonts) that the matching algorithm never gets chance.


4. Searching for fonts by foundry.

Below patch makes the selection algorithm a little more sensible (fonts of the same foundry rarely have much in common graphically). But it doesn't address the problem.


commit d858f9ea2f60b37aa6f44b3d824cbaf0f1f867ae
Author: David Reitter <address@hidden>
Date:   Fri Jan 29 00:31:17 2010 -0500

font_find_for_lface: do not try to find face by Foundry (Author) name only
    This is not sensible.

diff --git a/src/font.c b/src/font.c
index 557f1fb..b578c04 100644
--- a/src/font.c
+++ b/src/font.c
@@ -3451,6 +3451,10 @@ font_find_for_lface (f, attrs, spec, c)
       ASET (work, FONT_FAMILY_INDEX, family[i]);
       for (j = 0; SYMBOLP (foundry[j]); j++)
        {
+         if (NILP (family[i]) && ! NILP (foundry[j]))
+           /* do not look for "some foundry, any family".
+              That doesn't tend to yield similar fonts. */
+           continue;
          ASET (work, FONT_FOUNDRY_INDEX, foundry[j]);
          for (k = 0; SYMBOLP (registry[k]); k++)
            {


5. Fontsets are not the solution.

I'm looking for an automatic procedure.





reply via email to

[Prev in Thread] Current Thread [Next in Thread]