Commit a66678fd authored by YAMAMOTO Mitsuharu's avatar YAMAMOTO Mitsuharu
Browse files

Rename member for_overlaps_p in struct glyph_string to

for_overlaps.
(get_glyph_string_clip_rects): New function created from
get_glyph_string_clip_rect.  Set clipping rectangles according to
the value of for_overlaps.  Enable to store multiple clipping
rectangles.
(get_glyph_string_clip_rect): Use get_glyph_string_clip_rects.
(fill_composite_glyph_string, fill_glyph_string, draw_glyphs):
Rename argument OVERLAPS_P to OVERLAPS.  All uses in macros changed.
(x_fix_overlapping_area): Add OVERLAPS arg.  Pass it to	draw_glyphs.
(draw_phys_cursor_glyph): Set width of erased cursor to use it for
calculating clipping rectangles later.  Call
x_fix_overlapping_area with new OVERLAPS arg to draw only erased
cursor area.
(expose_overlaps): Call x_fix_overlapping_area with new
OVERLAPS arg to draw overlaps in both preceding and succeeding rows.
parent 41124e06
......@@ -1768,15 +1768,20 @@ frame_to_window_pixel_xy (w, x, y)
}
 
/* EXPORT:
Return in *R the clipping rectangle for glyph string S. */
Return in RECTS[] at most N clipping rectangles for glyph string S.
Return the number of stored rectangles. */
 
void
get_glyph_string_clip_rect (s, nr)
int
get_glyph_string_clip_rects (s, rects, n)
struct glyph_string *s;
NativeRectangle *nr;
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. */
......@@ -1819,10 +1824,27 @@ get_glyph_string_clip_rect (s, nr)
/* If S draws overlapping rows, it's sufficient to use the top and
bottom of the window for clipping because this glyph string
intentionally draws over other lines. */
if (s->for_overlaps_p)
if (s->for_overlaps)
{
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 & 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,11 +1903,71 @@ get_glyph_string_clip_rect (s, nr)
}
}
 
if ((s->for_overlaps & OVERLAPS_BOTH) == 0
|| (s->for_overlaps & OVERLAPS_BOTH) == OVERLAPS_BOTH && n == 1)
{
#ifdef CONVERT_FROM_XRECT
CONVERT_FROM_XRECT (r, *nr);
CONVERT_FROM_XRECT (r, *rects);
#else
*nr = r;
*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 & 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 & 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);
}
 
 
......@@ -18023,22 +18105,23 @@ get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
 
FACES is an array of faces for all components of this composition.
S->gidx is the index of the first component for S.
OVERLAPS_P non-zero means S should draw the foreground only, and
use its physical height for clipping.
OVERLAPS non-zero means S should draw the foreground only, and use
its physical height for clipping. See also draw_glyphs.
 
Value is the index of a component not in S. */
 
static int
fill_composite_glyph_string (s, faces, overlaps_p)
fill_composite_glyph_string (s, faces, overlaps)
struct glyph_string *s;
struct face **faces;
int overlaps_p;
int overlaps;
{
int i;
 
xassert (s);
 
s->for_overlaps_p = overlaps_p;
s->for_overlaps = overlaps;
 
s->face = faces[s->gidx];
s->font = s->face->font;
......@@ -18082,16 +18165,16 @@ fill_composite_glyph_string (s, faces, overlaps_p)
 
FACE_ID is the face id of the string. START is the index of the
first glyph to consider, END is the index of the last + 1.
OVERLAPS_P non-zero means S should draw the foreground only, and
use its physical height for clipping.
OVERLAPS non-zero means S should draw the foreground only, and use
its physical height for clipping. See also draw_glyphs.
 
Value is the index of the first glyph not in S. */
 
static int
fill_glyph_string (s, face_id, start, end, overlaps_p)
fill_glyph_string (s, face_id, start, end, overlaps)
struct glyph_string *s;
int face_id;
int start, end, overlaps_p;
int start, end, overlaps;
{
struct glyph *glyph, *last;
int voffset;
......@@ -18101,7 +18184,7 @@ fill_glyph_string (s, face_id, start, end, overlaps_p)
xassert (s->nchars == 0);
xassert (start >= 0 && end > start);
 
s->for_overlaps_p = overlaps_p,
s->for_overlaps = overlaps,
glyph = s->row->glyphs[s->area] + start;
last = s->row->glyphs[s->area] + end;
voffset = glyph->voffset;
......@@ -18578,7 +18661,7 @@ compute_overhangs_and_x (s, x, backward_p)
INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
append_glyph_string (&HEAD, &TAIL, s); \
s->x = (X); \
START = fill_glyph_string (s, face_id, START, END, overlaps_p); \
START = fill_glyph_string (s, face_id, START, END, overlaps); \
} \
while (0)
 
......@@ -18631,7 +18714,7 @@ compute_overhangs_and_x (s, x, backward_p)
if (n == 0) \
first_s = s; \
\
n = fill_composite_glyph_string (s, faces, overlaps_p); \
n = fill_composite_glyph_string (s, faces, overlaps); \
} \
\
++START; \
......@@ -18700,20 +18783,26 @@ compute_overhangs_and_x (s, x, backward_p)
DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
DRAW_IMAGE_RAISED draw an image with a raised relief around it
 
