emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] Changes to emacs/src/w32term.c


From: Kim F. Storm
Subject: [Emacs-diffs] Changes to emacs/src/w32term.c
Date: Sun, 16 Mar 2003 15:47:50 -0500

Index: emacs/src/w32term.c
diff -c emacs/src/w32term.c:1.179 emacs/src/w32term.c:1.180
*** emacs/src/w32term.c:1.179   Wed Mar 12 07:10:19 2003
--- emacs/src/w32term.c Sun Mar 16 15:47:48 2003
***************
*** 260,278 ****
  
  extern EMACS_INT extra_keyboard_modifiers;
  
- /* Enumeration for overriding/changing the face to use for drawing
-    glyphs in x_draw_glyphs.  */
- 
- enum draw_glyphs_face
- {
-   DRAW_NORMAL_TEXT,
-   DRAW_INVERSE_VIDEO,
-   DRAW_CURSOR,
-   DRAW_MOUSE_FACE,
-   DRAW_IMAGE_RAISED,
-   DRAW_IMAGE_SUNKEN
- };
- 
  static void x_update_window_end P_ ((struct window *, int, int));
  static void frame_to_window_pixel_xy P_ ((struct window *, int *, int *));
  void w32_delete_display P_ ((struct w32_display_info *));
--- 260,265 ----
***************
*** 344,352 ****
  static void w32_clip_to_row P_ ((struct window *, struct glyph_row *,
                                   HDC, int));
  static int x_phys_cursor_in_rect_p P_ ((struct window *, RECT *));
- static void notice_overwritten_cursor P_ ((struct window *,
-                                          enum glyph_row_area,
-                                          int, int, int, int));
  
  static Lisp_Object Qvendor_specific_keysyms;
  
--- 331,336 ----
***************
*** 897,931 ****
  
  /* Function prototypes of this page.  */
  
- static struct face *x_get_glyph_face_and_encoding P_ ((struct frame *,
-                                                      struct glyph *,
-                                                      wchar_t *,
-                                                        int *));
- static struct face *x_get_char_face_and_encoding P_ ((struct frame *, int,
-                                                     int, wchar_t *, int));
  static XCharStruct *w32_per_char_metric P_ ((XFontStruct *,
!                                              wchar_t *,
!                                              enum w32_char_font_type));
! static enum w32_char_font_type
!   w32_encode_char P_ ((int, wchar_t *, struct font_info *, int *));
! static void x_append_glyph P_ ((struct it *));
! static void x_append_composite_glyph P_ ((struct it *));
! static void x_append_stretch_glyph P_ ((struct it *it, Lisp_Object,
!                                       int, int, double));
! static void x_produce_glyphs P_ ((struct it *));
! static void x_produce_image_glyph P_ ((struct it *it));
! 
! 
! /* Dealing with bits of wchar_t as if they were an XChar2B.  */
! #define BUILD_WCHAR_T(byte1, byte2) \
!  ((wchar_t)((((byte1) & 0x00ff) << 8) | ((byte2) & 0x00ff)))
! 
! 
! #define BYTE1(ch) \
!  (((ch) & 0xff00) >> 8)
! 
! #define BYTE2(ch) \
!  ((ch) & 0x00ff)
  
  
  /* Get metrics of character CHAR2B in FONT.  Value is always non-null.
--- 881,889 ----
  
  /* Function prototypes of this page.  */
  
  static XCharStruct *w32_per_char_metric P_ ((XFontStruct *,
!                                              wchar_t *, int));
! static int w32_encode_char P_ ((int, wchar_t *, struct font_info *, int *));
  
  
  /* Get metrics of character CHAR2B in FONT.  Value is always non-null.
***************
*** 946,953 ****
      buf[0] = (char)(*char2b);
    else
      {
!       buf[0] = BYTE1 (*char2b);
!       buf[1] = BYTE2 (*char2b);
      }
  
    bdf_metric = w32_BDF_TextMetric (font->bdf, buf, dim);
--- 904,911 ----
      buf[0] = (char)(*char2b);
    else
      {
!       buf[0] = XCHAR2B_BYTE1 (char2b);
!       buf[1] = XCHAR2B_BYTE2 (char2b);
      }
  
    bdf_metric = w32_BDF_TextMetric (font->bdf, buf, dim);
***************
*** 1065,1071 ****
  w32_per_char_metric (font, char2b, font_type)
       XFontStruct *font;
       wchar_t *char2b;
!      enum w32_char_font_type font_type;
  {
    /* The result metric information.  */
    XCharStruct *pcm;
--- 1023,1029 ----
  w32_per_char_metric (font, char2b, font_type)
       XFontStruct *font;
       wchar_t *char2b;
!      int /* enum w32_char_font_type */ font_type;
  {
    /* The result metric information.  */
    XCharStruct *pcm;
***************
*** 1166,1172 ****
  /* Encode CHAR2B using encoding information from FONT_INFO.  CHAR2B is
     the two-byte form of C.  Encoding is returned in *CHAR2B.  */
  
! static INLINE enum w32_char_font_type
  w32_encode_char (c, char2b, font_info, two_byte_p)
       int c;
       wchar_t *char2b;
--- 1124,1130 ----
  /* Encode CHAR2B using encoding information from FONT_INFO.  CHAR2B is
     the two-byte form of C.  Encoding is returned in *CHAR2B.  */
  
! static int /* enum w32_char_font_type */
  w32_encode_char (c, char2b, font_info, two_byte_p)
       int c;
       wchar_t *char2b;
***************
*** 1181,1187 ****
  
    xassert (two_byte_p);
  
!   *two_byte_p = w32_font_is_double_byte (font);
  
    /* FONT_INFO may define a scheme by which to encode byte1 and byte2.
       This may be either a program in a special encoder language or a
--- 1139,1146 ----
  
    xassert (two_byte_p);
  
!   if (two_byte_p)
!     *two_byte_p = w32_font_is_double_byte (font);
  
    /* FONT_INFO may define a scheme by which to encode byte1 and byte2.
       This may be either a program in a special encoder language or a
***************
*** 1194,1207 ****
        if (CHARSET_DIMENSION (charset) == 1)
        {
          ccl->reg[0] = charset;
!         ccl->reg[1] = BYTE2 (*char2b);
          ccl->reg[2] = -1;
        }
        else
        {
          ccl->reg[0] = charset;
!         ccl->reg[1] = BYTE1 (*char2b);
!         ccl->reg[2] = BYTE2 (*char2b);
        }
  
        ccl_driver (ccl, NULL, NULL, 0, 0, NULL);
--- 1153,1166 ----
        if (CHARSET_DIMENSION (charset) == 1)
        {
          ccl->reg[0] = charset;
!         ccl->reg[1] = XCHAR2B_BYTE2 (char2b);
          ccl->reg[2] = -1;
        }
        else
        {
          ccl->reg[0] = charset;
!         ccl->reg[1] = XCHAR2B_BYTE1 (char2b);
!         ccl->reg[2] = XCHAR2B_BYTE2 (char2b);
        }
  
        ccl_driver (ccl, NULL, NULL, 0, 0, NULL);
***************
*** 1209,1217 ****
        /* We assume that MSBs are appropriately set/reset by CCL
         program.  */
        if (!*two_byte_p)       /* 1-byte font */
!       *char2b = BUILD_WCHAR_T (0, ccl->reg[1]);
        else
!       *char2b = BUILD_WCHAR_T (ccl->reg[1], ccl->reg[2]);
      }
    else if (font_info->encoding[charset])
      {
--- 1168,1176 ----
        /* We assume that MSBs are appropriately set/reset by CCL
         program.  */
        if (!*two_byte_p)       /* 1-byte font */
!       STORE_XCHAR2B (char2b, 0, ccl->reg[1]);
        else
!       STORE_XCHAR2B (char2b, ccl->reg[1], ccl->reg[2]);
      }
    else if (font_info->encoding[charset])
      {
***************
*** 1221,1238 ****
  
        if ((enc == 1 || enc == 2)
          && CHARSET_DIMENSION (charset) == 2)
!       *char2b = BUILD_WCHAR_T (BYTE1 (*char2b) | 0x80, BYTE2 (*char2b));
  
        if (enc == 1 || enc == 3
            || (enc == 4 && CHARSET_DIMENSION (charset) == 1))
!       *char2b = BUILD_WCHAR_T (BYTE1 (*char2b), BYTE2 (*char2b) | 0x80);
        else if (enc == 4)
          {
            int sjis1, sjis2;
  
!           ENCODE_SJIS (BYTE1 (*char2b), BYTE2 (*char2b),
                         sjis1, sjis2);
!           *char2b = BUILD_WCHAR_T (sjis1, sjis2);
          }
      }
    codepage = font_info->codepage;
--- 1180,1197 ----
  
        if ((enc == 1 || enc == 2)
          && CHARSET_DIMENSION (charset) == 2)
!       STORE_XCHAR2B (char2b, XCHAR2B_BYTE1 (char2b) | 0x80, XCHAR2B_BYTE2 
(char2b));
  
        if (enc == 1 || enc == 3
            || (enc == 4 && CHARSET_DIMENSION (charset) == 1))
!       STORE_XCHAR2B (char2b, XCHAR2B_BYTE1 (char2b), XCHAR2B_BYTE2 (char2b) | 
0x80);
        else if (enc == 4)
          {
            int sjis1, sjis2;
  
!           ENCODE_SJIS (XCHAR2B_BYTE1 (char2b), XCHAR2B_BYTE2 (char2b),
                         sjis1, sjis2);
!           STORE_XCHAR2B (char2b, sjis1, sjis2);
          }
      }
    codepage = font_info->codepage;
***************
*** 1244,1251 ****
         && charset != CHARSET_8_BIT_CONTROL && charset != 
