mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-01-09 21:20:45 -08:00
* 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.
This commit is contained in:
parent
e856c2162b
commit
8c2da0fa6c
4 changed files with 117 additions and 34 deletions
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
105
src/macterm.c
105
src/macterm.c
|
|
@ -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;
|
||||
|
||||
if (s->cmp == NULL
|
||||
&& s->first_glyph->type == CHAR_GLYPH)
|
||||
TextFont (font->mac_fontnum);
|
||||
TextSize (font->mac_fontsize);
|
||||
TextFace (font->mac_fontface);
|
||||
|
||||
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,
|
||||
|
|
|
|||
34
src/xdisp.c
34
src/xdisp.c
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue