unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
Subject: Re: ATSUI support on Carbon Emacs
Date: Thu, 06 Oct 2005 17:20:59 +0900	[thread overview]
Message-ID: <wlzmpndpjo.wl%mituharu@math.s.chiba-u.ac.jp> (raw)
In-Reply-To: <wlwtkx5vde.wl%mituharu@math.s.chiba-u.ac.jp>

>>>>> On Sat, 01 Oct 2005 20:28:45 +0900, YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp> said:

>   * Tall characters get thicker because they are overdrawn when
>     overlapping rows are redrawn.  This is the verical version of
>     the following problem:
>     http://lists.gnu.org/archive/html/emacs-devel/2005-01/msg00729.html

Some changes to the platform-independent part are needed to fix this,
just like the horizontal one.  In the following patch, overlapping
glyph drawing is divided into several cases: overlapping with the
preceding rows, overlapping with the succeeding rows, both of them,
and overlapping in the erased cursor area.  And clipping rectangles
are calculated according to the type of overlapping.

May I install this?  Such changes will be needed when we support other
anti-aliasing environments such as Xft.

				     YAMAMOTO Mitsuharu
				mituharu@math.s.chiba-u.ac.jp

Index: src/dispextern.h
===================================================================
RCS file: /cvsroot/emacs/emacs/src/dispextern.h,v
retrieving revision 1.209
diff -c -r1.209 dispextern.h
*** src/dispextern.h	30 Sep 2005 22:38:16 -0000	1.209
--- src/dispextern.h	6 Oct 2005 07:03:05 -0000
***************
*** 1182,1191 ****
       stipple pattern.  */
    unsigned stippled_p : 1;
  
!   /* 1 means only the foreground of this glyph string must be drawn,
!      and we should use the physical height of the line this glyph
!      string appears in as clip rect.  */
!   unsigned for_overlaps_p : 1;
  
    /* The GC to use for drawing this glyph string.  */
  #if defined(HAVE_X_WINDOWS) || defined(MAC_OS)
--- 1182,1199 ----
       stipple pattern.  */
    unsigned stippled_p : 1;
  
! #define OVERLAPS_PRED		(1 << 0)
! #define OVERLAPS_SUCC		(1 << 1)
! #define OVERLAPS_BOTH		(OVERLAPS_PRED | OVERLAPS_SUCC)
! #define OVERLAPS_ERASED_CURSOR 	(1 << 2)
!   /* Non-zero means only the foreground of this glyph string must be
!      drawn, and we should use the physical height of the line this
!      glyph string appears in as clip rect.  If the value is
!      OVERLAPS_ERASED_CURSOR, the clip rect is restricted to the rect
!      of the erased cursor.  OVERLAPS_PRED and OVERLAPS_SUCC mean we
!      draw overlaps with the preceding and the succeeding rows,
!      respectively.  */
!   unsigned for_overlaps_p : 3;
  
    /* The GC to use for drawing this glyph string.  */
  #if defined(HAVE_X_WINDOWS) || defined(MAC_OS)
***************
*** 2266,2272 ****
       This function is called from redraw_overlapping_rows after
       desired rows have been made current.  */
    void (*fix_overlapping_area) P_ ((struct window *w, struct glyph_row *row,
! 				    enum glyph_row_area area));
  
  #ifdef HAVE_WINDOW_SYSTEM
  
--- 2274,2280 ----
       This function is called from redraw_overlapping_rows after
       desired rows have been made current.  */
    void (*fix_overlapping_area) P_ ((struct window *w, struct glyph_row *row,
! 				    enum glyph_row_area area, int));
  
  #ifdef HAVE_WINDOW_SYSTEM
  
***************
*** 2664,2670 ****
  extern struct cursor_pos output_cursor;
  
  extern void x_fix_overlapping_area P_ ((struct window *, struct glyph_row *,
! 					enum glyph_row_area));
  extern void draw_phys_cursor_glyph P_ ((struct window *,
  					  struct glyph_row *,
  					  enum draw_glyphs_face));
--- 2672,2678 ----
  extern struct cursor_pos output_cursor;
  
  extern void x_fix_overlapping_area P_ ((struct window *, struct glyph_row *,
! 					enum glyph_row_area, int));
  extern void draw_phys_cursor_glyph P_ ((struct window *,
  					  struct glyph_row *,
  					  enum draw_glyphs_face));
***************
*** 2682,2687 ****
--- 2690,2697 ----
  extern void x_draw_vertical_border P_ ((struct window *w));
  
  extern void frame_to_window_pixel_xy P_ ((struct window *, int *, int *));
