Commit 8c2da0fa authored by Steven Tamm's avatar Steven Tamm
Browse files

* dispextern.h (struct glyph_string): New members clip_head and

	clip_tail.
* xdisp.c (get_glyph_string_clip_rect): Restrict horizontal clip
	region to the area between clip_head and clip_tail.
	(draw_glyphs): Record the area that need to be actually redrawn to
	the new variables clip_head and clip_tail when there are
	overhangs.  Set values of these variables to the corresponding
	members in struct glyph_string.  Refine x coordinates for
* macgui.h (STORE_XCHARSETSTRUCT): New macro.
* macterm.c (mac_compute_glyph_string_overhangs): Implement with
	QDTextBounds.
	(x_draw_glyph_string): Don't fill the background of the successor
	of a glyph with a right overhang if the successor will draw a
	cursor.
	(XLoadQueryFont): Obtain font metrics using QDTextBounds.
	(x_redisplay_interface): Add entry for
	compute_glyph_string_overhangs.
parent e856c216
......@@ -1193,6 +1193,11 @@ struct glyph_string
/* Slice */
struct glyph_slice slice;
/* Non-null means the horizontal clipping region starts from the
left edge of *clip_head, and ends with the right edge of
*clip_tail, not including their overhangs. */
struct glyph_string *clip_head, *clip_tail;
struct glyph_string *next, *prev;
};
......
......@@ -92,6 +92,13 @@ typedef struct _XCharStruct
int descent;
} XCharStruct;
#define STORE_XCHARSTRUCT(xcs, w, bds) \
((xcs).width = (w), \
(xcs).lbearing = (bds).left, \
(xcs).rbearing = (bds).right, \
(xcs).ascent = -(bds).top, \
(xcs).descent = (bds).bottom)
struct MacFontStruct {
char *fontname;
......
......@@ -1991,20 +1991,33 @@ static void
mac_compute_glyph_string_overhangs (s)
struct glyph_string *s;
{
#if 0
/* MAC_TODO: XTextExtents16 does nothing yet... */
Rect r;
MacFontStruct *font = s->font;
TextFont (font->mac_fontnum);
TextSize (font->mac_fontsize);
TextFace (font->mac_fontface);
if (s->cmp == NULL
&& s->first_glyph->type == CHAR_GLYPH)
if (s->two_byte_p)
QDTextBounds (s->nchars * 2, (char *)s->char2b, &r);
else
{
XCharStruct cs;
int direction, font_ascent, font_descent;
XTextExtents16 (s->font, s->char2b, s->nchars, &direction,
&font_ascent, &font_descent, &cs);
s->right_overhang = cs.rbearing > cs.width ? cs.rbearing - cs.width : 0;
s->left_overhang = cs.lbearing < 0 ? -cs.lbearing : 0;
int i;
char *buf = xmalloc (s->nchars);
if (buf == NULL)
SetRect (&r, 0, 0, 0, 0);
else
{
for (i = 0; i < s->nchars; ++i)
buf[i] = s->char2b[i].byte2;
QDTextBounds (s->nchars, buf, &r);
xfree (buf);
}
}
#endif
s->right_overhang = r.right > s->width ? r.right - s->width : 0;
s->left_overhang = r.left < 0 ? -r.left : 0;
}
......@@ -3072,10 +3085,12 @@ x_draw_glyph_string (s)
{
int relief_drawn_p = 0;
/* If S draws into the background of its successor, draw the
background of the successor first so that S can draw into it.
This makes S->next use XDrawString instead of XDrawImageString. */
if (s->next && s->right_overhang && !s->for_overlaps_p)
/* If S draws into the background of its successor that does not
draw a cursor, draw the background of the successor first so that
S can draw into it. This makes S->next use XDrawString instead
of XDrawImageString. */
if (s->next && s->right_overhang && !s->for_overlaps_p
&& s->next->hl != DRAW_CURSOR)
{
xassert (s->next->img == NULL);
x_set_glyph_string_gc (s->next);
......@@ -6756,30 +6771,40 @@ XLoadQueryFont (Display *dpy, char *fontname)
returns 15 for 12-point Monaco! */
char_width = CharWidth ('m');
font->max_bounds.rbearing = char_width;
font->max_bounds.lbearing = 0;
font->max_bounds.width = char_width;
font->max_bounds.ascent = the_fontinfo.ascent;
font->max_bounds.descent = the_fontinfo.descent;
if (is_two_byte_font)
{
font->per_char = NULL;
font->min_bounds = font->max_bounds;
if (fontface & italic)
font->max_bounds.rbearing = char_width + 1;
else
font->max_bounds.rbearing = char_width;
font->max_bounds.lbearing = 0;
font->max_bounds.width = char_width;
font->max_bounds.ascent = the_fontinfo.ascent;
font->max_bounds.descent = the_fontinfo.descent;
if (is_two_byte_font || CharWidth ('m') == CharWidth ('i'))
font->per_char = NULL;
font->min_bounds = font->max_bounds;
}
else
{
font->per_char = (XCharStruct *)
xmalloc (sizeof (XCharStruct) * (0xff - 0x20 + 1));
{
int c, min_width, max_width;
int c, min_width, max_width;
Rect char_bounds, min_bounds, max_bounds;
char ch;
min_width = max_width = char_width;
SetRect (&min_bounds, -32767, -32767, 32767, 32767);
SetRect (&max_bounds, 0, 0, 0, 0);
for (c = 0x20; c <= 0xff; c++)
{
font->per_char[c - 0x20] = font->max_bounds;
char_width = CharWidth (c);
font->per_char[c - 0x20].width = char_width;
font->per_char[c - 0x20].rbearing = char_width;
ch = c;
char_width = CharWidth (ch);
QDTextBounds (1, &ch, &char_bounds);
STORE_XCHARSTRUCT (font->per_char[c - 0x20],
char_width, char_bounds);
/* Some Japanese fonts (in SJIS encoding) return 0 as the
character width of 0x7f. */
if (char_width > 0)
......@@ -6787,9 +6812,25 @@ XLoadQueryFont (Display *dpy, char *fontname)
min_width = min (min_width, char_width);
max_width = max (max_width, char_width);
}
}
font->min_bounds.width = min_width;
font->max_bounds.width = max_width;
if (!EmptyRect (&char_bounds))
{
SetRect (&min_bounds,
max (min_bounds.left, char_bounds.left),
max (min_bounds.top, char_bounds.top),
min (min_bounds.right, char_bounds.right),
min (min_bounds.bottom, char_bounds.bottom));
UnionRect (&max_bounds, &char_bounds, &max_bounds);
}
}
STORE_XCHARSTRUCT (font->min_bounds, min_width, min_bounds);
STORE_XCHARSTRUCT (font->max_bounds, max_width, max_bounds);
if (min_width == max_width
&& max_bounds.left >= 0 && max_bounds.right <= max_width)
{
/* Fixed width and no overhangs. */
xfree (font->per_char);
font->per_char = NULL;
}
}
}
......@@ -9693,7 +9734,7 @@ static struct redisplay_interface x_redisplay_interface =
0, /* destroy_fringe_bitmap */
mac_per_char_metric,
mac_encode_char,
NULL, /* mac_compute_glyph_string_overhangs */
mac_compute_glyph_string_overhangs,
x_draw_glyph_string,
mac_define_frame_cursor,
mac_clear_frame_area,
......
......@@ -1786,6 +1786,24 @@ get_glyph_string_clip_rect (s, nr)
r.height = s->row->visible_height;
}
 
