diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/dispextern.h | 27 | ||||
| -rw-r--r-- | src/font.c | 10 | ||||
| -rw-r--r-- | src/nsterm.m | 10 | ||||
| -rw-r--r-- | src/w32term.c | 12 | ||||
| -rw-r--r-- | src/xdisp.c | 567 | ||||
| -rw-r--r-- | src/xfaces.c | 144 | ||||
| -rw-r--r-- | src/xterm.c | 10 |
7 files changed, 414 insertions, 366 deletions
diff --git a/src/dispextern.h b/src/dispextern.h index 7a15e2745b5..0615b16d712 100644 --- a/src/dispextern.h +++ b/src/dispextern.h | |||
| @@ -1607,6 +1607,7 @@ enum lface_attribute_index | |||
| 1607 | LFACE_INHERIT_INDEX, | 1607 | LFACE_INHERIT_INDEX, |
| 1608 | LFACE_FONTSET_INDEX, | 1608 | LFACE_FONTSET_INDEX, |
| 1609 | LFACE_DISTANT_FOREGROUND_INDEX, | 1609 | LFACE_DISTANT_FOREGROUND_INDEX, |
| 1610 | LFACE_EXTEND_INDEX, | ||
| 1610 | LFACE_VECTOR_SIZE | 1611 | LFACE_VECTOR_SIZE |
| 1611 | }; | 1612 | }; |
| 1612 | 1613 | ||
| @@ -1632,6 +1633,7 @@ enum face_box_type | |||
| 1632 | 1633 | ||
| 1633 | enum face_underline_type | 1634 | enum face_underline_type |
| 1634 | { | 1635 | { |
| 1636 | FACE_NO_UNDERLINE = 0, | ||
| 1635 | FACE_UNDER_LINE, | 1637 | FACE_UNDER_LINE, |
| 1636 | FACE_UNDER_WAVE | 1638 | FACE_UNDER_WAVE |
| 1637 | }; | 1639 | }; |
| @@ -1675,11 +1677,9 @@ struct face | |||
| 1675 | /* Pixel value or color index of background color. */ | 1677 | /* Pixel value or color index of background color. */ |
| 1676 | unsigned long background; | 1678 | unsigned long background; |
| 1677 | 1679 | ||
| 1678 | /* Pixel value or color index of underline color. */ | 1680 | /* Pixel value or color index of underline, overlined, |
| 1681 | strike-through, or box color. */ | ||
| 1679 | unsigned long underline_color; | 1682 | unsigned long underline_color; |
| 1680 | |||
| 1681 | /* Pixel value or color index of overlined, strike-through, or box | ||
| 1682 | color. */ | ||
| 1683 | unsigned long overline_color; | 1683 | unsigned long overline_color; |
| 1684 | unsigned long strike_through_color; | 1684 | unsigned long strike_through_color; |
| 1685 | unsigned long box_color; | 1685 | unsigned long box_color; |
| @@ -1706,7 +1706,7 @@ struct face | |||
| 1706 | ENUM_BF (face_box_type) box : 2; | 1706 | ENUM_BF (face_box_type) box : 2; |
| 1707 | 1707 | ||
| 1708 | /* Style of underlining. */ | 1708 | /* Style of underlining. */ |
| 1709 | ENUM_BF (face_underline_type) underline_type : 1; | 1709 | ENUM_BF (face_underline_type) underline : 2; |
| 1710 | 1710 | ||
| 1711 | /* If `box' above specifies a 3D type, true means use box_color for | 1711 | /* If `box' above specifies a 3D type, true means use box_color for |
| 1712 | drawing shadows. */ | 1712 | drawing shadows. */ |
| @@ -1714,7 +1714,6 @@ struct face | |||
| 1714 | 1714 | ||
| 1715 | /* Non-zero if text in this face should be underlined, overlined, | 1715 | /* Non-zero if text in this face should be underlined, overlined, |
| 1716 | strike-through or have a box drawn around it. */ | 1716 | strike-through or have a box drawn around it. */ |
| 1717 | bool_bf underline_p : 1; | ||
| 1718 | bool_bf overline_p : 1; | 1717 | bool_bf overline_p : 1; |
| 1719 | bool_bf strike_through_p : 1; | 1718 | bool_bf strike_through_p : 1; |
| 1720 | 1719 | ||
| @@ -1724,14 +1723,10 @@ struct face | |||
| 1724 | bool_bf foreground_defaulted_p : 1; | 1723 | bool_bf foreground_defaulted_p : 1; |
| 1725 | bool_bf background_defaulted_p : 1; | 1724 | bool_bf background_defaulted_p : 1; |
| 1726 | 1725 | ||
| 1727 | /* True means that either no color is specified for underlining or that | ||
| 1728 | the specified color couldn't be loaded. Use the foreground | ||
| 1729 | color when drawing in that case. */ | ||
| 1730 | bool_bf underline_defaulted_p : 1; | ||
| 1731 | |||
| 1732 | /* True means that either no color is specified for the corresponding | 1726 | /* True means that either no color is specified for the corresponding |
| 1733 | attribute or that the specified color couldn't be loaded. | 1727 | attribute or that the specified color couldn't be loaded. |
| 1734 | Use the foreground color when drawing in that case. */ | 1728 | Use the foreground color when drawing in that case. */ |
| 1729 | bool_bf underline_defaulted_p : 1; | ||
| 1735 | bool_bf overline_color_defaulted_p : 1; | 1730 | bool_bf overline_color_defaulted_p : 1; |
| 1736 | bool_bf strike_through_color_defaulted_p : 1; | 1731 | bool_bf strike_through_color_defaulted_p : 1; |
| 1737 | bool_bf box_color_defaulted_p : 1; | 1732 | bool_bf box_color_defaulted_p : 1; |
| @@ -1867,6 +1862,9 @@ struct face_cache | |||
| 1867 | ? FRAME_FACE_CACHE (F)->faces_by_id[ID] \ | 1862 | ? FRAME_FACE_CACHE (F)->faces_by_id[ID] \ |
| 1868 | : NULL) | 1863 | : NULL) |
| 1869 | 1864 | ||
| 1865 | #define FACE_EXTENSIBLE_P(F) \ | ||
| 1866 | (!NILP (F->lface[LFACE_EXTEND_INDEX])) | ||
| 1867 | |||
| 1870 | /* True if FACE is suitable for displaying ASCII characters. */ | 1868 | /* True if FACE is suitable for displaying ASCII characters. */ |
| 1871 | INLINE bool | 1869 | INLINE bool |
| 1872 | FACE_SUITABLE_FOR_ASCII_CHAR_P (struct face *face) | 1870 | FACE_SUITABLE_FOR_ASCII_CHAR_P (struct face *face) |
| @@ -3553,12 +3551,13 @@ int lookup_derived_face (struct window *, struct frame *, | |||
| 3553 | void init_frame_faces (struct frame *); | 3551 | void init_frame_faces (struct frame *); |
| 3554 | void free_frame_faces (struct frame *); | 3552 | void free_frame_faces (struct frame *); |
| 3555 | void recompute_basic_faces (struct frame *); | 3553 | void recompute_basic_faces (struct frame *); |
| 3556 | int face_at_buffer_position (struct window *, ptrdiff_t, ptrdiff_t *, ptrdiff_t, | 3554 | int face_at_buffer_position (struct window *, ptrdiff_t, ptrdiff_t *, |
| 3557 | bool, int); | 3555 | ptrdiff_t, bool, int, enum lface_attribute_index); |
| 3558 | int face_for_overlay_string (struct window *, ptrdiff_t, ptrdiff_t *, ptrdiff_t, | 3556 | int face_for_overlay_string (struct window *, ptrdiff_t, ptrdiff_t *, ptrdiff_t, |
| 3559 | bool, Lisp_Object); | 3557 | bool, Lisp_Object); |
| 3560 | int face_at_string_position (struct window *, Lisp_Object, ptrdiff_t, ptrdiff_t, | 3558 | int face_at_string_position (struct window *, Lisp_Object, ptrdiff_t, ptrdiff_t, |
| 3561 | ptrdiff_t *, enum face_id, bool); | 3559 | ptrdiff_t *, enum face_id, bool, |
| 3560 | enum lface_attribute_index); | ||
| 3562 | int merge_faces (struct window *, Lisp_Object, int, int); | 3561 | int merge_faces (struct window *, Lisp_Object, int, int); |
| 3563 | int compute_char_face (struct frame *, int, Lisp_Object); | 3562 | int compute_char_face (struct frame *, int, Lisp_Object); |
| 3564 | void free_all_realized_faces (Lisp_Object); | 3563 | void free_all_realized_faces (Lisp_Object); |
diff --git a/src/font.c b/src/font.c index 6bc977fd68e..7fdadb17c14 100644 --- a/src/font.c +++ b/src/font.c | |||
| @@ -3785,10 +3785,10 @@ font_at (int c, ptrdiff_t pos, struct face *face, struct window *w, | |||
| 3785 | 3785 | ||
| 3786 | if (STRINGP (string)) | 3786 | if (STRINGP (string)) |
| 3787 | face_id = face_at_string_position (w, string, pos, 0, &endptr, | 3787 | face_id = face_at_string_position (w, string, pos, 0, &endptr, |
| 3788 | DEFAULT_FACE_ID, false); | 3788 | DEFAULT_FACE_ID, false, 0); |
| 3789 | else | 3789 | else |
| 3790 | face_id = face_at_buffer_position (w, pos, &endptr, | 3790 | face_id = face_at_buffer_position (w, pos, &endptr, |
| 3791 | pos + 100, false, -1); | 3791 | pos + 100, false, -1, 0); |
| 3792 | face = FACE_FROM_ID (f, face_id); | 3792 | face = FACE_FROM_ID (f, face_id); |
| 3793 | } | 3793 | } |
| 3794 | if (multibyte) | 3794 | if (multibyte) |
| @@ -3832,7 +3832,7 @@ font_range (ptrdiff_t pos, ptrdiff_t pos_byte, ptrdiff_t *limit, | |||
| 3832 | 3832 | ||
| 3833 | if (NILP (string)) | 3833 | if (NILP (string)) |
| 3834 | face_id = face_at_buffer_position (w, pos, &ignore, *limit, | 3834 | face_id = face_at_buffer_position (w, pos, &ignore, *limit, |
| 3835 | false, -1); | 3835 | false, -1, 0); |
| 3836 | else | 3836 | else |
| 3837 | { | 3837 | { |
| 3838 | face_id = | 3838 | face_id = |
| @@ -3841,7 +3841,7 @@ font_range (ptrdiff_t pos, ptrdiff_t pos_byte, ptrdiff_t *limit, | |||
| 3841 | : lookup_basic_face (w, f, DEFAULT_FACE_ID); | 3841 | : lookup_basic_face (w, f, DEFAULT_FACE_ID); |
| 3842 | 3842 | ||
| 3843 | face_id = face_at_string_position (w, string, pos, 0, &ignore, | 3843 | face_id = face_at_string_position (w, string, pos, 0, &ignore, |
| 3844 | face_id, false); | 3844 | face_id, false, 0); |
| 3845 | } | 3845 | } |
| 3846 | face = FACE_FROM_ID (f, face_id); | 3846 | face = FACE_FROM_ID (f, face_id); |
| 3847 | } | 3847 | } |
| @@ -4618,7 +4618,7 @@ DEFUN ("internal-char-font", Finternal_char_font, Sinternal_char_font, 1, 2, 0, | |||
| 4618 | w = XWINDOW (window); | 4618 | w = XWINDOW (window); |
| 4619 | f = XFRAME (w->frame); | 4619 | f = XFRAME (w->frame); |
| 4620 | face_id = face_at_buffer_position (w, pos, &dummy, | 4620 | face_id = face_at_buffer_position (w, pos, &dummy, |
| 4621 | pos + 100, false, -1); | 4621 | pos + 100, false, -1, 0); |
| 4622 | } | 4622 | } |
| 4623 | if (! CHAR_VALID_P (c)) | 4623 | if (! CHAR_VALID_P (c)) |
| 4624 | return Qnil; | 4624 | return Qnil; |
diff --git a/src/nsterm.m b/src/nsterm.m index c8094d0ee37..5583c6105cb 100644 --- a/src/nsterm.m +++ b/src/nsterm.m | |||
| @@ -3404,9 +3404,9 @@ ns_draw_text_decoration (struct glyph_string *s, struct face *face, | |||
| 3404 | return; | 3404 | return; |
| 3405 | 3405 | ||
| 3406 | /* Do underline. */ | 3406 | /* Do underline. */ |
| 3407 | if (face->underline_p) | 3407 | if (face->underline) |
| 3408 | { | 3408 | { |
| 3409 | if (s->face->underline_type == FACE_UNDER_WAVE) | 3409 | if (s->face->underline == FACE_UNDER_WAVE) |
| 3410 | { | 3410 | { |
| 3411 | if (face->underline_defaulted_p) | 3411 | if (face->underline_defaulted_p) |
| 3412 | [defaultCol set]; | 3412 | [defaultCol set]; |
| @@ -3415,15 +3415,15 @@ ns_draw_text_decoration (struct glyph_string *s, struct face *face, | |||
| 3415 | 3415 | ||
| 3416 | ns_draw_underwave (s, width, x); | 3416 | ns_draw_underwave (s, width, x); |
| 3417 | } | 3417 | } |
| 3418 | else if (s->face->underline_type == FACE_UNDER_LINE) | 3418 | else if (s->face->underline == FACE_UNDER_LINE) |
| 3419 | { | 3419 | { |
| 3420 | 3420 | ||
| 3421 | NSRect r; | 3421 | NSRect r; |
| 3422 | unsigned long thickness, position; | 3422 | unsigned long thickness, position; |
| 3423 | 3423 | ||
| 3424 | /* If the prev was underlined, match its appearance. */ | 3424 | /* If the prev was underlined, match its appearance. */ |
| 3425 | if (s->prev && s->prev->face->underline_p | 3425 | if (s->prev |
| 3426 | && s->prev->face->underline_type == FACE_UNDER_LINE | 3426 | && s->prev->face->underline == FACE_UNDER_LINE |
| 3427 | && s->prev->underline_thickness > 0) | 3427 | && s->prev->underline_thickness > 0) |
| 3428 | { | 3428 | { |
| 3429 | thickness = s->prev->underline_thickness; | 3429 | thickness = s->prev->underline_thickness; |
diff --git a/src/w32term.c b/src/w32term.c index 82256db1721..9da0845836a 100644 --- a/src/w32term.c +++ b/src/w32term.c | |||
| @@ -2481,9 +2481,9 @@ w32_draw_glyph_string (struct glyph_string *s) | |||
| 2481 | if (!s->for_overlaps) | 2481 | if (!s->for_overlaps) |
| 2482 | { | 2482 | { |
| 2483 | /* Draw underline. */ | 2483 | /* Draw underline. */ |
| 2484 | if (s->face->underline_p) | 2484 | if (s->face->underline) |
| 2485 | { | 2485 | { |
| 2486 | if (s->face->underline_type == FACE_UNDER_WAVE) | 2486 | if (s->face->underline == FACE_UNDER_WAVE) |
| 2487 | { | 2487 | { |
| 2488 | COLORREF color; | 2488 | COLORREF color; |
| 2489 | 2489 | ||
| @@ -2494,13 +2494,13 @@ w32_draw_glyph_string (struct glyph_string *s) | |||
| 2494 | 2494 | ||
| 2495 | w32_draw_underwave (s, color); | 2495 | w32_draw_underwave (s, color); |
| 2496 | } | 2496 | } |
| 2497 | else if (s->face->underline_type == FACE_UNDER_LINE) | 2497 | else if (s->face->underline == FACE_UNDER_LINE) |
| 2498 | { | 2498 | { |
| 2499 | unsigned long thickness, position; | 2499 | unsigned long thickness, position; |
| 2500 | int y; | 2500 | int y; |
| 2501 | 2501 | ||
| 2502 | if (s->prev && s->prev->face->underline_p | 2502 | if (s->prev |
| 2503 | && s->prev->face->underline_type == FACE_UNDER_LINE) | 2503 | && s->prev->face->underline == FACE_UNDER_LINE) |
| 2504 | { | 2504 | { |
| 2505 | /* We use the same underline style as the previous one. */ | 2505 | /* We use the same underline style as the previous one. */ |
| 2506 | thickness = s->prev->underline_thickness; | 2506 | thickness = s->prev->underline_thickness; |
| @@ -2514,7 +2514,7 @@ w32_draw_glyph_string (struct glyph_string *s) | |||
| 2514 | BOOL use_underline_position_properties; | 2514 | BOOL use_underline_position_properties; |
| 2515 | Lisp_Object val | 2515 | Lisp_Object val |
| 2516 | = buffer_local_value (Qunderline_minimum_offset, | 2516 | = buffer_local_value (Qunderline_minimum_offset, |
| 2517 | s->w->contents); | 2517 | s->w->contents); |
| 2518 | if (FIXNUMP (val)) | 2518 | if (FIXNUMP (val)) |
| 2519 | minimum_offset = max (0, XFIXNUM (val)); | 2519 | minimum_offset = max (0, XFIXNUM (val)); |
| 2520 | else | 2520 | else |
diff --git a/src/xdisp.c b/src/xdisp.c index 1cfd7ef7601..30be492d9b4 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -431,17 +431,26 @@ static Lisp_Object list_of_error; | |||
| 431 | met, return the (nonnegative) column number, else return a negative | 431 | met, return the (nonnegative) column number, else return a negative |
| 432 | value. */ | 432 | value. */ |
| 433 | static int | 433 | static int |
| 434 | fill_column_indicator_column (struct it *it) | 434 | fill_column_indicator_column (struct it *it, int char_width) |
| 435 | { | 435 | { |
| 436 | if (Vdisplay_fill_column_indicator | 436 | if (Vdisplay_fill_column_indicator |
| 437 | && !it->w->pseudo_window_p | ||
| 437 | && it->continuation_lines_width == 0 | 438 | && it->continuation_lines_width == 0 |
| 438 | && CHARACTERP (Vdisplay_fill_column_indicator_character)) | 439 | && CHARACTERP (Vdisplay_fill_column_indicator_character)) |
| 439 | { | 440 | { |
| 440 | Lisp_Object col = (EQ (Vdisplay_fill_column_indicator_column, Qt) | 441 | Lisp_Object col = (EQ (Vdisplay_fill_column_indicator_column, Qt) |
| 441 | ? BVAR (current_buffer, fill_column) | 442 | ? BVAR (current_buffer, fill_column) |
| 442 | : Vdisplay_fill_column_indicator_column); | 443 | : Vdisplay_fill_column_indicator_column); |
| 444 | |||
| 445 | /* The stretch width needs to consider the latter | ||
| 446 | added glyph in append_space_for_newline. */ | ||
| 443 | if (RANGED_FIXNUMP (0, col, INT_MAX)) | 447 | if (RANGED_FIXNUMP (0, col, INT_MAX)) |
| 444 | return XFIXNUM (col); | 448 | { |
| 449 | int icol = XFIXNUM (col); | ||
| 450 | if (!INT_MULTIPLY_WRAPV (char_width, icol, &icol) | ||
| 451 | && !INT_ADD_WRAPV (it->lnum_pixel_width, icol, &icol)) | ||
| 452 | return icol; | ||
| 453 | } | ||
| 445 | } | 454 | } |
| 446 | return -1; | 455 | return -1; |
| 447 | } | 456 | } |
| @@ -984,7 +993,7 @@ static int handle_display_spec (struct it *, Lisp_Object, Lisp_Object, | |||
| 984 | static int handle_single_display_spec (struct it *, Lisp_Object, Lisp_Object, | 993 | static int handle_single_display_spec (struct it *, Lisp_Object, Lisp_Object, |
| 985 | Lisp_Object, struct text_pos *, | 994 | Lisp_Object, struct text_pos *, |
| 986 | ptrdiff_t, int, bool, bool); | 995 | ptrdiff_t, int, bool, bool); |
| 987 | static int underlying_face_id (struct it *); | 996 | static int underlying_face_id (const struct it *); |
| 988 | 997 | ||
| 989 | #define face_before_it_pos(IT) face_before_or_after_it_pos (IT, true) | 998 | #define face_before_it_pos(IT) face_before_or_after_it_pos (IT, true) |
| 990 | #define face_after_it_pos(IT) face_before_or_after_it_pos (IT, false) | 999 | #define face_after_it_pos(IT) face_before_or_after_it_pos (IT, false) |
| @@ -4148,56 +4157,20 @@ handle_fontified_prop (struct it *it) | |||
| 4148 | Faces | 4157 | Faces |
| 4149 | ***********************************************************************/ | 4158 | ***********************************************************************/ |
| 4150 | 4159 | ||
| 4151 | /* Set up iterator IT from face properties at its current position. | 4160 | static int |
| 4152 | Called from handle_stop. */ | 4161 | face_at_pos (const struct it *it, enum lface_attribute_index attr_filter) |
| 4153 | |||
| 4154 | static enum prop_handled | ||
| 4155 | handle_face_prop (struct it *it) | ||
| 4156 | { | 4162 | { |
| 4157 | int new_face_id; | ||
| 4158 | ptrdiff_t next_stop; | 4163 | ptrdiff_t next_stop; |
| 4159 | 4164 | ||
| 4160 | if (!STRINGP (it->string)) | 4165 | if (!STRINGP (it->string)) |
| 4161 | { | 4166 | { |
| 4162 | new_face_id | 4167 | return face_at_buffer_position (it->w, |
| 4163 | = face_at_buffer_position (it->w, | 4168 | IT_CHARPOS (*it), |
| 4164 | IT_CHARPOS (*it), | 4169 | &next_stop, |
| 4165 | &next_stop, | 4170 | (IT_CHARPOS (*it) |
| 4166 | (IT_CHARPOS (*it) | 4171 | + TEXT_PROP_DISTANCE_LIMIT), |
| 4167 | + TEXT_PROP_DISTANCE_LIMIT), | 4172 | false, it->base_face_id, |
| 4168 | false, it->base_face_id); | 4173 | attr_filter); |
| 4169 | |||
| 4170 | /* Is this a start of a run of characters with box face? | ||
| 4171 | Caveat: this can be called for a freshly initialized | ||
| 4172 | iterator; face_id is -1 in this case. We know that the new | ||
| 4173 | face will not change until limit, i.e. if the new face has a | ||
| 4174 | box, all characters up to limit will have one. But, as | ||
| 4175 | usual, we don't know whether limit is really the end. */ | ||
| 4176 | if (new_face_id != it->face_id) | ||
| 4177 | { | ||
| 4178 | struct face *new_face = FACE_FROM_ID (it->f, new_face_id); | ||
| 4179 | /* If it->face_id is -1, old_face below will be NULL, see | ||
| 4180 | the definition of FACE_FROM_ID_OR_NULL. This will happen | ||
| 4181 | if this is the initial call that gets the face. */ | ||
| 4182 | struct face *old_face = FACE_FROM_ID_OR_NULL (it->f, it->face_id); | ||
| 4183 | |||
| 4184 | /* If the value of face_id of the iterator is -1, we have to | ||
| 4185 | look in front of IT's position and see whether there is a | ||
| 4186 | face there that's different from new_face_id. */ | ||
| 4187 | if (!old_face && IT_CHARPOS (*it) > BEG) | ||
| 4188 | { | ||
| 4189 | int prev_face_id = face_before_it_pos (it); | ||
| 4190 | |||
| 4191 | old_face = FACE_FROM_ID_OR_NULL (it->f, prev_face_id); | ||
| 4192 | } | ||
| 4193 | |||
| 4194 | /* If the new face has a box, but the old face does not, | ||
| 4195 | this is the start of a run of characters with box face, | ||
| 4196 | i.e. this character has a shadow on the left side. */ | ||
| 4197 | it->start_of_box_run_p = (new_face->box != FACE_NO_BOX | ||
| 4198 | && (old_face == NULL || !old_face->box)); | ||
| 4199 | it->face_box_p = new_face->box != FACE_NO_BOX; | ||
| 4200 | } | ||
| 4201 | } | 4174 | } |
| 4202 | else | 4175 | else |
| 4203 | { | 4176 | { |
| @@ -4207,7 +4180,7 @@ handle_face_prop (struct it *it) | |||
| 4207 | Lisp_Object from_overlay | 4180 | Lisp_Object from_overlay |
| 4208 | = (it->current.overlay_string_index >= 0 | 4181 | = (it->current.overlay_string_index >= 0 |
| 4209 | ? it->string_overlays[it->current.overlay_string_index | 4182 | ? it->string_overlays[it->current.overlay_string_index |
| 4210 | % OVERLAY_STRING_CHUNK_SIZE] | 4183 | % OVERLAY_STRING_CHUNK_SIZE] |
| 4211 | : Qnil); | 4184 | : Qnil); |
| 4212 | 4185 | ||
| 4213 | /* See if we got to this string directly or indirectly from | 4186 | /* See if we got to this string directly or indirectly from |
| @@ -4222,7 +4195,7 @@ handle_face_prop (struct it *it) | |||
| 4222 | if (it->stack[i].current.overlay_string_index >= 0) | 4195 | if (it->stack[i].current.overlay_string_index >= 0) |
| 4223 | from_overlay | 4196 | from_overlay |
| 4224 | = it->string_overlays[it->stack[i].current.overlay_string_index | 4197 | = it->string_overlays[it->stack[i].current.overlay_string_index |
| 4225 | % OVERLAY_STRING_CHUNK_SIZE]; | 4198 | % OVERLAY_STRING_CHUNK_SIZE]; |
| 4226 | else if (! NILP (it->stack[i].from_overlay)) | 4199 | else if (! NILP (it->stack[i].from_overlay)) |
| 4227 | from_overlay = it->stack[i].from_overlay; | 4200 | from_overlay = it->stack[i].from_overlay; |
| 4228 | 4201 | ||
| @@ -4237,12 +4210,12 @@ handle_face_prop (struct it *it) | |||
| 4237 | only on text properties and ignores overlays. */ | 4210 | only on text properties and ignores overlays. */ |
| 4238 | base_face_id | 4211 | base_face_id |
| 4239 | = face_for_overlay_string (it->w, | 4212 | = face_for_overlay_string (it->w, |
| 4240 | IT_CHARPOS (*it), | 4213 | IT_CHARPOS (*it), |
| 4241 | &next_stop, | 4214 | &next_stop, |
| 4242 | (IT_CHARPOS (*it) | 4215 | (IT_CHARPOS (*it) |
| 4243 | + TEXT_PROP_DISTANCE_LIMIT), | 4216 | + TEXT_PROP_DISTANCE_LIMIT), |
| 4244 | false, | 4217 | false, |
| 4245 | from_overlay); | 4218 | from_overlay); |
| 4246 | } | 4219 | } |
| 4247 | else | 4220 | else |
| 4248 | { | 4221 | { |
| @@ -4271,35 +4244,60 @@ handle_face_prop (struct it *it) | |||
| 4271 | : underlying_face_id (it); | 4244 | : underlying_face_id (it); |
| 4272 | } | 4245 | } |
| 4273 | 4246 | ||
| 4274 | new_face_id = face_at_string_position (it->w, | 4247 | return face_at_string_position (it->w, |
| 4275 | it->string, | 4248 | it->string, |
| 4276 | IT_STRING_CHARPOS (*it), | 4249 | IT_STRING_CHARPOS (*it), |
| 4277 | bufpos, | 4250 | bufpos, |
| 4278 | &next_stop, | 4251 | &next_stop, |
| 4279 | base_face_id, false); | 4252 | base_face_id, false, |
| 4253 | attr_filter); | ||
| 4254 | } // !STRINGP (it->string)) | ||
| 4255 | } | ||
| 4256 | |||
| 4280 | 4257 | ||
| 4281 | /* Is this a start of a run of characters with box? Caveat: | 4258 | /* Set up iterator IT from face properties at its current position. |
| 4282 | this can be called for a freshly allocated iterator; face_id | 4259 | Called from handle_stop. */ |
| 4283 | is -1 is this case. We know that the new face will not | 4260 | static enum prop_handled |
| 4284 | change until the next check pos, i.e. if the new face has a | 4261 | handle_face_prop (struct it *it) |
| 4285 | box, all characters up to that position will have a | 4262 | { |
| 4286 | box. But, as usual, we don't know whether that position | 4263 | const int new_face_id = face_at_pos (it, 0); |
| 4287 | is really the end. */ | 4264 | |
| 4288 | if (new_face_id != it->face_id) | 4265 | |
| 4266 | /* Is this a start of a run of characters with box face? | ||
| 4267 | Caveat: this can be called for a freshly initialized | ||
| 4268 | iterator; face_id is -1 in this case. We know that the new | ||
| 4269 | face will not change until limit, i.e. if the new face has a | ||
| 4270 | box, all characters up to limit will have one. But, as | ||
| 4271 | usual, we don't know whether limit is really the end. */ | ||
| 4272 | if (new_face_id != it->face_id) | ||
| 4273 | { | ||
| 4274 | struct face *new_face = FACE_FROM_ID (it->f, new_face_id); | ||
| 4275 | /* If it->face_id is -1, old_face below will be NULL, see | ||
| 4276 | the definition of FACE_FROM_ID_OR_NULL. This will happen | ||
| 4277 | if this is the initial call that gets the face. */ | ||
| 4278 | struct face *old_face = FACE_FROM_ID_OR_NULL (it->f, it->face_id); | ||
| 4279 | |||
| 4280 | /* If the value of face_id of the iterator is -1, we have to | ||
| 4281 | look in front of IT's position and see whether there is a | ||
| 4282 | face there that's different from new_face_id. */ | ||
| 4283 | if (!STRINGP (it->string) | ||
| 4284 | && !old_face | ||
| 4285 | && IT_CHARPOS (*it) > BEG) | ||
| 4289 | { | 4286 | { |
| 4290 | struct face *new_face = FACE_FROM_ID (it->f, new_face_id); | 4287 | const int prev_face_id = face_before_it_pos (it); |
| 4291 | struct face *old_face = FACE_FROM_ID_OR_NULL (it->f, it->face_id); | ||
| 4292 | 4288 | ||
| 4293 | /* If new face has a box but old face hasn't, this is the | 4289 | old_face = FACE_FROM_ID_OR_NULL (it->f, prev_face_id); |
| 4294 | start of a run of characters with box, i.e. it has a | ||
| 4295 | shadow on the left side. */ | ||
| 4296 | it->start_of_box_run_p | ||
| 4297 | = new_face->box && (old_face == NULL || !old_face->box); | ||
| 4298 | it->face_box_p = new_face->box != FACE_NO_BOX; | ||
| 4299 | } | 4290 | } |
| 4291 | |||
| 4292 | /* If the new face has a box, but the old face does not, | ||
| 4293 | this is the start of a run of characters with box face, | ||
| 4294 | i.e. this character has a shadow on the left side. */ | ||
| 4295 | it->face_id = new_face_id; | ||
| 4296 | it->start_of_box_run_p = (new_face->box != FACE_NO_BOX | ||
| 4297 | && (old_face == NULL || !old_face->box)); | ||
| 4298 | it->face_box_p = new_face->box != FACE_NO_BOX; | ||
| 4300 | } | 4299 | } |
| 4301 | 4300 | ||
| 4302 | it->face_id = new_face_id; | ||
| 4303 | return HANDLED_NORMALLY; | 4301 | return HANDLED_NORMALLY; |
| 4304 | } | 4302 | } |
| 4305 | 4303 | ||
| @@ -4310,7 +4308,7 @@ handle_face_prop (struct it *it) | |||
| 4310 | Otherwise, use the iterator's base_face_id. */ | 4308 | Otherwise, use the iterator's base_face_id. */ |
| 4311 | 4309 | ||
| 4312 | static int | 4310 | static int |
| 4313 | underlying_face_id (struct it *it) | 4311 | underlying_face_id (const struct it *it) |
| 4314 | { | 4312 | { |
| 4315 | int face_id = it->base_face_id, i; | 4313 | int face_id = it->base_face_id, i; |
| 4316 | 4314 | ||
| @@ -4423,12 +4421,9 @@ face_before_or_after_it_pos (struct it *it, bool before_p) | |||
| 4423 | base_face_id = underlying_face_id (it); | 4421 | base_face_id = underlying_face_id (it); |
| 4424 | 4422 | ||
| 4425 | /* Get the face for ASCII, or unibyte. */ | 4423 | /* Get the face for ASCII, or unibyte. */ |
| 4426 | face_id = face_at_string_position (it->w, | 4424 | face_id = face_at_string_position (it->w, it->string, charpos, |
| 4427 | it->string, | 4425 | bufpos, &next_check_charpos, |
| 4428 | charpos, | 4426 | base_face_id, false, 0); |
| 4429 | bufpos, | ||
| 4430 | &next_check_charpos, | ||
| 4431 | base_face_id, false); | ||
| 4432 | 4427 | ||
| 4433 | /* Correct the face for charsets different from ASCII. Do it | 4428 | /* Correct the face for charsets different from ASCII. Do it |
| 4434 | for the multibyte case only. The face returned above is | 4429 | for the multibyte case only. The face returned above is |
| @@ -4527,7 +4522,7 @@ face_before_or_after_it_pos (struct it *it, bool before_p) | |||
| 4527 | face_id = face_at_buffer_position (it->w, | 4522 | face_id = face_at_buffer_position (it->w, |
| 4528 | CHARPOS (pos), | 4523 | CHARPOS (pos), |
| 4529 | &next_check_charpos, | 4524 | &next_check_charpos, |
| 4530 | limit, false, -1); | 4525 | limit, false, -1, 0); |
| 4531 | 4526 | ||
| 4532 | /* Correct the face for charsets different from ASCII. Do it | 4527 | /* Correct the face for charsets different from ASCII. Do it |
| 4533 | for the multibyte case only. The face returned above is | 4528 | for the multibyte case only. The face returned above is |
| @@ -7638,7 +7633,8 @@ get_next_display_element (struct it *it) | |||
| 7638 | next_face_id | 7633 | next_face_id |
| 7639 | = face_at_string_position (it->w, base_string, | 7634 | = face_at_string_position (it->w, base_string, |
| 7640 | CHARPOS (pos), 0, | 7635 | CHARPOS (pos), 0, |
| 7641 | &ignore, face_id, false); | 7636 | &ignore, face_id, |
| 7637 | false, 0); | ||
| 7642 | it->end_of_box_run_p | 7638 | it->end_of_box_run_p |
| 7643 | = (FACE_FROM_ID (it->f, next_face_id)->box | 7639 | = (FACE_FROM_ID (it->f, next_face_id)->box |
| 7644 | == FACE_NO_BOX); | 7640 | == FACE_NO_BOX); |
| @@ -7649,10 +7645,11 @@ get_next_display_element (struct it *it) | |||
| 7649 | else | 7645 | else |
| 7650 | { | 7646 | { |
| 7651 | next_face_id = | 7647 | next_face_id = |
| 7652 | face_at_buffer_position (it->w, CHARPOS (pos), &ignore, | 7648 | face_at_buffer_position (it->w, CHARPOS (pos), |
| 7649 | &ignore, | ||
| 7653 | CHARPOS (pos) | 7650 | CHARPOS (pos) |
| 7654 | + TEXT_PROP_DISTANCE_LIMIT, | 7651 | + TEXT_PROP_DISTANCE_LIMIT, |
| 7655 | false, -1); | 7652 | false, -1, 0); |
| 7656 | it->end_of_box_run_p | 7653 | it->end_of_box_run_p |
| 7657 | = (FACE_FROM_ID (it->f, next_face_id)->box | 7654 | = (FACE_FROM_ID (it->f, next_face_id)->box |
| 7658 | == FACE_NO_BOX); | 7655 | == FACE_NO_BOX); |
| @@ -21366,80 +21363,78 @@ compute_line_metrics (struct it *it) | |||
| 21366 | static bool | 21363 | static bool |
| 21367 | append_space_for_newline (struct it *it, bool default_face_p) | 21364 | append_space_for_newline (struct it *it, bool default_face_p) |
| 21368 | { | 21365 | { |
| 21369 | #ifdef HAVE_WINDOW_SYSTEM | 21366 | int n = it->glyph_row->used[TEXT_AREA]; |
| 21370 | if (FRAME_WINDOW_P (it->f)) | 21367 | |
| 21368 | if (it->glyph_row->glyphs[TEXT_AREA] + n | ||
| 21369 | < it->glyph_row->glyphs[1 + TEXT_AREA]) | ||
| 21371 | { | 21370 | { |
| 21372 | int n = it->glyph_row->used[TEXT_AREA]; | 21371 | /* Save some values that must not be changed. |
| 21373 | 21372 | Must save IT->c and IT->len because otherwise | |
| 21374 | if (it->glyph_row->glyphs[TEXT_AREA] + n | 21373 | ITERATOR_AT_END_P wouldn't work anymore after |
| 21375 | < it->glyph_row->glyphs[1 + TEXT_AREA]) | 21374 | append_space_for_newline has been called. */ |
| 21376 | { | 21375 | enum display_element_type saved_what = it->what; |
| 21377 | /* Save some values that must not be changed. | 21376 | int saved_c = it->c, saved_len = it->len; |
| 21378 | Must save IT->c and IT->len because otherwise | 21377 | int saved_char_to_display = it->char_to_display; |
| 21379 | ITERATOR_AT_END_P wouldn't work anymore after | 21378 | int saved_x = it->current_x; |
| 21380 | append_space_for_newline has been called. */ | 21379 | const int saved_face_id = it->face_id; |
| 21381 | enum display_element_type saved_what = it->what; | 21380 | bool saved_box_end = it->end_of_box_run_p; |
| 21382 | int saved_c = it->c, saved_len = it->len; | 21381 | struct text_pos saved_pos = it->position; |
| 21383 | int saved_char_to_display = it->char_to_display; | 21382 | Lisp_Object saved_object = it->object; |
| 21384 | int saved_x = it->current_x; | 21383 | struct face *face; |
| 21385 | int saved_face_id = it->face_id; | ||
| 21386 | bool saved_box_end = it->end_of_box_run_p; | ||
| 21387 | struct text_pos saved_pos; | ||
| 21388 | Lisp_Object saved_object; | ||
| 21389 | struct face *face; | ||
| 21390 | 21384 | ||
| 21391 | saved_object = it->object; | 21385 | it->what = IT_CHARACTER; |
| 21392 | saved_pos = it->position; | 21386 | memset (&it->position, 0, sizeof it->position); |
| 21387 | it->object = Qnil; | ||
| 21388 | it->len = 1; | ||
| 21393 | 21389 | ||
| 21394 | it->what = IT_CHARACTER; | 21390 | int char_width = 1; |
| 21395 | memset (&it->position, 0, sizeof it->position); | ||
| 21396 | it->object = Qnil; | ||
| 21397 | it->len = 1; | ||
| 21398 | 21391 | ||
| 21399 | int local_default_face_id = | 21392 | if (default_face_p |
| 21393 | #ifdef HAVE_WINDOW_SYSTEM | ||
| 21394 | || FRAME_WINDOW_P (it->f) | ||
| 21395 | #endif | ||
| 21396 | ) | ||
| 21397 | { | ||
| 21398 | const int local_default_face_id = | ||
| 21400 | lookup_basic_face (it->w, it->f, DEFAULT_FACE_ID); | 21399 | lookup_basic_face (it->w, it->f, DEFAULT_FACE_ID); |
| 21401 | struct face* default_face = | 21400 | struct face* default_face = |
| 21402 | FACE_FROM_ID_OR_NULL (it->f, local_default_face_id); | 21401 | FACE_FROM_ID_OR_NULL (it->f, local_default_face_id); |
| 21403 | 21402 | ||
| 21404 | /* Corner case for when display-fill-column-indicator-mode | 21403 | #ifdef HAVE_WINDOW_SYSTEM |
| 21405 | is active and the extra character should be added in the | 21404 | if (FRAME_WINDOW_P (it->f)) |
| 21406 | same place than the line. */ | 21405 | { |
| 21407 | int indicator_column = (it->w->pseudo_window_p == 0 | 21406 | struct font *font = (default_face->font |
| 21408 | ? fill_column_indicator_column (it) | 21407 | ? default_face->font |
| 21409 | : -1); | 21408 | : FRAME_FONT (it->f)); |
| 21410 | if (indicator_column >= 0) | 21409 | char_width = (font->average_width |
| 21411 | { | 21410 | ? font->average_width |
| 21412 | struct font *font = (default_face->font | 21411 | : font->space_width); |
| 21413 | ? default_face->font | ||
| 21414 | : FRAME_FONT (it->f)); | ||
| 21415 | const int char_width = (font->average_width | ||
| 21416 | ? font->average_width | ||
| 21417 | : font->space_width); | ||
| 21418 | int column_x; | ||
| 21419 | |||
| 21420 | if (!INT_MULTIPLY_WRAPV (indicator_column, char_width, | ||
| 21421 | &column_x) | ||
| 21422 | && !INT_ADD_WRAPV (it->lnum_pixel_width, column_x, | ||
| 21423 | &column_x) | ||
| 21424 | && it->current_x == column_x) | ||
| 21425 | { | ||
| 21426 | it->c = it->char_to_display | ||
| 21427 | = XFIXNAT (Vdisplay_fill_column_indicator_character); | ||
| 21428 | it->face_id | ||
| 21429 | = merge_faces (it->w, Qfill_column_indicator, | ||
| 21430 | 0, saved_face_id); | ||
| 21431 | face = FACE_FROM_ID (it->f, it->face_id); | ||
| 21432 | goto produce_glyphs; | ||
| 21433 | } | ||
| 21434 | } | 21412 | } |
| 21413 | #endif | ||
| 21414 | if (default_face_p) | ||
| 21415 | it->face_id = local_default_face_id; | ||
| 21416 | } | ||
| 21417 | /* Corner case for when display-fill-column-indicator-mode | ||
| 21418 | is active and the extra character should be added in the | ||
| 21419 | same place than the line. */ | ||
| 21420 | |||
| 21421 | const int indicator_column = | ||
| 21422 | fill_column_indicator_column (it, char_width); | ||
| 21435 | 21423 | ||
| 21424 | if (it->current_x == indicator_column) | ||
| 21425 | { | ||
| 21426 | it->c = it->char_to_display | ||
| 21427 | = XFIXNAT (Vdisplay_fill_column_indicator_character); | ||
| 21428 | it->face_id | ||
| 21429 | = merge_faces (it->w, Qfill_column_indicator, | ||
| 21430 | 0, saved_face_id); | ||
| 21431 | face = FACE_FROM_ID (it->f, it->face_id); | ||
| 21432 | } | ||
| 21433 | else | ||
| 21434 | { | ||
| 21436 | it->c = it->char_to_display = ' '; | 21435 | it->c = it->char_to_display = ' '; |
| 21437 | /* If the default face was remapped, be sure to use the | 21436 | /* If the default face was remapped, be sure to use the |
| 21438 | remapped face for the appended newline. */ | 21437 | remapped face for the appended newline. */ |
| 21439 | if (default_face_p) | ||
| 21440 | it->face_id = local_default_face_id; | ||
| 21441 | else if (it->face_before_selective_p) | ||
| 21442 | it->face_id = it->saved_face_id; | ||
| 21443 | 21438 | ||
| 21444 | face = FACE_FROM_ID (it->f, it->face_id); | 21439 | face = FACE_FROM_ID (it->f, it->face_id); |
| 21445 | it->face_id = FACE_FOR_CHAR (it->f, face, 0, -1, Qnil); | 21440 | it->face_id = FACE_FOR_CHAR (it->f, face, 0, -1, Qnil); |
| @@ -21453,10 +21448,11 @@ append_space_for_newline (struct it *it, bool default_face_p) | |||
| 21453 | so leave the box flag set. */ | 21448 | so leave the box flag set. */ |
| 21454 | && saved_x + FRAME_COLUMN_WIDTH (it->f) < it->last_visible_x) | 21449 | && saved_x + FRAME_COLUMN_WIDTH (it->f) < it->last_visible_x) |
| 21455 | it->end_of_box_run_p = false; | 21450 | it->end_of_box_run_p = false; |
| 21456 | 21451 | } | |
| 21457 | produce_glyphs: | 21452 | PRODUCE_GLYPHS (it); |
| 21458 | PRODUCE_GLYPHS (it); | 21453 | #ifdef HAVE_WINDOW_SYSTEM |
| 21459 | 21454 | if (FRAME_WINDOW_P (it->f)) | |
| 21455 | { | ||
| 21460 | /* Make sure this space glyph has the right ascent and | 21456 | /* Make sure this space glyph has the right ascent and |
| 21461 | descent values, or else cursor at end of line will look | 21457 | descent values, or else cursor at end of line will look |
| 21462 | funny, and height of empty lines will be incorrect. */ | 21458 | funny, and height of empty lines will be incorrect. */ |
| @@ -21477,8 +21473,8 @@ append_space_for_newline (struct it *it, bool default_face_p) | |||
| 21477 | gui_produce_glyph for newline characters. */ | 21473 | gui_produce_glyph for newline characters. */ |
| 21478 | height = get_it_property (it, Qline_height); | 21474 | height = get_it_property (it, Qline_height); |
| 21479 | if (CONSP (height) | 21475 | if (CONSP (height) |
| 21480 | && CONSP (XCDR (height)) | 21476 | && CONSP (XCDR (height)) |
| 21481 | && NILP (XCDR (XCDR (height)))) | 21477 | && NILP (XCDR (XCDR (height)))) |
| 21482 | { | 21478 | { |
| 21483 | total_height = XCAR (XCDR (height)); | 21479 | total_height = XCAR (XCDR (height)); |
| 21484 | height = XCAR (height); | 21480 | height = XCAR (height); |
| @@ -21507,12 +21503,12 @@ append_space_for_newline (struct it *it, bool default_face_p) | |||
| 21507 | 21503 | ||
| 21508 | if (!NILP (total_height)) | 21504 | if (!NILP (total_height)) |
| 21509 | spacing = calc_line_height_property (it, total_height, font, | 21505 | spacing = calc_line_height_property (it, total_height, font, |
| 21510 | boff, false); | 21506 | boff, false); |
| 21511 | else | 21507 | else |
| 21512 | { | 21508 | { |
| 21513 | spacing = get_it_property (it, Qline_spacing); | 21509 | spacing = get_it_property (it, Qline_spacing); |
| 21514 | spacing = calc_line_height_property (it, spacing, font, | 21510 | spacing = calc_line_height_property (it, spacing, font, |
| 21515 | boff, false); | 21511 | boff, false); |
| 21516 | } | 21512 | } |
| 21517 | if (FIXNUMP (spacing)) | 21513 | if (FIXNUMP (spacing)) |
| 21518 | { | 21514 | { |
| @@ -21535,22 +21531,21 @@ append_space_for_newline (struct it *it, bool default_face_p) | |||
| 21535 | 21531 | ||
| 21536 | g->ascent = it->max_ascent; | 21532 | g->ascent = it->max_ascent; |
| 21537 | g->descent = it->max_descent; | 21533 | g->descent = it->max_descent; |
| 21538 | |||
| 21539 | it->override_ascent = -1; | ||
| 21540 | it->constrain_row_ascent_descent_p = false; | ||
| 21541 | it->current_x = saved_x; | ||
| 21542 | it->object = saved_object; | ||
| 21543 | it->position = saved_pos; | ||
| 21544 | it->what = saved_what; | ||
| 21545 | it->face_id = saved_face_id; | ||
| 21546 | it->len = saved_len; | ||
| 21547 | it->c = saved_c; | ||
| 21548 | it->char_to_display = saved_char_to_display; | ||
| 21549 | it->end_of_box_run_p = saved_box_end; | ||
| 21550 | return true; | ||
| 21551 | } | 21534 | } |
| 21535 | #endif /* HAVE_WINDOW_SYSTEM */ | ||
| 21536 | it->override_ascent = -1; | ||
| 21537 | it->constrain_row_ascent_descent_p = false; | ||
| 21538 | it->current_x = saved_x; | ||
| 21539 | it->object = saved_object; | ||
| 21540 | it->position = saved_pos; | ||
| 21541 | it->what = saved_what; | ||
| 21542 | it->face_id = saved_face_id; | ||
| 21543 | it->len = saved_len; | ||
| 21544 | it->c = saved_c; | ||
| 21545 | it->char_to_display = saved_char_to_display; | ||
| 21546 | it->end_of_box_run_p = saved_box_end; | ||
| 21547 | return true; | ||
| 21552 | } | 21548 | } |
| 21553 | #endif | ||
| 21554 | 21549 | ||
| 21555 | return false; | 21550 | return false; |
| 21556 | } | 21551 | } |
| @@ -21566,7 +21561,6 @@ append_space_for_newline (struct it *it, bool default_face_p) | |||
| 21566 | static void | 21561 | static void |
| 21567 | extend_face_to_end_of_line (struct it *it) | 21562 | extend_face_to_end_of_line (struct it *it) |
| 21568 | { | 21563 | { |
| 21569 | struct face *face; | ||
| 21570 | struct frame *f = it->f; | 21564 | struct frame *f = it->f; |
| 21571 | 21565 | ||
| 21572 | /* If line is already filled, do nothing. Non window-system frames | 21566 | /* If line is already filled, do nothing. Non window-system frames |
| @@ -21584,12 +21578,17 @@ extend_face_to_end_of_line (struct it *it) | |||
| 21584 | || WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0)) | 21578 | || WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0)) |
| 21585 | return; | 21579 | return; |
| 21586 | 21580 | ||
| 21587 | /* Face extension extends the background and box of IT->face_id | 21581 | const int extend_face_id = (it->face_id == DEFAULT_FACE_ID |
| 21582 | || it->s != NULL) | ||
| 21583 | ? DEFAULT_FACE_ID | ||
| 21584 | : face_at_pos (it, LFACE_EXTEND_INDEX); | ||
| 21585 | |||
| 21586 | /* Face extension extends the background and box of IT->extend_face_id | ||
| 21588 | to the end of the line. If the background equals the background | 21587 | to the end of the line. If the background equals the background |
| 21589 | of the frame, we don't have to do anything. */ | 21588 | of the frame, we don't have to do anything. */ |
| 21590 | face = FACE_FROM_ID (f, (it->face_before_selective_p | 21589 | struct face *face = FACE_FROM_ID (f, (it->face_before_selective_p |
| 21591 | ? it->saved_face_id | 21590 | ? it->saved_face_id |
| 21592 | : it->face_id)); | 21591 | : extend_face_id)); |
| 21593 | 21592 | ||
| 21594 | if (FRAME_WINDOW_P (f) | 21593 | if (FRAME_WINDOW_P (f) |
| 21595 | && MATRIX_ROW_DISPLAYS_TEXT_P (it->glyph_row) | 21594 | && MATRIX_ROW_DISPLAYS_TEXT_P (it->glyph_row) |
| @@ -21612,9 +21611,7 @@ extend_face_to_end_of_line (struct it *it) | |||
| 21612 | that the character will always be single byte in unibyte | 21611 | that the character will always be single byte in unibyte |
| 21613 | text. */ | 21612 | text. */ |
| 21614 | if (!ASCII_CHAR_P (it->c)) | 21613 | if (!ASCII_CHAR_P (it->c)) |
| 21615 | { | ||
| 21616 | it->face_id = FACE_FOR_CHAR (f, face, 0, -1, Qnil); | 21614 | it->face_id = FACE_FOR_CHAR (f, face, 0, -1, Qnil); |
| 21617 | } | ||
| 21618 | 21615 | ||
| 21619 | /* The default face, possibly remapped. */ | 21616 | /* The default face, possibly remapped. */ |
| 21620 | struct face *default_face = | 21617 | struct face *default_face = |
| @@ -21665,79 +21662,81 @@ extend_face_to_end_of_line (struct it *it) | |||
| 21665 | /* Display fill column indicator if not in modeline or | 21662 | /* Display fill column indicator if not in modeline or |
| 21666 | toolbar and display fill column indicator mode is | 21663 | toolbar and display fill column indicator mode is |
| 21667 | active. */ | 21664 | active. */ |
| 21668 | int indicator_column = (it->w->pseudo_window_p == 0 | 21665 | |
| 21669 | ? fill_column_indicator_column (it) | 21666 | struct font *font = (default_face->font |
| 21670 | : -1); | 21667 | ? default_face->font |
| 21671 | if (indicator_column >= 0) | 21668 | : FRAME_FONT (f)); |
| 21669 | |||
| 21670 | const int char_width = (font->average_width | ||
| 21671 | ? font->average_width | ||
| 21672 | : font->space_width); | ||
| 21673 | |||
| 21674 | const int indicator_column = | ||
| 21675 | fill_column_indicator_column (it, char_width); | ||
| 21676 | |||
| 21677 | const char saved_char = it->char_to_display; | ||
| 21678 | const struct text_pos saved_pos = it->position; | ||
| 21679 | const bool saved_avoid_cursor = it->avoid_cursor_p; | ||
| 21680 | const bool saved_box_start = it->start_of_box_run_p; | ||
| 21681 | Lisp_Object save_object = it->object; | ||
| 21682 | const int saved_face_id = it->face_id; | ||
| 21683 | |||
| 21684 | it->face_id = extend_face_id; | ||
| 21685 | it->avoid_cursor_p = true; | ||
| 21686 | it->object = Qnil; | ||
| 21687 | |||
| 21688 | if (indicator_column >= 0 | ||
| 21689 | && indicator_column > it->current_x | ||
| 21690 | && indicator_column < it->last_visible_x) | ||
| 21672 | { | 21691 | { |
| 21673 | struct font *font = (default_face->font | ||
| 21674 | ? default_face->font | ||
| 21675 | : FRAME_FONT (f)); | ||
| 21676 | const int char_width = (font->average_width | ||
| 21677 | ? font->average_width | ||
| 21678 | : font->space_width); | ||
| 21679 | int column_x; | ||
| 21680 | |||
| 21681 | if (!INT_MULTIPLY_WRAPV (indicator_column, char_width, &column_x) | ||
| 21682 | && !INT_ADD_WRAPV (it->lnum_pixel_width, column_x, &column_x) | ||
| 21683 | && column_x >= it->current_x | ||
| 21684 | && column_x <= it->last_visible_x) | ||
| 21685 | { | ||
| 21686 | const char saved_char = it->char_to_display; | ||
| 21687 | const struct text_pos saved_pos = it->position; | ||
| 21688 | const bool saved_avoid_cursor = it->avoid_cursor_p; | ||
| 21689 | const int saved_face_id = it->face_id; | ||
| 21690 | const bool saved_box_start = it->start_of_box_run_p; | ||
| 21691 | Lisp_Object save_object = it->object; | ||
| 21692 | |||
| 21693 | /* The stretch width needs to considet the latter | ||
| 21694 | added glyph. */ | ||
| 21695 | const int stretch_width | ||
| 21696 | = column_x - it->current_x - char_width; | ||
| 21697 | |||
| 21698 | memset (&it->position, 0, sizeof it->position); | ||
| 21699 | it->avoid_cursor_p = true; | ||
| 21700 | it->object = Qnil; | ||
| 21701 | |||
| 21702 | /* Only generate a stretch glyph if there is distance | ||
| 21703 | between current_x and and the indicator position. */ | ||
| 21704 | if (stretch_width > 0) | ||
| 21705 | { | ||
| 21706 | int stretch_ascent = (((it->ascent + it->descent) | ||
| 21707 | * FONT_BASE (font)) / FONT_HEIGHT (font)); | ||
| 21708 | append_stretch_glyph (it, Qnil, stretch_width, | ||
| 21709 | it->ascent + it->descent, | ||
| 21710 | stretch_ascent); | ||
| 21711 | } | ||
| 21712 | 21692 | ||
| 21713 | /* Generate the glyph indicator only if | 21693 | /* Here we substract char_width because we want the |
| 21714 | append_space_for_newline didn't already. */ | 21694 | column indicator in the column INDICATOR_COLUMN, not |
| 21715 | if (it->current_x < column_x) | 21695 | after it. */ |
| 21716 | { | 21696 | const int stretch_width = |
| 21717 | it->char_to_display | 21697 | indicator_column - it->current_x - char_width; |
| 21718 | = XFIXNAT (Vdisplay_fill_column_indicator_character); | 21698 | |
| 21719 | it->face_id | 21699 | memset (&it->position, 0, sizeof it->position); |
| 21720 | = merge_faces (it->w, Qfill_column_indicator, | 21700 | |
| 21721 | 0, saved_face_id); | 21701 | /* Only generate a stretch glyph if there is distance |
| 21722 | PRODUCE_GLYPHS (it); | 21702 | between current_x and and the indicator position. */ |
| 21723 | } | 21703 | if (stretch_width > 0) |
| 21724 | 21704 | { | |
| 21725 | /* Restore the face after the indicator was generated. */ | 21705 | int stretch_ascent = (((it->ascent + it->descent) |
| 21726 | it->face_id = saved_face_id; | 21706 | * FONT_BASE (font)) / FONT_HEIGHT (font)); |
| 21727 | 21707 | append_stretch_glyph (it, Qnil, stretch_width, | |
| 21728 | /* If there is space after the indicator generate an | 21708 | it->ascent + it->descent, |
| 21729 | extra empty glyph to restore the face. Issue was | 21709 | stretch_ascent); |
| 21730 | observed in X systems. */ | 21710 | } |
| 21731 | it->char_to_display = ' '; | 21711 | |
| 21732 | PRODUCE_GLYPHS (it); | 21712 | /* Generate the glyph indicator only if |
| 21733 | 21713 | append_space_for_newline didn't already. */ | |
| 21734 | it->char_to_display = saved_char; | 21714 | if (it->current_x < indicator_column) |
| 21735 | it->position = saved_pos; | 21715 | { |
| 21736 | it->avoid_cursor_p = saved_avoid_cursor; | 21716 | const int save_face_id = it->face_id; |
| 21737 | it->start_of_box_run_p = saved_box_start; | 21717 | it->char_to_display |
| 21738 | it->object = save_object; | 21718 | = XFIXNAT (Vdisplay_fill_column_indicator_character); |
| 21739 | } | 21719 | it->face_id |
| 21720 | = merge_faces (it->w, Qfill_column_indicator, | ||
| 21721 | 0, extend_face_id); | ||
| 21722 | PRODUCE_GLYPHS (it); | ||
| 21723 | it->face_id = save_face_id; | ||
| 21724 | } | ||
| 21740 | } | 21725 | } |
| 21726 | |||
| 21727 | /* If there is space after the indicator generate an | ||
| 21728 | extra empty glyph to restore the face. Issue was | ||
| 21729 | observed in X systems. */ | ||
| 21730 | it->char_to_display = ' '; | ||
| 21731 | PRODUCE_GLYPHS (it); | ||
| 21732 | |||
| 21733 | it->char_to_display = saved_char; | ||
| 21734 | it->position = saved_pos; | ||
| 21735 | it->avoid_cursor_p = saved_avoid_cursor; | ||
| 21736 | it->start_of_box_run_p = saved_box_start; | ||
| 21737 | it->object = save_object; | ||
| 21738 | it->face_id = saved_face_id; | ||
| 21739 | |||
| 21741 | } | 21740 | } |
| 21742 | if (it->glyph_row->reversed_p) | 21741 | if (it->glyph_row->reversed_p) |
| 21743 | { | 21742 | { |
| @@ -21783,10 +21782,9 @@ extend_face_to_end_of_line (struct it *it) | |||
| 21783 | /* The last row's stretch glyph should get the default | 21782 | /* The last row's stretch glyph should get the default |
| 21784 | face, to avoid painting the rest of the window with | 21783 | face, to avoid painting the rest of the window with |
| 21785 | the region face, if the region ends at ZV. */ | 21784 | the region face, if the region ends at ZV. */ |
| 21786 | if (it->glyph_row->ends_at_zv_p) | 21785 | it->face_id = (it->glyph_row->ends_at_zv_p ? |
| 21787 | it->face_id = default_face->id; | 21786 | default_face->id : face->id); |
| 21788 | else | 21787 | |
| 21789 | it->face_id = face->id; | ||
| 21790 | it->start_of_box_run_p = false; | 21788 | it->start_of_box_run_p = false; |
| 21791 | append_stretch_glyph (it, Qnil, stretch_width, | 21789 | append_stretch_glyph (it, Qnil, stretch_width, |
| 21792 | it->ascent + it->descent, stretch_ascent); | 21790 | it->ascent + it->descent, stretch_ascent); |
| @@ -21808,14 +21806,11 @@ extend_face_to_end_of_line (struct it *it) | |||
| 21808 | { | 21806 | { |
| 21809 | /* Save some values that must not be changed. */ | 21807 | /* Save some values that must not be changed. */ |
| 21810 | int saved_x = it->current_x; | 21808 | int saved_x = it->current_x; |
| 21811 | struct text_pos saved_pos; | 21809 | struct text_pos saved_pos = it->position; |
| 21812 | Lisp_Object saved_object; | 21810 | Lisp_Object saved_object = it->object;; |
| 21813 | enum display_element_type saved_what = it->what; | 21811 | enum display_element_type saved_what = it->what; |
| 21814 | int saved_face_id = it->face_id; | 21812 | int saved_face_id = it->face_id; |
| 21815 | 21813 | ||
| 21816 | saved_object = it->object; | ||
| 21817 | saved_pos = it->position; | ||
| 21818 | |||
| 21819 | it->what = IT_CHARACTER; | 21814 | it->what = IT_CHARACTER; |
| 21820 | memset (&it->position, 0, sizeof it->position); | 21815 | memset (&it->position, 0, sizeof it->position); |
| 21821 | it->object = Qnil; | 21816 | it->object = Qnil; |
| @@ -21854,34 +21849,31 @@ extend_face_to_end_of_line (struct it *it) | |||
| 21854 | /* The last row's blank glyphs should get the default face, to | 21849 | /* The last row's blank glyphs should get the default face, to |
| 21855 | avoid painting the rest of the window with the region face, | 21850 | avoid painting the rest of the window with the region face, |
| 21856 | if the region ends at ZV. */ | 21851 | if the region ends at ZV. */ |
| 21857 | if (it->glyph_row->ends_at_zv_p) | 21852 | it->face_id = (it->glyph_row->ends_at_zv_p ? |
| 21858 | it->face_id = default_face->id; | 21853 | default_face->id : face->id); |
| 21859 | else | ||
| 21860 | it->face_id = face->id; | ||
| 21861 | 21854 | ||
| 21862 | /* Display fill-column indicator if needed. */ | 21855 | /* Display fill-column indicator if needed. */ |
| 21863 | int indicator_column = fill_column_indicator_column (it); | 21856 | /* We need to subtract 1 to the indicator_column here because we |
| 21864 | if (indicator_column >= 0 | 21857 | will add the indicator IN the column indicator number, not |
| 21865 | && INT_ADD_WRAPV (it->lnum_pixel_width, indicator_column, | 21858 | after it. We compare the variable it->current_x before |
| 21866 | &indicator_column)) | 21859 | producing the glyph. When FRAME_WINDOW_P we substract |
| 21867 | indicator_column = -1; | 21860 | CHAR_WIDTH calculating STRETCH_WIDTH for the same reason. */ |
| 21861 | const int indicator_column = | ||
| 21862 | fill_column_indicator_column (it, 1) - 1; | ||
| 21868 | do | 21863 | do |
| 21869 | { | 21864 | { |
| 21870 | int saved_face_id; | 21865 | if (it->current_x != indicator_column) |
| 21871 | bool indicate = it->current_x == indicator_column; | 21866 | PRODUCE_GLYPHS (it); |
| 21872 | if (indicate) | 21867 | else |
| 21873 | { | 21868 | { |
| 21874 | saved_face_id = it->face_id; | 21869 | int saved_face_id = it->face_id; |
| 21875 | it->face_id | 21870 | it->face_id |
| 21876 | = merge_faces (it->w, Qfill_column_indicator, 0, saved_face_id); | 21871 | = merge_faces (it->w, Qfill_column_indicator, 0, extend_face_id); |
| 21877 | it->c = it->char_to_display | 21872 | it->c = it->char_to_display |
| 21878 | = XFIXNAT (Vdisplay_fill_column_indicator_character); | 21873 | = XFIXNAT (Vdisplay_fill_column_indicator_character); |
| 21879 | } | ||
| 21880 | 21874 | ||
| 21881 | PRODUCE_GLYPHS (it); | 21875 | PRODUCE_GLYPHS (it); |
| 21882 | 21876 | ||
| 21883 | if (indicate) | ||
| 21884 | { | ||
| 21885 | it->face_id = saved_face_id; | 21877 | it->face_id = saved_face_id; |
| 21886 | it->c = it->char_to_display = ' '; | 21878 | it->c = it->char_to_display = ' '; |
| 21887 | } | 21879 | } |
| @@ -26581,8 +26573,8 @@ display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_st | |||
| 26581 | 26573 | ||
| 26582 | /* Initialize the iterator IT for iteration over STRING beginning | 26574 | /* Initialize the iterator IT for iteration over STRING beginning |
| 26583 | with index START. */ | 26575 | with index START. */ |
| 26584 | reseat_to_string (it, NILP (lisp_string) ? string : NULL, lisp_string, start, | 26576 | reseat_to_string (it, NILP (lisp_string) ? string : NULL, lisp_string, |
| 26585 | precision, field_width, multibyte); | 26577 | start, precision, field_width, multibyte); |
| 26586 | if (string && STRINGP (lisp_string)) | 26578 | if (string && STRINGP (lisp_string)) |
| 26587 | /* LISP_STRING is the one returned by decode_mode_spec. We should | 26579 | /* LISP_STRING is the one returned by decode_mode_spec. We should |
| 26588 | ignore its text properties. */ | 26580 | ignore its text properties. */ |
| @@ -26597,7 +26589,7 @@ display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_st | |||
| 26597 | 26589 | ||
| 26598 | it->face_id | 26590 | it->face_id |
| 26599 | = face_at_string_position (it->w, face_string, face_string_pos, | 26591 | = face_at_string_position (it->w, face_string, face_string_pos, |
| 26600 | 0, &endptr, it->base_face_id, false); | 26592 | 0, &endptr, it->base_face_id, false, 0); |
| 26601 | face = FACE_FROM_ID (it->f, it->face_id); | 26593 | face = FACE_FROM_ID (it->f, it->face_id); |
| 26602 | it->face_box_p = face->box != FACE_NO_BOX; | 26594 | it->face_box_p = face->box != FACE_NO_BOX; |
| 26603 | } | 26595 | } |
| @@ -28502,7 +28494,7 @@ font_for_underline_metrics (struct glyph_string *s) | |||
| 28502 | for (g = s->first_glyph - 1; g >= g0; g--) | 28494 | for (g = s->first_glyph - 1; g >= g0; g--) |
| 28503 | { | 28495 | { |
| 28504 | struct face *prev_face = FACE_FROM_ID (s->f, g->face_id); | 28496 | struct face *prev_face = FACE_FROM_ID (s->f, g->face_id); |
| 28505 | if (!(prev_face && prev_face->underline_p)) | 28497 | if (!(prev_face && prev_face->underline != FACE_NO_UNDERLINE)) |
| 28506 | break; | 28498 | break; |
| 28507 | } | 28499 | } |
| 28508 | 28500 | ||
| @@ -32068,7 +32060,7 @@ mouse_face_from_buffer_pos (Lisp_Object window, | |||
| 32068 | hlinfo->mouse_face_face_id | 32060 | hlinfo->mouse_face_face_id |
| 32069 | = face_at_buffer_position (w, mouse_charpos, &ignore, | 32061 | = face_at_buffer_position (w, mouse_charpos, &ignore, |
| 32070 | mouse_charpos + 1, | 32062 | mouse_charpos + 1, |
| 32071 | !hlinfo->mouse_face_hidden, -1); | 32063 | !hlinfo->mouse_face_hidden, -1, 0); |
| 32072 | show_mouse_face (hlinfo, DRAW_MOUSE_FACE); | 32064 | show_mouse_face (hlinfo, DRAW_MOUSE_FACE); |
| 32073 | } | 32065 | } |
| 32074 | 32066 | ||
| @@ -32757,11 +32749,10 @@ note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y, | |||
| 32757 | hlinfo->mouse_face_past_end = false; | 32749 | hlinfo->mouse_face_past_end = false; |
| 32758 | hlinfo->mouse_face_window = window; | 32750 | hlinfo->mouse_face_window = window; |
| 32759 | 32751 | ||
| 32760 | hlinfo->mouse_face_face_id = face_at_string_position (w, string, | 32752 | hlinfo->mouse_face_face_id = |
| 32761 | charpos, | 32753 | face_at_string_position (w, string, charpos, 0, &ignore, |
| 32762 | 0, &ignore, | 32754 | glyph->face_id, true, 0); |
| 32763 | glyph->face_id, | 32755 | |
| 32764 | true); | ||
| 32765 | show_mouse_face (hlinfo, DRAW_MOUSE_FACE); | 32756 | show_mouse_face (hlinfo, DRAW_MOUSE_FACE); |
| 32766 | mouse_face_shown = true; | 32757 | mouse_face_shown = true; |
| 32767 | 32758 | ||
| @@ -33187,7 +33178,7 @@ note_mouse_highlight (struct frame *f, int x, int y) | |||
| 33187 | hlinfo->mouse_face_window = window; | 33178 | hlinfo->mouse_face_window = window; |
| 33188 | hlinfo->mouse_face_face_id | 33179 | hlinfo->mouse_face_face_id |
| 33189 | = face_at_string_position (w, object, pos, 0, &ignore, | 33180 | = face_at_string_position (w, object, pos, 0, &ignore, |
| 33190 | glyph->face_id, true); | 33181 | glyph->face_id, true, 0); |
| 33191 | show_mouse_face (hlinfo, DRAW_MOUSE_FACE); | 33182 | show_mouse_face (hlinfo, DRAW_MOUSE_FACE); |
| 33192 | cursor = No_Cursor; | 33183 | cursor = No_Cursor; |
| 33193 | } | 33184 | } |
diff --git a/src/xfaces.c b/src/xfaces.c index 0c99eea1567..5a741ae8cc6 100644 --- a/src/xfaces.c +++ b/src/xfaces.c | |||
| @@ -347,7 +347,8 @@ static struct face_cache *make_face_cache (struct frame *); | |||
| 347 | static void free_face_cache (struct face_cache *); | 347 | static void free_face_cache (struct face_cache *); |
| 348 | static bool merge_face_ref (struct window *w, | 348 | static bool merge_face_ref (struct window *w, |
| 349 | struct frame *, Lisp_Object, Lisp_Object *, | 349 | struct frame *, Lisp_Object, Lisp_Object *, |
| 350 | bool, struct named_merge_point *); | 350 | bool, struct named_merge_point *, |
| 351 | enum lface_attribute_index); | ||
| 351 | static int color_distance (Emacs_Color *x, Emacs_Color *y); | 352 | static int color_distance (Emacs_Color *x, Emacs_Color *y); |
| 352 | 353 | ||
| 353 | #ifdef HAVE_WINDOW_SYSTEM | 354 | #ifdef HAVE_WINDOW_SYSTEM |
| @@ -1209,7 +1210,7 @@ free_face_colors (struct frame *f, struct face *face) | |||
| 1209 | IF_DEBUG (--ncolors_allocated); | 1210 | IF_DEBUG (--ncolors_allocated); |
| 1210 | } | 1211 | } |
| 1211 | 1212 | ||
| 1212 | if (face->underline_p | 1213 | if (face->underline |
| 1213 | && !face->underline_defaulted_p) | 1214 | && !face->underline_defaulted_p) |
| 1214 | { | 1215 | { |
| 1215 | x_free_colors (f, &face->underline_color, 1); | 1216 | x_free_colors (f, &face->underline_color, 1); |
| @@ -1590,6 +1591,7 @@ the WIDTH times as wide as FACE on FRAME. */) | |||
| 1590 | #define LFACE_FONT(LFACE) AREF ((LFACE), LFACE_FONT_INDEX) | 1591 | #define LFACE_FONT(LFACE) AREF ((LFACE), LFACE_FONT_INDEX) |
| 1591 | #define LFACE_INHERIT(LFACE) AREF ((LFACE), LFACE_INHERIT_INDEX) | 1592 | #define LFACE_INHERIT(LFACE) AREF ((LFACE), LFACE_INHERIT_INDEX) |
| 1592 | #define LFACE_FONTSET(LFACE) AREF ((LFACE), LFACE_FONTSET_INDEX) | 1593 | #define LFACE_FONTSET(LFACE) AREF ((LFACE), LFACE_FONTSET_INDEX) |
| 1594 | #define LFACE_EXTEND(LFACE) AREF ((LFACE), LFACE_EXTEND_INDEX) | ||
| 1593 | #define LFACE_DISTANT_FOREGROUND(LFACE) \ | 1595 | #define LFACE_DISTANT_FOREGROUND(LFACE) \ |
| 1594 | AREF ((LFACE), LFACE_DISTANT_FOREGROUND_INDEX) | 1596 | AREF ((LFACE), LFACE_DISTANT_FOREGROUND_INDEX) |
| 1595 | 1597 | ||
| @@ -1633,6 +1635,10 @@ check_lface_attrs (Lisp_Object attrs[LFACE_VECTOR_SIZE]) | |||
| 1633 | || SYMBOLP (attrs[LFACE_UNDERLINE_INDEX]) | 1635 | || SYMBOLP (attrs[LFACE_UNDERLINE_INDEX]) |
| 1634 | || STRINGP (attrs[LFACE_UNDERLINE_INDEX]) | 1636 | || STRINGP (attrs[LFACE_UNDERLINE_INDEX]) |
| 1635 | || CONSP (attrs[LFACE_UNDERLINE_INDEX])); | 1637 | || CONSP (attrs[LFACE_UNDERLINE_INDEX])); |
| 1638 | eassert (UNSPECIFIEDP (attrs[LFACE_EXTEND_INDEX]) | ||
| 1639 | || IGNORE_DEFFACE_P (attrs[LFACE_EXTEND_INDEX]) | ||
| 1640 | || SYMBOLP (attrs[LFACE_EXTEND_INDEX]) | ||
| 1641 | || STRINGP (attrs[LFACE_EXTEND_INDEX])); | ||
| 1636 | eassert (UNSPECIFIEDP (attrs[LFACE_OVERLINE_INDEX]) | 1642 | eassert (UNSPECIFIEDP (attrs[LFACE_OVERLINE_INDEX]) |
| 1637 | || IGNORE_DEFFACE_P (attrs[LFACE_OVERLINE_INDEX]) | 1643 | || IGNORE_DEFFACE_P (attrs[LFACE_OVERLINE_INDEX]) |
| 1638 | || SYMBOLP (attrs[LFACE_OVERLINE_INDEX]) | 1644 | || SYMBOLP (attrs[LFACE_OVERLINE_INDEX]) |
| @@ -1905,7 +1911,8 @@ get_lface_attributes (struct window *w, | |||
| 1905 | attrs[i] = Qunspecified; | 1911 | attrs[i] = Qunspecified; |
| 1906 | 1912 | ||
| 1907 | return merge_face_ref (w, f, XCDR (face_remapping), attrs, | 1913 | return merge_face_ref (w, f, XCDR (face_remapping), attrs, |
| 1908 | signal_p, named_merge_points); | 1914 | signal_p, named_merge_points, |
| 1915 | 0); | ||
| 1909 | } | 1916 | } |
| 1910 | } | 1917 | } |
| 1911 | 1918 | ||
| @@ -2060,7 +2067,8 @@ merge_face_vectors (struct window *w, | |||
| 2060 | if (!UNSPECIFIEDP (from[LFACE_INHERIT_INDEX]) | 2067 | if (!UNSPECIFIEDP (from[LFACE_INHERIT_INDEX]) |
| 2061 | && !NILP (from[LFACE_INHERIT_INDEX])) | 2068 | && !NILP (from[LFACE_INHERIT_INDEX])) |
| 2062 | merge_face_ref (w, f, from[LFACE_INHERIT_INDEX], | 2069 | merge_face_ref (w, f, from[LFACE_INHERIT_INDEX], |
| 2063 | to, false, named_merge_points); | 2070 | to, false, named_merge_points, |
| 2071 | 0); | ||
| 2064 | 2072 | ||
| 2065 | if (FONT_SPEC_P (from[LFACE_FONT_INDEX])) | 2073 | if (FONT_SPEC_P (from[LFACE_FONT_INDEX])) |
| 2066 | { | 2074 | { |
| @@ -2126,7 +2134,8 @@ merge_face_vectors (struct window *w, | |||
| 2126 | static bool | 2134 | static bool |
| 2127 | merge_named_face (struct window *w, | 2135 | merge_named_face (struct window *w, |
| 2128 | struct frame *f, Lisp_Object face_name, Lisp_Object *to, | 2136 | struct frame *f, Lisp_Object face_name, Lisp_Object *to, |
| 2129 | struct named_merge_point *named_merge_points) | 2137 | struct named_merge_point *named_merge_points, |
| 2138 | enum lface_attribute_index attr_filter) | ||
| 2130 | { | 2139 | { |
| 2131 | struct named_merge_point named_merge_point; | 2140 | struct named_merge_point named_merge_point; |
| 2132 | 2141 | ||
| @@ -2136,9 +2145,13 @@ merge_named_face (struct window *w, | |||
| 2136 | { | 2145 | { |
| 2137 | Lisp_Object from[LFACE_VECTOR_SIZE]; | 2146 | Lisp_Object from[LFACE_VECTOR_SIZE]; |
| 2138 | bool ok = get_lface_attributes (w, f, face_name, from, false, | 2147 | bool ok = get_lface_attributes (w, f, face_name, from, false, |
| 2139 | named_merge_points); | 2148 | named_merge_points); |
| 2140 | 2149 | ||
| 2141 | if (ok) | 2150 | eassert (attr_filter < LFACE_VECTOR_SIZE); |
| 2151 | |||
| 2152 | if (ok && (attr_filter == 0 | ||
| 2153 | || (!NILP (from[attr_filter]) | ||
| 2154 | && !UNSPECIFIEDP (from[attr_filter])))) | ||
| 2142 | merge_face_vectors (w, f, from, to, named_merge_points); | 2155 | merge_face_vectors (w, f, from, to, named_merge_points); |
| 2143 | 2156 | ||
| 2144 | return ok; | 2157 | return ok; |
| @@ -2269,6 +2282,11 @@ filter_face_ref (Lisp_Object face_ref, | |||
| 2269 | of ERR_MSGS). Use NAMED_MERGE_POINTS to detect loops in face | 2282 | of ERR_MSGS). Use NAMED_MERGE_POINTS to detect loops in face |
| 2270 | inheritance or list structure; it may be 0 for most callers. | 2283 | inheritance or list structure; it may be 0 for most callers. |
| 2271 | 2284 | ||
| 2285 | ATTR_FILTER is the index of a parameter that conditions the merging | ||
| 2286 | for named faces (case 1) to only the face_ref where | ||
| 2287 | lface[merge_face_ref] is non-nil. To merge unconditionally set this | ||
| 2288 | value to 0. | ||
| 2289 | |||
| 2272 | FACE_REF may be a single face specification or a list of such | 2290 | FACE_REF may be a single face specification or a list of such |
| 2273 | specifications. Each face specification can be: | 2291 | specifications. Each face specification can be: |
| 2274 | 2292 | ||
| @@ -2297,7 +2315,8 @@ filter_face_ref (Lisp_Object face_ref, | |||
| 2297 | static bool | 2315 | static bool |
| 2298 | merge_face_ref (struct window *w, | 2316 | merge_face_ref (struct window *w, |
| 2299 | struct frame *f, Lisp_Object face_ref, Lisp_Object *to, | 2317 | struct frame *f, Lisp_Object face_ref, Lisp_Object *to, |
| 2300 | bool err_msgs, struct named_merge_point *named_merge_points) | 2318 | bool err_msgs, struct named_merge_point *named_merge_points, |
| 2319 | enum lface_attribute_index attr_filter) | ||
| 2301 | { | 2320 | { |
| 2302 | bool ok = true; /* Succeed without an error? */ | 2321 | bool ok = true; /* Succeed without an error? */ |
| 2303 | Lisp_Object filtered_face_ref; | 2322 | Lisp_Object filtered_face_ref; |
| @@ -2509,7 +2528,15 @@ merge_face_ref (struct window *w, | |||
| 2509 | /* This is not really very useful; it's just like a | 2528 | /* This is not really very useful; it's just like a |
| 2510 | normal face reference. */ | 2529 | normal face reference. */ |
| 2511 | if (! merge_face_ref (w, f, value, to, | 2530 | if (! merge_face_ref (w, f, value, to, |
| 2512 | err_msgs, named_merge_points)) | 2531 | err_msgs, named_merge_points, |
| 2532 | attr_filter)) | ||
| 2533 | err = true; | ||
| 2534 | } | ||
| 2535 | else if (EQ (keyword, QCextend)) | ||
| 2536 | { | ||
| 2537 | if (EQ (value, Qt) || NILP (value)) | ||
| 2538 | to[LFACE_EXTEND_INDEX] = value; | ||
| 2539 | else | ||
| 2513 | err = true; | 2540 | err = true; |
| 2514 | } | 2541 | } |
| 2515 | else | 2542 | else |
| @@ -2532,16 +2559,19 @@ merge_face_ref (struct window *w, | |||
| 2532 | Lisp_Object next = XCDR (face_ref); | 2559 | Lisp_Object next = XCDR (face_ref); |
| 2533 | 2560 | ||
| 2534 | if (! NILP (next)) | 2561 | if (! NILP (next)) |
| 2535 | ok = merge_face_ref (w, f, next, to, err_msgs, named_merge_points); | 2562 | ok = merge_face_ref (w, f, next, to, err_msgs, |
| 2563 | named_merge_points, attr_filter); | ||
| 2536 | 2564 | ||
| 2537 | if (! merge_face_ref (w, f, first, to, err_msgs, named_merge_points)) | 2565 | if (! merge_face_ref (w, f, first, to, err_msgs, |
| 2566 | named_merge_points, attr_filter)) | ||
| 2538 | ok = false; | 2567 | ok = false; |
| 2539 | } | 2568 | } |
| 2540 | } | 2569 | } |
| 2541 | else | 2570 | else |
| 2542 | { | 2571 | { |
| 2543 | /* FACE_REF ought to be a face name. */ | 2572 | /* FACE_REF ought to be a face name. */ |
| 2544 | ok = merge_named_face (w, f, face_ref, to, named_merge_points); | 2573 | ok = merge_named_face (w, f, face_ref, to, named_merge_points, |
| 2574 | attr_filter); | ||
| 2545 | if (!ok && err_msgs) | 2575 | if (!ok && err_msgs) |
| 2546 | add_to_log ("Invalid face reference: %s", face_ref); | 2576 | add_to_log ("Invalid face reference: %s", face_ref); |
| 2547 | } | 2577 | } |
| @@ -3030,6 +3060,17 @@ FRAME 0 means change the face on all frames, and change the default | |||
| 3030 | old_value = LFACE_INVERSE (lface); | 3060 | old_value = LFACE_INVERSE (lface); |
| 3031 | ASET (lface, LFACE_INVERSE_INDEX, value); | 3061 | ASET (lface, LFACE_INVERSE_INDEX, value); |
| 3032 | } | 3062 | } |
| 3063 | else if (EQ (attr, QCextend)) | ||
| 3064 | { | ||
| 3065 | if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value)) | ||
| 3066 | { | ||
| 3067 | CHECK_SYMBOL (value); | ||
| 3068 | if (!EQ (value, Qt) && !NILP (value)) | ||
| 3069 | signal_error ("Invalid extend face attribute value", value); | ||
| 3070 | } | ||
| 3071 | old_value = LFACE_EXTEND (lface); | ||
| 3072 | ASET (lface, LFACE_EXTEND_INDEX, value); | ||
| 3073 | } | ||
| 3033 | else if (EQ (attr, QCforeground)) | 3074 | else if (EQ (attr, QCforeground)) |
| 3034 | { | 3075 | { |
| 3035 | /* Compatibility with 20.x. */ | 3076 | /* Compatibility with 20.x. */ |
| @@ -3503,7 +3544,9 @@ DEFUN ("internal-set-lisp-face-attribute-from-resource", | |||
| 3503 | value = face_boolean_x_resource_value (value, true); | 3544 | value = face_boolean_x_resource_value (value, true); |
| 3504 | else if (EQ (attr, QCweight) || EQ (attr, QCslant) || EQ (attr, QCwidth)) | 3545 | else if (EQ (attr, QCweight) || EQ (attr, QCslant) || EQ (attr, QCwidth)) |
| 3505 | value = intern (SSDATA (value)); | 3546 | value = intern (SSDATA (value)); |
| 3506 | else if (EQ (attr, QCreverse_video) || EQ (attr, QCinverse_video)) | 3547 | else if (EQ (attr, QCreverse_video) |
| 3548 | || EQ (attr, QCinverse_video) | ||
| 3549 | || EQ (attr, QCextend)) | ||
| 3507 | value = face_boolean_x_resource_value (value, true); | 3550 | value = face_boolean_x_resource_value (value, true); |
| 3508 | else if (EQ (attr, QCunderline) | 3551 | else if (EQ (attr, QCunderline) |
| 3509 | || EQ (attr, QCoverline) | 3552 | || EQ (attr, QCoverline) |
| @@ -3727,6 +3770,8 @@ frames). If FRAME is omitted or nil, use the selected frame. */) | |||
| 3727 | value = LFACE_SWIDTH (lface); | 3770 | value = LFACE_SWIDTH (lface); |
| 3728 | else if (EQ (keyword, QCinherit)) | 3771 | else if (EQ (keyword, QCinherit)) |
| 3729 | value = LFACE_INHERIT (lface); | 3772 | value = LFACE_INHERIT (lface); |
| 3773 | else if (EQ (keyword, QCextend)) | ||
| 3774 | value = LFACE_EXTEND (lface); | ||
| 3730 | else if (EQ (keyword, QCfont)) | 3775 | else if (EQ (keyword, QCfont)) |
| 3731 | value = LFACE_FONT (lface); | 3776 | value = LFACE_FONT (lface); |
| 3732 | else if (EQ (keyword, QCfontset)) | 3777 | else if (EQ (keyword, QCfontset)) |
| @@ -3754,7 +3799,9 @@ Value is nil if ATTR doesn't have a discrete set of valid values. */) | |||
| 3754 | 3799 | ||
| 3755 | if (EQ (attr, QCunderline) || EQ (attr, QCoverline) | 3800 | if (EQ (attr, QCunderline) || EQ (attr, QCoverline) |
| 3756 | || EQ (attr, QCstrike_through) | 3801 | || EQ (attr, QCstrike_through) |
| 3757 | || EQ (attr, QCinverse_video) || EQ (attr, QCreverse_video)) | 3802 | || EQ (attr, QCinverse_video) |
| 3803 | || EQ (attr, QCreverse_video) | ||
| 3804 | || EQ (attr, QCextend)) | ||
| 3758 | result = list2 (Qt, Qnil); | 3805 | result = list2 (Qt, Qnil); |
| 3759 | 3806 | ||
| 3760 | return result; | 3807 | return result; |
| @@ -4505,7 +4552,8 @@ lookup_face (struct frame *f, Lisp_Object *attr) | |||
| 4505 | suitable face is found, realize a new one. */ | 4552 | suitable face is found, realize a new one. */ |
| 4506 | 4553 | ||
| 4507 | int | 4554 | int |
| 4508 | face_for_font (struct frame *f, Lisp_Object font_object, struct face *base_face) | 4555 | face_for_font (struct frame *f, Lisp_Object font_object, |
| 4556 | struct face *base_face) | ||
| 4509 | { | 4557 | { |
| 4510 | struct face_cache *cache = FRAME_FACE_CACHE (f); | 4558 | struct face_cache *cache = FRAME_FACE_CACHE (f); |
| 4511 | unsigned hash; | 4559 | unsigned hash; |
| @@ -4740,7 +4788,7 @@ DEFUN ("face-attributes-as-vector", Fface_attributes_as_vector, | |||
| 4740 | Lisp_Object lface = make_vector (LFACE_VECTOR_SIZE, Qunspecified); | 4788 | Lisp_Object lface = make_vector (LFACE_VECTOR_SIZE, Qunspecified); |
| 4741 | merge_face_ref (NULL, XFRAME (selected_frame), | 4789 | merge_face_ref (NULL, XFRAME (selected_frame), |
| 4742 | plist, XVECTOR (lface)->contents, | 4790 | plist, XVECTOR (lface)->contents, |
| 4743 | true, 0); | 4791 | true, NULL, 0); |
| 4744 | return lface; | 4792 | return lface; |
| 4745 | } | 4793 | } |
| 4746 | 4794 | ||
| @@ -4784,6 +4832,9 @@ gui_supports_face_attributes_p (struct frame *f, | |||
| 4784 | || (!UNSPECIFIEDP (attrs[LFACE_INVERSE_INDEX]) | 4832 | || (!UNSPECIFIEDP (attrs[LFACE_INVERSE_INDEX]) |
| 4785 | && face_attr_equal_p (attrs[LFACE_INVERSE_INDEX], | 4833 | && face_attr_equal_p (attrs[LFACE_INVERSE_INDEX], |
| 4786 | def_attrs[LFACE_INVERSE_INDEX])) | 4834 | def_attrs[LFACE_INVERSE_INDEX])) |
| 4835 | || (!UNSPECIFIEDP (attrs[LFACE_EXTEND_INDEX]) | ||
| 4836 | && face_attr_equal_p (attrs[LFACE_EXTEND_INDEX], | ||
| 4837 | def_attrs[LFACE_EXTEND_INDEX])) | ||
| 4787 | || (!UNSPECIFIEDP (attrs[LFACE_FOREGROUND_INDEX]) | 4838 | || (!UNSPECIFIEDP (attrs[LFACE_FOREGROUND_INDEX]) |
| 4788 | && face_attr_equal_p (attrs[LFACE_FOREGROUND_INDEX], | 4839 | && face_attr_equal_p (attrs[LFACE_FOREGROUND_INDEX], |
| 4789 | def_attrs[LFACE_FOREGROUND_INDEX])) | 4840 | def_attrs[LFACE_FOREGROUND_INDEX])) |
| @@ -5094,7 +5145,7 @@ face for italic. */) | |||
| 5094 | 5145 | ||
| 5095 | for (i = 0; i < LFACE_VECTOR_SIZE; i++) | 5146 | for (i = 0; i < LFACE_VECTOR_SIZE; i++) |
| 5096 | attrs[i] = Qunspecified; | 5147 | attrs[i] = Qunspecified; |
| 5097 | merge_face_ref (NULL, f, attributes, attrs, true, 0); | 5148 | merge_face_ref (NULL, f, attributes, attrs, true, NULL, 0); |
| 5098 | 5149 | ||
| 5099 | def_face = FACE_FROM_ID_OR_NULL (f, DEFAULT_FACE_ID); | 5150 | def_face = FACE_FROM_ID_OR_NULL (f, DEFAULT_FACE_ID); |
| 5100 | if (def_face == NULL) | 5151 | if (def_face == NULL) |
| @@ -5362,6 +5413,9 @@ realize_default_face (struct frame *f) | |||
| 5362 | ASET (lface, LFACE_FONTSET_INDEX, Qnil); | 5413 | ASET (lface, LFACE_FONTSET_INDEX, Qnil); |
| 5363 | } | 5414 | } |
| 5364 | 5415 | ||
| 5416 | if (UNSPECIFIEDP (LFACE_EXTEND (lface))) | ||
| 5417 | ASET (lface, LFACE_EXTEND_INDEX, Qnil); | ||
| 5418 | |||
| 5365 | if (UNSPECIFIEDP (LFACE_UNDERLINE (lface))) | 5419 | if (UNSPECIFIEDP (LFACE_UNDERLINE (lface))) |
| 5366 | ASET (lface, LFACE_UNDERLINE_INDEX, Qnil); | 5420 | ASET (lface, LFACE_UNDERLINE_INDEX, Qnil); |
| 5367 | 5421 | ||
| @@ -5698,16 +5752,14 @@ realize_gui_face (struct face_cache *cache, Lisp_Object attrs[LFACE_VECTOR_SIZE] | |||
| 5698 | if (EQ (underline, Qt)) | 5752 | if (EQ (underline, Qt)) |
| 5699 | { | 5753 | { |
| 5700 | /* Use default color (same as foreground color). */ | 5754 | /* Use default color (same as foreground color). */ |
| 5701 | face->underline_p = true; | 5755 | face->underline = FACE_UNDER_LINE; |
| 5702 | face->underline_type = FACE_UNDER_LINE; | ||
| 5703 | face->underline_defaulted_p = true; | 5756 | face->underline_defaulted_p = true; |
| 5704 | face->underline_color = 0; | 5757 | face->underline_color = 0; |
| 5705 | } | 5758 | } |
| 5706 | else if (STRINGP (underline)) | 5759 | else if (STRINGP (underline)) |
| 5707 | { | 5760 | { |
| 5708 | /* Use specified color. */ | 5761 | /* Use specified color. */ |
| 5709 | face->underline_p = true; | 5762 | face->underline = FACE_UNDER_LINE; |
| 5710 | face->underline_type = FACE_UNDER_LINE; | ||
| 5711 | face->underline_defaulted_p = false; | 5763 | face->underline_defaulted_p = false; |
| 5712 | face->underline_color | 5764 | face->underline_color |
| 5713 | = load_color (f, face, underline, | 5765 | = load_color (f, face, underline, |
| @@ -5715,7 +5767,7 @@ realize_gui_face (struct face_cache *cache, Lisp_Object attrs[LFACE_VECTOR_SIZE] | |||
| 5715 | } | 5767 | } |
| 5716 | else if (NILP (underline)) | 5768 | else if (NILP (underline)) |
| 5717 | { | 5769 | { |
| 5718 | face->underline_p = false; | 5770 | face->underline = FACE_NO_UNDERLINE; |
| 5719 | face->underline_defaulted_p = false; | 5771 | face->underline_defaulted_p = false; |
| 5720 | face->underline_color = 0; | 5772 | face->underline_color = 0; |
| 5721 | } | 5773 | } |
| @@ -5723,10 +5775,9 @@ realize_gui_face (struct face_cache *cache, Lisp_Object attrs[LFACE_VECTOR_SIZE] | |||
| 5723 | { | 5775 | { |
| 5724 | /* `(:color COLOR :style STYLE)'. | 5776 | /* `(:color COLOR :style STYLE)'. |
| 5725 | STYLE being one of `line' or `wave'. */ | 5777 | STYLE being one of `line' or `wave'. */ |
| 5726 | face->underline_p = true; | 5778 | face->underline = FACE_UNDER_LINE; |
| 5727 | face->underline_color = 0; | 5779 | face->underline_color = 0; |
| 5728 | face->underline_defaulted_p = true; | 5780 | face->underline_defaulted_p = true; |
| 5729 | face->underline_type = FACE_UNDER_LINE; | ||
| 5730 | 5781 | ||
| 5731 | /* FIXME? This is also not robust about checking the precise form. | 5782 | /* FIXME? This is also not robust about checking the precise form. |
| 5732 | See comments in Finternal_set_lisp_face_attribute. */ | 5783 | See comments in Finternal_set_lisp_face_attribute. */ |
| @@ -5759,9 +5810,9 @@ realize_gui_face (struct face_cache *cache, Lisp_Object attrs[LFACE_VECTOR_SIZE] | |||
| 5759 | else if (EQ (keyword, QCstyle)) | 5810 | else if (EQ (keyword, QCstyle)) |
| 5760 | { | 5811 | { |
| 5761 | if (EQ (value, Qline)) | 5812 | if (EQ (value, Qline)) |
| 5762 | face->underline_type = FACE_UNDER_LINE; | 5813 | face->underline = FACE_UNDER_LINE; |
| 5763 | else if (EQ (value, Qwave)) | 5814 | else if (EQ (value, Qwave)) |
| 5764 | face->underline_type = FACE_UNDER_WAVE; | 5815 | face->underline = FACE_UNDER_WAVE; |
| 5765 | } | 5816 | } |
| 5766 | } | 5817 | } |
| 5767 | } | 5818 | } |
| @@ -5980,7 +6031,7 @@ compute_char_face (struct frame *f, int ch, Lisp_Object prop) | |||
| 5980 | Lisp_Object attrs[LFACE_VECTOR_SIZE]; | 6031 | Lisp_Object attrs[LFACE_VECTOR_SIZE]; |
| 5981 | struct face *default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID); | 6032 | struct face *default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID); |
| 5982 | memcpy (attrs, default_face->lface, sizeof attrs); | 6033 | memcpy (attrs, default_face->lface, sizeof attrs); |
| 5983 | merge_face_ref (NULL, f, prop, attrs, true, 0); | 6034 | merge_face_ref (NULL, f, prop, attrs, true, NULL, 0); |
| 5984 | face_id = lookup_face (f, attrs); | 6035 | face_id = lookup_face (f, attrs); |
| 5985 | } | 6036 | } |
| 5986 | 6037 | ||
| @@ -5992,6 +6043,8 @@ compute_char_face (struct frame *f, int ch, Lisp_Object prop) | |||
| 5992 | which a different face is needed, as far as text properties and | 6043 | which a different face is needed, as far as text properties and |
| 5993 | overlays are concerned. W is a window displaying current_buffer. | 6044 | overlays are concerned. W is a window displaying current_buffer. |
| 5994 | 6045 | ||
| 6046 | ATTR_FILTER is passed merge_face_ref. | ||
| 6047 | |||
| 5995 | REGION_BEG, REGION_END delimit the region, so it can be | 6048 | REGION_BEG, REGION_END delimit the region, so it can be |
| 5996 | highlighted. | 6049 | highlighted. |
| 5997 | 6050 | ||
| @@ -6011,7 +6064,8 @@ compute_char_face (struct frame *f, int ch, Lisp_Object prop) | |||
| 6011 | int | 6064 | int |
| 6012 | face_at_buffer_position (struct window *w, ptrdiff_t pos, | 6065 | face_at_buffer_position (struct window *w, ptrdiff_t pos, |
| 6013 | ptrdiff_t *endptr, ptrdiff_t limit, | 6066 | ptrdiff_t *endptr, ptrdiff_t limit, |
| 6014 | bool mouse, int base_face_id) | 6067 | bool mouse, int base_face_id, |
| 6068 | enum lface_attribute_index attr_filter) | ||
| 6015 | { | 6069 | { |
| 6016 | struct frame *f = XFRAME (w->frame); | 6070 | struct frame *f = XFRAME (w->frame); |
| 6017 | Lisp_Object attrs[LFACE_VECTOR_SIZE]; | 6071 | Lisp_Object attrs[LFACE_VECTOR_SIZE]; |
| @@ -6080,11 +6134,11 @@ face_at_buffer_position (struct window *w, ptrdiff_t pos, | |||
| 6080 | } | 6134 | } |
| 6081 | 6135 | ||
| 6082 | /* Begin with attributes from the default face. */ | 6136 | /* Begin with attributes from the default face. */ |
| 6083 | memcpy (attrs, default_face->lface, sizeof attrs); | 6137 | memcpy (attrs, default_face->lface, sizeof(attrs)); |
| 6084 | 6138 | ||
| 6085 | /* Merge in attributes specified via text properties. */ | 6139 | /* Merge in attributes specified via text properties. */ |
| 6086 | if (!NILP (prop)) | 6140 | if (!NILP (prop)) |
| 6087 | merge_face_ref (w, f, prop, attrs, true, 0); | 6141 | merge_face_ref (w, f, prop, attrs, true, NULL, attr_filter); |
| 6088 | 6142 | ||
| 6089 | /* Now merge the overlay data. */ | 6143 | /* Now merge the overlay data. */ |
| 6090 | noverlays = sort_overlays (overlay_vec, noverlays, w); | 6144 | noverlays = sort_overlays (overlay_vec, noverlays, w); |
| @@ -6104,7 +6158,7 @@ face_at_buffer_position (struct window *w, ptrdiff_t pos, | |||
| 6104 | so discard the mouse-face text property, if any, and | 6158 | so discard the mouse-face text property, if any, and |
| 6105 | use the overlay property instead. */ | 6159 | use the overlay property instead. */ |
| 6106 | memcpy (attrs, default_face->lface, sizeof attrs); | 6160 | memcpy (attrs, default_face->lface, sizeof attrs); |
| 6107 | merge_face_ref (w, f, prop, attrs, true, 0); | 6161 | merge_face_ref (w, f, prop, attrs, true, NULL, attr_filter); |
| 6108 | } | 6162 | } |
| 6109 | 6163 | ||
| 6110 | oend = OVERLAY_END (overlay_vec[i]); | 6164 | oend = OVERLAY_END (overlay_vec[i]); |
| @@ -6121,8 +6175,9 @@ face_at_buffer_position (struct window *w, ptrdiff_t pos, | |||
| 6121 | ptrdiff_t oendpos; | 6175 | ptrdiff_t oendpos; |
| 6122 | 6176 | ||
| 6123 | prop = Foverlay_get (overlay_vec[i], propname); | 6177 | prop = Foverlay_get (overlay_vec[i], propname); |
| 6178 | |||
| 6124 | if (!NILP (prop)) | 6179 | if (!NILP (prop)) |
| 6125 | merge_face_ref (w, f, prop, attrs, true, 0); | 6180 | merge_face_ref (w, f, prop, attrs, true, NULL, attr_filter); |
| 6126 | 6181 | ||
| 6127 | oend = OVERLAY_END (overlay_vec[i]); | 6182 | oend = OVERLAY_END (overlay_vec[i]); |
| 6128 | oendpos = OVERLAY_POSITION (oend); | 6183 | oendpos = OVERLAY_POSITION (oend); |
| @@ -6188,7 +6243,7 @@ face_for_overlay_string (struct window *w, ptrdiff_t pos, | |||
| 6188 | 6243 | ||
| 6189 | /* Merge in attributes specified via text properties. */ | 6244 | /* Merge in attributes specified via text properties. */ |
| 6190 | if (!NILP (prop)) | 6245 | if (!NILP (prop)) |
| 6191 | merge_face_ref (w, f, prop, attrs, true, 0); | 6246 | merge_face_ref (w, f, prop, attrs, true, NULL, 0); |
| 6192 | 6247 | ||
| 6193 | *endptr = endpos; | 6248 | *endptr = endpos; |
| 6194 | 6249 | ||
| @@ -6221,9 +6276,10 @@ face_for_overlay_string (struct window *w, ptrdiff_t pos, | |||
| 6221 | 6276 | ||
| 6222 | int | 6277 | int |
| 6223 | face_at_string_position (struct window *w, Lisp_Object string, | 6278 | face_at_string_position (struct window *w, Lisp_Object string, |
| 6224 | ptrdiff_t pos, ptrdiff_t bufpos, | 6279 | ptrdiff_t pos, ptrdiff_t bufpos, |
| 6225 | ptrdiff_t *endptr, enum face_id base_face_id, | 6280 | ptrdiff_t *endptr, enum face_id base_face_id, |
| 6226 | bool mouse_p) | 6281 | bool mouse_p, |
| 6282 | enum lface_attribute_index attr_filter) | ||
| 6227 | { | 6283 | { |
| 6228 | Lisp_Object prop, position, end, limit; | 6284 | Lisp_Object prop, position, end, limit; |
| 6229 | struct frame *f = XFRAME (WINDOW_FRAME (w)); | 6285 | struct frame *f = XFRAME (WINDOW_FRAME (w)); |
| @@ -6267,7 +6323,7 @@ face_at_string_position (struct window *w, Lisp_Object string, | |||
| 6267 | 6323 | ||
| 6268 | /* Merge in attributes specified via text properties. */ | 6324 | /* Merge in attributes specified via text properties. */ |
| 6269 | if (!NILP (prop)) | 6325 | if (!NILP (prop)) |
| 6270 | merge_face_ref (w, f, prop, attrs, true, 0); | 6326 | merge_face_ref (w, f, prop, attrs, true, NULL, attr_filter); |
| 6271 | 6327 | ||
| 6272 | /* Look up a realized face with the given face attributes, | 6328 | /* Look up a realized face with the given face attributes, |
| 6273 | or realize a new one for ASCII characters. */ | 6329 | or realize a new one for ASCII characters. */ |
| @@ -6296,9 +6352,8 @@ merge_faces (struct window *w, Lisp_Object face_name, int face_id, | |||
| 6296 | { | 6352 | { |
| 6297 | struct frame *f = WINDOW_XFRAME (w); | 6353 | struct frame *f = WINDOW_XFRAME (w); |
| 6298 | Lisp_Object attrs[LFACE_VECTOR_SIZE]; | 6354 | Lisp_Object attrs[LFACE_VECTOR_SIZE]; |
| 6299 | struct face *base_face; | 6355 | struct face *base_face = FACE_FROM_ID_OR_NULL (f, base_face_id); |
| 6300 | 6356 | ||
| 6301 | base_face = FACE_FROM_ID_OR_NULL (f, base_face_id); | ||
| 6302 | if (!base_face) | 6357 | if (!base_face) |
| 6303 | return base_face_id; | 6358 | return base_face_id; |
| 6304 | 6359 | ||
| @@ -6318,17 +6373,19 @@ merge_faces (struct window *w, Lisp_Object face_name, int face_id, | |||
| 6318 | 6373 | ||
| 6319 | if (!NILP (face_name)) | 6374 | if (!NILP (face_name)) |
| 6320 | { | 6375 | { |
| 6321 | if (!merge_named_face (w, f, face_name, attrs, 0)) | 6376 | if (!merge_named_face (w, f, face_name, attrs, NULL, 0)) |
| 6322 | return base_face_id; | 6377 | return base_face_id; |
| 6323 | } | 6378 | } |
| 6324 | else | 6379 | else |
| 6325 | { | 6380 | { |
| 6326 | struct face *face; | ||
| 6327 | if (face_id < 0) | 6381 | if (face_id < 0) |
| 6328 | return base_face_id; | 6382 | return base_face_id; |
| 6329 | face = FACE_FROM_ID_OR_NULL (f, face_id); | 6383 | |
| 6384 | struct face *face = FACE_FROM_ID_OR_NULL (f, face_id); | ||
| 6385 | |||
| 6330 | if (!face) | 6386 | if (!face) |
| 6331 | return base_face_id; | 6387 | return base_face_id; |
| 6388 | |||
| 6332 | merge_face_vectors (w, f, face->lface, attrs, 0); | 6389 | merge_face_vectors (w, f, face->lface, attrs, 0); |
| 6333 | } | 6390 | } |
| 6334 | 6391 | ||
| @@ -6416,7 +6473,7 @@ dump_realized_face (struct face *face) | |||
| 6416 | #endif | 6473 | #endif |
| 6417 | fprintf (stderr, "fontset: %d\n", face->fontset); | 6474 | fprintf (stderr, "fontset: %d\n", face->fontset); |
| 6418 | fprintf (stderr, "underline: %d (%s)\n", | 6475 | fprintf (stderr, "underline: %d (%s)\n", |
| 6419 | face->underline_p, | 6476 | face->underline, |
| 6420 | SDATA (Fsymbol_name (face->lface[LFACE_UNDERLINE_INDEX]))); | 6477 | SDATA (Fsymbol_name (face->lface[LFACE_UNDERLINE_INDEX]))); |
| 6421 | fprintf (stderr, "hash: %" PRIuPTR "\n", face->hash); | 6478 | fprintf (stderr, "hash: %" PRIuPTR "\n", face->hash); |
| 6422 | } | 6479 | } |
| @@ -6541,6 +6598,7 @@ syms_of_xfaces (void) | |||
| 6541 | DEFSYM (QCstrike_through, ":strike-through"); | 6598 | DEFSYM (QCstrike_through, ":strike-through"); |
| 6542 | DEFSYM (QCbox, ":box"); | 6599 | DEFSYM (QCbox, ":box"); |
| 6543 | DEFSYM (QCinherit, ":inherit"); | 6600 | DEFSYM (QCinherit, ":inherit"); |
| 6601 | DEFSYM (QCextend, ":extend"); | ||
| 6544 | 6602 | ||
| 6545 | /* Symbols used for Lisp face attribute values. */ | 6603 | /* Symbols used for Lisp face attribute values. */ |
| 6546 | DEFSYM (QCcolor, ":color"); | 6604 | DEFSYM (QCcolor, ":color"); |
diff --git a/src/xterm.c b/src/xterm.c index b49c9d6893a..5d8b1482a6d 100644 --- a/src/xterm.c +++ b/src/xterm.c | |||
| @@ -3813,9 +3813,9 @@ x_draw_glyph_string (struct glyph_string *s) | |||
| 3813 | if (!s->for_overlaps) | 3813 | if (!s->for_overlaps) |
| 3814 | { | 3814 | { |
| 3815 | /* Draw underline. */ | 3815 | /* Draw underline. */ |
| 3816 | if (s->face->underline_p) | 3816 | if (s->face->underline) |
| 3817 | { | 3817 | { |
| 3818 | if (s->face->underline_type == FACE_UNDER_WAVE) | 3818 | if (s->face->underline == FACE_UNDER_WAVE) |
| 3819 | { | 3819 | { |
| 3820 | if (s->face->underline_defaulted_p) | 3820 | if (s->face->underline_defaulted_p) |
| 3821 | x_draw_underwave (s); | 3821 | x_draw_underwave (s); |
| @@ -3829,13 +3829,13 @@ x_draw_glyph_string (struct glyph_string *s) | |||
| 3829 | XSetForeground (display, s->gc, xgcv.foreground); | 3829 | XSetForeground (display, s->gc, xgcv.foreground); |
| 3830 | } | 3830 | } |
| 3831 | } | 3831 | } |
| 3832 | else if (s->face->underline_type == FACE_UNDER_LINE) | 3832 | else if (s->face->underline == FACE_UNDER_LINE) |
| 3833 | { | 3833 | { |
| 3834 | unsigned long thickness, position; | 3834 | unsigned long thickness, position; |
| 3835 | int y; | 3835 | int y; |
| 3836 | 3836 | ||
| 3837 | if (s->prev && s->prev->face->underline_p | 3837 | if (s->prev && |
| 3838 | && s->prev->face->underline_type == FACE_UNDER_LINE) | 3838 | s->prev->face->underline == FACE_UNDER_LINE) |
| 3839 | { | 3839 | { |
| 3840 | /* We use the same underline style as the previous one. */ | 3840 | /* We use the same underline style as the previous one. */ |
| 3841 | thickness = s->prev->underline_thickness; | 3841 | thickness = s->prev->underline_thickness; |