CHARSET_8_BIT_GRAPHIC)
      {
        char temp[3];
!       temp[0] = BYTE1 (*char2b);
!       temp[1] = BYTE2 (*char2b);
        temp[2] = '\0';
        if (codepage != CP_UNICODE)
          {
--- 1203,1210 ----
         && charset != CHARSET_8_BIT_CONTROL && charset != 
CHARSET_8_BIT_GRAPHIC)
      {
        char temp[3];
!       temp[0] = XCHAR2B_BYTE1 (char2b);
!       temp[1] = XCHAR2B_BYTE2 (char2b);
        temp[2] = '\0';
        if (codepage != CP_UNICODE)
          {
***************
*** 1270,2360 ****
  }
  
  
- /* Get face and two-byte form of character C in face FACE_ID on frame
-    F.  The encoding of C is returned in *CHAR2B.  MULTIBYTE_P non-zero
-    means we want to display multibyte text.  Value is a pointer to a
-    realized face that is ready for display.  */
- 
- static INLINE struct face *
- x_get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p)
-      struct frame *f;
-      int c, face_id;
-      wchar_t *char2b;
-      int multibyte_p;
- {
-   struct face *face = FACE_FROM_ID (f, face_id);
- 
-   if (!multibyte_p)
-     {
-       /* Unibyte case.  We don't have to encode, but we have to make
-        sure to use a face suitable for unibyte.  */
-       *char2b = BUILD_WCHAR_T (0, c);
-       face_id = FACE_FOR_CHAR (f, face, c);
-       face = FACE_FROM_ID (f, face_id);
-     }
-   else if (c < 128 && face_id < BASIC_FACE_ID_SENTINEL)
-     {
-       /* Case of ASCII in a face known to fit ASCII.  */
-       *char2b = BUILD_WCHAR_T (0, c);
-     }
-   else
-     {
-       int c1, c2, charset;
- 
-       /* Split characters into bytes.  If c2 is -1 afterwards, C is
-        really a one-byte character so that byte1 is zero.  */
-       SPLIT_CHAR (c, charset, c1, c2);
-       if (c2 > 0)
-       *char2b = BUILD_WCHAR_T (c1, c2);
-       else
-       *char2b = BUILD_WCHAR_T (0, c1);
- 
-       /* Maybe encode the character in *CHAR2B.  */
-       if (face->font != NULL)
-       {
-         struct font_info *font_info
-           = FONT_INFO_FROM_ID (f, face->font_info_id);
-         if (font_info)
-             w32_encode_char (c, char2b, font_info, &multibyte_p);
-       }
-     }
- 
-   /* Make sure X resources of the face are allocated.  */
-   xassert (face != NULL);
-   PREPARE_FACE_FOR_DISPLAY (f, face);
- 
-   return face;
- }
- 
- 
- /* Get face and two-byte form of character glyph GLYPH on frame F.
-    The encoding of GLYPH->u.ch is returned in *CHAR2B.  Value is
-    a pointer to a realized face that is ready for display.  */
- 
- static INLINE struct face *
- x_get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
-      struct frame *f;
-      struct glyph *glyph;
-      wchar_t *char2b;
-      int *two_byte_p;
- {
-   struct face *face;
-   int dummy = 0;
- 
-   xassert (glyph->type == CHAR_GLYPH);
-   face = FACE_FROM_ID (f, glyph->face_id);
- 
-   if (two_byte_p)
-     *two_byte_p = 0;
-   else
-     two_byte_p = &dummy;
- 
-   if (!glyph->multibyte_p)
-     {
-       /* Unibyte case.  We don't have to encode, but we have to make
-        sure to use a face suitable for unibyte.  */
-       *char2b = BUILD_WCHAR_T (0, glyph->u.ch);
-     }
-   else if (glyph->u.ch < 128
-          && glyph->face_id < BASIC_FACE_ID_SENTINEL)
-     {
-       /* Case of ASCII in a face known to fit ASCII.  */
-       *char2b = BUILD_WCHAR_T (0, glyph->u.ch);
-     }
-   else
-     {
-       int c1, c2, charset;
- 
-       /* Split characters into bytes.  If c2 is -1 afterwards, C is
-        really a one-byte character so that byte1 is zero.  */
-       SPLIT_CHAR (glyph->u.ch, charset, c1, c2);
-       if (c2 > 0)
-       *char2b = BUILD_WCHAR_T (c1, c2);
-       else
-       *char2b = BUILD_WCHAR_T (0, c1);
- 
-       /* Maybe encode the character in *CHAR2B.  */
-       if (charset != CHARSET_ASCII)
-       {
-         struct font_info *font_info
-           = FONT_INFO_FROM_ID (f, face->font_info_id);
-         if (font_info)
-           {
-             glyph->w32_font_type
-                 = w32_encode_char (glyph->u.ch, char2b, font_info, 
two_byte_p);
-           }
-       }
-     }
- 
-   /* Make sure X resources of the face are allocated.  */
-   xassert (face != NULL);
-   PREPARE_FACE_FOR_DISPLAY (f, face);
-   return face;
- }
- 
- 
- /* Store one glyph for IT->char_to_display in IT->glyph_row.
-    Called from x_produce_glyphs when IT->glyph_row is non-null.  */
- 
- static INLINE void
- x_append_glyph (it)
-      struct it *it;
- {
-   struct glyph *glyph;
-   enum glyph_row_area area = it->area;
- 
-   xassert (it->glyph_row);
-   xassert (it->char_to_display != '\n' && it->char_to_display != '\t');
- 
-   glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
-   if (glyph < it->glyph_row->glyphs[area + 1])
-     {
-       glyph->charpos = CHARPOS (it->position);
-       glyph->object = it->object;
-       glyph->pixel_width = it->pixel_width;
-       glyph->voffset = it->voffset;
-       glyph->type = CHAR_GLYPH;
-       glyph->multibyte_p = it->multibyte_p;
-       glyph->left_box_line_p = it->start_of_box_run_p;
-       glyph->right_box_line_p = it->end_of_box_run_p;
-       glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
-                                     || it->phys_descent > it->descent);
-       glyph->padding_p = 0;
-       glyph->glyph_not_available_p = it->glyph_not_available_p;
-       glyph->face_id = it->face_id;
-       glyph->u.ch = it->char_to_display;
-       glyph->w32_font_type = UNKNOWN_FONT;
-       ++it->glyph_row->used[area];
-     }
- }
- 
- /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
-    Called from x_produce_glyphs when IT->glyph_row is non-null.  */
- 
- static INLINE void
- x_append_composite_glyph (it)
-      struct it *it;
- {
-   struct glyph *glyph;
-   enum glyph_row_area area = it->area;
- 
-   xassert (it->glyph_row);
- 
-   glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
-   if (glyph < it->glyph_row->glyphs[area + 1])
-     {
-       glyph->charpos = CHARPOS (it->position);
-       glyph->object = it->object;
-       glyph->pixel_width = it->pixel_width;
-       glyph->voffset = it->voffset;
-       glyph->type = COMPOSITE_GLYPH;
-       glyph->multibyte_p = it->multibyte_p;
-       glyph->left_box_line_p = it->start_of_box_run_p;
-       glyph->right_box_line_p = it->end_of_box_run_p;
-       glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
-                                     || it->phys_descent > it->descent);
-       glyph->padding_p = 0;
-       glyph->glyph_not_available_p = 0;
-       glyph->face_id = it->face_id;
-       glyph->u.cmp_id = it->cmp_id;
-       glyph->w32_font_type = UNKNOWN_FONT;
-       ++it->glyph_row->used[area];
-     }
- }
- 
- 
- /* Change IT->ascent and IT->height according to the setting of
-    IT->voffset.  */
- 
- static INLINE void
- take_vertical_position_into_account (it)
-      struct it *it;
- {
-   if (it->voffset)
-     {
-       if (it->voffset < 0)
-       /* Increase the ascent so that we can display the text higher
-          in the line.  */
-       it->ascent += abs (it->voffset);
-       else
-       /* Increase the descent so that we can display the text lower
-          in the line.  */
-       it->descent += it->voffset;
-     }
- }
- 
- 
- /* Produce glyphs/get display metrics for the image IT is loaded with.
-    See the description of struct display_iterator in dispextern.h for
-    an overview of struct display_iterator.  */
- 
- static void
- x_produce_image_glyph (it)
-      struct it *it;
- {
-   struct image *img;
-   struct face *face;
- 
-   xassert (it->what == IT_IMAGE);
- 
-   face = FACE_FROM_ID (it->f, it->face_id);
-   img = IMAGE_FROM_ID (it->f, it->image_id);
-   xassert (img);
- 
-   /* Make sure X resources of the face and image are loaded.  */
-   PREPARE_FACE_FOR_DISPLAY (it->f, face);
-   prepare_image_for_display (it->f, img);
- 
-   it->ascent = it->phys_ascent = image_ascent (img, face);
-   it->descent = it->phys_descent = img->height + 2 * img->vmargin - 
it->ascent;
-   it->pixel_width = img->width + 2 * img->hmargin;
- 
-   it->nglyphs = 1;
- 
-   if (face->box != FACE_NO_BOX)
-     {
-       if (face->box_line_width > 0)
-       {
-         it->ascent += face->box_line_width;
-         it->descent += face->box_line_width;
-       }
- 
-       if (it->start_of_box_run_p)
-       it->pixel_width += abs (face->box_line_width);
-       if (it->end_of_box_run_p)
-       it->pixel_width += abs (face->box_line_width);
-     }
- 
-   take_vertical_position_into_account (it);
- 
-   if (it->glyph_row)
-     {
-       struct glyph *glyph;
-       enum glyph_row_area area = it->area;
- 
-       glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
-       if (glyph < it->glyph_row->glyphs[area + 1])
-       {
-         glyph->charpos = CHARPOS (it->position);
-         glyph->object = it->object;
-         glyph->pixel_width = it->pixel_width;
-         glyph->voffset = it->voffset;
-         glyph->type = IMAGE_GLYPH;
-         glyph->multibyte_p = it->multibyte_p;
-         glyph->left_box_line_p = it->start_of_box_run_p;
-         glyph->right_box_line_p = it->end_of_box_run_p;
-         glyph->overlaps_vertically_p = 0;
-           glyph->padding_p = 0;
-         glyph->glyph_not_available_p = 0;
-         glyph->face_id = it->face_id;
-         glyph->u.img_id = img->id;
-           glyph->w32_font_type = UNKNOWN_FONT;
-         ++it->glyph_row->used[area];
-       }
-     }
- }
- 
- 
- /* Append a stretch glyph to IT->glyph_row.  OBJECT is the source
-    of the glyph, WIDTH and HEIGHT are the width and height of the
-    stretch.  ASCENT is the percentage/100 of HEIGHT to use for the
-    ascent of the glyph (0 <= ASCENT <= 1).  */
- 
- static void
- x_append_stretch_glyph (it, object, width, height, ascent)
-      struct it *it;
-      Lisp_Object object;
-      int width, height;
-      double ascent;
- {
-   struct glyph *glyph;
-   enum glyph_row_area area = it->area;
- 
-   xassert (ascent >= 0 && ascent <= 1);
- 
-   glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
-   if (glyph < it->glyph_row->glyphs[area + 1])
-     {
-       glyph->charpos = CHARPOS (it->position);
-       glyph->object = object;
-       glyph->pixel_width = width;
-       glyph->voffset = it->voffset;
-       glyph->type = STRETCH_GLYPH;
-       glyph->multibyte_p = it->multibyte_p;
-       glyph->left_box_line_p = it->start_of_box_run_p;
-       glyph->right_box_line_p = it->end_of_box_run_p;
-       glyph->overlaps_vertically_p = 0;
-       glyph->padding_p = 0;
-       glyph->glyph_not_available_p = 0;
-       glyph->face_id = it->face_id;
-       glyph->u.stretch.ascent = height * ascent;
-       glyph->u.stretch.height = height;
-       glyph->w32_font_type = UNKNOWN_FONT;
-       ++it->glyph_row->used[area];
-     }
- }
- 
- 
- /* Produce a stretch glyph for iterator IT.  IT->object is the value
-    of the glyph property displayed.  The value must be a list
-    `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
-    being recognized:
- 
-    1. `:width WIDTH' specifies that the space should be WIDTH *
-    canonical char width wide.  WIDTH may be an integer or floating
-    point number.
- 
-    2. `:relative-width FACTOR' specifies that the width of the stretch
-    should be computed from the width of the first character having the
-    `glyph' property, and should be FACTOR times that width.
- 
-    3. `:align-to HPOS' specifies that the space should be wide enough
-    to reach HPOS, a value in canonical character units.
- 
-    Exactly one of the above pairs must be present.
- 
-    4. `:height HEIGHT' specifies that the height of the stretch produced
-    should be HEIGHT, measured in canonical character units.
- 
-    5. `:relative-height FACTOR' specifies that the height of the
-    stretch should be FACTOR times the height of the characters having
-    the glyph property.
- 
-    Either none or exactly one of 4 or 5 must be present.
- 
-    6. `:ascent ASCENT'  specifies that ASCENT percent of the height
-    of the stretch should be used for the ascent of the stretch.
-    ASCENT must be in the range 0 <= ASCENT <= 100.  */
- 
- #define NUMVAL(X)                             \
-      ((INTEGERP (X) || FLOATP (X))            \
-       ? XFLOATINT (X)                         \
-       : - 1)
- 
- 
- static void
- x_produce_stretch_glyph (it)
-      struct it *it;
- {
-   /* (space :width WIDTH :height HEIGHT.  */
- #if GLYPH_DEBUG
-   extern Lisp_Object Qspace;
- #endif
-   extern Lisp_Object QCwidth, QCheight, QCascent;
-   extern Lisp_Object QCrelative_width, QCrelative_height;
-   extern Lisp_Object QCalign_to;
-   Lisp_Object prop, plist;
-   double width = 0, height = 0, ascent = 0;
-   struct face *face = FACE_FROM_ID (it->f, it->face_id);
-   XFontStruct *font = face->font ? face->font : FRAME_FONT (it->f);
- 
-   PREPARE_FACE_FOR_DISPLAY (it->f, face);
- 
-   /* List should start with `space'.  */
-   xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
-   plist = XCDR (it->object);
- 
-   /* Compute the width of the stretch.  */
-   if (prop = Fplist_get (plist, QCwidth),
-       NUMVAL (prop) > 0)
-     /* Absolute width `:width WIDTH' specified and valid.  */
-     width = NUMVAL (prop) * CANON_X_UNIT (it->f);
-   else if (prop = Fplist_get (plist, QCrelative_width),
-          NUMVAL (prop) > 0)
-     {
-       /* Relative width `:relative-width FACTOR' specified and valid.
-        Compute the width of the characters having the `glyph'
-        property.  */
-       struct it it2;
-       unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
- 
-       it2 = *it;
-       if (it->multibyte_p)
-       {
-         int maxlen = ((IT_BYTEPOS (*it) >= GPT ? ZV : GPT)
-                       - IT_BYTEPOS (*it));
-         it2.c = STRING_CHAR_AND_LENGTH (p, maxlen, it2.len);
-       }
-       else
-       it2.c = *p, it2.len = 1;
- 
-       it2.glyph_row = NULL;
-       it2.what = IT_CHARACTER;
-       x_produce_glyphs (&it2);
-       width = NUMVAL (prop) * it2.pixel_width;
-     }
-   else if (prop = Fplist_get (plist, QCalign_to),
-          NUMVAL (prop) > 0)
-     width = NUMVAL (prop) * CANON_X_UNIT (it->f) - it->current_x;
-   else
-     /* Nothing specified -> width defaults to canonical char width.  */
-     width = CANON_X_UNIT (it->f);
- 
-   /* Compute height.  */
-   if (prop = Fplist_get (plist, QCheight),
-       NUMVAL (prop) > 0)
-     height = NUMVAL (prop) * CANON_Y_UNIT (it->f);
-   else if (prop = Fplist_get (plist, QCrelative_height),
-          NUMVAL (prop) > 0)
-     height = FONT_HEIGHT (font) * NUMVAL (prop);
-   else
-     height = FONT_HEIGHT (font);
- 
-   /* Compute percentage of height used for ascent.  If
-      `:ascent ASCENT' is present and valid, use that.  Otherwise,
-      derive the ascent from the font in use.  */
-   if (prop = Fplist_get (plist, QCascent),
-       NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
-     ascent = NUMVAL (prop) / 100.0;
-   else
-     ascent = (double) FONT_BASE (font) / FONT_HEIGHT (font);
- 
-   if (width <= 0)
-     width = 1;
-   if (height <= 0)
-     height = 1;
- 
-   if (it->glyph_row)
-     {
-       Lisp_Object object = it->stack[it->sp - 1].string;
-       if (!STRINGP (object))
-       object = it->w->buffer;
-       x_append_stretch_glyph (it, object, width, height, ascent);
-     }
- 
-   it->pixel_width = width;
-   it->ascent = it->phys_ascent = height * ascent;
-   it->descent = it->phys_descent = height - it->ascent;
-   it->nglyphs = 1;
- 
-   if (face->box != FACE_NO_BOX)
-     {
-       if (face->box_line_width > 0)
-       {
-         it->ascent += face->box_line_width;
-         it->descent += face->box_line_width;
-       }
- 
-       if (it->start_of_box_run_p)
-       it->pixel_width += abs (face->box_line_width);
-       if (it->end_of_box_run_p)
-       it->pixel_width += abs (face->box_line_width);
-     }
- 
-   take_vertical_position_into_account (it);
- }
- 
- /* Return proper value to be used as baseline offset of font that has
-    ASCENT and DESCENT to draw characters by the font at the vertical
-    center of the line of frame F.
- 
-    Here, out task is to find the value of BOFF in the following figure;
- 
-       -------------------------+-----------+-
-        -+-+---------+-+        |           |
-         | |         | |        |           |
-         | |         | |        F_ASCENT    F_HEIGHT
-         | |         | ASCENT   |           |
-      HEIGHT |         | |        |           |
-         | |         |-|-+------+-----------|------- baseline
-         | |         | | BOFF   |           |
-         | |---------|-+-+      |           |
-         | |         | DESCENT  |           |
-        -+-+---------+-+        F_DESCENT   |
-       -------------------------+-----------+-
- 
-       -BOFF + DESCENT + (F_HEIGHT - HEIGHT) / 2 = F_DESCENT
-       BOFF = DESCENT +  (F_HEIGHT - HEIGHT) / 2 - F_DESCENT
-       DESCENT = FONT->descent
-       HEIGHT = FONT_HEIGHT (FONT)
-       F_DESCENT = (F->output_data.x->font->descent
-                    - F->output_data.x->baseline_offset)
-       F_HEIGHT = FRAME_LINE_HEIGHT (F)
- */
- 
- #define VCENTER_BASELINE_OFFSET(FONT, F)                      \
-   (FONT_DESCENT (FONT)                                                \
-    + (FRAME_LINE_HEIGHT ((F)) - FONT_HEIGHT ((FONT))          \
-       + (FRAME_LINE_HEIGHT ((F)) > FONT_HEIGHT ((FONT)))) / 2 \
-    - (FONT_DESCENT (FRAME_FONT (F)) - FRAME_BASELINE_OFFSET (F)))
- 
- /* Produce glyphs/get display metrics for the display element IT is
-    loaded with.  See the description of struct display_iterator in
-    dispextern.h for an overview of struct display_iterator.  */
- 
- static void
- x_produce_glyphs (it)
-      struct it *it;
- {
-   it->glyph_not_available_p = 0;
- 
-   if (it->what == IT_CHARACTER)
-     {
-       wchar_t char2b;
-       XFontStruct *font;
-       struct face *face = FACE_FROM_ID (it->f, it->face_id);
-       XCharStruct *pcm;
-       int font_not_found_p;
-       struct font_info *font_info;
-       int boff;                 /* baseline offset */
-       /* We may change it->multibyte_p upon unibyte<->multibyte
-        conversion.  So, save the current value now and restore it
-        later.
- 
-        Note: It seems that we don't have to record multibyte_p in
-        struct glyph because the character code itself tells if or
-        not the character is multibyte.  Thus, in the future, we must
-        consider eliminating the field `multibyte_p' in the struct
-        glyph.
-       */
-       int saved_multibyte_p = it->multibyte_p;
- 
-       /* Maybe translate single-byte characters to multibyte, or the
-          other way.  */
-       it->char_to_display = it->c;
-       if (!ASCII_BYTE_P (it->c))
-         {
-           if (unibyte_display_via_language_environment
-               && SINGLE_BYTE_CHAR_P (it->c)
-               && (it->c >= 0240
-                   || !NILP (Vnonascii_translation_table)))
-             {
-               it->char_to_display = unibyte_char_to_multibyte (it->c);
-               it->multibyte_p = 1;
-             it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
-             face = FACE_FROM_ID (it->f, it->face_id);
-           }
-         else if (!SINGLE_BYTE_CHAR_P (it->c)
-                  && !it->multibyte_p)
-           {
-               it->multibyte_p = 1;
-             it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
-             face = FACE_FROM_ID (it->f, it->face_id);
-           }
-         }
- 
-       /* Get font to use.  Encode IT->char_to_display.  */
-       x_get_char_face_and_encoding (it->f, it->char_to_display,
-                                     it->face_id, &char2b,
-                                     it->multibyte_p);
-       font = face->font;
- 
-       /* When no suitable font found, use the default font.  */
-       font_not_found_p = font == NULL;
-       if (font_not_found_p)
-         {
-           font = FRAME_FONT (it->f);
-         boff = it->f->output_data.w32->baseline_offset;
-         font_info = NULL;
-       }
-       else
-       {
-         font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
-         boff = font_info->baseline_offset;
-         if (font_info->vertical_centering)
-           boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
-       }
- 
-       if (it->char_to_display >= ' '
-         && (!it->multibyte_p || it->char_to_display < 128))
-       {
-         /* Either unibyte or ASCII.  */
-         int stretched_p;
- 
-         it->nglyphs = 1;
- 
-           pcm = w32_per_char_metric (font, &char2b,
-                                      font->bdf ? BDF_1D_FONT : ANSI_FONT);
-         it->ascent = FONT_BASE (font) + boff;
-         it->descent = FONT_DESCENT (font) - boff;
- 
-           if (pcm)
-             {
-               it->phys_ascent = pcm->ascent + boff;
-               it->phys_descent = pcm->descent - boff;
-               it->pixel_width = pcm->width;
-             }
-           else
-             {
-               it->glyph_not_available_p = 1;
-               it->phys_ascent = FONT_BASE (font) + boff;
-               it->phys_descent = FONT_DESCENT (font) - boff;
-               it->pixel_width = FONT_WIDTH (font);
-             }
- 
-         /* If this is a space inside a region of text with
-            `space-width' property, change its width.  */
-         stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
-         if (stretched_p)
-           it->pixel_width *= XFLOATINT (it->space_width);
- 
-         /* If face has a box, add the box thickness to the character
-            height.  If character has a box line to the left and/or
-            right, add the box line width to the character's width.  */
-         if (face->box != FACE_NO_BOX)
-           {
-             int thick = face->box_line_width;
- 
-             if (thick > 0)
-               {
-                 it->ascent += thick;
-                 it->descent += thick;
-               }
-             else
-               thick = -thick;
- 
-             if (it->start_of_box_run_p)
-               it->pixel_width += thick;
-             if (it->end_of_box_run_p)
-               it->pixel_width += thick;
-           }
- 
-         /* If face has an overline, add the height of the overline
-            (1 pixel) and a 1 pixel margin to the character height.  */
-         if (face->overline_p)
-           it->ascent += 2;
- 
-         take_vertical_position_into_account (it);
- 
-         /* If we have to actually produce glyphs, do it.  */
-         if (it->glyph_row)
-           {
-             if (stretched_p)
-               {
-                 /* Translate a space with a `space-width' property
-                    into a stretch glyph.  */
-                 double ascent = (double) FONT_BASE (font)
-                                 / FONT_HEIGHT (font);
-                 x_append_stretch_glyph (it, it->object, it->pixel_width,
-                                         it->ascent + it->descent, ascent);
-               }
-             else
-               x_append_glyph (it);
- 
-             /* If characters with lbearing or rbearing are displayed
-                in this line, record that fact in a flag of the
-                glyph row.  This is used to optimize X output code.  */
-             if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
-               it->glyph_row->contains_overlapping_glyphs_p = 1;
-           }
-       }
-       else if (it->char_to_display == '\n')
-       {
-         /* A newline has no width but we need the height of the line.  */
-         it->pixel_width = 0;
-         it->nglyphs = 0;
-         it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
-         it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
- 
-         if (face->box != FACE_NO_BOX
-             && face->box_line_width > 0)
-           {
-             it->ascent += face->box_line_width;
-             it->descent += face->box_line_width;
-           }
-       }
-       else if (it->char_to_display == '\t')
-       {
-         int tab_width = it->tab_width * CANON_X_UNIT (it->f);
-         int x = it->current_x + it->continuation_lines_width;
-         int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
- 
-         /* If the distance from the current position to the next tab
-            stop is less than a canonical character width, use the
-            tab stop after that.  */
-         if (next_tab_x - x < CANON_X_UNIT (it->f))
-           next_tab_x += tab_width;
- 
-         it->pixel_width = next_tab_x - x;
-         it->nglyphs = 1;
-         it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
-         it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
- 
-         if (it->glyph_row)
-           {
-             double ascent = (double) it->ascent / (it->ascent + it->descent);
-             x_append_stretch_glyph (it, it->object, it->pixel_width,
-                                     it->ascent + it->descent, ascent);
-           }
-       }
-       else
-       {
-         /* A multi-byte character.
-              If we found a font, this font should give us the right
-              metrics.  If we didn't find a font, use the frame's
-              default font and calculate the width of the character
-              from the charset width; this is what old redisplay code
-              did.  */
-           enum w32_char_font_type type;
- 
-           if (font->bdf && CHARSET_DIMENSION (CHAR_CHARSET (it->c)) == 1)
-             type = BDF_1D_FONT;
-           else if (font->bdf)
-             type = BDF_2D_FONT;
-           else
-             type = UNICODE_FONT;
- 
-           pcm = w32_per_char_metric (font, &char2b, type);
- 
-         if (font_not_found_p || !pcm)
-           {
-             int charset = CHAR_CHARSET (it->char_to_display);
- 
-             it->glyph_not_available_p = 1;
-             it->pixel_width = (FONT_WIDTH (FRAME_FONT (it->f))
-                                * CHARSET_WIDTH (charset));
-             it->phys_ascent = FONT_BASE (font) + boff;
-             it->phys_descent = FONT_DESCENT (font) - boff;
-           }
-         else
-           {
-             it->pixel_width = pcm->width;
-               it->phys_ascent = pcm->ascent + boff;
-               it->phys_descent = pcm->descent - boff;
-               if (it->glyph_row
-                   && (pcm->lbearing < 0
-                       || pcm->rbearing > pcm->width))
-                 it->glyph_row->contains_overlapping_glyphs_p = 1;
-             }
-           it->nglyphs = 1;
-           it->ascent = FONT_BASE (font) + boff;
-           it->descent = FONT_DESCENT (font) - boff;
-         if (face->box != FACE_NO_BOX)
-           {
-             int thick = face->box_line_width;
- 
-             if (thick > 0)
-               {
-                 it->ascent += thick;
-                 it->descent += thick;
-               }
-             else
-               thick = - thick;
- 
-             if (it->start_of_box_run_p)
-               it->pixel_width += thick;
-             if (it->end_of_box_run_p)
-               it->pixel_width += thick;
-           }
- 
-         /* If face has an overline, add the height of the overline
-            (1 pixel) and a 1 pixel margin to the character height.  */
-         if (face->overline_p)
-           it->ascent += 2;
- 
-         take_vertical_position_into_account (it);
- 
-         if (it->glyph_row)
-           x_append_glyph (it);
-       }
-       it->multibyte_p = saved_multibyte_p;
-     }
-   else if (it->what == IT_COMPOSITION)
-     {
-       /* Note: A composition is represented as one glyph in the
-        glyph matrix.  There are no padding glyphs.  */
-       wchar_t char2b;
-       XFontStruct *font;
-       struct face *face = FACE_FROM_ID (it->f, it->face_id);
-       XCharStruct *pcm;
-       int font_not_found_p;
-       struct font_info *font_info;
-       int boff;                       /* baseline offset */
-       struct composition *cmp = composition_table[it->cmp_id];
- 
-       /* Maybe translate single-byte characters to multibyte.  */
-       it->char_to_display = it->c;
-       if (unibyte_display_via_language_environment
-         && SINGLE_BYTE_CHAR_P (it->c)
-         && (it->c >= 0240
-             || (it->c >= 0200
-                 && !NILP (Vnonascii_translation_table))))
-       {
-         it->char_to_display = unibyte_char_to_multibyte (it->c);
-       }
- 
-       /* Get face and font to use.  Encode IT->char_to_display.  */
-       it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
-       face = FACE_FROM_ID (it->f, it->face_id);
-       x_get_char_face_and_encoding (it->f, it->char_to_display,
-                                   it->face_id, &char2b, it->multibyte_p);
-       font = face->font;
- 
-       /* When no suitable font found, use the default font.  */
-       font_not_found_p = font == NULL;
-       if (font_not_found_p)
-       {
-         font = FRAME_FONT (it->f);
-         boff = it->f->output_data.w32->baseline_offset;
-         font_info = NULL;
-       }
-       else
-       {
-         font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
-         boff = font_info->baseline_offset;
-         if (font_info->vertical_centering)
-           boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
-       }
- 
-       /* There are no padding glyphs, so there is only one glyph to
-        produce for the composition.  Important is that pixel_width,
-        ascent and descent are the values of what is drawn by
-        draw_glyphs (i.e. the values of the overall glyphs composed).  */
-       it->nglyphs = 1;
- 
-       /* If we have not yet calculated pixel size data of glyphs of
-        the composition for the current face font, calculate them
-        now.  Theoretically, we have to check all fonts for the
-        glyphs, but that requires much time and memory space.  So,
-        here we check only the font of the first glyph.  This leads
-        to incorrect display very rarely, and C-l (recenter) can
-        correct the display anyway.  */
-       if (cmp->font != (void *) font)
-       {
-         /* Ascent and descent of the font of the first character of
-            this composition (adjusted by baseline offset).  Ascent
-            and descent of overall glyphs should not be less than
-            them respectively.  */
-         int font_ascent = FONT_BASE (font) + boff;
-         int font_descent = FONT_DESCENT (font) - boff;
-         /* Bounding box of the overall glyphs.  */
-         int leftmost, rightmost, lowest, highest;
-         int i, width, ascent, descent;
-           enum w32_char_font_type font_type;
- 
-         cmp->font = (void *) font;
- 
-           if (font->bdf && CHARSET_DIMENSION (CHAR_CHARSET (it->c)) == 1)
-             font_type = BDF_1D_FONT;
-           else if (font->bdf)
-             font_type = BDF_2D_FONT;
-           else
-             font_type = UNICODE_FONT;
- 
-         /* Initialize the bounding box.  */
-         if (font_info
-               && (pcm = w32_per_char_metric (font, &char2b, font_type)))
-           {
-             width = pcm->width;
-             ascent = pcm->ascent;
-             descent = pcm->descent;
-           }
-         else
-           {
-             width = FONT_WIDTH (font);
-             ascent = FONT_BASE (font);
-             descent = FONT_DESCENT (font);
-           }
- 
-         rightmost = width;
-         lowest = - descent + boff;
-         highest = ascent + boff;
-         leftmost = 0;
- 
-         if (font_info
-             && font_info->default_ascent
-             && CHAR_TABLE_P (Vuse_default_ascent)
-             && !NILP (Faref (Vuse_default_ascent,
-                              make_number (it->char_to_display))))
-           highest = font_info->default_ascent + boff;
- 
-         /* Draw the first glyph at the normal position.  It may be
-            shifted to right later if some other glyphs are drawn at
-            the left.  */
-         cmp->offsets[0] = 0;
-         cmp->offsets[1] = boff;
- 
-         /* Set cmp->offsets for the remaining glyphs.  */
-         for (i = 1; i < cmp->glyph_len; i++)
-           {
-             int left, right, btm, top;
-             int ch = COMPOSITION_GLYPH (cmp, i);
-             int face_id = FACE_FOR_CHAR (it->f, face, ch);
- 
-             face = FACE_FROM_ID (it->f, face_id);
-             x_get_char_face_and_encoding (it->f, ch, face->id, &char2b,
-                                           it->multibyte_p);
-             font = face->font;
-             if (font == NULL)
-               {
-                 font = FRAME_FONT (it->f);
-                 boff = it->f->output_data.w32->baseline_offset;
-                 font_info = NULL;
-               }
-             else
-               {
-                 font_info
-                   = FONT_INFO_FROM_ID (it->f, face->font_info_id);
-                 boff = font_info->baseline_offset;
-                 if (font_info->vertical_centering)
-                   boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
-               }
- 
-               if (font->bdf && CHARSET_DIMENSION (CHAR_CHARSET (ch)) == 1)
-                 font_type = BDF_1D_FONT;
-               else if (font->bdf)
-                 font_type = BDF_2D_FONT;
-               else
-                 font_type = UNICODE_FONT;
- 
-             if (font_info
-                   && (pcm = w32_per_char_metric (font, &char2b, font_type)))
-               {
-                 width = pcm->width;
-                 ascent = pcm->ascent;
-                 descent = pcm->descent;
-               }
-             else
-               {
-                 width = FONT_WIDTH (font);
-                 ascent = 1;
-                 descent = 0;
-               }
- 
-             if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
-               {
-                 /* Relative composition with or without
-                    alternate chars.  */
-                 left = (leftmost + rightmost - width) / 2;
-                 btm = - descent + boff;
-                 if (font_info && font_info->relative_compose
-                     && (! CHAR_TABLE_P (Vignore_relative_composition)
-                         || NILP (Faref (Vignore_relative_composition,
-                                         make_number (ch)))))
-                   {
- 
-                     if (- descent >= font_info->relative_compose)
-                       /* One extra pixel between two glyphs.  */
-                       btm = highest + 1;
-                     else if (ascent <= 0)
-                       /* One extra pixel between two glyphs.  */
-                       btm = lowest - 1 - ascent - descent;
-                   }
-               }
-             else
-               {
-                 /* A composition rule is specified by an integer
-                    value that encodes global and new reference
-                    points (GREF and NREF).  GREF and NREF are
-                    specified by numbers as below:
- 
-                       0---1---2 -- ascent
-                       |       |
-                       |       |
-                       |       |
-                       9--10--11 -- center
-                       |       |
-                    ---3---4---5--- baseline
-                       |       |
-                       6---7---8 -- descent
-                 */
-                 int rule = COMPOSITION_RULE (cmp, i);
-                 int gref, nref, grefx, grefy, nrefx, nrefy;
- 
-                 COMPOSITION_DECODE_RULE (rule, gref, nref);
-                 grefx = gref % 3, nrefx = nref % 3;
-                 grefy = gref / 3, nrefy = nref / 3;
- 
-                 left = (leftmost
-                         + grefx * (rightmost - leftmost) / 2
-                         - nrefx * width / 2);
-                 btm = ((grefy == 0 ? highest
-                         : grefy == 1 ? 0
-                         : grefy == 2 ? lowest
-                         : (highest + lowest) / 2)
-                        - (nrefy == 0 ? ascent + descent
-                           : nrefy == 1 ? descent - boff
-                           : nrefy == 2 ? 0
-                           : (ascent + descent) / 2));
-               }
- 
-             cmp->offsets[i * 2] = left;
-             cmp->offsets[i * 2 + 1] = btm + descent;
- 
-             /* Update the bounding box of the overall glyphs. */
-             right = left + width;
-             top = btm + descent + ascent;
-             if (left < leftmost)
-               leftmost = left;
-             if (right > rightmost)
-               rightmost = right;
-             if (top > highest)
-               highest = top;
-             if (btm < lowest)
-               lowest = btm;
-           }
- 
-         /* If there are glyphs whose x-offsets are negative,
-            shift all glyphs to the right and make all x-offsets
-            non-negative.  */
-         if (leftmost < 0)
-           {
-             for (i = 0; i < cmp->glyph_len; i++)
-               cmp->offsets[i * 2] -= leftmost;
-             rightmost -= leftmost;
-           }
- 
-         cmp->pixel_width = rightmost;
-         cmp->ascent = highest;
-         cmp->descent = - lowest;
-         if (cmp->ascent < font_ascent)
-           cmp->ascent = font_ascent;
-         if (cmp->descent < font_descent)
-           cmp->descent = font_descent;
-       }
- 
-       it->pixel_width = cmp->pixel_width;
-       it->ascent = it->phys_ascent = cmp->ascent;
-       it->descent = it->phys_descent = cmp->descent;
- 
-       if (face->box != FACE_NO_BOX)
-       {
-         int thick = face->box_line_width;
- 
-         if (thick > 0)
-           {
-             it->ascent += thick;
-             it->descent += thick;
-           }
-         else
-           thick = - thick;
- 
-         if (it->start_of_box_run_p)
-           it->pixel_width += thick;
-         if (it->end_of_box_run_p)
-           it->pixel_width += thick;
-       }
- 
-       /* If face has an overline, add the height of the overline
-        (1 pixel) and a 1 pixel margin to the character height.  */
-       if (face->overline_p)
-       it->ascent += 2;
- 
-       take_vertical_position_into_account (it);
- 
-       if (it->glyph_row)
-       x_append_composite_glyph (it);
-     }
-   else if (it->what == IT_IMAGE)
-     x_produce_image_glyph (it);
-   else if (it->what == IT_STRETCH)
-     x_produce_stretch_glyph (it);
- 
-   /* Accumulate dimensions.  Note: can't assume that it->descent > 0
-      because this isn't true for images with `:ascent 100'.  */
-   xassert (it->ascent >= 0 && it->descent >= 0);
-   if (it->area == TEXT_AREA)
-     it->current_x += it->pixel_width;
- 
-   it->descent += it->extra_line_spacing;
- 
-   it->max_ascent = max (it->max_ascent, it->ascent);
-   it->max_descent = max (it->max_descent, it->descent);
-   it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
-   it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
- }
- 
- 
  /* Estimate the pixel height of the mode or top line on frame F.
     FACE_ID specifies what line's height to estimate.  */
  
--- 1229,1234 ----
***************
*** 2387,2509 ****
                            Glyph display
   ***********************************************************************/
  
- /* A sequence of glyphs to be drawn in the same face.
- 
-    This data structure is not really completely X specific, so it
-    could possibly, at least partially, be useful for other systems.  It
-    is currently not part of the external redisplay interface because
-    it's not clear what other systems will need.  */
- 
- struct glyph_string
- {
-   /* X-origin of the string.  */
-   int x;
- 
-   /* Y-origin and y-position of the base line of this string.  */
-   int y, ybase;
- 
-   /* The width of the string, not including a face extension.  */
-   int width;
- 
-   /* The width of the string, including a face extension.  */
-   int background_width;
- 
-   /* The height of this string.  This is the height of the line this
-      string is drawn in, and can be different from the height of the
-      font the string is drawn in.  */
-   int height;
- 
-   /* Number of pixels this string overwrites in front of its x-origin.
-      This number is zero if the string has an lbearing >= 0; it is
-      -lbearing, if the string has an lbearing < 0.  */
-   int left_overhang;
- 
-   /* Number of pixels this string overwrites past its right-most
-      nominal x-position, i.e. x + width.  Zero if the string's
-      rbearing is <= its nominal width, rbearing - width otherwise.  */
-   int right_overhang;
- 
-   /* The frame on which the glyph string is drawn.  */
-   struct frame *f;
- 
-   /* The window on which the glyph string is drawn.  */
-   struct window *w;
- 
-   /* X display and window for convenience.  */
-   Window window;
- 
-   /* The glyph row for which this string was built.  It determines the
-      y-origin and height of the string.  */
-   struct glyph_row *row;
- 
-   /* The area within row.  */
-   enum glyph_row_area area;
- 
-   /* Characters to be drawn, and number of characters.  */
-   wchar_t *char2b;
-   int nchars;
- 
-   /* A face-override for drawing cursors, mouse face and similar.  */
-   enum draw_glyphs_face hl;
- 
-   /* Face in which this string is to be drawn.  */
-   struct face *face;
- 
-   /* Font in which this string is to be drawn.  */
-   XFontStruct *font;
- 
-   /* Font info for this string.  */
-   struct font_info *font_info;
- 
-   /* Non-null means this string describes (part of) a composition.
-      All characters from char2b are drawn composed.  */
-   struct composition *cmp;
- 
-   /* Index of this glyph string's first character in the glyph
-      definition of CMP.  If this is zero, this glyph string describes
-      the first character of a composition.  */
-   int gidx;
- 
-   /* 1 means this glyph strings face has to be drawn to the right end
-      of the window's drawing area.  */
-   unsigned extends_to_end_of_line_p : 1;
- 
-   /* 1 means the background of this string has been drawn.  */
-   unsigned background_filled_p : 1;
- 
-   /* 1 means glyph string must be drawn with 16-bit functions.  */
-   unsigned two_byte_p : 1;
- 
-   /* 1 means that the original font determined for drawing this glyph
-      string could not be loaded.  The member `font' has been set to
-      the frame's default font in this case.  */
-   unsigned font_not_found_p : 1;
- 
-   /* 1 means that the face in which this glyph string is drawn has a
-      stipple pattern.  */
-   unsigned stippled_p : 1;
- 
-   /* 1 means only the foreground of this glyph string must be drawn,
-      and we should use the physical height of the line this glyph
-      string appears in as clip rect.  */
-   unsigned for_overlaps_p : 1;
- 
-   /* The GC to use for drawing this glyph string.  */
-   XGCValues *gc;
- 
-   HDC hdc;
- 
-   /* A pointer to the first glyph in the string.  This glyph
-      corresponds to char2b[0].  Needed to draw rectangles if
-      font_not_found_p is 1.  */
-   struct glyph *first_glyph;
- 
-   /* Image, if any.  */
-   struct image *img;
- 
-   struct glyph_string *next, *prev;
- };
- 
  
  /* Encapsulate the different ways of displaying text under W32.  */
  
--- 1261,1266 ----
***************
*** 2519,2580 ****
      w32_BDF_TextOut (s->gc->font->bdf, s->hdc,
                       x, y, (char *) chars, charset_dim,
                       nchars * charset_dim, 0);
!   else if (s->first_glyph->w32_font_type == UNICODE_FONT)
      ExtTextOutW (s->hdc, x, y, 0, NULL, chars, nchars, NULL);
    else
      ExtTextOutA (s->hdc, x, y, 0, NULL, (char *) chars,
                 nchars * charset_dim, NULL);
! }
! 
! #if GLYPH_DEBUG
! 
! static void
! x_dump_glyph_string (s)
!      struct glyph_string *s;
! {
!   fprintf (stderr, "glyph string\n");
!   fprintf (stderr, "  x, y, w, h = %d, %d, %d, %d\n",
!          s->x, s->y, s->width, s->height);
!   fprintf (stderr, "  ybase = %d\n", s->ybase);
!   fprintf (stderr, "  hl = %d\n", s->hl);
!   fprintf (stderr, "  left overhang = %d, right = %d\n",
!          s->left_overhang, s->right_overhang);
!   fprintf (stderr, "  nchars = %d\n", s->nchars);
!   fprintf (stderr, "  extends to end of line = %d\n",
!          s->extends_to_end_of_line_p);
!   fprintf (stderr, "  font height = %d\n", FONT_HEIGHT (s->font));
!   fprintf (stderr, "  bg width = %d\n", s->background_width);
! }
! 
! #endif /* GLYPH_DEBUG */
  
  
  
