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;
}
{
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);
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)
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;
+ }
}
}
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,
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. */
{
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;
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
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)
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
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)
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. */
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;