From mboxrd@z Thu Jan 1 00:00:00 1970 Path: main.gmane.org!not-for-mail From: Werner LEMBERG Newsgroups: gmane.emacs.devel Subject: variable line spacing Date: Sun, 10 Mar 2002 10:31:14 +0100 (CET) Sender: emacs-devel-admin@gnu.org Message-ID: <20020310.103114.71101308.wl@gnu.org> NNTP-Posting-Host: main.gmane.org Mime-Version: 1.0 Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-Trace: main.gmane.org 1015765402 6582 80.91.224.249 (10 Mar 2002 13:03:22 GMT) X-Complaints-To: usenet@main.gmane.org NNTP-Posting-Date: Sun, 10 Mar 2002 13:03:22 +0000 (UTC) Cc: gerd@gnu.org Original-Received: from quimby.gnus.org ([80.91.224.244]) by main.gmane.org with esmtp (Exim 3.33 #1 (Debian)) id 16k2yw-0001i3-00 for ; Sun, 10 Mar 2002 14:03:22 +0100 Original-Received: from fencepost.gnu.org ([199.232.76.164]) by quimby.gnus.org with esmtp (Exim 3.12 #1 (Debian)) id 16k30C-0007WD-00 for ; Sun, 10 Mar 2002 14:04:40 +0100 Original-Received: from localhost ([127.0.0.1] helo=fencepost.gnu.org) by fencepost.gnu.org with esmtp (Exim 3.34 #1 (Debian)) id 16k2yh-0007SR-00; Sun, 10 Mar 2002 08:03:07 -0500 Original-Received: from mx2.utanet.at ([195.70.253.46] helo=smtp1.utaiop.at) by fencepost.gnu.org with esmtp (Exim 3.34 #1 (Debian)) id 16k2vx-0007Po-00; Sun, 10 Mar 2002 08:00:17 -0500 Original-Received: from multi1.utaiop.at ([10.70.253.35]) by smtp1.utaiop.at (Netscape Messaging Server 4.15) with ESMTP id GSRDGE02.5PR; Sun, 10 Mar 2002 14:00:14 +0100 Original-Received: from orion.local ([212.152.209.151]) by multi1.utaiop.at (Netscape Messaging Server 4.15) with ESMTP id GSRDFX00.Y8O; Sun, 10 Mar 2002 13:59:57 +0100 Original-Received: from localhost (localhost [127.0.0.1]) by orion.local (8.11.6/8.11.6/SuSE Linux 0.5) with ESMTP id g2A9VFI21893; Sun, 10 Mar 2002 10:31:15 +0100 Original-To: emacs-devel@gnu.org X-Mailer: Mew version 3.0.54 on Emacs 21.2.50.1 / Mule 5.0 (SAKAKI) Errors-To: emacs-devel-admin@gnu.org X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.0.5 Precedence: bulk List-Help: List-Post: List-Subscribe: , List-Id: Emacs development discussions. List-Unsubscribe: , List-Archive: Xref: main.gmane.org gmane.emacs.devel:1838 X-Report-Spam: http://spam.gmane.org/gmane.emacs.devel:1838 Here is my preliminary patch for implementing variable line spacing. . It defines a buffer/frame variable `line-spacing-no-overlap'. If non-nil, increase line space for lines with over-sized ascents and/or descents. Currently, it automatically increases the line spacing by one pixel above and below for such lines. Eventually I will make the amount configurable. Another question: Shall this be a user variable? I wonder why `line-spacing' itself isn't a user variable... . I tried to improve the drawing of extra line spacing (set with the `line-spacing' variable). Currently, it looks very ugly if line-spacing is set to a large value since it is only applied to the descender. My fix tries to add extra line spacing to both the ascent and the descent. Nevertheless, my solution isn't completely satisfactory. Cf. the places marked with `XXX'. Gerd, any idea how to handle this gracefully? Please comment. Werner PS: The changes to macfns.c are missing in the patch. ====================================================================== Index: src/buffer.c =================================================================== RCS file: /cvsroot/emacs/emacs/src/buffer.c,v retrieving revision 1.380 diff -u -r1.380 buffer.c --- src/buffer.c 4 Mar 2002 23:20:06 -0000 1.380 +++ src/buffer.c 7 Mar 2002 05:39:32 -0000 @@ -646,6 +646,7 @@ b->enable_multibyte_characters = buffer_defaults.enable_multibyte_characters; b->cursor_type = buffer_defaults.cursor_type; b->extra_line_spacing = buffer_defaults.extra_line_spacing; + b->line_spacing_no_overlap = buffer_defaults.line_spacing_no_overlap; b->display_error_modiff = 0; } @@ -4824,6 +4825,7 @@ buffer_defaults.direction_reversed = Qnil; buffer_defaults.cursor_type = Qt; buffer_defaults.extra_line_spacing = Qnil; + buffer_defaults.line_spacing_no_overlap = Qnil; #ifdef DOS_NT buffer_defaults.buffer_file_type = Qnil; /* TEXT */ @@ -4905,6 +4907,7 @@ XSETFASTINT (buffer_local_flags.header_line_format, idx); ++idx; XSETFASTINT (buffer_local_flags.cursor_type, idx); ++idx; XSETFASTINT (buffer_local_flags.extra_line_spacing, idx); ++idx; + XSETFASTINT (buffer_local_flags.line_spacing_no_overlap, idx); ++idx; /* Need more room? */ if (idx >= MAX_PER_BUFFER_VARS) @@ -5082,6 +5085,11 @@ doc: /* Default value of `line-spacing' for buffers that don't override it. This is the same as (default-value 'line-spacing). */); + DEFVAR_LISP_NOPRO ("default-line-spacing-no-overlap", + &buffer_defaults.line_spacing_no_overlap, + doc: /* Default value of `line-spacing-no-overlap' for buffers that don't override it. +This is the same as (default-value 'line-spacing-no-overlap). */); + DEFVAR_LISP_NOPRO ("default-abbrev-mode", &buffer_defaults.abbrev_mode, doc: /* Default value of `abbrev-mode' for buffers that do not override it. @@ -5613,6 +5621,16 @@ ¤t_buffer->extra_line_spacing, Qnil, doc: /* Additional space to put between lines when displaying a buffer. The space is measured in pixels, and put below lines on window systems. */); + + DEFVAR_PER_BUFFER ("line-spacing-no-overlap", + ¤t_buffer->line_spacing_no_overlap, Qnil, + doc: /* Non-nil means glyph ascenders and descenders won't overlap. +By default, Emacs doesn't increase the line space if it encounters +glyphs that draw vertically outside of their logical bounds. This +can cause overlapping, making the affected glyphs unreadable. + +Contrary to `line-spacing', only lines with over-sized glyphs are +moved apart; other lines are not affected. */); DEFVAR_LISP ("kill-buffer-query-functions", &Vkill_buffer_query_functions, doc: /* List of functions called with no args to query before killing a buffer. */); Index: src/buffer.h =================================================================== RCS file: /cvsroot/emacs/emacs/src/buffer.h,v retrieving revision 1.85 diff -u -r1.85 buffer.h --- src/buffer.h 10 Jan 2002 11:13:17 -0000 1.85 +++ src/buffer.h 7 Mar 2002 05:39:34 -0000 @@ -743,6 +743,10 @@ /* An integer > 0 means put that number of pixels below text lines in the display of this buffer. */ Lisp_Object extra_line_spacing; + + /* True if lines with vertically oversized glyphs should not + overlap. */ + Lisp_Object line_spacing_no_overlap; }; Index: src/dispextern.h =================================================================== RCS file: /cvsroot/emacs/emacs/src/dispextern.h,v retrieving revision 1.130 diff -u -r1.130 dispextern.h --- src/dispextern.h 4 Mar 2002 23:41:00 -0000 1.130 +++ src/dispextern.h 7 Mar 2002 05:39:44 -0000 @@ -1780,8 +1780,12 @@ int last_visible_y; /* Additional space in pixels between lines (for window systems - only.) */ + only). */ int extra_line_spacing; + + /* 1 means lines with vertically oversized glyphs don't overlap + (for window systems only). */ + unsigned line_spacing_no_overlap_p : 1; /* If non-null, glyphs are produced in glyph_row with each call to produce_glyphs. */ Index: src/frame.h =================================================================== RCS file: /cvsroot/emacs/emacs/src/frame.h,v retrieving revision 1.95 diff -u -r1.95 frame.h --- src/frame.h 16 Feb 2002 23:54:04 -0000 1.95 +++ src/frame.h 7 Mar 2002 05:39:46 -0000 @@ -369,6 +369,10 @@ /* Additional space to put between text lines on this frame. */ int extra_line_spacing; + /* 1 means lines with vertically oversized glyphs don't overlap + (for window systems only). */ + unsigned line_spacing_no_overlap_p : 1; + /* Set to non-zero in change_frame_size when size of frame changed Clear the frame in clear_garbaged_frames if set. */ unsigned resized_p : 1; Index: src/w32fns.c =================================================================== RCS file: /cvsroot/emacs/emacs/src/w32fns.c,v retrieving revision 1.157 diff -u -r1.157 w32fns.c --- src/w32fns.c 23 Feb 2002 18:14:06 -0000 1.157 +++ src/w32fns.c 7 Mar 2002 05:40:23 -0000 @@ -692,6 +692,8 @@ /* TODO: Native Input Method support; see x_create_im. */ void x_set_foreground_color P_ ((struct frame *, Lisp_Object, Lisp_Object)); static void x_set_line_spacing P_ ((struct frame *, Lisp_Object, Lisp_Object)); +static void x_set_line_spacing_no_overlap P_ ((struct frame *, Lisp_Object, + Lisp_Object)); static void x_set_fullscreen P_ ((struct frame *, Lisp_Object, Lisp_Object)); void x_set_background_color P_ ((struct frame *, Lisp_Object, Lisp_Object)); void x_set_mouse_color P_ ((struct frame *, Lisp_Object, Lisp_Object)); @@ -745,6 +747,7 @@ {"tool-bar-lines", x_set_tool_bar_lines}, {"screen-gamma", x_set_screen_gamma}, {"line-spacing", x_set_line_spacing}, + {"line-spacing-no-overlap", x_set_line_spacing_no_overlap}, {"left-fringe", x_set_fringe_width}, {"right-fringe", x_set_fringe_width}, {"fullscreen", x_set_fullscreen}, @@ -2018,6 +2021,15 @@ Fcons (new_value, Qnil))); if (FRAME_VISIBLE_P (f)) redraw_frame (f); +} + + +static void +x_set_line_spacing_no_overlap (f, arg, oldval) + struct frame *f; + Lisp_Object arg, oldval; +{ + f->line_spacing_no_overlap_p = !EQ (Qnil, arg); } Index: src/xdisp.c =================================================================== RCS file: /cvsroot/emacs/emacs/src/xdisp.c,v retrieving revision 1.735 diff -u -r1.735 xdisp.c --- src/xdisp.c 6 Mar 2002 14:03:07 -0000 1.735 +++ src/xdisp.c 7 Mar 2002 05:41:00 -0000 @@ -1526,6 +1526,10 @@ it->extra_line_spacing = XFASTINT (current_buffer->extra_line_spacing); else if (it->f->extra_line_spacing > 0) it->extra_line_spacing = it->f->extra_line_spacing; + + it->line_spacing_no_overlap_p + = (!NILP (current_buffer->line_spacing_no_overlap) + || it->f->line_spacing_no_overlap_p); } /* If realized faces have been removed, e.g. because of face @@ -10818,7 +10822,7 @@ return 0; IF_DEBUG (debug_method_add (w, "twu1")); - + /* Display up to a row that can be reused. The variable last_text_row is set to the last row displayed that displays text. Note that it.vpos == 0 if or if not there is a @@ -10827,7 +10831,14 @@ first_row_y = it.current_y; w->cursor.vpos = -1; last_text_row = last_reused_text_row = NULL; - + + /* XXX: Give up if we have some extra line spacing. This is not the + correct solution, but I couldn't find out how add the ascent part + of the extra line spacing to the top row before scrolling (which + has been removed in `compute_line_metrics'). */ + if (it.extra_line_spacing) + return 0; + while (it.current_y < it.last_visible_y && IT_CHARPOS (it) < CHARPOS (start) && !fonts_changed_p) @@ -11000,6 +11011,13 @@ xassert (first_row_to_display->y < yb); init_to_row_start (&it, w, first_row_to_display); + /* XXX: Give up if we have some extra line spacing. This is not the + correct solution, but I couldn't find out how remove the ascent + part of the extra line spacing in the top row after scrolling + (similar to `compute_line_metrics'). */ + if (it.extra_line_spacing) + return 0; + nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix) - start_vpos); it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix) @@ -12564,14 +12582,42 @@ row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row) || MATRIX_ROW_OVERLAPS_PRED_P (row)); + /* If `line_spacing_no_overlap_p' is true, make the row taller + for over-sized descents. */ + if (row->phys_height - row->phys_ascent > row->height - row->ascent + && it->line_spacing_no_overlap_p) + row->height += (row->phys_height - row->phys_ascent) + - (row->height - row->ascent) + + 1; + + /* Remove first line's ascent part of the extra line spacing */ + if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)) + { + row->ascent -= it->extra_line_spacing / 2; + row->height -= it->extra_line_spacing / 2; + } + /* If first line's physical ascent is larger than its logical ascent, use the physical ascent, and make the row taller. - This makes accented characters fully visible. */ - if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix) - && row->phys_ascent > row->ascent) + This makes accented characters fully visible. + If `line_spacing_no_overlap_p' is true, do this for all + affected lines. */ + if (row->phys_ascent > row->ascent + && (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix) + || it->line_spacing_no_overlap_p)) { row->height += row->phys_ascent - row->ascent; row->ascent = row->phys_ascent; + + /* Similar to over-sized descents, we add one pixel if + `line_spacing_no_overlap_p' is true and we are not + in the first row. */ + if (row != MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix) + && it->line_spacing_no_overlap_p) + { + row->height += 1; + row->ascent += 1; + } } /* Compute how much of the line is visible. */ Index: src/xfns.c =================================================================== RCS file: /cvsroot/emacs/emacs/src/xfns.c,v retrieving revision 1.540 diff -u -r1.540 xfns.c --- src/xfns.c 3 Mar 2002 20:07:42 -0000 1.540 +++ src/xfns.c 7 Mar 2002 05:41:45 -0000 @@ -736,6 +736,8 @@ static void x_disable_image P_ ((struct frame *, struct image *)); void x_set_foreground_color P_ ((struct frame *, Lisp_Object, Lisp_Object)); static void x_set_line_spacing P_ ((struct frame *, Lisp_Object, Lisp_Object)); +static void x_set_line_spacing_no_overlap P_ ((struct frame *, Lisp_Object, + Lisp_Object)); static void x_set_wait_for_wm P_ ((struct frame *, Lisp_Object, Lisp_Object)); static void x_set_fullscreen P_ ((struct frame *, Lisp_Object, Lisp_Object)); void x_set_background_color P_ ((struct frame *, Lisp_Object, Lisp_Object)); @@ -808,6 +810,7 @@ {"scroll-bar-background", x_set_scroll_bar_background}, {"screen-gamma", x_set_screen_gamma}, {"line-spacing", x_set_line_spacing}, + {"line-spacing-no-overlap", x_set_line_spacing_no_overlap}, {"left-fringe", x_set_fringe_width}, {"right-fringe", x_set_fringe_width}, {"wait-for-wm", x_set_wait_for_wm}, @@ -1423,6 +1426,15 @@ Fcons (new_value, Qnil))); if (FRAME_VISIBLE_P (f)) redraw_frame (f); +} + + +static void +x_set_line_spacing_no_overlap (f, arg, oldval) + struct frame *f; + Lisp_Object arg, oldval; +{ + f->line_spacing_no_overlap_p = !EQ (Qnil, arg); } Index: src/xterm.c =================================================================== RCS file: /cvsroot/emacs/emacs/src/xterm.c,v retrieving revision 1.710 diff -u -r1.710 xterm.c --- src/xterm.c 4 Mar 2002 23:40:59 -0000 1.710 +++ src/xterm.c 7 Mar 2002 05:42:29 -0000 @@ -2323,8 +2323,9 @@ xassert (it->ascent >= 0 && it->descent >= 0); if (it->area == TEXT_AREA) it->current_x += it->pixel_width; - - it->descent += it->extra_line_spacing; + + it->ascent += it->extra_line_spacing / 2; + it->descent += it->extra_line_spacing - it->extra_line_spacing / 2; it->max_ascent = max (it->max_ascent, it->ascent); it->max_descent = max (it->max_descent, it->descent); _______________________________________________ Emacs-devel mailing list Emacs-devel@gnu.org http://mail.gnu.org/mailman/listinfo/emacs-devel