Mercurial > emacs
changeset 50154:10038ae9db85
Remove consolidated defines and code.
(BUILD_WCHAR_T, BYTE1, BYTE2): Macros removed; callers changed
to use STORE_XCHAR2B, XCHAR2B_BYTE1, XCHAR2B_BYTE2 instead.
(w32_per_char_metric): Change font_type arg to int for RIF.
(w32_encode_char): Return int according to RIF requirements.
(w32_compute_glyph_string_overhangs): Adapt to RIF.
(w32_get_glyph_overhangs): New function for RIF. Uses generic
x_get_glyph_overhangs.
(w32_redisplay_interface): Add new members.
author | Kim F. Storm <storm@cua.dk> |
---|---|
date | Sun, 16 Mar 2003 20:47:48 +0000 |
parents | 04ca11636b72 |
children | 2b702ff059f8 |
files | src/w32term.c |
diffstat | 1 files changed, 35 insertions(+), 2266 deletions(-) [+] |
line wrap: on
line diff
--- a/src/w32term.c Sun Mar 16 20:47:30 2003 +0000 +++ b/src/w32term.c Sun Mar 16 20:47:48 2003 +0000 @@ -260,19 +260,6 @@ 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 *)); @@ -344,9 +331,6 @@ 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; @@ -897,35 +881,9 @@ /* 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) + 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,8 +904,8 @@ buf[0] = (char)(*char2b); else { - buf[0] = BYTE1 (*char2b); - buf[1] = BYTE2 (*char2b); + buf[0] = XCHAR2B_BYTE1 (char2b); + buf[1] = XCHAR2B_BYTE2 (char2b); } bdf_metric = w32_BDF_TextMetric (font->bdf, buf, dim); @@ -1065,7 +1023,7 @@ w32_per_char_metric (font, char2b, font_type) XFontStruct *font; wchar_t *char2b; - enum w32_char_font_type font_type; + int /* enum w32_char_font_type */ font_type; { /* The result metric information. */ XCharStruct *pcm; @@ -1166,7 +1124,7 @@ /* 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 +static int /* enum w32_char_font_type */ w32_encode_char (c, char2b, font_info, two_byte_p) int c; wchar_t *char2b; @@ -1181,7 +1139,8 @@ xassert (two_byte_p); - *two_byte_p = w32_font_is_double_byte (font); + 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,14 +1153,14 @@ if (CHARSET_DIMENSION (charset) == 1) { ccl->reg[0] = charset; - ccl->reg[1] = BYTE2 (*char2b); + ccl->reg[1] = XCHAR2B_BYTE2 (char2b); ccl->reg[2] = -1; } else { ccl->reg[0] = charset; - ccl->reg[1] = BYTE1 (*char2b); - ccl->reg[2] = BYTE2 (*char2b); + ccl->reg[1] = XCHAR2B_BYTE1 (char2b); + ccl->reg[2] = XCHAR2B_BYTE2 (char2b); } ccl_driver (ccl, NULL, NULL, 0, 0, NULL); @@ -1209,9 +1168,9 @@ /* 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]); + STORE_XCHAR2B (char2b, 0, ccl->reg[1]); else - *char2b = BUILD_WCHAR_T (ccl->reg[1], ccl->reg[2]); + STORE_XCHAR2B (char2b, ccl->reg[1], ccl->reg[2]); } else if (font_info->encoding[charset]) { @@ -1221,18 +1180,18 @@ if ((enc == 1 || enc == 2) && CHARSET_DIMENSION (charset) == 2) - *char2b = BUILD_WCHAR_T (BYTE1 (*char2b) | 0x80, BYTE2 (*char2b)); + STORE_XCHAR2B (char2b, XCHAR2B_BYTE1 (char2b) | 0x80, XCHAR2B_BYTE2 (char2b)); if (enc == 1 || enc == 3 || (enc == 4 && CHARSET_DIMENSION (charset) == 1)) - *char2b = BUILD_WCHAR_T (BYTE1 (*char2b), BYTE2 (*char2b) | 0x80); + STORE_XCHAR2B (char2b, XCHAR2B_BYTE1 (char2b), XCHAR2B_BYTE2 (char2b) | 0x80); else if (enc == 4) { int sjis1, sjis2; - ENCODE_SJIS (BYTE1 (*char2b), BYTE2 (*char2b), + ENCODE_SJIS (XCHAR2B_BYTE1 (char2b), XCHAR2B_BYTE2 (char2b), sjis1, sjis2); - *char2b = BUILD_WCHAR_T (sjis1, sjis2); + STORE_XCHAR2B (char2b, sjis1, sjis2); } } codepage = font_info->codepage; @@ -1244,8 +1203,8 @@ && charset != CHARSET_8_BIT_CONTROL && charset != CHARSET_8_BIT_GRAPHIC) { char temp[3]; - temp[0] = BYTE1 (*char2b); - temp[1] = BYTE2 (*char2b); + temp[0] = XCHAR2B_BYTE1 (char2b); + temp[1] = XCHAR2B_BYTE2 (char2b); temp[2] = '\0'; if (codepage != CP_UNICODE) { @@ -1270,1091 +1229,6 @@ } -/* 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. */ @@ -2387,123 +1261,6 @@ 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. */ @@ -2519,62 +1276,15 @@ 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) + 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); } -#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 *, @@ -2583,14 +1293,9 @@ 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)); @@ -2599,7 +1304,6 @@ 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, @@ -2608,69 +1312,12 @@ 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. */ @@ -2933,11 +1580,12 @@ } -/* Compute left and right overhang of glyph string S. If S is a glyph +/* 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 INLINE void -x_compute_glyph_string_overhangs (s) +static void +w32_compute_glyph_string_overhangs (s) struct glyph_string *s; { /* TODO: Windows does not appear to have a method for @@ -2946,198 +1594,19 @@ } -/* 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) +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! */ - w32_get_glyph_overhangs (hdc, glyph, f, left, right); + x_get_glyph_overhangs (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 @@ -3265,7 +1734,7 @@ /* 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]); + 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,663 +2696,6 @@ } -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 @@ -5206,7 +3018,6 @@ { /* This function intentionally left blank. */ } - /*********************************************************************** @@ -9173,52 +6984,6 @@ 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 @@ -11041,9 +8806,13 @@ w32_cursor_to, x_flush, x_clear_mouse_face, - x_get_glyph_overhangs, + w32_get_glyph_overhangs, x_fix_overlapping_area, - w32_draw_fringe_bitmap + w32_draw_fringe_bitmap, + w32_per_char_metric, + w32_encode_char, + NULL, /* w32_compute_glyph_string_overhangs */ + x_draw_glyph_string }; void