- static void x_append_glyph_string_lists P_ ((struct glyph_string **,
-                                            struct glyph_string **,
-                                            struct glyph_string *,
-                                            struct glyph_string *));
- static void x_prepend_glyph_string_lists P_ ((struct glyph_string **,
-                                             struct glyph_string **,
-                                             struct glyph_string *,
-                                             struct glyph_string *));
- static void x_append_glyph_string P_ ((struct glyph_string **,
-                                      struct glyph_string **,
-                                      struct glyph_string *));
- static int x_left_overwritten P_ ((struct glyph_string *));
- static int x_left_overwriting P_ ((struct glyph_string *));
- static int x_right_overwritten P_ ((struct glyph_string *));
- static int x_right_overwriting P_ ((struct glyph_string *));
- static int x_fill_glyph_string P_ ((struct glyph_string *, int, int, int,
-                                     int));
- static void w32_init_glyph_string P_ ((struct glyph_string *, HDC hdc,
-                                        wchar_t *, struct window *,
-                                        struct glyph_row *,
-                                        enum glyph_row_area, int,
-                                        enum draw_glyphs_face));
- static int x_draw_glyphs P_ ((struct window *, int , struct glyph_row *,
-                             enum glyph_row_area, int, int,
-                             enum draw_glyphs_face, int));
  static void x_set_glyph_string_clipping P_ ((struct glyph_string *));
  static void x_set_glyph_string_gc P_ ((struct glyph_string *));
  static void x_draw_glyph_string_background P_ ((struct glyph_string *,
--- 1276,1290 ----
      w32_BDF_TextOut (s->gc->font->bdf, s->hdc,
                       x, y, (char *) chars, charset_dim,
                       nchars * charset_dim, 0);
!   else if (s->first_glyph->font_type == UNICODE_FONT)
      ExtTextOutW (s->hdc, x, y, 0, NULL, chars, nchars, NULL);
    else
      ExtTextOutA (s->hdc, x, y, 0, NULL, (char *) chars,
                 nchars * charset_dim, NULL);
! }
  
  
  
  static void x_set_glyph_string_clipping P_ ((struct glyph_string *));
  static void x_set_glyph_string_gc P_ ((struct glyph_string *));
  static void x_draw_glyph_string_background P_ ((struct glyph_string *,
***************
*** 2583,2596 ****
  static void x_draw_composite_glyph_string_foreground P_ ((struct glyph_string 
*));
  static void x_draw_glyph_string_box P_ ((struct glyph_string *));
  static void x_draw_glyph_string  P_ ((struct glyph_string *));
- static void x_compute_glyph_string_overhangs P_ ((struct glyph_string *));
  static void x_set_cursor_gc P_ ((struct glyph_string *));
  static void x_set_mode_line_face_gc P_ ((struct glyph_string *));
  static void x_set_mouse_face_gc P_ ((struct glyph_string *));
- static void w32_get_glyph_overhangs P_ ((HDC hdc, struct glyph *,
-                                          struct frame *,
-                                          int *, int *));
- static void x_compute_overhangs_and_x P_ ((struct glyph_string *, int, int));
  static int w32_alloc_lighter_color (struct frame *, COLORREF *, double, int);
  static void w32_setup_relief_color P_ ((struct frame *, struct relief *,
                                          double, int, COLORREF));
--- 1293,1301 ----
***************
*** 2599,2605 ****
  static void x_draw_image_relief P_ ((struct glyph_string *));
  static void x_draw_image_foreground P_ ((struct glyph_string *));
  static void w32_draw_image_foreground_1 P_ ((struct glyph_string *, HBITMAP));
- static void x_fill_image_glyph_string P_ ((struct glyph_string *));
  static void x_clear_glyph_string_rect P_ ((struct glyph_string *, int,
                                           int, int, int));
  static void w32_draw_relief_rect P_ ((struct frame *, int, int, int, int,
--- 1304,1309 ----
***************
*** 2608,2676 ****
                                 int, int, int, RECT *));
  static void x_fix_overlapping_area P_ ((struct window *, struct glyph_row *,
                                        enum glyph_row_area));
- static int x_fill_stretch_glyph_string P_ ((struct glyph_string *,
-                                           struct glyph_row *,
-                                           enum glyph_row_area, int, int));
  
  #if GLYPH_DEBUG
  static void x_check_font P_ ((struct frame *, XFontStruct *));
  #endif
  
  
- /* Append the list of glyph strings with head H and tail T to the list
-    with head *HEAD and tail *TAIL.  Set *HEAD and *TAIL to the result.  */
- 
- static INLINE void
- x_append_glyph_string_lists (head, tail, h, t)
-      struct glyph_string **head, **tail;
-      struct glyph_string *h, *t;
- {
-   if (h)
-     {
-       if (*head)
-       (*tail)->next = h;
-       else
-       *head = h;
-       h->prev = *tail;
-       *tail = t;
-     }
- }
- 
- 
- /* Prepend the list of glyph strings with head H and tail T to the
-    list with head *HEAD and tail *TAIL.  Set *HEAD and *TAIL to the
-    result.  */
- 
- static INLINE void
- x_prepend_glyph_string_lists (head, tail, h, t)
-      struct glyph_string **head, **tail;
-      struct glyph_string *h, *t;
- {
-   if (h)
-     {
-       if (*head)
-       (*head)->prev = t;
-       else
-       *tail = t;
-       t->next = *head;
-       *head = h;
-     }
- }
- 
- 
- /* Append glyph string S to the list with head *HEAD and tail *TAIL.
-    Set *HEAD and *TAIL to the resulting list.  */
- 
- static INLINE void
- x_append_glyph_string (head, tail, s)
-      struct glyph_string **head, **tail;
-      struct glyph_string *s;
- {
-   s->next = s->prev = NULL;
-   x_append_glyph_string_lists (head, tail, s, s);
- }
- 
- 
  /* Set S->gc to a suitable GC for drawing glyph string S in cursor
     face.  */
  
--- 1312,1323 ----
***************
*** 2933,2943 ****
  }
  
  
! /* Compute left and right overhang of glyph string S.  If S is a glyph
     string for a composition, assume overhangs don't exist.  */
  
! static INLINE void
! x_compute_glyph_string_overhangs (s)
       struct glyph_string *s;
  {
    /* TODO: Windows does not appear to have a method for
--- 1580,1591 ----
  }
  
  
! /* RIF:
!    Compute left and right overhang of glyph string S.  If S is a glyph
     string for a composition, assume overhangs don't exist.  */
  
! static void
! w32_compute_glyph_string_overhangs (s)
       struct glyph_string *s;
  {
    /* TODO: Windows does not appear to have a method for
***************
*** 2946,3143 ****
  }
  
  
- /* Compute overhangs and x-positions for glyph string S and its
-    predecessors, or successors.  X is the starting x-position for S.
-    BACKWARD_P non-zero means process predecessors.  */
- 
- static void
- x_compute_overhangs_and_x (s, x, backward_p)
-      struct glyph_string *s;
-      int x;
-      int backward_p;
- {
-   if (backward_p)
-     {
-       while (s)
-       {
-         x_compute_glyph_string_overhangs (s);
-         x -= s->width;
-         s->x = x;
-         s = s->prev;
-       }
-     }
-   else
-     {
-       while (s)
-       {
-         x_compute_glyph_string_overhangs (s);
-         s->x = x;
-         x += s->width;
-         s = s->next;
-       }
-     }
- }
- 
- 
- /* Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
-    frame F.  Overhangs of glyphs other than type CHAR_GLYPH are
-    assumed to be zero.  */
- 
- static void
- w32_get_glyph_overhangs (hdc, glyph, f, left, right)
-      HDC hdc;
-      struct glyph *glyph;
-      struct frame *f;
-      int *left, *right;
- {
-   *left = *right = 0;
- 
-   if (glyph->type == CHAR_GLYPH)
-     {
-       XFontStruct *font;
-       struct face *face;
-       wchar_t char2b;
-       XCharStruct *pcm;
- 
-       face = x_get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
-       font = face->font;
- 
-       if (font
-           && (pcm = w32_per_char_metric (font, &char2b,
-                                          glyph->w32_font_type)))
-       {
-         if (pcm->rbearing > pcm->width)
-           *right = pcm->rbearing - pcm->width;
-         if (pcm->lbearing < 0)
-           *left = -pcm->lbearing;
-       }
-     }
- }
- 
- 
  static void
! x_get_glyph_overhangs (glyph, f, left, right)
       struct glyph *glyph;
       struct frame *f;
       int *left, *right;
  {
    HDC hdc = get_frame_dc (f);
    /* Convert to unicode! */
!   w32_get_glyph_overhangs (hdc, glyph, f, left, right);
    release_frame_dc (f, hdc);
  }
  
  
- /* Return the index of the first glyph preceding glyph string S that
-    is overwritten by S because of S's left overhang.  Value is -1
-    if no glyphs are overwritten.  */
- 
- static int
- x_left_overwritten (s)
-      struct glyph_string *s;
- {
-   int k;
- 
-   if (s->left_overhang)
-     {
-       int x = 0, i;
-       struct glyph *glyphs = s->row->glyphs[s->area];
-       int first = s->first_glyph - glyphs;
- 
-       for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
-       x -= glyphs[i].pixel_width;
- 
-       k = i + 1;
-     }
-   else
-     k = -1;
- 
-   return k;
- }
- 
- 
- /* Return the index of the first glyph preceding glyph string S that
-    is overwriting S because of its right overhang.  Value is -1 if no
-    glyph in front of S overwrites S.  */
- 
- static int
- x_left_overwriting (s)
-      struct glyph_string *s;
- {
-   int i, k, x;
-   struct glyph *glyphs = s->row->glyphs[s->area];
-   int first = s->first_glyph - glyphs;
- 
-   k = -1;
-   x = 0;
-   for (i = first - 1; i >= 0; --i)
-     {
-       int left, right;
-       w32_get_glyph_overhangs (s->hdc, glyphs + i, s->f, &left, &right);
-       if (x + right > 0)
-       k = i;
-       x -= glyphs[i].pixel_width;
-     }
- 
-   return k;
- }
- 
- 
- /* Return the index of the last glyph following glyph string S that is
-    not overwritten by S because of S's right overhang.  Value is -1 if
-    no such glyph is found.  */
- 
- static int
- x_right_overwritten (s)
-      struct glyph_string *s;
- {
-   int k = -1;
- 
-   if (s->right_overhang)
-     {
-       int x = 0, i;
-       struct glyph *glyphs = s->row->glyphs[s->area];
-       int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
-       int end = s->row->used[s->area];
- 
-       for (i = first; i < end && s->right_overhang > x; ++i)
-       x += glyphs[i].pixel_width;
- 
-       k = i;
-     }
- 
-   return k;
- }
- 
- 
- /* Return the index of the last glyph following glyph string S that
-    overwrites S because of its left overhang.  Value is negative
-    if no such glyph is found.  */
- 
- static int
- x_right_overwriting (s)
-      struct glyph_string *s;
- {
-   int i, k, x;
-   int end = s->row->used[s->area];
-   struct glyph *glyphs = s->row->glyphs[s->area];
-   int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
- 
-   k = -1;
-   x = 0;
-   for (i = first; i < end; ++i)
-     {
-       int left, right;
-       w32_get_glyph_overhangs (s->hdc, glyphs + i, s->f, &left, &right);
-       if (x - left < 0)
-       k = i;
-       x += glyphs[i].pixel_width;
-     }
- 
-   return k;
- }
- 
- 
  /* Fill rectangle X, Y, W, H with background color of glyph string S.  */
  
  static INLINE void
--- 1594,1612 ----
  }
  
  
  static void
! w32_get_glyph_overhangs (glyph, f, left, right)
       struct glyph *glyph;
       struct frame *f;
       int *left, *right;
  {
    HDC hdc = get_frame_dc (f);
    /* Convert to unicode! */
!   x_get_glyph_overhangs (glyph, f, left, right);
    release_frame_dc (f, hdc);
  }
  
  
  /* Fill rectangle X, Y, W, H with background color of glyph string S.  */
  
  static INLINE void
***************
*** 3265,3271 ****
        /* If we can use 8-bit functions, condense S->char2b.  */
        if (!s->two_byte_p)
          for (i = 0; i < s->nchars; ++i)
!           char1b[i] = BYTE2 (s->char2b[i]);
  
        /* Draw text with TextOut and friends. */
        w32_text_out (s, x, s->ybase - boff, s->char2b, s->nchars);
--- 1734,1740 ----
        /* If we can use 8-bit functions, condense S->char2b.  */
        if (!s->two_byte_p)
          for (i = 0; i < s->nchars; ++i)
!           char1b[i] = XCHAR2B_BYTE2 (&s->char2b[i]);
  
        /* Draw text with TextOut and friends. */
        w32_text_out (s, x, s->ybase - boff, s->char2b, s->nchars);
***************
*** 4227,4889 ****
  }
  
  
- static int x_fill_composite_glyph_string P_ ((struct glyph_string *,
-                                             struct face **, int));
- 
- 
- /* Fill glyph string S with composition components specified by S->cmp.
- 
-    FACES is an array of faces for all components of this composition.
-    S->gidx is the index of the first component for S.
-    OVERLAPS_P non-zero means S should draw the foreground only, and
-    use its physical height for clipping.
- 
-    Value is the index of a component not in S.  */
- 
- static int
- x_fill_composite_glyph_string (s, faces, overlaps_p)
-      struct glyph_string *s;
-      struct face **faces;
-      int overlaps_p;
- {
-   int i;
- 
-   xassert (s);
- 
-   s->for_overlaps_p = overlaps_p;
- 
-   s->face = faces[s->gidx];
-   s->font = s->face->font;
-   s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
- 
-   /* For all glyphs of this composition, starting at the offset
-      S->gidx, until we reach the end of the definition or encounter a
-      glyph that requires the different face, add it to S.  */
-   ++s->nchars;
-   for (i = s->gidx + 1; i < s->cmp->glyph_len && faces[i] == s->face; ++i)
-     ++s->nchars;
- 
-   /* All glyph strings for the same composition has the same width,
-      i.e. the width set for the first component of the composition.  */
- 
-   s->width = s->first_glyph->pixel_width;
- 
-   /* If the specified font could not be loaded, use the frame's
-      default font, but record the fact that we couldn't load it in
-      the glyph string so that we can draw rectangles for the
-      characters of the glyph string.  */
-   if (s->font == NULL)
-     {
-       s->font_not_found_p = 1;
-       s->font = FRAME_FONT (s->f);
-     }
- 
-   /* Adjust base line for subscript/superscript text.  */
-   s->ybase += s->first_glyph->voffset;
- 
-   xassert (s->face && s->face->gc);
- 
-   /* This glyph string must always be drawn with 16-bit functions.  */
-   s->two_byte_p = 1;
- 
-   return s->gidx + s->nchars;
- }
- 
- 
- /* Fill glyph string S from a sequence of character glyphs.
- 
-    FACE_ID is the face id of the string.  START is the index of the
-    first glyph to consider, END is the index of the last + 1.
-    OVERLAPS_P non-zero means S should draw the foreground only, and
-    use its physical height for clipping.
- 
-    Value is the index of the first glyph not in S.  */
- 
- static int
- x_fill_glyph_string (s, face_id, start, end, overlaps_p)
-      struct glyph_string *s;
-      int face_id;
-      int start, end, overlaps_p;
- {
-   struct glyph *glyph, *last;
-   int voffset;
-   int glyph_not_available_p;
- 
-   xassert (s->f == XFRAME (s->w->frame));
-   xassert (s->nchars == 0);
-   xassert (start >= 0 && end > start);
- 
-   s->for_overlaps_p = overlaps_p;
-   glyph = s->row->glyphs[s->area] + start;
-   last = s->row->glyphs[s->area] + end;
-   voffset = glyph->voffset;
- 
-   glyph_not_available_p = glyph->glyph_not_available_p;
- 
-   while (glyph < last
-        && glyph->type == CHAR_GLYPH
-        && glyph->voffset == voffset
-        /* Same face id implies same font, nowadays.  */
-        && glyph->face_id == face_id
-          && glyph->glyph_not_available_p == glyph_not_available_p)
-     {
-       int two_byte_p;
- 
-       s->face = x_get_glyph_face_and_encoding (s->f, glyph,
-                                              s->char2b + s->nchars,
-                                                &two_byte_p);
-       s->two_byte_p = two_byte_p;
-       ++s->nchars;
-       xassert (s->nchars <= end - start);
-       s->width += glyph->pixel_width;
-       ++glyph;
-     }
- 
-   s->font = s->face->font;
-   s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
- 
-   /* If the specified font could not be loaded, use the frame's font,
-      but record the fact that we couldn't load it in
-      S->font_not_found_p so that we can draw rectangles for the
-      characters of the glyph string.  */
-   if (s->font == NULL || glyph_not_available_p)
-     {
-       s->font_not_found_p = 1;
-       s->font = FRAME_FONT (s->f);
-     }
- 
-   /* Adjust base line for subscript/superscript text.  */
-   s->ybase += voffset;
- 
-   xassert (s->face && s->face->gc);
-   return glyph - s->row->glyphs[s->area];
- }
- 
- 
- /* Fill glyph string S from image glyph S->first_glyph.  */
- 
- static void
- x_fill_image_glyph_string (s)
-      struct glyph_string *s;
- {
-   xassert (s->first_glyph->type == IMAGE_GLYPH);
-   s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
-   xassert (s->img);
-   s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
-   s->font = s->face->font;
-   s->width = s->first_glyph->pixel_width;
- 
-   /* Adjust base line for subscript/superscript text.  */
-   s->ybase += s->first_glyph->voffset;
- }
- 
- 
- /* Fill glyph string S from a sequence of stretch glyphs.
- 
-    ROW is the glyph row in which the glyphs are found, AREA is the
-    area within the row.  START is the index of the first glyph to
-    consider, END is the index of the last + 1.
- 
-    Value is the index of the first glyph not in S.  */
- 
- static int
- x_fill_stretch_glyph_string (s, row, area, start, end)
-      struct glyph_string *s;
-      struct glyph_row *row;
-      enum glyph_row_area area;
-      int start, end;
- {
-   struct glyph *glyph, *last;
-   int voffset, face_id;
- 
-   xassert (s->first_glyph->type == STRETCH_GLYPH);
- 
-   glyph = s->row->glyphs[s->area] + start;
-   last = s->row->glyphs[s->area] + end;
-   face_id = glyph->face_id;
-   s->face = FACE_FROM_ID (s->f, face_id);
-   s->font = s->face->font;
-   s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
-   s->width = glyph->pixel_width;
-   voffset = glyph->voffset;
- 
-   for (++glyph;
-        (glyph < last
-       && glyph->type == STRETCH_GLYPH
-       && glyph->voffset == voffset
-       && glyph->face_id == face_id);
-        ++glyph)
-     s->width += glyph->pixel_width;
- 
-   /* Adjust base line for subscript/superscript text.  */
-   s->ybase += voffset;
- 
-   xassert (s->face);
-   return glyph - s->row->glyphs[s->area];
- }
- 
- 
- /* Initialize glyph string S.  CHAR2B is a suitably allocated vector
-    of XChar2b structures for S; it can't be allocated in
-    x_init_glyph_string because it must be allocated via `alloca'.  W
-    is the window on which S is drawn.  ROW and AREA are the glyph row
-    and area within the row from which S is constructed.  START is the
-    index of the first glyph structure covered by S.  HL is a
-    face-override for drawing S.  */
- 
- static void
- w32_init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
-      struct glyph_string *s;
-      HDC hdc;
-      wchar_t *char2b;
-      struct window *w;
-      struct glyph_row *row;
-      enum glyph_row_area area;
-      int start;
-      enum draw_glyphs_face hl;
- {
-   bzero (s, sizeof *s);
-   s->w = w;
-   s->f = XFRAME (w->frame);
-   s->hdc = hdc;
-   s->window = FRAME_W32_WINDOW (s->f);
-   s->char2b = char2b;
-   s->hl = hl;
-   s->row = row;
-   s->area = area;
-   s->first_glyph = row->glyphs[area] + start;
-   s->height = row->height;
-   s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
- 
-   /* Display the internal border below the tool-bar window.  */
-   if (s->w == XWINDOW (s->f->tool_bar_window))
-     s->y -= s->f->output_data.w32->internal_border_width;
- 
-   s->ybase = s->y + row->ascent;
- }
- 
- 
- /* Set background width of glyph string S.  START is the index of the
-    first glyph following S.  LAST_X is the right-most x-position + 1
-    in the drawing area.  */
- 
- static INLINE void
- x_set_glyph_string_background_width (s, start, last_x)
-      struct glyph_string *s;
-      int start;
-      int last_x;
- {
-   /* If the face of this glyph string has to be drawn to the end of
-      the drawing area, set S->extends_to_end_of_line_p.  */
-   struct face *default_face = FACE_FROM_ID (s->f, DEFAULT_FACE_ID);
- 
-   if (start == s->row->used[s->area]
-       && s->area == TEXT_AREA
-       && ((s->hl == DRAW_NORMAL_TEXT
-          && (s->row->fill_line_p
-              || s->face->background != default_face->background
-              || s->face->stipple != default_face->stipple
-              || s->row->mouse_face_p))
-         || s->hl == DRAW_MOUSE_FACE
-         || ((s->hl == DRAW_IMAGE_RAISED || s->hl == DRAW_IMAGE_SUNKEN)
-             && s->row->fill_line_p)))
-     s->extends_to_end_of_line_p = 1;
- 
-   /* If S extends its face to the end of the line, set its
-      background_width to the distance to the right edge of the drawing
-      area.  */
-   if (s->extends_to_end_of_line_p)
-     s->background_width = last_x - s->x + 1;
-   else
-     s->background_width = s->width;
- }
- 
- 
- /* Add a glyph string for a stretch glyph to the list of strings
-    between HEAD and TAIL.  START is the index of the stretch glyph in
-    row area AREA of glyph row ROW.  END is the index of the last glyph
-    in that glyph row area.  X is the current output position assigned
-    to the new glyph string constructed.  HL overrides that face of the
-    glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn.  LAST_X
-    is the right-most x-position of the drawing area.  */
- 
- #define BUILD_STRETCH_GLYPH_STRING(hdc, W, ROW, AREA, START, END, HEAD, TAIL, 
HL, X, LAST_X)              \
-      do                                                                       
    \
-        {                                                                  \
-        s = (struct glyph_string *) alloca (sizeof *s);                    \
-        w32_init_glyph_string (s, hdc, NULL, W, ROW, AREA, START, HL);     \
-        START = x_fill_stretch_glyph_string (s, ROW, AREA, START, END);        
    \
-        x_append_glyph_string (&HEAD, &TAIL, s);                           \
-          s->x = (X);                                                      \
-        }                                                                  \
-      while (0)
- 
- 
- /* Add a glyph string for an image glyph to the list of strings
-    between HEAD and TAIL.  START is the index of the image glyph in
-    row area AREA of glyph row ROW.  END is the index of the last glyph
-    in that glyph row area.  X is the current output position assigned
-    to the new glyph string constructed.  HL overrides that face of the
-    glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn.  LAST_X
-    is the right-most x-position of the drawing area.  */
- 
- #define BUILD_IMAGE_GLYPH_STRING(hdc, W, ROW, AREA, START, END, HEAD, TAIL, 
HL, X, LAST_X)                    \
-      do                                                                       
\
-        {                                                              \
-        s = (struct glyph_string *) alloca (sizeof *s);                \
-        w32_init_glyph_string (s, hdc, NULL, W, ROW, AREA, START, HL); \
-        x_fill_image_glyph_string (s);                                 \
-        x_append_glyph_string (&HEAD, &TAIL, s);                       \
-        ++START;                                                       \
-          s->x = (X);                                                  \
-        }                                                              \
-      while (0)
- 
- 
- /* Add a glyph string for a sequence of character glyphs to the list
-    of strings between HEAD and TAIL.  START is the index of the first
-    glyph in row area AREA of glyph row ROW that is part of the new
-    glyph string.  END is the index of the last glyph in that glyph row
-    area.  X is the current output position assigned to the new glyph
-    string constructed.  HL overrides that face of the glyph; e.g. it
-    is DRAW_CURSOR if a cursor has to be drawn.  LAST_X is the
-    right-most x-position of the drawing area.  */
- 
- #define BUILD_CHAR_GLYPH_STRINGS(hdc, W, ROW, AREA, START, END, HEAD, TAIL, 
HL, X, LAST_X, OVERLAPS_P)                           \
-      do                                                                       
   \