If OVERLAPS_P is non-zero, draw only the foreground of characters
and clip to the physical height of ROW.
If OVERLAPS is non-zero, draw only the foreground of characters and
clip to the physical height of ROW. Non-zero value also defines
the overlapping part to be drawn:
OVERLAPS_PRED overlap with preceding rows
OVERLAPS_SUCC overlap with succeeding rows
OVERLAPS_BOTH overlap with both preceding/succeeding rows
OVERLAPS_ERASED_CURSOR overlap with erased cursor area
 
Value is the x-position reached, relative to AREA of W. */
 
static int
draw_glyphs (w, x, row, area, start, end, hl, overlaps_p)
draw_glyphs (w, x, row, area, start, end, hl, overlaps)
struct window *w;
int x;
struct glyph_row *row;
enum glyph_row_area area;
int start, end;
enum draw_glyphs_face hl;
int overlaps_p;
int overlaps;
{
struct glyph_string *head, *tail;
struct glyph_string *s;
......@@ -18762,7 +18851,7 @@ draw_glyphs (w, x, row, area, start, end, hl, overlaps_p)
/* If there are any glyphs with lbearing < 0 or rbearing > width in
the row, redraw some glyphs in front or following the glyph
strings built above. */
if (head && !overlaps_p && row->contains_overlapping_glyphs_p)
if (head && !overlaps && row->contains_overlapping_glyphs_p)
{
int dummy_x = 0;
struct glyph_string *h, *t;
......@@ -18855,7 +18944,7 @@ draw_glyphs (w, x, row, area, start, end, hl, overlaps_p)
/* When drawing overlapping rows, only the glyph strings'
foreground is drawn, which doesn't erase a cursor
completely. */
&& !overlaps_p)
&& !overlaps)
{
int x0 = clip_head ? clip_head->x : (head ? head->x : x);
int x1 = (clip_tail ? clip_tail->x + clip_tail->background_width
......@@ -20588,13 +20677,15 @@ notice_overwritten_cursor (w, area, x0, x1, y0, y1)
#ifdef HAVE_WINDOW_SYSTEM
 
/* EXPORT for RIF:
Fix the display of area AREA of overlapping row ROW in window W. */
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)
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,7 +20708,7 @@ x_fix_overlapping_area (w, row, area)
 
draw_glyphs (w, start_x, row, area,
start, i,
DRAW_NORMAL_TEXT, 1);
DRAW_NORMAL_TEXT, overlaps);
}
else
{
......@@ -20659,13 +20750,17 @@ draw_phys_cursor_glyph (w, row, hl)
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);
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);
x_fix_overlapping_area (w, row + 1, TEXT_AREA,
OVERLAPS_ERASED_CURSOR);
}
}
}
......@@ -22456,13 +22551,13 @@ expose_overlaps (w, first_overlapping_row, last_overlapping_row)
xassert (row->enabled_p && !row->mode_line_p);
 
if (row->used[LEFT_MARGIN_AREA])
x_fix_overlapping_area (w, row, 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);
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);
x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA, OVERLAPS_BOTH);
}
}
 
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment