[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#1127: Can't set default face to get the font I want
From: |
Kenichi Handa |
Subject: |
bug#1127: Can't set default face to get the font I want |
Date: |
Tue, 14 Oct 2008 17:18:37 +0900 |
User-agent: |
SEMI/1.14.3 (Ushinoya) FLIM/1.14.2 (Yagi-Nishiguchi) APEL/10.2 Emacs/23.0.60 (i686-pc-linux-gnu) MULE/6.0 (HANACHIRUSATO) |
In article <87iqryl9jc.fsf@cyd.mit.edu>, Chong Yidong <cyd@stupidchicken.com>
writes:
> Hi Handa-san,
> > % xrdb -remove
> > % src/emacs -Q --eval '(customize-face (quote default))'
> >
> > I seem to be unable to select my beloved
> > "-misc-fixed-medium-r-semicondensed--13-*-*-*-*-*-*-*". If I set
> > family=fixed, foundry=misc, width=semicondensed, height=100,
> > I get -misc-fixed-medium-r-normal--13-120-75-75-c-70-iso8859-1;
> > It appears that the "semicondensed" part is ignored.
> This appears to be a problem in the font_score algorithm in font.c. The
> font passed in as the argument has the `semicondensed' width property,
> but the font found has `normal'.
I can reproduce that problem, but I don't think it's a
problem of font_score. For instance,
(list-fonts (font-spec :family "fixed" :foundry "misc")
nil nil
(font-spec :width 'semicondensed))
correctly prefers semicondensed fonts.
> I found the problem: in internal-set-lisp-face-attribute, we do the
> following:
> if (prop_index)
> /* If a font-related attribute other than QCfont and QCfontset
> is specified, and if the original QCfont attribute has a font
> (font-spec or font-object), set the corresponding property in
> the font to nil so that the font selector doesn't think that
> the attribute is mandatory. */
> font_clear_prop (XVECTOR (lface)->contents, prop_index);
> The FONT_AVGWIDTH_INDEX entry also needs to be cleared out at this time,
> otherwise the font backend won't find the semicondensed font. I've
> checked in a fix.
It's reasonable to clear FONT_AVGWIDTH_INDEX of a font if
:width is changed, but your change clears that
unconditionally. I think we should install the attached
change instead.
Anyway, I don't think that fixes the current problem. The
source of the problme I observed is this.
When multiple font-related attributes of a face are
customized, internal-set-lisp-face-attribute is called
multiple times. For instance, when we customize family,
foundry, and width (as you did),
internal-set-lisp-face-attribute is called with attr :family
and :width with these values in this sequence (note that my
defualt font is now "dejavu sans mono"):
(:family unspecified)
(:width normal)
(:family "dejavu sans mono")
(:width semi-condensed)
(:family "fixed")
As "dejavu sans mono" doesn't have semi-condensed variation,
the 4th call doesn't change the width, and then the 5th call
changes the family to "fixed".
Next, I tried this:
At first customize family and foudnry only, then customize
width to semi-condensed. But with the last customization of
width, internal-set-lisp-face-attribute is called as this:
(:family unspecified)
(:width unspecified)
(:width normal)
(:family "dejavu sans mono")
(:width semi-condensed)
(:family "fixed")
When the function is called to change width to
semi-condensed, somehow the family was already set back to
"dejavu sans mono", so, again, the font can't be changed to
semi-condensed.
At the moment, I don't know why
internal-set-lisp-face-attribute is called in that way.
---
Kenichi Handa
handa@ni.aist.go.jp
*** font.c.~1.87.~ 2008-10-14 13:55:27.000000000 +0900
--- font.c 2008-10-14 16:01:44.000000000 +0900
***************
*** 2996,3001 ****
--- 2996,3002 ----
if (! FONTP (font))
return;
if (NILP (AREF (font, prop))
+ && prop != FONT_WIDTH_INDEX
&& prop != FONT_FAMILY_INDEX && prop != FONT_FOUNDRY_INDEX
&& prop != FONT_SIZE_INDEX)
return;
***************
*** 3018,3023 ****
--- 3019,3026 ----
ASET (font, FONT_SPACING_INDEX, Qnil);
ASET (font, FONT_AVGWIDTH_INDEX, Qnil);
}
+ else if (prop == FONT_WIDTH_INDEX)
+ ASET (font, FONT_AVGWIDTH_INDEX, Qnil);
attrs[LFACE_FONT_INDEX] = font;
}