-        {                                                                 \
-        int c, face_id;                                           \
-        wchar_t *char2b;                                                  \
-                                                                          \
-        c = (ROW)->glyphs[AREA][START].u.ch;                              \
-        face_id = (ROW)->glyphs[AREA][START].face_id;                     \
-                                                                          \
-        s = (struct glyph_string *) alloca (sizeof *s);                   \
-        char2b = (wchar_t *) alloca ((END - START) * sizeof *char2b);     \
-        w32_init_glyph_string (s, hdc, char2b, W, ROW, AREA, START, HL);  \
-        x_append_glyph_string (&HEAD, &TAIL, s);                          \
-        s->x = (X);                                                       \
-        START = x_fill_glyph_string (s, face_id, START, END,              \
-                                           OVERLAPS_P);                        
   \
-        }                                                                 \
-      while (0)
- 
- 
- /* Add a glyph string for a composite sequence to the list of strings
-    between HEAD and TAIL.  START is the index of the first glyph in
-    row area AREA of glyph row ROW that is part of the new glyph
-    string.  END is the index of the last glyph in that glyph row area.
-    X is the current output position assigned to the new glyph string
-    constructed.  HL overrides that face of the glyph; e.g. it is
-    DRAW_CURSOR if a cursor has to be drawn.  LAST_X is the right-most
-    x-position of the drawing area.  */
- 
- #define BUILD_COMPOSITE_GLYPH_STRING(hdc, W, ROW, AREA, START, END, HEAD, 
TAIL, HL, X, LAST_X, OVERLAPS_P)      \
-   do {                                                                        
  \
-     int cmp_id = (ROW)->glyphs[AREA][START].u.cmp_id;                   \
-     int face_id = (ROW)->glyphs[AREA][START].face_id;                   \
-     struct face *base_face = FACE_FROM_ID (XFRAME (w->frame), face_id);       
  \
-     struct composition *cmp = composition_table[cmp_id];                \
-     int glyph_len = cmp->glyph_len;                                     \
-     wchar_t *char2b;                                                    \
-     struct face **faces;                                                \
-     struct glyph_string *first_s = NULL;                                \
-     int n;                                                              \
-                                                                         \
-     base_face = base_face->ascii_face;                                        
  \
-     char2b = (wchar_t *) alloca ((sizeof *char2b) * glyph_len);               
  \
-     faces = (struct face **) alloca ((sizeof *faces) * glyph_len);      \
-     /* At first, fill in `char2b' and `faces'.  */                      \
-     for (n = 0; n < glyph_len; n++)                                     \
-       {                                                                       
  \
-       int c = COMPOSITION_GLYPH (cmp, n);                               \
-       int this_face_id = FACE_FOR_CHAR (XFRAME (w->frame), base_face, c); \
-       faces[n] = FACE_FROM_ID (XFRAME (w->frame), this_face_id);        \
-       x_get_char_face_and_encoding (XFRAME (w->frame), c,               \
-                                     this_face_id, char2b + n, 1);       \
-       }                                                                       
  \
-                                                                         \
-     /* Make glyph_strings for each glyph sequence that is drawable by   \
-        the same face, and append them to HEAD/TAIL.  */                       
  \
-     for (n = 0; n < cmp->glyph_len;)                                    \
-            {                                                            \
-       s = (struct glyph_string *) alloca (sizeof *s);                   \
-       w32_init_glyph_string (s, hdc, char2b + n, W, ROW, AREA, START, HL); \
-       x_append_glyph_string (&(HEAD), &(TAIL), s);                      \
-       s->cmp = cmp;                                                     \
-       s->gidx = n;                                                      \
-       s->x = (X);                                                       \
-                                                                         \
-       if (n == 0)                                                       \
-         first_s = s;                                                    \
-                                                                         \
-       n = x_fill_composite_glyph_string (s, faces, OVERLAPS_P);         \
-       }                                                                       
  \
-                                                                         \
-     ++START;                                                            \
-     s = first_s;                                                        \
-   } while (0)
- 
- 
- /* Build a list of glyph strings between HEAD and TAIL for the glyphs
-    of AREA of glyph row ROW on window W between indices START and END.
-    HL overrides the face for drawing glyph strings, e.g. it is
-    DRAW_CURSOR to draw a cursor.  X and LAST_X are start and end
-    x-positions of the drawing area.
- 
-    This is an ugly monster macro construct because we must use alloca
-    to allocate glyph strings (because x_draw_glyphs can be called
-    asynchronously).  */
- 
- #define BUILD_GLYPH_STRINGS(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, 
LAST_X, OVERLAPS_P)                        \
-      do                                                                       
   \