if (s->clip_head)
if (r.x < s->clip_head->x)
{
if (r.width >= s->clip_head->x - r.x)
r.width -= s->clip_head->x - r.x;
else
r.width = 0;
r.x = s->clip_head->x;
}
if (s->clip_tail)
if (r.x + r.width > s->clip_tail->x + s->clip_tail->background_width)
{
if (s->clip_tail->x + s->clip_tail->background_width >= r.x)
r.width = s->clip_tail->x + s->clip_tail->background_width - r.x;
else
r.width = 0;
}
/* 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. */
......@@ -18233,6 +18251,7 @@ draw_glyphs (w, x, row, area, start, end, hl, overlaps_p)
{
struct glyph_string *head, *tail;
struct glyph_string *s;
struct glyph_string *clip_head = NULL, *clip_tail = NULL;
int last_x, area_width;
int x_reached;
int i, j;
......@@ -18301,6 +18320,7 @@ draw_glyphs (w, x, row, area, start, end, hl, overlaps_p)
start = i;
compute_overhangs_and_x (t, head->x, 1);
prepend_glyph_string_lists (&head, &tail, h, t);
clip_head = head;
}
 
/* Prepend glyph strings for glyphs in front of the first glyph
......@@ -18313,6 +18333,7 @@ draw_glyphs (w, x, row, area, start, end, hl, overlaps_p)
i = left_overwriting (head);
if (i >= 0)
{
clip_head = head;
BUILD_GLYPH_STRINGS (i, start, h, t,
DRAW_NORMAL_TEXT, dummy_x, last_x);
for (s = h; s; s = s->next)
......@@ -18332,6 +18353,7 @@ draw_glyphs (w, x, row, area, start, end, hl, overlaps_p)
DRAW_NORMAL_TEXT, x, last_x);
compute_overhangs_and_x (h, tail->x + tail->width, 0);
append_glyph_string_lists (&head, &tail, h, t);
clip_tail = tail;
}
 
/* Append glyph strings for glyphs following the last glyph
......@@ -18342,6 +18364,7 @@ draw_glyphs (w, x, row, area, start, end, hl, overlaps_p)
i = right_overwriting (tail);
if (i >= 0)
{
clip_tail = tail;
BUILD_GLYPH_STRINGS (end, i, h, t,
DRAW_NORMAL_TEXT, x, last_x);
for (s = h; s; s = s->next)
......@@ -18349,6 +18372,12 @@ draw_glyphs (w, x, row, area, start, end, hl, overlaps_p)
compute_overhangs_and_x (h, tail->x + tail->width, 0);
append_glyph_string_lists (&head, &tail, h, t);
}
if (clip_head || clip_tail)
for (s = head; s; s = s->next)
{
s->clip_head = clip_head;
s->clip_tail = clip_tail;
}
}
 
/* Draw all strings. */
......@@ -18362,8 +18391,9 @@ draw_glyphs (w, x, row, area, start, end, hl, overlaps_p)
completely. */
&& !overlaps_p)
{
int x0 = head ? head->x : x;
int x1 = tail ? tail->x + tail->background_width : x;
int x0 = clip_head ? clip_head->x : (head ? head->x : x);
int x1 = (clip_tail ? clip_tail->x + clip_tail->background_width
: (tail ? tail->x + tail->background_width : x));
 
int text_left = window_box_left (w, TEXT_AREA);
x0 -= text_left;
......
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