[Top][All Lists]

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

Re: Zero height line causing arithmetic errors

From: Kenichi Handa
Subject: Re: Zero height line causing arithmetic errors
Date: Thu, 19 Jun 2008 10:12:51 +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 <address@hidden>, Stefan Monnier <address@hidden> writes:

> My MPC.el package uses an overlay placed at the end of a line with an
> after-string of #("\n" 0 1 (face (:height 0.05 :inverse-video t)))
> in order to place a horizontal line in the display.

> In Emacs-22, this worked fine (except the line was a bit thicker than
> 0.05 times the base line height).  In Emacs-CVS until recently this
> worked except that the line was full-height (i.e. 13 pixels in my case).
> Recently, it has started to cause more problems because now
> FRAME_SMALLEST_FONT_HEIGHT returns 0, and that value is used at 2 places
> in the divisor position.

> I guess the 0 is because 13 pixels (default font height) * 0.05 -> 0.65
> pixels which are truncated to 0.

> I currently use the patch below, which makes it all work again (tho
> still with the problem that the 0.05 isn't taken into account and line
> line is 13 pixel think), but I suspect it's not the right place to fix
> it,

For the problem of FRAME_SMALLEST_FONT_HEIGHT being set to
0, I installed the similar change.

And, for the problem of too tall line-height, I found the
culprit is XftTextExtents8.  When the pixelsize of a font is
less than 5 or so, for some font, it returns strange values
in `extents' argument.   For instance, with the attached
test problem, I get this result:

% ./xfttest 'bitstream vera sans mono'
pixelsize=9, ascent=8, descent=2
pixelsize=8, ascent=7, descent=2
pixelsize=7, ascent=6, descent=2
pixelsize=6, ascent=5, descent=2
pixelsize=5, ascent=4, descent=2
pixelsize=4, ascent=4, descent=1
pixelsize=3, ascent=3, descent=1
pixelsize=2, ascent=2, descent=1
pixelsize=1, ascent=1, descent=1
pixelsize=0, ascent=1, descent=1
% ./xfttest 'dejavu sans mono'
pixelsize=9, ascent=8, descent=2
pixelsize=8, ascent=7, descent=2
pixelsize=7, ascent=6, descent=2
pixelsize=6, ascent=5, descent=1
pixelsize=5, ascent=5, descent=1
pixelsize=4, ascent=5, descent=2  <-- increasing!
pixelsize=3, ascent=4, descent=4
pixelsize=2, ascent=5, descent=5
pixelsize=1, ascent=5, descent=5
pixelsize=0, ascent=5, descent=5

I don't know which component of these has a bug:
  o the font "dejavu sans mono",
  o freetype
  o xft

Anyway, I installed a quick dirty workaround; not believe
the result of XftTextExtents8 if the pixelsize is less than

With that change, if your default font is scalable, the
following code works as expected.

(let ((buf (get-buffer-create "test"))
  (set-buffer buf)
  (insert "first line\n")
  (setq overlay (make-overlay (1- (point)) (point)))
  (overlay-put overlay 'after-string
               (propertize "\n" 'face '(:height 0.01 :inverse-video t)))
  (switch-to-buffer buf))

But, note that the line height is still 2, not 1.  That's
because the display engine calculate the line height by
ascent+descent, and both ascent and descent doesn't become 0
in the structure XftFont even though `height' member is 1.
It may be another Xft (or freetype) problem.

Kenichi Handa

PS. You can compile xfttest.c by this command:
% gcc -g -o xfttest `xft-config --cflags` `xft-config --libs` xfttest.c

----- xfttest.c ----
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <X11/Xlib.h>
#include <X11/Xft/Xft.h>

char *str = "!\"#$%&'()*+,-./0123456789:;<=>address@hidden|}~";

show_height (Display *display, XftFont *font)
  XGlyphInfo extents;

  XftTextExtents8 (display, font, str, 94, &extents);
  printf (" ascent=%d, descent=%d\n", extents.y, extents.height - extents.y);

main (int argc, char **argv)
  int size;
  char name[256], *p;
  Display *display;
  if (argc < 2)
      fprintf (stderr, "Usage: xfttest FAMILYNAME\n");
      exit (1);
  display = XOpenDisplay (NULL);
  if (! display)
      fprintf (stderr, "Can't open the display\n");
      exit (1);
  strcpy (name, argv[1]);
  p = name + strlen (name);
  for (size = 9; size >= 0; size--)
      XftFont *font;

      sprintf (p, ":pixelsize=%d", size);
      font = XftFontOpenName (display, 0, name);
      printf ("pixelsize=%d,", size);
      show_height (display, font);
      XftFontClose (display, font);
  exit (0);

reply via email to

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