-        {                                                                 \
-        HEAD = TAIL = NULL;                                               \
-        while (START < END)                                               \
-          {                                                               \
-              struct glyph *first_glyph = (ROW)->glyphs[AREA] + START;    \
-              switch (first_glyph->type)                                       
   \
-              {                                                           \
-              case CHAR_GLYPH:                                            \
-                  BUILD_CHAR_GLYPH_STRINGS (hdc, W, ROW, AREA, START, END,  \
-                                          HEAD, TAIL, HL, X, LAST_X,      \
-                                            OVERLAPS_P);                       
   \
-                break;                                                    \
-                                                                          \
-                case COMPOSITE_GLYPH:                                       \
-                  BUILD_COMPOSITE_GLYPH_STRING (hdc, W, ROW, AREA, START,   \
-                                                END, HEAD, TAIL, HL, X,     \
-                                                LAST_X, OVERLAPS_P);        \
-                break;                                                    \
-                                                                          \
-              case STRETCH_GLYPH:                                         \
-                BUILD_STRETCH_GLYPH_STRING (hdc, W, ROW, AREA, START, END,\
-                                            HEAD, TAIL, HL, X, LAST_X);   \
-                break;                                                    \
-                                                                          \
-              case IMAGE_GLYPH:                                           \
-                BUILD_IMAGE_GLYPH_STRING (hdc, W, ROW, AREA, START, END,  \
-                                          HEAD, TAIL, HL, X, LAST_X);     \
-                break;                                                    \
-                                                                          \
-              default:                                                    \
-                abort ();                                                 \
-              }                                                           \
-                                                                          \
-              x_set_glyph_string_background_width (s, START, LAST_X);     \
-            (X) += s->width;                                              \
-             }                                                            \
-        }                                                                 \
-      while (0)
- 
- 
- /* Draw glyphs between START and END in AREA of ROW on window W,
-    starting at x-position X.  X is relative to AREA in W.  HL is a
-    face-override with the following meaning:
- 
-    DRAW_NORMAL_TEXT   draw normally
-    DRAW_CURSOR                draw in cursor face
-    DRAW_MOUSE_FACE    draw in mouse face.
-    DRAW_INVERSE_VIDEO draw in mode line face
-    DRAW_IMAGE_SUNKEN  draw an image with a sunken relief around it
-    DRAW_IMAGE_RAISED  draw an image with a raised relief around it
- 
-    If OVERLAPS_P is non-zero, draw only the foreground of characters
-    and clip to the physical height of ROW.
- 
-    Value is the x-position reached, relative to AREA of W.  */
- 
- static int
- x_draw_glyphs (w, x, row, area, start, end, hl, overlaps_p)
-      struct window *w;
-      int x;
-      struct glyph_row *row;
-      enum glyph_row_area area;
-      int start, end;
-      enum draw_glyphs_face hl;
-      int overlaps_p;
- {
-   struct glyph_string *head, *tail;
-   struct glyph_string *s;
-   int last_x, area_width;
-   int x_reached;
-   int i, j;
-   HDC hdc = get_frame_dc (XFRAME (WINDOW_FRAME (w)));
- 
-   /* Let's rather be paranoid than getting a SEGV.  */
-   end = min (end, row->used[area]);
-   start = max (0, start);
-   start = min (end, start);
- 
-   /* Translate X to frame coordinates.  Set last_x to the right
-      end of the drawing area.  */
-   if (row->full_width_p)
-     {
-       /* X is relative to the left edge of W, without scroll bars
-        or fringes.  */
-       struct frame *f = XFRAME (WINDOW_FRAME (w));
-       int window_left_x = WINDOW_LEFT_MARGIN (w) * CANON_X_UNIT (f);
- 
-       x += window_left_x;
-       area_width = XFASTINT (w->width) * CANON_X_UNIT (f);
-       last_x = window_left_x + area_width;
- 
-       if (FRAME_HAS_VERTICAL_SCROLL_BARS (f))
-       {
-         int width = FRAME_SCROLL_BAR_WIDTH (f) * CANON_X_UNIT (f);
-         if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f))
-           last_x += width;
-         else
-           x -= width;
-       }
- 
-       x += FRAME_INTERNAL_BORDER_WIDTH (f);
-       last_x -= FRAME_INTERNAL_BORDER_WIDTH (f);
-     }
-   else
-     {
-       x = WINDOW_AREA_TO_FRAME_PIXEL_X (w, area, x);
-       area_width = window_box_width (w, area);
-       last_x = WINDOW_AREA_TO_FRAME_PIXEL_X (w, area, area_width);
-     }
- 
-   /* Build a doubly-linked list of glyph_string structures between
-      head and tail from what we have to draw.  Note that the macro
-      BUILD_GLYPH_STRINGS will modify its start parameter.  That's
-      the reason we use a separate variable `i'.  */
-   i = start;
-   BUILD_GLYPH_STRINGS (hdc, w, row, area, i, end, head, tail, hl, x, last_x,
-                        overlaps_p);
-   if (tail)
-     x_reached = tail->x + tail->background_width;
-   else
-     x_reached = x;
- 
-   /* If there are any glyphs with lbearing < 0 or rbearing > width in
-      the row, redraw some glyphs in front or following the glyph
-      strings built above.  */
-   if (head && !overlaps_p && row->contains_overlapping_glyphs_p)
-     {
-       int dummy_x = 0;
-       struct glyph_string *h, *t;
- 
-       /* Compute overhangs for all glyph strings.  */
-       for (s = head; s; s = s->next)
-       x_compute_glyph_string_overhangs (s);
- 
-       /* Prepend glyph strings for glyphs in front of the first glyph
-        string that are overwritten because of the first glyph
-        string's left overhang.  The background of all strings
-        prepended must be drawn because the first glyph string
-        draws over it.  */
-       i = x_left_overwritten (head);
-       if (i >= 0)
-       {
-         j = i;
-         BUILD_GLYPH_STRINGS (hdc, w, row, area, j, start, h, t,
-                              DRAW_NORMAL_TEXT, dummy_x, last_x,
-                                overlaps_p);
-         start = i;
-         x_compute_overhangs_and_x (t, head->x, 1);
-         x_prepend_glyph_string_lists (&head, &tail, h, t);
-       }
- 
-       /* Prepend glyph strings for glyphs in front of the first glyph
-        string that overwrite that glyph string because of their
-        right overhang.  For these strings, only the foreground must
-        be drawn, because it draws over the glyph string at `head'.
-        The background must not be drawn because this would overwrite
-        right overhangs of preceding glyphs for which no glyph
-        strings exist.  */
-       i = x_left_overwriting (head);
-       if (i >= 0)
-       {
-         BUILD_GLYPH_STRINGS (hdc, w, row, area, i, start, h, t,
-                              DRAW_NORMAL_TEXT, dummy_x, last_x,
-                                overlaps_p);
-         for (s = h; s; s = s->next)
-           s->background_filled_p = 1;
-         x_compute_overhangs_and_x (t, head->x, 1);
-         x_prepend_glyph_string_lists (&head, &tail, h, t);
-       }
- 
-       /* Append glyphs strings for glyphs following the last glyph
-        string tail that are overwritten by tail.  The background of
-        these strings has to be drawn because tail's foreground draws
-        over it.  */
-       i = x_right_overwritten (tail);
-       if (i >= 0)
-       {
-         BUILD_GLYPH_STRINGS (hdc, w, row, area, end, i, h, t,
-                              DRAW_NORMAL_TEXT, x, last_x,
-                                overlaps_p);
-         x_compute_overhangs_and_x (h, tail->x + tail->width, 0);
-         x_append_glyph_string_lists (&head, &tail, h, t);
-       }
- 
-       /* Append glyph strings for glyphs following the last glyph
-        string tail that overwrite tail.  The foreground of such
-        glyphs has to be drawn because it writes into the background
-        of tail.  The background must not be drawn because it could
-        paint over the foreground of following glyphs.  */
-       i = x_right_overwriting (tail);
-       if (i >= 0)
-       {
-         BUILD_GLYPH_STRINGS (hdc, w, row, area, end, i, h, t,
-                              DRAW_NORMAL_TEXT, x, last_x,
-                                overlaps_p);
-         for (s = h; s; s = s->next)
-           s->background_filled_p = 1;
-         x_compute_overhangs_and_x (h, tail->x + tail->width, 0);
-         x_append_glyph_string_lists (&head, &tail, h, t);
-       }
-     }
- 
-   /* Draw all strings.  */
-   for (s = head; s; s = s->next)
-     x_draw_glyph_string (s);
- 
-   if (area == TEXT_AREA
-       && !row->full_width_p
-       /* When drawing overlapping rows, only the glyph strings'
-        foreground is drawn, which doesn't erase a cursor
-        completely. */
-       && !overlaps_p)
-     {
-       int x0 = head ? head->x : x;
-       int x1 = tail ? tail->x + tail->background_width : x;
- 
-       x0 = FRAME_TO_WINDOW_PIXEL_X (w, x0);
-       x1 = FRAME_TO_WINDOW_PIXEL_X (w, x1);
- 
-       if (!row->full_width_p && XFASTINT (w->left_margin_width) != 0)
-       {
-         int left_area_width = window_box_width (w, LEFT_MARGIN_AREA);
-         x0 -= left_area_width;
-         x1 -= left_area_width;
-       }
- 
-       notice_overwritten_cursor (w, area, x0, x1,
-                                row->y, MATRIX_ROW_BOTTOM_Y (row));
-     }
- 
-   /* Value is the x-position up to which drawn, relative to AREA of W.
-      This doesn't include parts drawn because of overhangs.  */
-   x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
-   if (!row->full_width_p)
-     {
-       if (area > LEFT_MARGIN_AREA)
-       x_reached -= window_box_width (w, LEFT_MARGIN_AREA);
-       if (area > TEXT_AREA)
-       x_reached -= window_box_width (w, TEXT_AREA);
-     }
- 
-   release_frame_dc (XFRAME (WINDOW_FRAME (w)), hdc);
- 
-   return x_reached;
- }
- 
- 
  /* Fix the display of area AREA of overlapping row ROW in window W.  */
  
  static void
