Subject: bug#17973: Thin space not thin at all

From: Stefan Monnier <[email-masked]>
Date: Thu, 10 Jul 2014 12:37:27 -0400

> Do you customize face-font-selection-order?  It's default
> value is (:width :height :weight :slant), which means that
> the function font_select_entity (called from
> font_find_for_lface) selects a font whose :width is
> semicondensed even if that font has very different height
> from what specified.

Ah, right, that explains it.  Hmm... I guess ideally, Emacs should
consider a height that's "too far" from the requested one as a failure
and then try again ignoring some of the specs.

The patch below expresses the first part, but it looks like the second
part doesn't exit: Emacs just doesn't find any font to use for the "thin
space" of C-x SPC and indicates it to me with one of those big squares
that say "0020", which is a lot more intrusive than the problem I'm
trying to fix.

And (setq scalable-fonts-allowed t) doesn't help either.

Maybe a solution/workaround for the specific problem of such "thin
lines" is to replace the (:height 0.2) face with another face that
specifies "any family".  If I use (:height 0.2 :family "Monospace"),
indeed, the problem disappears.  Is there a better "any family" than
"Monospace"?

        Stefan

PS: The patch below also happens to give me assertion failures
fontset.c:897: Emacs fatal error: assertion failed: fontset_id_valid_p (face->fontset)
I haven't investigated any further, tho (and the line number might be off
because of local changes anyway).

=== modified file 'src/font.c'
--- src/font.c	2014-07-09 13:45:53 +0000
+++ src/font.c	2014-07-10 16:11:04 +0000
@@ -2165,10 +2165,14 @@
 	 lowest bit is set if the DPI is different.  */
       EMACS_INT diff;
       EMACS_INT pixel_size = XINT (spec_prop[FONT_SIZE_INDEX]);
+      EMACS_INT entity_size = XINT (AREF (entity, FONT_SIZE_INDEX));
 
       if (CONSP (Vface_font_rescale_alist))
 	pixel_size *= font_rescale_ratio (entity);
-      diff = eabs (pixel_size - XINT (AREF (entity, FONT_SIZE_INDEX))) << 1;
+      if (pixel_size * 2 < entity_size || entity_size * 2 < pixel_size)
+	/* This size is wrong by more than a factor 2: reject it!  */
+	return 0xFFFFFFFF;
+      diff = eabs (pixel_size - entity_size) << 1;
       if (! NILP (spec_prop[FONT_DPI_INDEX])
 	  && ! EQ (spec_prop[FONT_DPI_INDEX], AREF (entity, FONT_DPI_INDEX)))
 	diff |= 1;