]> git.eshelyaron.com Git - emacs.git/commitdiff
* dispextern.h (struct glyph_string): New members clip_head and
authorSteven Tamm <steventamm@mac.com>
Mon, 24 Jan 2005 17:59:36 +0000 (17:59 +0000)
committerSteven Tamm <steventamm@mac.com>
Mon, 24 Jan 2005 17:59:36 +0000 (17:59 +0000)
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.

src/dispextern.h
src/macgui.h
src/macterm.c
src/xdisp.c

index 53ae50f3c2ac38e1013891b4617ab8e290454d5e..89a8fe39aeb6c6782356ec69ed855057e403b0d3 100644 (file)
@@ -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;
 };
 
index 1e1447dfaa8b5252c9f84c79cf23a4b0cf14e4de..cb157bb8c252d048cb21d60d416331d144a1a5ac 100644 (file)
@@ -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;
 
index 24aaa52947b61a8490363ff70b5151b8f2b807e3..60eee6a4a843656eaded30659eee9baaf4d6056a 100644 (file)
@@ -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,
index afcc4844ab26caa1fdd5e4764de1c5b74602a364..5f09fcc68b6d25ff8fd559119b631f695106c17b 100644 (file)
@@ -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;