+ extern int get_glyph_string_clip_rects P_ ((struct glyph_string *,
+ 					    NativeRectangle *, int));
  extern void get_glyph_string_clip_rect P_ ((struct glyph_string *,
  					    NativeRectangle *nr));
  extern Lisp_Object find_hot_spot P_ ((Lisp_Object, int, int));
Index: src/dispnew.c
===================================================================
RCS file: /cvsroot/emacs/emacs/src/dispnew.c,v
retrieving revision 1.356
diff -c -r1.356 dispnew.c
*** src/dispnew.c	1 Sep 2005 14:16:19 -0000	1.356
--- src/dispnew.c	6 Oct 2005 07:03:06 -0000
***************
*** 4035,4057 ****
  
        if (row->overlapping_p && i > 0 && bottom_y < yb)
  	{
! 	  if (row->used[LEFT_MARGIN_AREA])
! 	    rif->fix_overlapping_area (w, row, LEFT_MARGIN_AREA);
  
! 	  if (row->used[TEXT_AREA])
! 	    rif->fix_overlapping_area (w, row, TEXT_AREA);
  
! 	  if (row->used[RIGHT_MARGIN_AREA])
! 	    rif->fix_overlapping_area (w, row, RIGHT_MARGIN_AREA);
  
! 	  /* Record in neighbour rows that ROW overwrites part of their
! 	     display.  */
! 	  if (row->phys_ascent > row->ascent && i > 0)
! 	    MATRIX_ROW (w->current_matrix, i - 1)->overlapped_p = 1;
! 	  if ((row->phys_height - row->phys_ascent
! 	       > row->height - row->ascent)
! 	      && bottom_y < yb)
! 	    MATRIX_ROW (w->current_matrix, i + 1)->overlapped_p = 1;
  	}
  
        if (bottom_y >= yb)
--- 4035,4067 ----
  
        if (row->overlapping_p && i > 0 && bottom_y < yb)
  	{
! 	  int overlaps = 0;
  
! 	  if (MATRIX_ROW_OVERLAPS_PRED_P (row)
! 	      && !MATRIX_ROW (w->current_matrix, i - 1)->overlapped_p)
! 	    overlaps |= OVERLAPS_PRED;
! 	  if (MATRIX_ROW_OVERLAPS_SUCC_P (row)
! 	      && !MATRIX_ROW (w->current_matrix, i + 1)->overlapped_p)
! 	    overlaps |= OVERLAPS_SUCC;
  
! 	  if (overlaps)
! 	    {
! 	      if (row->used[LEFT_MARGIN_AREA])
! 		rif->fix_overlapping_area (w, row, LEFT_MARGIN_AREA, overlaps);
  
! 	      if (row->used[TEXT_AREA])
! 		rif->fix_overlapping_area (w, row, TEXT_AREA, overlaps);
! 
! 	      if (row->used[RIGHT_MARGIN_AREA])
! 		rif->fix_overlapping_area (w, row, RIGHT_MARGIN_AREA, overlaps);
! 
! 	      /* Record in neighbour rows that ROW overwrites part of
! 		 their display.  */
! 	      if (overlaps & OVERLAPS_PRED)
! 		MATRIX_ROW (w->current_matrix, i - 1)->overlapped_p = 1;
! 	      if (overlaps & OVERLAPS_SUCC)
! 		MATRIX_ROW (w->current_matrix, i + 1)->overlapped_p = 1;
! 	    }
  	}
  
        if (bottom_y >= yb)
Index: src/xdisp.c
===================================================================
RCS file: /cvsroot/emacs/emacs/src/xdisp.c,v
retrieving revision 1.1057
diff -c -r1.1057 xdisp.c
*** src/xdisp.c	1 Oct 2005 20:42:09 -0000	1.1057
--- src/xdisp.c	6 Oct 2005 07:03:06 -0000
***************
*** 1768,1782 ****
  }
  
  /* EXPORT:
!    Return in *R the clipping rectangle for glyph string S.  */
  
! void
! get_glyph_string_clip_rect (s, nr)
       struct glyph_string *s;
