diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/dispextern.h | 5 | ||||
| -rw-r--r-- | src/macgui.h | 7 | ||||
| -rw-r--r-- | src/macterm.c | 105 | ||||
| -rw-r--r-- | src/xdisp.c | 34 |
4 files changed, 117 insertions, 34 deletions
diff --git a/src/dispextern.h b/src/dispextern.h index 53ae50f3c2a..89a8fe39aeb 100644 --- a/src/dispextern.h +++ b/src/dispextern.h | |||
| @@ -1193,6 +1193,11 @@ struct glyph_string | |||
| 1193 | /* Slice */ | 1193 | /* Slice */ |
| 1194 | struct glyph_slice slice; | 1194 | struct glyph_slice slice; |
| 1195 | 1195 | ||
| 1196 | /* Non-null means the horizontal clipping region starts from the | ||
| 1197 | left edge of *clip_head, and ends with the right edge of | ||
| 1198 | *clip_tail, not including their overhangs. */ | ||
| 1199 | struct glyph_string *clip_head, *clip_tail; | ||
| 1200 | |||
| 1196 | struct glyph_string *next, *prev; | 1201 | struct glyph_string *next, *prev; |
| 1197 | }; | 1202 | }; |
| 1198 | 1203 | ||
diff --git a/src/macgui.h b/src/macgui.h index 1e1447dfaa8..cb157bb8c25 100644 --- a/src/macgui.h +++ b/src/macgui.h | |||
| @@ -92,6 +92,13 @@ typedef struct _XCharStruct | |||
| 92 | int descent; | 92 | int descent; |
| 93 | } XCharStruct; | 93 | } XCharStruct; |
| 94 | 94 | ||
| 95 | #define STORE_XCHARSTRUCT(xcs, w, bds) \ | ||
| 96 | ((xcs).width = (w), \ | ||
| 97 | (xcs).lbearing = (bds).left, \ | ||
| 98 | (xcs).rbearing = (bds).right, \ | ||
| 99 | (xcs).ascent = -(bds).top, \ | ||
| 100 | (xcs).descent = (bds).bottom) | ||
| 101 | |||
| 95 | struct MacFontStruct { | 102 | struct MacFontStruct { |
| 96 | char *fontname; | 103 | char *fontname; |
| 97 | 104 | ||
diff --git a/src/macterm.c b/src/macterm.c index 24aaa52947b..60eee6a4a84 100644 --- a/src/macterm.c +++ b/src/macterm.c | |||
| @@ -1991,20 +1991,33 @@ static void | |||
| 1991 | mac_compute_glyph_string_overhangs (s) | 1991 | mac_compute_glyph_string_overhangs (s) |
| 1992 | struct glyph_string *s; | 1992 | struct glyph_string *s; |
| 1993 | { | 1993 | { |
| 1994 | #if 0 | 1994 | Rect r; |
| 1995 | /* MAC_TODO: XTextExtents16 does nothing yet... */ | 1995 | MacFontStruct *font = s->font; |
| 1996 | |||
| 1997 | TextFont (font->mac_fontnum); | ||
| 1998 | TextSize (font->mac_fontsize); | ||
| 1999 | TextFace (font->mac_fontface); | ||
| 1996 | 2000 | ||
| 1997 | if (s->cmp == NULL | 2001 | if (s->two_byte_p) |
| 1998 | && s->first_glyph->type == CHAR_GLYPH) | 2002 | QDTextBounds (s->nchars * 2, (char *)s->char2b, &r); |
| 2003 | else | ||
| 1999 | { | 2004 | { |
| 2000 | XCharStruct cs; | 2005 | int i; |
| 2001 | int direction, font_ascent, font_descent; | 2006 | char *buf = xmalloc (s->nchars); |
| 2002 | XTextExtents16 (s->font, s->char2b, s->nchars, &direction, | 2007 | |
| 2003 | &font_ascent, &font_descent, &cs); | 2008 | if (buf == NULL) |
| 2004 | s->right_overhang = cs.rbearing > cs.width ? cs.rbearing - cs.width : 0; | 2009 | SetRect (&r, 0, 0, 0, 0); |
| 2005 | s->left_overhang = cs.lbearing < 0 ? -cs.lbearing : 0; | 2010 | else |
| 2011 | { | ||
| 2012 | for (i = 0; i < s->nchars; ++i) | ||
| 2013 | buf[i] = s->char2b[i].byte2; | ||
| 2014 | QDTextBounds (s->nchars, buf, &r); | ||
| 2015 | xfree (buf); | ||
| 2016 | } | ||
| 2006 | } | 2017 | } |
| 2007 | #endif | 2018 | |
| 2019 | s->right_overhang = r.right > s->width ? r.right - s->width : 0; | ||
| 2020 | s->left_overhang = r.left < 0 ? -r.left : 0; | ||
| 2008 | } | 2021 | } |
| 2009 | 2022 | ||
| 2010 | 2023 | ||
| @@ -3072,10 +3085,12 @@ x_draw_glyph_string (s) | |||
| 3072 | { | 3085 | { |
| 3073 | int relief_drawn_p = 0; | 3086 | int relief_drawn_p = 0; |
| 3074 | 3087 | ||
| 3075 | /* If S draws into the background of its successor, draw the | 3088 | /* If S draws into the background of its successor that does not |
| 3076 | background of the successor first so that S can draw into it. | 3089 | draw a cursor, draw the background of the successor first so that |
| 3077 | This makes S->next use XDrawString instead of XDrawImageString. */ | 3090 | S can draw into it. This makes S->next use XDrawString instead |
| 3078 | if (s->next && s->right_overhang && !s->for_overlaps_p) | 3091 | of XDrawImageString. */ |
| 3092 | if (s->next && s->right_overhang && !s->for_overlaps_p | ||
| 3093 | && s->next->hl != DRAW_CURSOR) | ||
| 3079 | { | 3094 | { |
| 3080 | xassert (s->next->img == NULL); | 3095 | xassert (s->next->img == NULL); |
| 3081 | x_set_glyph_string_gc (s->next); | 3096 | x_set_glyph_string_gc (s->next); |
| @@ -6756,30 +6771,40 @@ XLoadQueryFont (Display *dpy, char *fontname) | |||
| 6756 | returns 15 for 12-point Monaco! */ | 6771 | returns 15 for 12-point Monaco! */ |
| 6757 | char_width = CharWidth ('m'); | 6772 | char_width = CharWidth ('m'); |
| 6758 | 6773 | ||
| 6759 | font->max_bounds.rbearing = char_width; | 6774 | if (is_two_byte_font) |
| 6760 | font->max_bounds.lbearing = 0; | 6775 | { |
| 6761 | font->max_bounds.width = char_width; | 6776 | font->per_char = NULL; |
| 6762 | font->max_bounds.ascent = the_fontinfo.ascent; | ||
| 6763 | font->max_bounds.descent = the_fontinfo.descent; | ||
| 6764 | 6777 | ||
| 6765 | font->min_bounds = font->max_bounds; | 6778 | if (fontface & italic) |
| 6779 | font->max_bounds.rbearing = char_width + 1; | ||
| 6780 | else | ||
| 6781 | font->max_bounds.rbearing = char_width; | ||
| 6782 | font->max_bounds.lbearing = 0; | ||
| 6783 | font->max_bounds.width = char_width; | ||
| 6784 | font->max_bounds.ascent = the_fontinfo.ascent; | ||
| 6785 | font->max_bounds.descent = the_fontinfo.descent; | ||
| 6766 | 6786 | ||
| 6767 | if (is_two_byte_font || CharWidth ('m') == CharWidth ('i')) | 6787 | font->min_bounds = font->max_bounds; |
| 6768 | font->per_char = NULL; | 6788 | } |
| 6769 | else | 6789 | else |
| 6770 | { | 6790 | { |
| 6771 | font->per_char = (XCharStruct *) | 6791 | font->per_char = (XCharStruct *) |
| 6772 | xmalloc (sizeof (XCharStruct) * (0xff - 0x20 + 1)); | 6792 | xmalloc (sizeof (XCharStruct) * (0xff - 0x20 + 1)); |
| 6773 | { | 6793 | { |
| 6774 | int c, min_width, max_width; | 6794 | int c, min_width, max_width; |
| 6795 | Rect char_bounds, min_bounds, max_bounds; | ||
| 6796 | char ch; | ||
| 6775 | 6797 | ||
| 6776 | min_width = max_width = char_width; | 6798 | min_width = max_width = char_width; |
| 6799 | SetRect (&min_bounds, -32767, -32767, 32767, 32767); | ||
| 6800 | SetRect (&max_bounds, 0, 0, 0, 0); | ||
| 6777 | for (c = 0x20; c <= 0xff; c++) | 6801 | for (c = 0x20; c <= 0xff; c++) |
| 6778 | { | 6802 | { |
| 6779 | font->per_char[c - 0x20] = font->max_bounds; | 6803 | ch = c; |
| 6780 | char_width = CharWidth (c); | 6804 | char_width = CharWidth (ch); |
| 6781 | font->per_char[c - 0x20].width = char_width; | 6805 | QDTextBounds (1, &ch, &char_bounds); |
| 6782 | font->per_char[c - 0x20].rbearing = char_width; | 6806 | STORE_XCHARSTRUCT (font->per_char[c - 0x20], |
| 6807 | char_width, char_bounds); | ||
| 6783 | /* Some Japanese fonts (in SJIS encoding) return 0 as the | 6808 | /* Some Japanese fonts (in SJIS encoding) return 0 as the |
| 6784 | character width of 0x7f. */ | 6809 | character width of 0x7f. */ |
| 6785 | if (char_width > 0) | 6810 | if (char_width > 0) |
| @@ -6787,9 +6812,25 @@ XLoadQueryFont (Display *dpy, char *fontname) | |||
| 6787 | min_width = min (min_width, char_width); | 6812 | min_width = min (min_width, char_width); |
| 6788 | max_width = max (max_width, char_width); | 6813 | max_width = max (max_width, char_width); |
| 6789 | } | 6814 | } |
| 6790 | } | 6815 | if (!EmptyRect (&char_bounds)) |
| 6791 | font->min_bounds.width = min_width; | 6816 | { |
| 6792 | font->max_bounds.width = max_width; | 6817 | SetRect (&min_bounds, |
| 6818 | max (min_bounds.left, char_bounds.left), | ||
| 6819 | max (min_bounds.top, char_bounds.top), | ||
| 6820 | min (min_bounds.right, char_bounds.right), | ||
| 6821 | min (min_bounds.bottom, char_bounds.bottom)); | ||
| 6822 | UnionRect (&max_bounds, &char_bounds, &max_bounds); | ||
| 6823 | } | ||
| 6824 | } | ||
| 6825 | STORE_XCHARSTRUCT (font->min_bounds, min_width, min_bounds); | ||
| 6826 | STORE_XCHARSTRUCT (font->max_bounds, max_width, max_bounds); | ||
| 6827 | if (min_width == max_width | ||
| 6828 | && max_bounds.left >= 0 && max_bounds.right <= max_width) | ||
| 6829 | { | ||
| 6830 | /* Fixed width and no overhangs. */ | ||
| 6831 | xfree (font->per_char); | ||
| 6832 | font->per_char = NULL; | ||
| 6833 | } | ||
| 6793 | } | 6834 | } |
| 6794 | } | 6835 | } |
| 6795 | 6836 | ||
| @@ -9693,7 +9734,7 @@ static struct redisplay_interface x_redisplay_interface = | |||
| 9693 | 0, /* destroy_fringe_bitmap */ | 9734 | 0, /* destroy_fringe_bitmap */ |
| 9694 | mac_per_char_metric, | 9735 | mac_per_char_metric, |
| 9695 | mac_encode_char, | 9736 | mac_encode_char, |
| 9696 | NULL, /* mac_compute_glyph_string_overhangs */ | 9737 | mac_compute_glyph_string_overhangs, |
| 9697 | x_draw_glyph_string, | 9738 | x_draw_glyph_string, |
| 9698 | mac_define_frame_cursor, | 9739 | mac_define_frame_cursor, |
| 9699 | mac_clear_frame_area, | 9740 | mac_clear_frame_area, |
diff --git a/src/xdisp.c b/src/xdisp.c index afcc4844ab2..5f09fcc68b6 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -1786,6 +1786,24 @@ get_glyph_string_clip_rect (s, nr) | |||
| 1786 | r.height = s->row->visible_height; | 1786 | r.height = s->row->visible_height; |
| 1787 | } | 1787 | } |
| 1788 | 1788 | ||
| 1789 | if (s->clip_head) | ||
| 1790 | if (r.x < s->clip_head->x) | ||
| 1791 | { | ||
| 1792 | if (r.width >= s->clip_head->x - r.x) | ||
| 1793 | r.width -= s->clip_head->x - r.x; | ||
| 1794 | else | ||
| 1795 | r.width = 0; | ||
| 1796 | r.x = s->clip_head->x; | ||
| 1797 | } | ||
| 1798 | if (s->clip_tail) | ||
| 1799 | if (r.x + r.width > s->clip_tail->x + s->clip_tail->background_width) | ||
| 1800 | { | ||
| 1801 | if (s->clip_tail->x + s->clip_tail->background_width >= r.x) | ||
| 1802 | r.width = s->clip_tail->x + s->clip_tail->background_width - r.x; | ||
| 1803 | else | ||
| 1804 | r.width = 0; | ||
| 1805 | } | ||
| 1806 | |||
| 1789 | /* If S draws overlapping rows, it's sufficient to use the top and | 1807 | /* If S draws overlapping rows, it's sufficient to use the top and |
| 1790 | bottom of the window for clipping because this glyph string | 1808 | bottom of the window for clipping because this glyph string |
| 1791 | intentionally draws over other lines. */ | 1809 | intentionally draws over other lines. */ |
| @@ -18233,6 +18251,7 @@ draw_glyphs (w, x, row, area, start, end, hl, overlaps_p) | |||
| 18233 | { | 18251 | { |
| 18234 | struct glyph_string *head, *tail; | 18252 | struct glyph_string *head, *tail; |
| 18235 | struct glyph_string *s; | 18253 | struct glyph_string *s; |
| 18254 | struct glyph_string *clip_head = NULL, *clip_tail = NULL; | ||
| 18236 | int last_x, area_width; | 18255 | int last_x, area_width; |
| 18237 | int x_reached; | 18256 | int x_reached; |
| 18238 | int i, j; | 18257 | int i, j; |
| @@ -18301,6 +18320,7 @@ draw_glyphs (w, x, row, area, start, end, hl, overlaps_p) | |||
| 18301 | start = i; | 18320 | start = i; |
| 18302 | compute_overhangs_and_x (t, head->x, 1); | 18321 | compute_overhangs_and_x (t, head->x, 1); |
| 18303 | prepend_glyph_string_lists (&head, &tail, h, t); | 18322 | prepend_glyph_string_lists (&head, &tail, h, t); |
| 18323 | clip_head = head; | ||
| 18304 | } | 18324 | } |
| 18305 | 18325 | ||
| 18306 | /* Prepend glyph strings for glyphs in front of the first glyph | 18326 | /* 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) | |||
| 18313 | i = left_overwriting (head); | 18333 | i = left_overwriting (head); |
| 18314 | if (i >= 0) | 18334 | if (i >= 0) |
| 18315 | { | 18335 | { |
| 18336 | clip_head = head; | ||
| 18316 | BUILD_GLYPH_STRINGS (i, start, h, t, | 18337 | BUILD_GLYPH_STRINGS (i, start, h, t, |
| 18317 | DRAW_NORMAL_TEXT, dummy_x, last_x); | 18338 | DRAW_NORMAL_TEXT, dummy_x, last_x); |
| 18318 | for (s = h; s; s = s->next) | 18339 | for (s = h; s; s = s->next) |
| @@ -18332,6 +18353,7 @@ draw_glyphs (w, x, row, area, start, end, hl, overlaps_p) | |||
| 18332 | DRAW_NORMAL_TEXT, x, last_x); | 18353 | DRAW_NORMAL_TEXT, x, last_x); |
| 18333 | compute_overhangs_and_x (h, tail->x + tail->width, 0); | 18354 | compute_overhangs_and_x (h, tail->x + tail->width, 0); |
| 18334 | append_glyph_string_lists (&head, &tail, h, t); | 18355 | append_glyph_string_lists (&head, &tail, h, t); |
| 18356 | clip_tail = tail; | ||
| 18335 | } | 18357 | } |
| 18336 | 18358 | ||
| 18337 | /* Append glyph strings for glyphs following the last glyph | 18359 | /* Append glyph strings for glyphs following the last glyph |
| @@ -18342,6 +18364,7 @@ draw_glyphs (w, x, row, area, start, end, hl, overlaps_p) | |||
| 18342 | i = right_overwriting (tail); | 18364 | i = right_overwriting (tail); |
| 18343 | if (i >= 0) | 18365 | if (i >= 0) |
| 18344 | { | 18366 | { |
| 18367 | clip_tail = tail; | ||
| 18345 | BUILD_GLYPH_STRINGS (end, i, h, t, | 18368 | BUILD_GLYPH_STRINGS (end, i, h, t, |
| 18346 | DRAW_NORMAL_TEXT, x, last_x); | 18369 | DRAW_NORMAL_TEXT, x, last_x); |
| 18347 | for (s = h; s; s = s->next) | 18370 | for (s = h; s; s = s->next) |
| @@ -18349,6 +18372,12 @@ draw_glyphs (w, x, row, area, start, end, hl, overlaps_p) | |||
| 18349 | compute_overhangs_and_x (h, tail->x + tail->width, 0); | 18372 | compute_overhangs_and_x (h, tail->x + tail->width, 0); |
| 18350 | append_glyph_string_lists (&head, &tail, h, t); | 18373 | append_glyph_string_lists (&head, &tail, h, t); |
| 18351 | } | 18374 | } |
| 18375 | if (clip_head || clip_tail) | ||
| 18376 | for (s = head; s; s = s->next) | ||
| 18377 | { | ||
| 18378 | s->clip_head = clip_head; | ||
| 18379 | s->clip_tail = clip_tail; | ||
| 18380 | } | ||
| 18352 | } | 18381 | } |
| 18353 | 18382 | ||
| 18354 | /* Draw all strings. */ | 18383 | /* Draw all strings. */ |
| @@ -18362,8 +18391,9 @@ draw_glyphs (w, x, row, area, start, end, hl, overlaps_p) | |||
| 18362 | completely. */ | 18391 | completely. */ |
| 18363 | && !overlaps_p) | 18392 | && !overlaps_p) |
| 18364 | { | 18393 | { |
| 18365 | int x0 = head ? head->x : x; | 18394 | int x0 = clip_head ? clip_head->x : (head ? head->x : x); |
| 18366 | int x1 = tail ? tail->x + tail->background_width : x; | 18395 | int x1 = (clip_tail ? clip_tail->x + clip_tail->background_width |
| 18396 | : (tail ? tail->x + tail->background_width : x)); | ||
| 18367 | 18397 | ||
| 18368 | int text_left = window_box_left (w, TEXT_AREA); | 18398 | int text_left = window_box_left (w, TEXT_AREA); |
| 18369 | x0 -= text_left; | 18399 | x0 -= text_left; |