--- 2696,2701 ----
***************
*** 5206,5212 ****
  {
    /* This function intentionally left blank.  */
  }
- 
  
  
  /***********************************************************************
--- 3018,3023 ----
***************
*** 9173,9224 ****
                             Text Cursor
   ***********************************************************************/
  
- /* Notice when the text cursor of window W has been completely
-    overwritten by a drawing operation that outputs glyphs in AREA
-    starting at X0 and ending at X1 in the line starting at Y0 and
-    ending at Y1.  X coordinates are area-relative.  X1 < 0 means all
-    the rest of the line after X0 has been written.  Y coordinates
-    are window-relative.  */
- 
- static void
- notice_overwritten_cursor (w, area, x0, x1, y0, y1)
-      struct window *w;
-      enum glyph_row_area area;
-      int x0, x1, y0, y1;
- {
-   if (area == TEXT_AREA && w->phys_cursor_on_p)
-     {
-       int cx0 = w->phys_cursor.x;
-       int cx1 = cx0 + w->phys_cursor_width;
-       int cy0 = w->phys_cursor.y;
-       int cy1 = cy0 + w->phys_cursor_height;
- 
-       if (x0 <= cx0 && (x1 < 0 || x1 >= cx1))
-       {
-         /* The cursor image will be completely removed from the
-            screen if the output area intersects the cursor area in
-            y-direction.  When we draw in [y0 y1[, and some part of
-            the cursor is at y < y0, that part must have been drawn
-            before.  When scrolling, the cursor is erased before
-            actually scrolling, so we don't come here.  When not
-            scrolling, the rows above the old cursor row must have
-            changed, and in this case these rows must have written
-            over the cursor image.
- 
-            Likewise if part of the cursor is below y1, with the
-            exception of the cursor being in the first blank row at
-            the buffer and window end because update_text_area
-            doesn't draw that row.  (Except when it does, but
-            that's handled in update_text_area.)  */
- 
-         if (((y0 >= cy0 && y0 < cy1) || (y1 > cy0 && y1 < cy1))
-             && w->current_matrix->rows[w->phys_cursor.vpos].displays_text_p)
-           w->phys_cursor_on_p = 0;
-       }
-     }
- }
- 
- 
  /* Set clipping for output in glyph row ROW.  W is the window in which
     we operate.  GC is the graphics context to set clipping in.
     WHOLE_LINE_P non-zero means include the areas used for truncation
--- 6984,6989 ----
***************
*** 11041,11049 ****
    w32_cursor_to,
    x_flush,
    x_clear_mouse_face,
!   x_get_glyph_overhangs,
    x_fix_overlapping_area,
!   w32_draw_fringe_bitmap
  };
  
  void
--- 8806,8818 ----
    w32_cursor_to,
    x_flush,
    x_clear_mouse_face,
!   w32_get_glyph_overhangs,
    x_fix_overlapping_area,
!   w32_draw_fringe_bitmap,
!   w32_per_char_metric,
!   w32_encode_char,
!   NULL, /* w32_compute_glyph_string_overhangs */
!   x_draw_glyph_string
  };
  
  void




reply via email to

[Prev in Thread] Current Thread [Next in Thread]