!      NativeRectangle *nr;
  {
    XRectangle r;
  
    if (s->row->full_width_p)
      {
        /* Draw full-width.  X coordinates are relative to S->w->left_col.  */
--- 1768,1787 ----
  }
  
  /* EXPORT:
!    Return in RECTS[] at most N clipping rectangles for glyph string S.
!    Return the number of stored rectangles.  */
  
! int
! get_glyph_string_clip_rects (s, rects, n)
       struct glyph_string *s;
!      NativeRectangle *rects;
!      int n;
  {
    XRectangle r;
  
+   if (n <= 0)
+     return 0;
+ 
    if (s->row->full_width_p)
      {
        /* Draw full-width.  X coordinates are relative to S->w->left_col.  */
***************
*** 1823,1828 ****
--- 1828,1850 ----
      {
        r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
        r.height = window_text_bottom_y (s->w) - r.y;
+ 
+       /* Alas, the above simple strategy does not work for the
+ 	 environments with anti-aliased text: if the same text is
+ 	 drawn onto the same place multiple times, it gets thicker.
+ 	 If the overlap we are processing is for the erased cursor, we
+ 	 take the intersection with the rectagle of the cursor.  */
+       if (s->for_overlaps_p & OVERLAPS_ERASED_CURSOR)
+ 	{
+ 	  XRectangle rc, r_save = r;
+ 
+ 	  rc.x = WINDOW_TEXT_TO_FRAME_PIXEL_X (s->w, s->w->phys_cursor.x);
+ 	  rc.y = s->w->phys_cursor.y;
+ 	  rc.width = s->w->phys_cursor_width;
+ 	  rc.height = s->w->phys_cursor_height;
+ 
+ 	  x_intersect_rectangles (&r_save, &rc, &r);
+ 	}
      }
    else
      {
***************
*** 1881,1891 ****
  	}
      }
  
  #ifdef CONVERT_FROM_XRECT
!   CONVERT_FROM_XRECT (r, *nr);
  #else
!   *nr = r;
  #endif
  }
  
  
--- 1903,1973 ----
  	}
      }
  
+   if ((s->for_overlaps_p & OVERLAPS_BOTH) == 0
+       || (s->for_overlaps_p & OVERLAPS_BOTH) == OVERLAPS_BOTH && n == 1)
+     {
  #ifdef CONVERT_FROM_XRECT
!       CONVERT_FROM_XRECT (r, *rects);
  #else
!       *rects = r;
! #endif
!       return 1;
!     }
!   else
!     {
!       /* If we are processing overlapping and allowed to return
! 	 multiple clipping rectangles, we exclude the row of the glyph
! 	 string from the clipping rectangle.  This is to avoid drawing
! 	 the same text on the environment with anti-aliasing.  */
! #ifdef CONVERT_FROM_XRECT
!       XRectangle rs[2];
! #else
!       XRectangle *rs = rects;
! #endif
!       int i = 0, row_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, s->row->y);
! 
!       if (s->for_overlaps_p & OVERLAPS_PRED)
! 	{
! 	  rs[i] = r;
! 	  if (r.y + r.height > row_y)
! 	    if (r.y < row_y)
! 	      rs[i].height = row_y - r.y;
! 	    else
! 	      rs[i].height = 0;
! 	  i++;
! 	}
!       if (s->for_overlaps_p & OVERLAPS_SUCC)
! 	{
! 	  rs[i] = r;
! 	  if (r.y < row_y + s->row->visible_height)
! 	    if (r.y + r.height > row_y + s->row->visible_height)
! 	      {
! 		rs[i].y = row_y + s->row->visible_height;
! 		rs[i].height = r.y + r.height - rs[i].y;
! 	      }
! 	    else
! 	      rs[i].height = 0;
! 	  i++;
! 	}
! 
!       n = i;
! #ifdef CONVERT_FROM_XRECT
!       for (i = 0; i < n; i++)
! 	CONVERT_FROM_XRECT (rs[i], rects[i]);
  #endif
+       return n;
+     }
+ }
+ 
+ /* EXPORT:
+    Return in *NR the clipping rectangle for glyph string S.  */
+ 
+ void
+ get_glyph_string_clip_rect (s, nr)
+      struct glyph_string *s;
+      NativeRectangle *nr;
+ {
+   get_glyph_string_clip_rects (s, nr, 1);
  }
  
  
***************
*** 20588,20600 ****
  #ifdef HAVE_WINDOW_SYSTEM
  
  /* EXPORT for RIF:
!    Fix the display of area AREA of overlapping row ROW in window W.  */
  
  void
