From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: YAMAMOTO Mitsuharu Newsgroups: gmane.emacs.devel Subject: Re: ATSUI support on Carbon Emacs Date: Thu, 06 Oct 2005 17:20:59 +0900 Organization: Faculty of Science, Chiba University Message-ID: References: NNTP-Posting-Host: main.gmane.org Mime-Version: 1.0 (generated by SEMI 1.14.6 - "Maruoka") Content-Type: text/plain; charset=US-ASCII X-Trace: sea.gmane.org 1128591354 2471 80.91.229.2 (6 Oct 2005 09:35:54 GMT) X-Complaints-To: usenet@sea.gmane.org NNTP-Posting-Date: Thu, 6 Oct 2005 09:35:54 +0000 (UTC) Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Thu Oct 06 11:35:43 2005 Return-path: Original-Received: from lists.gnu.org ([199.232.76.165]) by ciao.gmane.org with esmtp (Exim 4.43) id 1ENS8X-000885-Dc for ged-emacs-devel@m.gmane.org; Thu, 06 Oct 2005 11:34:01 +0200 Original-Received: from localhost ([127.0.0.1] helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1ENS8W-0005Yc-LM for ged-emacs-devel@m.gmane.org; Thu, 06 Oct 2005 05:34:00 -0400 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1ENQzz-0003TG-K7 for emacs-devel@gnu.org; Thu, 06 Oct 2005 04:21:07 -0400 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1ENQzw-0003T3-U7 for emacs-devel@gnu.org; Thu, 06 Oct 2005 04:21:06 -0400 Original-Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1ENQzw-0003T0-9p for emacs-devel@gnu.org; Thu, 06 Oct 2005 04:21:04 -0400 Original-Received: from [133.82.132.2] (helo=mathmail.math.s.chiba-u.ac.jp) by monty-python.gnu.org with esmtp (Exim 4.34) id 1ENQzv-0003cO-Ni for emacs-devel@gnu.org; Thu, 06 Oct 2005 04:21:04 -0400 Original-Received: from church.math.s.chiba-u.ac.jp (church [133.82.132.36]) by mathmail.math.s.chiba-u.ac.jp (Postfix) with ESMTP id 592372CB7 for ; Thu, 6 Oct 2005 17:20:59 +0900 (JST) Original-To: emacs-devel@gnu.org In-Reply-To: User-Agent: Wanderlust/2.14.0 (Africa) SEMI/1.14.6 (Maruoka) FLIM/1.14.6 (Marutamachi) APEL/10.6 Emacs/22.0.50 (sparc-sun-solaris2.8) MULE/5.0 (SAKAKI) X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:43607 Archived-At: >>>>> On Sat, 01 Oct 2005 20:28:45 +0900, YAMAMOTO Mitsuharu 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); } }