}
/* 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. */
/* 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
{
}
}
+ 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);
}
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;
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;
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;
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)
if (n == 0) \
first_s = s; \
\
- n = fill_composite_glyph_string (s, faces, overlaps_p); \
+ n = fill_composite_glyph_string (s, faces, overlaps); \
} \
\
++START; \
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;
/* 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;
/* 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
#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;
draw_glyphs (w, start_x, row, area,
start, i,
- DRAW_NORMAL_TEXT, 1);
+ DRAW_NORMAL_TEXT, overlaps);
}
else
{
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);
}
}
}
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);
}
}