! x_fix_overlapping_area (w, row, area)
       struct window *w;
       struct glyph_row *row;
       enum glyph_row_area area;
  {
    int i, x;
  
--- 20670,20684 ----
  #ifdef HAVE_WINDOW_SYSTEM
  
  /* EXPORT for RIF:
!    Fix the display of area AREA of overlapping row ROW in window W
!    with respect to the overlapping part OVERLAPS.  */
  
  void
! x_fix_overlapping_area (w, row, area, overlaps)
       struct window *w;
       struct glyph_row *row;
       enum glyph_row_area area;
+      int overlaps;
  {
    int i, x;
  
***************
*** 20617,20623 ****
  
  	  draw_glyphs (w, start_x, row, area,
  		       start, i,
! 		       DRAW_NORMAL_TEXT, 1);
  	}
        else
  	{
--- 20701,20707 ----
  
  	  draw_glyphs (w, start_x, row, area,
  		       start, i,
! 		       DRAW_NORMAL_TEXT, overlaps);
  	}
        else
  	{
***************
*** 20659,20671 ****
  	 are redrawn.  */
        else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
  	{
  	  if (row > w->current_matrix->rows
  	      && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
! 	    x_fix_overlapping_area (w, row - 1, TEXT_AREA);
  
  	  if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
  	      && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
! 	    x_fix_overlapping_area (w, row + 1, TEXT_AREA);
  	}
      }
  }
--- 20743,20759 ----
  	 are redrawn.  */
        else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
  	{
+ 	  w->phys_cursor_width = x1 - w->phys_cursor.x;
+ 
  	  if (row > w->current_matrix->rows
  	      && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
! 	    x_fix_overlapping_area (w, row - 1, TEXT_AREA,
! 				    OVERLAPS_ERASED_CURSOR);
  
  	  if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
  	      && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
! 	    x_fix_overlapping_area (w, row + 1, TEXT_AREA,
! 				    OVERLAPS_ERASED_CURSOR);
  	}
      }
  }
***************
*** 22456,22468 ****
  	xassert (row->enabled_p && !row->mode_line_p);
  
  	if (row->used[LEFT_MARGIN_AREA])
! 	  x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA);
  
  	if (row->used[TEXT_AREA])
! 	  x_fix_overlapping_area (w, row, TEXT_AREA);
  
  	if (row->used[RIGHT_MARGIN_AREA])
! 	  x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA);
        }
  }
  
--- 22544,22556 ----
  	xassert (row->enabled_p && !row->mode_line_p);
  
  	if (row->used[LEFT_MARGIN_AREA])
! 	  x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA, OVERLAPS_BOTH);
  
  	if (row->used[TEXT_AREA])
! 	  x_fix_overlapping_area (w, row, TEXT_AREA, OVERLAPS_BOTH);
  
  	if (row->used[RIGHT_MARGIN_AREA])
! 	  x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA, OVERLAPS_BOTH);
        }
  }

  reply	other threads:[~2005-10-06  8:20 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-10-01 11:28 ATSUI support on Carbon Emacs YAMAMOTO Mitsuharu
2005-10-06  8:20 ` YAMAMOTO Mitsuharu [this message]
2005-10-06 10:55   ` Kim F. Storm
2005-10-07  8:07     ` YAMAMOTO Mitsuharu
2005-10-07 14:02       ` Romain Francoise
2005-10-07 21:47         ` Kim F. Storm
2005-10-08  2:41           ` YAMAMOTO Mitsuharu
2005-10-09 13:18           ` Romain Francoise
2005-10-11 14:26 ` David Reitter
2005-10-12  5:03   ` YAMAMOTO Mitsuharu
2005-10-12  9:24     ` David Reitter
2005-10-13  8:17       ` YAMAMOTO Mitsuharu
2005-11-12  5:52         ` YAMAMOTO Mitsuharu
2005-10-20 12:44 ` Eli Zaretskii
2005-10-21  1:10   ` YAMAMOTO Mitsuharu
2005-10-21  9:32     ` Eli Zaretskii
2005-10-21  9:58       ` YAMAMOTO Mitsuharu
2005-10-21 14:45         ` Eli Zaretskii
2005-10-24  1:05           ` YAMAMOTO Mitsuharu
2005-10-24  9:37             ` Eli Zaretskii
2005-10-25  0:00 ` Sébastien Kirche
2005-10-25  8:19   ` YAMAMOTO Mitsuharu
2005-10-25 18:57     ` Sébastien Kirche
2005-10-25 21:00       ` Sébastien Kirche
2005-10-27  1:36         ` YAMAMOTO Mitsuharu
2005-10-27 16:44           ` Sébastien Kirche
2005-10-28 10:35             ` YAMAMOTO Mitsuharu
2005-10-29  1:11               ` Sébastien Kirche
2006-03-12  8:52 ` YAMAMOTO Mitsuharu
2006-04-26  9:13   ` YAMAMOTO Mitsuharu
2006-04-26  9:50     ` YAMAMOTO Mitsuharu
2006-05-01  1:34     ` YAMAMOTO Mitsuharu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=wlzmpndpjo.wl%mituharu@math.s.chiba-u.ac.jp \
    --to=mituharu@math.s.chiba-u.ac.jp \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).