aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAlexandre Adolphe2019-08-10 22:57:24 +0200
committerNoam Postavsky2020-04-01 18:02:55 -0400
commit34ae2d0c220c945443e94a43d043a4a63c444bf4 (patch)
tree50c1599ceb4eb4e6fada3b16ef6cfc56da895645 /src
parentb538cd88b484e54d9afa970dc7bdd93ba39ad03d (diff)
downloademacs-34ae2d0c220c945443e94a43d043a4a63c444bf4.tar.gz
emacs-34ae2d0c220c945443e94a43d043a4a63c444bf4.zip
Allow negative line width for :box face attribute
Separate values for box line width and height and allow both to be negative which makes the visual width and height of the boxed string unchanged (Bug#13011). * doc/lispref/display.texi (Face Attributes): Modify :box attribute description to reflect the new possibilities. * lisp/cus-face.el (custom-face-attributes): Set box attribute to get two integer to set vertical and horizontal width and modify pre-filter to accept dotted list of two int as valid box attribute. * src/dispextern.h (face): Use two int for box horizontal and vertical line width. * src/nsfont.m (nsfont_draw): Use new face attributes. * src/nsterm.m (ns_draw_box, ns_draw_relief): Support separated horizontal and vertical box line width. (ns_dumpglyphs_box_or_relief, ns_maybe_dumpglyphs_background) (ns_dumpglyphs_image, ns_draw_glyph_string_foreground) (ns_draw_composite_glyph_string_foreground): Use new face attributes. * src/w32term.c (w32_draw_box_rect, w32_draw_relief_rect): Support separated horizontal and vertical box line width. (x_draw_glyph_string_background, x_draw_glyph_string_foreground) (x_draw_composite_glyph_string_foreground) (x_draw_glyphless_glyph_string_foreground, x_draw_glyph_string_box) (x_draw_image_foreground, x_draw_image_relief) (w32_draw_image_foreground_1, x_draw_image_glyph_string): Use new face attributes. * src/xfaces.c (Sinternal_set_lisp_face_attribute, realize_x_face): Accept box attribute as a list of two ints. * src/xdisp.c (estimate_mode_line_height, produce_image_glyph) (produce_xwidget_glyph, x_produce_glyphs): Use new face attributes. * src/xterm.c (x_draw_box_rect, x_draw_relief_rect): Support separated horizontal and vertical box line width. (x_draw_glyph_string_background, x_draw_glyph_string_foreground) (x_draw_composite_glyph_string_foreground) (x_draw_glyphless_glyph_string_foreground, x_draw_glyph_string_box) (x_draw_image_foreground, x_draw_image_relief, x_draw_image_foreground_1) (x_draw_image_glyph_string): Use new face attributes.
Diffstat (limited to 'src')
-rw-r--r--src/dispextern.h17
-rw-r--r--src/nsfont.m7
-rw-r--r--src/nsterm.m56
-rw-r--r--src/w32term.c59
-rw-r--r--src/xdisp.c123
-rw-r--r--src/xfaces.c32
-rw-r--r--src/xterm.c115
7 files changed, 207 insertions, 202 deletions
diff --git a/src/dispextern.h b/src/dispextern.h
index 08380f1f17f..555946f84cb 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -1693,12 +1693,17 @@ struct face
1693 int fontset; 1693 int fontset;
1694 1694
1695 /* Non-zero means characters in this face have a box of that 1695 /* Non-zero means characters in this face have a box of that
1696 thickness around them. If this value is negative, its absolute 1696 thickness around them. Vertical (left and right) and horizontal
1697 value indicates the thickness, and the horizontal (top and 1697 (top and bottom) borders size can be set separatedly using an
1698 bottom) borders of box are drawn inside of the character glyphs' 1698 associated list of two ints in the form
1699 area. The vertical (left and right) borders of the box are drawn 1699 (vertical_size . horizontal_size). In case one of the value is
1700 in the same way as when this value is positive. */ 1700 negative, its absolute value indicates the thickness, and the
1701 int box_line_width; 1701 borders of box are drawn inside of the character glyphs' area
1702 potentially over the glyph itself but the glyph drawing size is
1703 not increase. If a (signed) int N is use instead of a list, it
1704 is the same as setting ( abs(N) . N ) values. */
1705 int box_vertical_line_width;
1706 int box_horizontal_line_width;
1702 1707
1703 /* Type of box drawn. A value of FACE_NO_BOX means no box is drawn 1708 /* Type of box drawn. A value of FACE_NO_BOX means no box is drawn
1704 around text in this face. A value of FACE_SIMPLE_BOX means a box 1709 around text in this face. A value of FACE_SIMPLE_BOX means a box
diff --git a/src/nsfont.m b/src/nsfont.m
index 9bec3691786..e41a698a2ff 100644
--- a/src/nsfont.m
+++ b/src/nsfont.m
@@ -1043,7 +1043,7 @@ nsfont_draw (struct glyph_string *s, int from, int to, int x, int y,
1043 1043
1044 r.origin.x = s->x; 1044 r.origin.x = s->x;
1045 if (s->face->box != FACE_NO_BOX && s->first_glyph->left_box_line_p) 1045 if (s->face->box != FACE_NO_BOX && s->first_glyph->left_box_line_p)
1046 r.origin.x += abs (s->face->box_line_width); 1046 r.origin.x += max (s->face->box_vertical_line_width, 0);
1047 1047
1048 r.origin.y = s->y; 1048 r.origin.y = s->y;
1049 r.size.height = FONT_HEIGHT (font); 1049 r.size.height = FONT_HEIGHT (font);
@@ -1105,7 +1105,7 @@ nsfont_draw (struct glyph_string *s, int from, int to, int x, int y,
1105 { 1105 {
1106 NSRect br = r; 1106 NSRect br = r;
1107 int fibw = FRAME_INTERNAL_BORDER_WIDTH (s->f); 1107 int fibw = FRAME_INTERNAL_BORDER_WIDTH (s->f);
1108 int mbox_line_width = max (s->face->box_line_width, 0); 1108 int mbox_line_width = max (s->face->box_vertical_line_width, 0);
1109 1109
1110 if (s->row->full_width_p) 1110 if (s->row->full_width_p)
1111 { 1111 {
@@ -1129,9 +1129,10 @@ nsfont_draw (struct glyph_string *s, int from, int to, int x, int y,
1129 } 1129 }
1130 else 1130 else
1131 { 1131 {
1132 int correction = abs (s->face->box_line_width)+1; 1132 int correction = abs (s->face->box_horizontal_line_width)+1;
1133 br.origin.y += correction; 1133 br.origin.y += correction;
1134 br.size.height -= 2*correction; 1134 br.size.height -= 2*correction;
1135 correction = abs (s->face->box_vertical_line_width)+1;
1135 br.origin.x += correction; 1136 br.origin.x += correction;
1136 br.size.width -= 2*correction; 1137 br.size.width -= 2*correction;
1137 } 1138 }
diff --git a/src/nsterm.m b/src/nsterm.m
index 04fc0512234..3ce223307ba 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -3639,8 +3639,8 @@ ns_draw_text_decoration (struct glyph_string *s, struct face *face,
3639} 3639}
3640 3640
3641static void 3641static void
3642ns_draw_box (NSRect r, CGFloat thickness, NSColor *col, 3642ns_draw_box (NSRect r, CGFloat hthickness, CGFloat vthickness,
3643 char left_p, char right_p) 3643 NSColor *col, char left_p, char right_p)
3644/* -------------------------------------------------------------------------- 3644/* --------------------------------------------------------------------------
3645 Draw an unfilled rect inside r, optionally leaving left and/or right open. 3645 Draw an unfilled rect inside r, optionally leaving left and/or right open.
3646 Note we can't just use an NSDrawRect command, because of the possibility 3646 Note we can't just use an NSDrawRect command, because of the possibility
@@ -3651,28 +3651,28 @@ ns_draw_box (NSRect r, CGFloat thickness, NSColor *col,
3651 [col set]; 3651 [col set];
3652 3652
3653 /* top, bottom */ 3653 /* top, bottom */
3654 s.size.height = thickness; 3654 s.size.height = hthickness;
3655 NSRectFill (s); 3655 NSRectFill (s);
3656 s.origin.y += r.size.height - thickness; 3656 s.origin.y += r.size.height - hthickness;
3657 NSRectFill (s); 3657 NSRectFill (s);
3658 3658
3659 s.size.height = r.size.height; 3659 s.size.height = r.size.height;
3660 s.origin.y = r.origin.y; 3660 s.origin.y = r.origin.y;
3661 3661
3662 /* left, right (optional) */ 3662 /* left, right (optional) */
3663 s.size.width = thickness; 3663 s.size.width = vthickness;
3664 if (left_p) 3664 if (left_p)
3665 NSRectFill (s); 3665 NSRectFill (s);
3666 if (right_p) 3666 if (right_p)
3667 { 3667 {
3668 s.origin.x += r.size.width - thickness; 3668 s.origin.x += r.size.width - vthickness;
3669 NSRectFill (s); 3669 NSRectFill (s);
3670 } 3670 }
3671} 3671}
3672 3672
3673 3673
3674static void 3674static void
3675ns_draw_relief (NSRect r, int thickness, char raised_p, 3675ns_draw_relief (NSRect r, int hthickness, int vthickness, char raised_p,
3676 char top_p, char bottom_p, char left_p, char right_p, 3676 char top_p, char bottom_p, char left_p, char right_p,
3677 struct glyph_string *s) 3677 struct glyph_string *s)
3678/* -------------------------------------------------------------------------- 3678/* --------------------------------------------------------------------------
@@ -3722,27 +3722,27 @@ ns_draw_relief (NSRect r, int thickness, char raised_p,
3722 /* TODO: mitering. Using NSBezierPath doesn't work because of color switch. */ 3722 /* TODO: mitering. Using NSBezierPath doesn't work because of color switch. */
3723 3723
3724 /* top */ 3724 /* top */
3725 sr.size.height = thickness; 3725 sr.size.height = hthickness;
3726 if (top_p) NSRectFill (sr); 3726 if (top_p) NSRectFill (sr);
3727 3727
3728 /* left */ 3728 /* left */
3729 sr.size.height = r.size.height; 3729 sr.size.height = r.size.height;
3730 sr.size.width = thickness; 3730 sr.size.width = vthickness;
3731 if (left_p) NSRectFill (sr); 3731 if (left_p) NSRectFill (sr);
3732 3732
3733 [(raised_p ? darkCol : lightCol) set]; 3733 [(raised_p ? darkCol : lightCol) set];
3734 3734
3735 /* bottom */ 3735 /* bottom */
3736 sr.size.width = r.size.width; 3736 sr.size.width = r.size.width;
3737 sr.size.height = thickness; 3737 sr.size.height = hthickness;
3738 sr.origin.y += r.size.height - thickness; 3738 sr.origin.y += r.size.height - hthickness;
3739 if (bottom_p) NSRectFill (sr); 3739 if (bottom_p) NSRectFill (sr);
3740 3740
3741 /* right */ 3741 /* right */
3742 sr.size.height = r.size.height; 3742 sr.size.height = r.size.height;
3743 sr.origin.y = r.origin.y; 3743 sr.origin.y = r.origin.y;
3744 sr.size.width = thickness; 3744 sr.size.width = vthickness;
3745 sr.origin.x += r.size.width - thickness; 3745 sr.origin.x += r.size.width - vthickness;
3746 if (right_p) NSRectFill (sr); 3746 if (right_p) NSRectFill (sr);
3747} 3747}
3748 3748
@@ -3758,7 +3758,7 @@ ns_dumpglyphs_box_or_relief (struct glyph_string *s)
3758 char left_p, right_p; 3758 char left_p, right_p;
3759 struct glyph *last_glyph; 3759 struct glyph *last_glyph;
3760 NSRect r; 3760 NSRect r;
3761 int thickness; 3761 int hthickness, vthickness;
3762 struct face *face; 3762 struct face *face;
3763 3763
3764 if (s->hl == DRAW_MOUSE_FACE) 3764 if (s->hl == DRAW_MOUSE_FACE)
@@ -3771,7 +3771,8 @@ ns_dumpglyphs_box_or_relief (struct glyph_string *s)
3771 else 3771 else
3772 face = s->face; 3772 face = s->face;
3773 3773
3774 thickness = face->box_line_width; 3774 vthickness = face->box_vertical_line_width;
3775 hthickness = face->box_horizontal_line_width;
3775 3776
3776 NSTRACE ("ns_dumpglyphs_box_or_relief"); 3777 NSTRACE ("ns_dumpglyphs_box_or_relief");
3777 3778
@@ -3796,14 +3797,15 @@ ns_dumpglyphs_box_or_relief (struct glyph_string *s)
3796 /* TODO: Sometimes box_color is 0 and this seems wrong; should investigate. */ 3797 /* TODO: Sometimes box_color is 0 and this seems wrong; should investigate. */
3797 if (s->face->box == FACE_SIMPLE_BOX && s->face->box_color) 3798 if (s->face->box == FACE_SIMPLE_BOX && s->face->box_color)
3798 { 3799 {
3799 ns_draw_box (r, abs (thickness), 3800 ns_draw_box (r, abs (hthickness), abs (vthickness),
3800 ns_lookup_indexed_color (face->box_color, s->f), 3801 ns_lookup_indexed_color (face->box_color, s->f),
3801 left_p, right_p); 3802 left_p, right_p);
3802 } 3803 }
3803 else 3804 else
3804 { 3805 {
3805 ns_draw_relief (r, abs (thickness), s->face->box == FACE_RAISED_BOX, 3806 ns_draw_relief (r, abs (hthickness), abs (vthickness),
3806 1, 1, left_p, right_p, s); 3807 s->face->box == FACE_RAISED_BOX,
3808 1, 1, left_p, right_p, s);
3807 } 3809 }
3808} 3810}
3809 3811
@@ -3819,7 +3821,7 @@ ns_maybe_dumpglyphs_background (struct glyph_string *s, char force_p)
3819 3821
3820 if (!s->background_filled_p/* || s->hl == DRAW_MOUSE_FACE*/) 3822 if (!s->background_filled_p/* || s->hl == DRAW_MOUSE_FACE*/)
3821 { 3823 {
3822 int box_line_width = max (s->face->box_line_width, 0); 3824 int box_line_width = max (s->face->box_horizontal_line_width, 0);
3823 if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width 3825 if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width
3824 /* When xdisp.c ignores FONT_HEIGHT, we cannot trust font 3826 /* When xdisp.c ignores FONT_HEIGHT, we cannot trust font
3825 dimensions, since the actual glyphs might be much 3827 dimensions, since the actual glyphs might be much
@@ -3870,7 +3872,7 @@ ns_dumpglyphs_image (struct glyph_string *s, NSRect r)
3870 -------------------------------------------------------------------------- */ 3872 -------------------------------------------------------------------------- */
3871{ 3873{
3872 EmacsImage *img = s->img->pixmap; 3874 EmacsImage *img = s->img->pixmap;
3873 int box_line_vwidth = max (s->face->box_line_width, 0); 3875 int box_line_vwidth = max (s->face->box_horizontal_line_width, 0);
3874 int x = s->x, y = s->ybase - image_ascent (s->img, s->face, &s->slice); 3876 int x = s->x, y = s->ybase - image_ascent (s->img, s->face, &s->slice);
3875 int bg_x, bg_y, bg_height; 3877 int bg_x, bg_y, bg_height;
3876 int th; 3878 int th;
@@ -3883,7 +3885,7 @@ ns_dumpglyphs_image (struct glyph_string *s, NSRect r)
3883 3885
3884 if (s->face->box != FACE_NO_BOX 3886 if (s->face->box != FACE_NO_BOX
3885 && s->first_glyph->left_box_line_p && s->slice.x == 0) 3887 && s->first_glyph->left_box_line_p && s->slice.x == 0)
3886 x += abs (s->face->box_line_width); 3888 x += max (s->face->box_vertical_line_width, 0);
3887 3889
3888 bg_x = x; 3890 bg_x = x;
3889 bg_y = s->slice.y == 0 ? s->y : s->y + box_line_vwidth; 3891 bg_y = s->slice.y == 0 ? s->y : s->y + box_line_vwidth;
@@ -4003,7 +4005,7 @@ ns_dumpglyphs_image (struct glyph_string *s, NSRect r)
4003 r.origin.y = y - th; 4005 r.origin.y = y - th;
4004 r.size.width = s->slice.width + 2*th-1; 4006 r.size.width = s->slice.width + 2*th-1;
4005 r.size.height = s->slice.height + 2*th-1; 4007 r.size.height = s->slice.height + 2*th-1;
4006 ns_draw_relief (r, th, raised_p, 4008 ns_draw_relief (r, th, th, raised_p,
4007 s->slice.y == 0, 4009 s->slice.y == 0,
4008 s->slice.y + s->slice.height == s->img->height, 4010 s->slice.y + s->slice.height == s->img->height,
4009 s->slice.x == 0, 4011 s->slice.x == 0,
@@ -4017,7 +4019,7 @@ ns_dumpglyphs_image (struct glyph_string *s, NSRect r)
4017 { 4019 {
4018 int thickness = abs (s->img->relief); 4020 int thickness = abs (s->img->relief);
4019 if (thickness == 0) thickness = 1; 4021 if (thickness == 0) thickness = 1;
4020 ns_draw_box (br, thickness, FRAME_CURSOR_COLOR (s->f), 1, 1); 4022 ns_draw_box (br, thickness, thickness, FRAME_CURSOR_COLOR (s->f), 1, 1);
4021 } 4023 }
4022} 4024}
4023 4025
@@ -4100,7 +4102,7 @@ ns_draw_glyph_string_foreground (struct glyph_string *s)
4100 of S to the right of that box line. */ 4102 of S to the right of that box line. */
4101 if (s->face && s->face->box != FACE_NO_BOX 4103 if (s->face && s->face->box != FACE_NO_BOX
4102 && s->first_glyph->left_box_line_p) 4104 && s->first_glyph->left_box_line_p)
4103 x = s->x + eabs (s->face->box_line_width); 4105 x = s->x + max (s->face->box_vertical_line_width, 0);
4104 else 4106 else
4105 x = s->x; 4107 x = s->x;
4106 4108
@@ -4126,7 +4128,7 @@ ns_draw_composite_glyph_string_foreground (struct glyph_string *s)
4126 of S to the right of that box line. */ 4128 of S to the right of that box line. */
4127 if (s->face && s->face->box != FACE_NO_BOX 4129 if (s->face && s->face->box != FACE_NO_BOX
4128 && s->first_glyph->left_box_line_p) 4130 && s->first_glyph->left_box_line_p)
4129 x = s->x + eabs (s->face->box_line_width); 4131 x = s->x + max (s->face->box_vertical_line_width, 0);
4130 else 4132 else
4131 x = s->x; 4133 x = s->x;
4132 4134
@@ -4142,7 +4144,7 @@ ns_draw_composite_glyph_string_foreground (struct glyph_string *s)
4142 if (s->cmp_from == 0) 4144 if (s->cmp_from == 0)
4143 { 4145 {
4144 NSRect r = NSMakeRect (s->x, s->y, s->width-1, s->height -1); 4146 NSRect r = NSMakeRect (s->x, s->y, s->width-1, s->height -1);
4145 ns_draw_box (r, 1, FRAME_CURSOR_COLOR (s->f), 1, 1); 4147 ns_draw_box (r, 1, 1, FRAME_CURSOR_COLOR (s->f), 1, 1);
4146 } 4148 }
4147 } 4149 }
4148 else if (! s->first_glyph->u.cmp.automatic) 4150 else if (! s->first_glyph->u.cmp.automatic)
diff --git a/src/w32term.c b/src/w32term.c
index 76cf6bd6964..5fa77d58e10 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -888,10 +888,10 @@ static void w32_draw_image_foreground_1 (struct glyph_string *, HBITMAP);
888static void w32_clear_glyph_string_rect (struct glyph_string *, int, 888static void w32_clear_glyph_string_rect (struct glyph_string *, int,
889 int, int, int); 889 int, int, int);
890static void w32_draw_relief_rect (struct frame *, int, int, int, int, 890static void w32_draw_relief_rect (struct frame *, int, int, int, int,
891 int, int, int, int, int, int, 891 int, int, int, int, int, int, int,
892 RECT *); 892 RECT *);
893static void w32_draw_box_rect (struct glyph_string *, int, int, int, int, 893static void w32_draw_box_rect (struct glyph_string *, int, int, int, int,
894 int, bool, bool, RECT *); 894 int, int, bool, bool, RECT *);
895 895
896 896
897/* Set S->gc to a suitable GC for drawing glyph string S in cursor 897/* Set S->gc to a suitable GC for drawing glyph string S in cursor
@@ -1160,7 +1160,7 @@ w32_draw_glyph_string_background (struct glyph_string *s, bool force_p)
1160 shouldn't be drawn in the first place. */ 1160 shouldn't be drawn in the first place. */
1161 if (!s->background_filled_p) 1161 if (!s->background_filled_p)
1162 { 1162 {
1163 int box_line_width = max (s->face->box_line_width, 0); 1163 int box_line_width = max (s->face->box_horizontal_line_width, 0);
1164 1164
1165#if 0 /* TODO: stipple */ 1165#if 0 /* TODO: stipple */
1166 if (s->stippled_p) 1166 if (s->stippled_p)
@@ -1206,7 +1206,7 @@ w32_draw_glyph_string_foreground (struct glyph_string *s)
1206 of S to the right of that box line. */ 1206 of S to the right of that box line. */
1207 if (s->face->box != FACE_NO_BOX 1207 if (s->face->box != FACE_NO_BOX
1208 && s->first_glyph->left_box_line_p) 1208 && s->first_glyph->left_box_line_p)
1209 x = s->x + eabs (s->face->box_line_width); 1209 x = s->x + max (s->face->box_vertical_line_width, 0);
1210 else 1210 else
1211 x = s->x; 1211 x = s->x;
1212 1212
@@ -1264,7 +1264,7 @@ w32_draw_composite_glyph_string_foreground (struct glyph_string *s)
1264 of S to the right of that box line. */ 1264 of S to the right of that box line. */
1265 if (s->face && s->face->box != FACE_NO_BOX 1265 if (s->face && s->face->box != FACE_NO_BOX
1266 && s->first_glyph->left_box_line_p) 1266 && s->first_glyph->left_box_line_p)
1267 x = s->x + eabs (s->face->box_line_width); 1267 x = s->x + max (s->face->box_vertical_line_width, 0);
1268 else 1268 else
1269 x = s->x; 1269 x = s->x;
1270 1270
@@ -1361,7 +1361,7 @@ w32_draw_glyphless_glyph_string_foreground (struct glyph_string *s)
1361 of S to the right of that box line. */ 1361 of S to the right of that box line. */
1362 if (s->face->box != FACE_NO_BOX 1362 if (s->face->box != FACE_NO_BOX
1363 && s->first_glyph->left_box_line_p) 1363 && s->first_glyph->left_box_line_p)
1364 x = s->x + eabs (s->face->box_line_width); 1364 x = s->x + max (s->face->box_vertical_line_width, 0);
1365 else 1365 else
1366 x = s->x; 1366 x = s->x;
1367 1367
@@ -1617,7 +1617,7 @@ w32_setup_relief_colors (struct glyph_string *s)
1617static void 1617static void
1618w32_draw_relief_rect (struct frame *f, 1618w32_draw_relief_rect (struct frame *f,
1619 int left_x, int top_y, int right_x, int bottom_y, 1619 int left_x, int top_y, int right_x, int bottom_y,
1620 int width, int raised_p, 1620 int hwidth, int vwidth, int raised_p,
1621 int top_p, int bot_p, int left_p, int right_p, 1621 int top_p, int bot_p, int left_p, int right_p,
1622 RECT *clip_rect) 1622 RECT *clip_rect)
1623{ 1623{
@@ -1634,14 +1634,14 @@ w32_draw_relief_rect (struct frame *f,
1634 1634
1635 /* Top. */ 1635 /* Top. */
1636 if (top_p) 1636 if (top_p)
1637 for (i = 0; i < width; ++i) 1637 for (i = 0; i < hwidth; ++i)
1638 w32_fill_area (f, hdc, gc.foreground, 1638 w32_fill_area (f, hdc, gc.foreground,
1639 left_x + i * left_p, top_y + i, 1639 left_x + i * left_p, top_y + i,
1640 right_x - left_x - i * (left_p + right_p ) + 1, 1); 1640 right_x - left_x - i * (left_p + right_p ) + 1, 1);
1641 1641
1642 /* Left. */ 1642 /* Left. */
1643 if (left_p) 1643 if (left_p)
1644 for (i = 0; i < width; ++i) 1644 for (i = 0; i < vwidth; ++i)
1645 w32_fill_area (f, hdc, gc.foreground, 1645 w32_fill_area (f, hdc, gc.foreground,
1646 left_x + i, top_y + (i + 1) * top_p, 1, 1646 left_x + i, top_y + (i + 1) * top_p, 1,
1647 bottom_y - top_y - (i + 1) * (bot_p + top_p) + 1); 1647 bottom_y - top_y - (i + 1) * (bot_p + top_p) + 1);
@@ -1653,14 +1653,14 @@ w32_draw_relief_rect (struct frame *f,
1653 1653
1654 /* Bottom. */ 1654 /* Bottom. */
1655 if (bot_p) 1655 if (bot_p)
1656 for (i = 0; i < width; ++i) 1656 for (i = 0; i < hwidth; ++i)
1657 w32_fill_area (f, hdc, gc.foreground, 1657 w32_fill_area (f, hdc, gc.foreground,
1658 left_x + i * left_p, bottom_y - i, 1658 left_x + i * left_p, bottom_y - i,
1659 right_x - left_x - i * (left_p + right_p) + 1, 1); 1659 right_x - left_x - i * (left_p + right_p) + 1, 1);
1660 1660
1661 /* Right. */ 1661 /* Right. */
1662 if (right_p) 1662 if (right_p)
1663 for (i = 0; i < width; ++i) 1663 for (i = 0; i < vwidth; ++i)
1664 w32_fill_area (f, hdc, gc.foreground, 1664 w32_fill_area (f, hdc, gc.foreground,
1665 right_x - i, top_y + (i + 1) * top_p, 1, 1665 right_x - i, top_y + (i + 1) * top_p, 1,
1666 bottom_y - top_y - (i + 1) * (bot_p + top_p) + 1); 1666 bottom_y - top_y - (i + 1) * (bot_p + top_p) + 1);
@@ -1680,31 +1680,31 @@ w32_draw_relief_rect (struct frame *f,
1680 1680
1681static void 1681static void
1682w32_draw_box_rect (struct glyph_string *s, 1682w32_draw_box_rect (struct glyph_string *s,
1683 int left_x, int top_y, int right_x, int bottom_y, int width, 1683 int left_x, int top_y, int right_x, int bottom_y, int hwidth,
1684 bool left_p, bool right_p, RECT *clip_rect) 1684 int vwidth, bool left_p, bool right_p, RECT *clip_rect)
1685{ 1685{
1686 w32_set_clip_rectangle (s->hdc, clip_rect); 1686 w32_set_clip_rectangle (s->hdc, clip_rect);
1687 1687
1688 /* Top. */ 1688 /* Top. */
1689 w32_fill_area (s->f, s->hdc, s->face->box_color, 1689 w32_fill_area (s->f, s->hdc, s->face->box_color,
1690 left_x, top_y, right_x - left_x + 1, width); 1690 left_x, top_y, right_x - left_x + 1, hwidth);
1691 1691
1692 /* Left. */ 1692 /* Left. */
1693 if (left_p) 1693 if (left_p)
1694 { 1694 {
1695 w32_fill_area (s->f, s->hdc, s->face->box_color, 1695 w32_fill_area (s->f, s->hdc, s->face->box_color,
1696 left_x, top_y, width, bottom_y - top_y + 1); 1696 left_x, top_y, vwidth, bottom_y - top_y + 1);
1697 } 1697 }
1698 1698
1699 /* Bottom. */ 1699 /* Bottom. */
1700 w32_fill_area (s->f, s->hdc, s->face->box_color, 1700 w32_fill_area (s->f, s->hdc, s->face->box_color,
1701 left_x, bottom_y - width + 1, right_x - left_x + 1, width); 1701 left_x, bottom_y - hwidth + 1, right_x - left_x + 1, hwidth);
1702 1702
1703 /* Right. */ 1703 /* Right. */
1704 if (right_p) 1704 if (right_p)
1705 { 1705 {
1706 w32_fill_area (s->f, s->hdc, s->face->box_color, 1706 w32_fill_area (s->f, s->hdc, s->face->box_color,
1707 right_x - width + 1, top_y, width, bottom_y - top_y + 1); 1707 right_x - vwidth + 1, top_y, vwidth, bottom_y - top_y + 1);
1708 } 1708 }
1709 1709
1710 w32_set_clip_rectangle (s->hdc, NULL); 1710 w32_set_clip_rectangle (s->hdc, NULL);
@@ -1716,7 +1716,7 @@ w32_draw_box_rect (struct glyph_string *s,
1716static void 1716static void
1717w32_draw_glyph_string_box (struct glyph_string *s) 1717w32_draw_glyph_string_box (struct glyph_string *s)
1718{ 1718{
1719 int width, left_x, right_x, top_y, bottom_y, last_x; 1719 int hwidth, vwidth, left_x, right_x, top_y, bottom_y, last_x;
1720 bool left_p, right_p, raised_p; 1720 bool left_p, right_p, raised_p;
1721 struct glyph *last_glyph; 1721 struct glyph *last_glyph;
1722 RECT clip_rect; 1722 RECT clip_rect;
@@ -1730,7 +1730,8 @@ w32_draw_glyph_string_box (struct glyph_string *s)
1730 ? s->first_glyph 1730 ? s->first_glyph
1731 : s->first_glyph + s->nchars - 1); 1731 : s->first_glyph + s->nchars - 1);
1732 1732
1733 width = eabs (s->face->box_line_width); 1733 vwidth = eabs (s->face->box_vertical_line_width);
1734 hwidth = eabs (s->face->box_horizontal_line_width);
1734 raised_p = s->face->box == FACE_RAISED_BOX; 1735 raised_p = s->face->box == FACE_RAISED_BOX;
1735 left_x = s->x; 1736 left_x = s->x;
1736 right_x = ((s->row->full_width_p && s->extends_to_end_of_line_p 1737 right_x = ((s->row->full_width_p && s->extends_to_end_of_line_p
@@ -1751,13 +1752,13 @@ w32_draw_glyph_string_box (struct glyph_string *s)
1751 get_glyph_string_clip_rect (s, &clip_rect); 1752 get_glyph_string_clip_rect (s, &clip_rect);
1752 1753
1753 if (s->face->box == FACE_SIMPLE_BOX) 1754 if (s->face->box == FACE_SIMPLE_BOX)
1754 w32_draw_box_rect (s, left_x, top_y, right_x, bottom_y, width, 1755 w32_draw_box_rect (s, left_x, top_y, right_x, bottom_y, hwidth,
1755 left_p, right_p, &clip_rect); 1756 vwidth, left_p, right_p, &clip_rect);
1756 else 1757 else
1757 { 1758 {
1758 w32_setup_relief_colors (s); 1759 w32_setup_relief_colors (s);
1759 w32_draw_relief_rect (s->f, left_x, top_y, right_x, bottom_y, 1760 w32_draw_relief_rect (s->f, left_x, top_y, right_x, bottom_y, hwidth,
1760 width, raised_p, 1, 1, left_p, right_p, &clip_rect); 1761 vwidth, raised_p, 1, 1, left_p, right_p, &clip_rect);
1761 } 1762 }
1762} 1763}
1763 1764
@@ -1795,7 +1796,7 @@ w32_draw_image_foreground (struct glyph_string *s)
1795 if (s->face->box != FACE_NO_BOX 1796 if (s->face->box != FACE_NO_BOX
1796 && s->first_glyph->left_box_line_p 1797 && s->first_glyph->left_box_line_p
1797 && s->slice.x == 0) 1798 && s->slice.x == 0)
1798 x += eabs (s->face->box_line_width); 1799 x += max (s->face->box_vertical_line_width, 0);
1799 1800
1800 /* If there is a margin around the image, adjust x- and y-position 1801 /* If there is a margin around the image, adjust x- and y-position
1801 by that margin. */ 1802 by that margin. */
@@ -1982,7 +1983,7 @@ w32_draw_image_relief (struct glyph_string *s)
1982 if (s->face->box != FACE_NO_BOX 1983 if (s->face->box != FACE_NO_BOX
1983 && s->first_glyph->left_box_line_p 1984 && s->first_glyph->left_box_line_p
1984 && s->slice.x == 0) 1985 && s->slice.x == 0)
1985 x += eabs (s->face->box_line_width); 1986 x += max (s->face->box_vertical_line_width, 0);
1986 1987
1987 /* If there is a margin around the image, adjust x- and y-position 1988 /* If there is a margin around the image, adjust x- and y-position
1988 by that margin. */ 1989 by that margin. */
@@ -2034,7 +2035,7 @@ w32_draw_image_relief (struct glyph_string *s)
2034 2035
2035 w32_setup_relief_colors (s); 2036 w32_setup_relief_colors (s);
2036 get_glyph_string_clip_rect (s, &r); 2037 get_glyph_string_clip_rect (s, &r);
2037 w32_draw_relief_rect (s->f, x, y, x1, y1, thick, raised_p, 2038 w32_draw_relief_rect (s->f, x, y, x1, y1, thick, thick, raised_p,
2038 top_p, bot_p, left_p, right_p, &r); 2039 top_p, bot_p, left_p, right_p, &r);
2039} 2040}
2040 2041
@@ -2054,7 +2055,7 @@ w32_draw_image_foreground_1 (struct glyph_string *s, HBITMAP pixmap)
2054 if (s->face->box != FACE_NO_BOX 2055 if (s->face->box != FACE_NO_BOX
2055 && s->first_glyph->left_box_line_p 2056 && s->first_glyph->left_box_line_p
2056 && s->slice.x == 0) 2057 && s->slice.x == 0)
2057 x += eabs (s->face->box_line_width); 2058 x += max (s->face->box_vertical_line_width, 0);
2058 2059
2059 /* If there is a margin around the image, adjust x- and y-position 2060 /* If there is a margin around the image, adjust x- and y-position
2060 by that margin. */ 2061 by that margin. */
@@ -2167,8 +2168,8 @@ static void
2167w32_draw_image_glyph_string (struct glyph_string *s) 2168w32_draw_image_glyph_string (struct glyph_string *s)
2168{ 2169{
2169 int x, y; 2170 int x, y;
2170 int box_line_hwidth = eabs (s->face->box_line_width); 2171 int box_line_hwidth = max (s->face->box_vertical_line_width, 0);
2171 int box_line_vwidth = max (s->face->box_line_width, 0); 2172 int box_line_vwidth = max (s->face->box_horizontal_line_width, 0);
2172 int height, width; 2173 int height, width;
2173 HBITMAP pixmap = 0; 2174 HBITMAP pixmap = 0;
2174 2175
diff --git a/src/xdisp.c b/src/xdisp.c
index 61c798c59e8..cbdef7ad118 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -2061,8 +2061,8 @@ estimate_mode_line_height (struct frame *f, enum face_id face_id)
2061 { 2061 {
2062 if (face->font) 2062 if (face->font)
2063 height = normal_char_height (face->font, -1); 2063 height = normal_char_height (face->font, -1);
2064 if (face->box_line_width > 0) 2064 if (face->box_horizontal_line_width > 0)
2065 height += 2 * face->box_line_width; 2065 height += 2 * face->box_horizontal_line_width;
2066 } 2066 }
2067 } 2067 }
2068 2068
@@ -28900,18 +28900,21 @@ produce_image_glyph (struct it *it)
28900 28900
28901 if (face->box != FACE_NO_BOX) 28901 if (face->box != FACE_NO_BOX)
28902 { 28902 {
28903 if (face->box_line_width > 0) 28903 if (face->box_horizontal_line_width > 0)
28904 { 28904 {
28905 if (slice.y == 0) 28905 if (slice.y == 0)
28906 it->ascent += face->box_line_width; 28906 it->ascent += face->box_horizontal_line_width;
28907 if (slice.y + slice.height == img->height) 28907 if (slice.y + slice.height == img->height)
28908 it->descent += face->box_line_width; 28908 it->descent += face->box_horizontal_line_width;
28909 } 28909 }
28910 28910
28911 if (it->start_of_box_run_p && slice.x == 0) 28911 if (face->box_vertical_line_width > 0)
28912 it->pixel_width += eabs (face->box_line_width); 28912 {
28913 if (it->end_of_box_run_p && slice.x + slice.width == img->width) 28913 if (it->start_of_box_run_p && slice.x == 0)
28914 it->pixel_width += eabs (face->box_line_width); 28914 it->pixel_width += face->box_vertical_line_width;
28915 if (it->end_of_box_run_p && slice.x + slice.width == img->width)
28916 it->pixel_width += face->box_vertical_line_width;
28917 }
28915 } 28918 }
28916 28919
28917 take_vertical_position_into_account (it); 28920 take_vertical_position_into_account (it);
@@ -29009,15 +29012,18 @@ produce_xwidget_glyph (struct it *it)
29009 29012
29010 if (face->box != FACE_NO_BOX) 29013 if (face->box != FACE_NO_BOX)
29011 { 29014 {
29012 if (face->box_line_width > 0) 29015 if (face->box_horizontal_line_width > 0)
29013 { 29016 {
29014 it->ascent += face->box_line_width; 29017 it->ascent += face->box_horizontal_line_width;
29015 it->descent += face->box_line_width; 29018 it->descent += face->box_horizontal_line_width;
29016 } 29019 }
29017 29020
29018 if (it->start_of_box_run_p) 29021 if (face->box_vertical_line_width > 0)
29019 it->pixel_width += eabs (face->box_line_width); 29022 {
29020 it->pixel_width += eabs (face->box_line_width); 29023 if (it->start_of_box_run_p)
29024 it->pixel_width += face->box_vertical_line_width;
29025 it->pixel_width += face->box_vertical_line_width;
29026 }
29021 } 29027 }
29022 29028
29023 take_vertical_position_into_account (it); 29029 take_vertical_position_into_account (it);
@@ -29780,6 +29786,31 @@ produce_glyphless_glyph (struct it *it, bool for_no_font, Lisp_Object acronym)
29780} 29786}
29781 29787
29782 29788
29789/* If face has a box, add the box thickness to the character
29790 height. If character has a box line to the left and/or
29791 right, add the box line width to the character's width. */
29792#define IT_APPLY_FACE_BOX(it, face) \
29793 do { \
29794 if (face->box != FACE_NO_BOX) \
29795 { \
29796 int thick = face->box_horizontal_line_width; \
29797 if (thick > 0) \
29798 { \
29799 it->ascent += thick; \
29800 it->descent += thick; \
29801 } \
29802 \
29803 thick = face->box_vertical_line_width; \
29804 if (thick > 0) \
29805 { \
29806 if (it->start_of_box_run_p) \
29807 it->pixel_width += thick; \
29808 if (it->end_of_box_run_p) \
29809 it->pixel_width += thick; \
29810 } \
29811 } \
29812 } while (false)
29813
29783/* RIF: 29814/* RIF:
29784 Produce glyphs/get display metrics for the display element IT is 29815 Produce glyphs/get display metrics for the display element IT is
29785 loaded with. See the description of struct it in dispextern.h 29816 loaded with. See the description of struct it in dispextern.h
@@ -29895,26 +29926,7 @@ gui_produce_glyphs (struct it *it)
29895 if (stretched_p) 29926 if (stretched_p)
29896 it->pixel_width *= XFLOATINT (it->space_width); 29927 it->pixel_width *= XFLOATINT (it->space_width);
29897 29928
29898 /* If face has a box, add the box thickness to the character 29929 IT_APPLY_FACE_BOX(it, face);
29899 height. If character has a box line to the left and/or
29900 right, add the box line width to the character's width. */
29901 if (face->box != FACE_NO_BOX)
29902 {
29903 int thick = face->box_line_width;
29904
29905 if (thick > 0)
29906 {
29907 it->ascent += thick;
29908 it->descent += thick;
29909 }
29910 else
29911 thick = -thick;
29912
29913 if (it->start_of_box_run_p)
29914 it->pixel_width += thick;
29915 if (it->end_of_box_run_p)
29916 it->pixel_width += thick;
29917 }
29918 29930
29919 /* If face has an overline, add the height of the overline 29931 /* If face has an overline, add the height of the overline
29920 (1 pixel) and a 1 pixel margin to the character height. */ 29932 (1 pixel) and a 1 pixel margin to the character height. */
@@ -30029,10 +30041,10 @@ gui_produce_glyphs (struct it *it)
30029 30041
30030 if ((it->max_ascent > 0 || it->max_descent > 0) 30042 if ((it->max_ascent > 0 || it->max_descent > 0)
30031 && face->box != FACE_NO_BOX 30043 && face->box != FACE_NO_BOX
30032 && face->box_line_width > 0) 30044 && face->box_horizontal_line_width > 0)
30033 { 30045 {
30034 it->ascent += face->box_line_width; 30046 it->ascent += face->box_horizontal_line_width;
30035 it->descent += face->box_line_width; 30047 it->descent += face->box_horizontal_line_width;
30036 } 30048 }
30037 if (!NILP (height) 30049 if (!NILP (height)
30038 && XFIXNUM (height) > it->ascent + it->descent) 30050 && XFIXNUM (height) > it->ascent + it->descent)
@@ -30439,23 +30451,7 @@ gui_produce_glyphs (struct it *it)
30439 it->pixel_width = cmp->pixel_width; 30451 it->pixel_width = cmp->pixel_width;
30440 it->ascent = it->phys_ascent = cmp->ascent; 30452 it->ascent = it->phys_ascent = cmp->ascent;
30441 it->descent = it->phys_descent = cmp->descent; 30453 it->descent = it->phys_descent = cmp->descent;
30442 if (face->box != FACE_NO_BOX) 30454 IT_APPLY_FACE_BOX(it, face);
30443 {
30444 int thick = face->box_line_width;
30445
30446 if (thick > 0)
30447 {
30448 it->ascent += thick;
30449 it->descent += thick;
30450 }
30451 else
30452 thick = - thick;
30453
30454 if (it->start_of_box_run_p)
30455 it->pixel_width += thick;
30456 if (it->end_of_box_run_p)
30457 it->pixel_width += thick;
30458 }
30459 30455
30460 /* If face has an overline, add the height of the overline 30456 /* If face has an overline, add the height of the overline
30461 (1 pixel) and a 1 pixel margin to the character height. */ 30457 (1 pixel) and a 1 pixel margin to the character height. */
@@ -30489,23 +30485,8 @@ gui_produce_glyphs (struct it *it)
30489 it->glyph_row->contains_overlapping_glyphs_p = true; 30485 it->glyph_row->contains_overlapping_glyphs_p = true;
30490 it->ascent = it->phys_ascent = metrics.ascent; 30486 it->ascent = it->phys_ascent = metrics.ascent;
30491 it->descent = it->phys_descent = metrics.descent; 30487 it->descent = it->phys_descent = metrics.descent;
30492 if (face->box != FACE_NO_BOX) 30488 IT_APPLY_FACE_BOX(it, face);
30493 {
30494 int thick = face->box_line_width;
30495 30489
30496 if (thick > 0)
30497 {
30498 it->ascent += thick;
30499 it->descent += thick;
30500 }
30501 else
30502 thick = - thick;
30503
30504 if (it->start_of_box_run_p)
30505 it->pixel_width += thick;
30506 if (it->end_of_box_run_p)
30507 it->pixel_width += thick;
30508 }
30509 /* If face has an overline, add the height of the overline 30490 /* If face has an overline, add the height of the overline
30510 (1 pixel) and a 1 pixel margin to the character height. */ 30491 (1 pixel) and a 1 pixel margin to the character height. */
30511 if (face->overline_p) 30492 if (face->overline_p)
diff --git a/src/xfaces.c b/src/xfaces.c
index 711ec48bbdd..bab142ade0f 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -3128,6 +3128,8 @@ FRAME 0 means change the face on all frames, and change the default
3128 valid_p = XFIXNUM (value) != 0; 3128 valid_p = XFIXNUM (value) != 0;
3129 else if (STRINGP (value)) 3129 else if (STRINGP (value))
3130 valid_p = SCHARS (value) > 0; 3130 valid_p = SCHARS (value) > 0;
3131 else if (CONSP (value) && FIXNUMP (XCAR (value)) && FIXNUMP (XCDR (value)))
3132 valid_p = true;
3131 else if (CONSP (value)) 3133 else if (CONSP (value))
3132 { 3134 {
3133 Lisp_Object tem; 3135 Lisp_Object tem;
@@ -3146,7 +3148,9 @@ FRAME 0 means change the face on all frames, and change the default
3146 3148
3147 if (EQ (k, QCline_width)) 3149 if (EQ (k, QCline_width))
3148 { 3150 {
3149 if (!FIXNUMP (v) || XFIXNUM (v) == 0) 3151 if ((!CONSP(v) || !FIXNUMP (XCAR (v)) || XFIXNUM (XCAR (v)) == 0
3152 || !FIXNUMP (XCDR (v)) || XFIXNUM (XCDR (v)) == 0)
3153 && (!FIXNUMP (v) || XFIXNUM (v) == 0))
3150 break; 3154 break;
3151 } 3155 }
3152 else if (EQ (k, QCcolor)) 3156 else if (EQ (k, QCcolor))
@@ -5815,7 +5819,7 @@ realize_gui_face (struct face_cache *cache, Lisp_Object attrs[LFACE_VECTOR_SIZE]
5815 face->box_color = load_color (f, face, attrs[LFACE_BOX_INDEX], 5819 face->box_color = load_color (f, face, attrs[LFACE_BOX_INDEX],
5816 LFACE_BOX_INDEX); 5820 LFACE_BOX_INDEX);
5817 face->box = FACE_SIMPLE_BOX; 5821 face->box = FACE_SIMPLE_BOX;
5818 face->box_line_width = 1; 5822 face->box_vertical_line_width = face->box_horizontal_line_width = 1;
5819 } 5823 }
5820 else if (FIXNUMP (box)) 5824 else if (FIXNUMP (box))
5821 { 5825 {
@@ -5823,9 +5827,19 @@ realize_gui_face (struct face_cache *cache, Lisp_Object attrs[LFACE_VECTOR_SIZE]
5823 face. */ 5827 face. */
5824 eassert (XFIXNUM (box) != 0); 5828 eassert (XFIXNUM (box) != 0);
5825 face->box = FACE_SIMPLE_BOX; 5829 face->box = FACE_SIMPLE_BOX;
5826 face->box_line_width = XFIXNUM (box); 5830 face->box_vertical_line_width = eabs(XFIXNUM (box));
5831 face->box_horizontal_line_width = XFIXNUM (box);
5832 face->box_color = face->foreground;
5833 face->box_color_defaulted_p = true;
5834 }
5835 else if (CONSP (box) && FIXNUMP (XCAR (box)) && FIXNUMP (XCDR (box)))
5836 {
5837 /* `(VWIDTH . HWIDTH)'. */
5838 face->box = FACE_SIMPLE_BOX;
5827 face->box_color = face->foreground; 5839 face->box_color = face->foreground;
5828 face->box_color_defaulted_p = true; 5840 face->box_color_defaulted_p = true;
5841 face->box_vertical_line_width = XFIXNUM (XCAR (box));
5842 face->box_horizontal_line_width = XFIXNUM (XCDR (box));
5829 } 5843 }
5830 else if (CONSP (box)) 5844 else if (CONSP (box))
5831 { 5845 {
@@ -5834,7 +5848,7 @@ realize_gui_face (struct face_cache *cache, Lisp_Object attrs[LFACE_VECTOR_SIZE]
5834 face->box = FACE_SIMPLE_BOX; 5848 face->box = FACE_SIMPLE_BOX;
5835 face->box_color = face->foreground; 5849 face->box_color = face->foreground;
5836 face->box_color_defaulted_p = true; 5850 face->box_color_defaulted_p = true;
5837 face->box_line_width = 1; 5851 face->box_vertical_line_width = face->box_horizontal_line_width = 1;
5838 5852
5839 while (CONSP (box)) 5853 while (CONSP (box))
5840 { 5854 {
@@ -5850,8 +5864,14 @@ realize_gui_face (struct face_cache *cache, Lisp_Object attrs[LFACE_VECTOR_SIZE]
5850 5864
5851 if (EQ (keyword, QCline_width)) 5865 if (EQ (keyword, QCline_width))
5852 { 5866 {
5853 if (FIXNUMP (value) && XFIXNUM (value) != 0) 5867 if (CONSP (value) && FIXNUMP (XCAR (value)) && FIXNUMP (XCDR (value))) {
5854 face->box_line_width = XFIXNUM (value); 5868 face->box_vertical_line_width = XFIXNUM (XCAR (value));
5869 face->box_horizontal_line_width = XFIXNUM (XCDR (value));
5870 }
5871 else if (FIXNUMP (value) && XFIXNUM (value) != 0) {
5872 face->box_vertical_line_width = eabs (XFIXNUM (value));
5873 face->box_horizontal_line_width = XFIXNUM (value);
5874 }
5855 } 5875 }
5856 else if (EQ (keyword, QCcolor)) 5876 else if (EQ (keyword, QCcolor))
5857 { 5877 {
diff --git a/src/xterm.c b/src/xterm.c
index d7d992c91b2..fc68c77048f 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -1754,7 +1754,7 @@ x_draw_glyph_string_background (struct glyph_string *s, bool force_p)
1754 shouldn't be drawn in the first place. */ 1754 shouldn't be drawn in the first place. */
1755 if (!s->background_filled_p) 1755 if (!s->background_filled_p)
1756 { 1756 {
1757 int box_line_width = max (s->face->box_line_width, 0); 1757 int box_line_width = max (s->face->box_horizontal_line_width, 0);
1758 1758
1759 if (s->stippled_p) 1759 if (s->stippled_p)
1760 { 1760 {
@@ -1799,7 +1799,7 @@ x_draw_glyph_string_foreground (struct glyph_string *s)
1799 of S to the right of that box line. */ 1799 of S to the right of that box line. */
1800 if (s->face->box != FACE_NO_BOX 1800 if (s->face->box != FACE_NO_BOX
1801 && s->first_glyph->left_box_line_p) 1801 && s->first_glyph->left_box_line_p)
1802 x = s->x + eabs (s->face->box_line_width); 1802 x = s->x + max (s->face->box_vertical_line_width, 0);
1803 else 1803 else
1804 x = s->x; 1804 x = s->x;
1805 1805
@@ -1849,7 +1849,7 @@ x_draw_glyph_string_foreground (struct glyph_string *s)
1849 if (!(s->for_overlaps 1849 if (!(s->for_overlaps
1850 || (s->background_filled_p && s->hl != DRAW_CURSOR))) 1850 || (s->background_filled_p && s->hl != DRAW_CURSOR)))
1851 { 1851 {
1852 int box_line_width = max (s->face->box_line_width, 0); 1852 int box_line_width = max (s->face->box_horizontal_line_width, 0);
1853 1853
1854 if (s->stippled_p) 1854 if (s->stippled_p)
1855 { 1855 {
@@ -1893,7 +1893,7 @@ x_draw_composite_glyph_string_foreground (struct glyph_string *s)
1893 of S to the right of that box line. */ 1893 of S to the right of that box line. */
1894 if (s->face && s->face->box != FACE_NO_BOX 1894 if (s->face && s->face->box != FACE_NO_BOX
1895 && s->first_glyph->left_box_line_p) 1895 && s->first_glyph->left_box_line_p)
1896 x = s->x + eabs (s->face->box_line_width); 1896 x = s->x + max (s->face->box_vertical_line_width, 0);
1897 else 1897 else
1898 x = s->x; 1898 x = s->x;
1899 1899
@@ -2004,7 +2004,7 @@ x_draw_glyphless_glyph_string_foreground (struct glyph_string *s)
2004 of S to the right of that box line. */ 2004 of S to the right of that box line. */
2005 if (s->face && s->face->box != FACE_NO_BOX 2005 if (s->face && s->face->box != FACE_NO_BOX
2006 && s->first_glyph->left_box_line_p) 2006 && s->first_glyph->left_box_line_p)
2007 x = s->x + eabs (s->face->box_line_width); 2007 x = s->x + max (s->face->box_vertical_line_width, 0);
2008 else 2008 else
2009 x = s->x; 2009 x = s->x;
2010 2010
@@ -2769,7 +2769,7 @@ x_setup_relief_colors (struct glyph_string *s)
2769static void 2769static void
2770x_draw_relief_rect (struct frame *f, 2770x_draw_relief_rect (struct frame *f,
2771 int left_x, int top_y, int right_x, int bottom_y, 2771 int left_x, int top_y, int right_x, int bottom_y,
2772 int width, bool raised_p, bool top_p, bool bot_p, 2772 int hwidth, int vwidth, bool raised_p, bool top_p, bool bot_p,
2773 bool left_p, bool right_p, 2773 bool left_p, bool right_p,
2774 XRectangle *clip_rect) 2774 XRectangle *clip_rect)
2775{ 2775{
@@ -2794,7 +2794,7 @@ x_draw_relief_rect (struct frame *f,
2794 if (left_p) 2794 if (left_p)
2795 { 2795 {
2796 x_fill_rectangle (f, top_left_gc, left_x, top_y, 2796 x_fill_rectangle (f, top_left_gc, left_x, top_y,
2797 width, bottom_y + 1 - top_y); 2797 vwidth, bottom_y + 1 - top_y);
2798 if (top_p) 2798 if (top_p)
2799 corners |= 1 << CORNER_TOP_LEFT; 2799 corners |= 1 << CORNER_TOP_LEFT;
2800 if (bot_p) 2800 if (bot_p)
@@ -2802,8 +2802,8 @@ x_draw_relief_rect (struct frame *f,
2802 } 2802 }
2803 if (right_p) 2803 if (right_p)
2804 { 2804 {
2805 x_fill_rectangle (f, bottom_right_gc, right_x + 1 - width, top_y, 2805 x_fill_rectangle (f, bottom_right_gc, right_x + 1 - vwidth, top_y,
2806 width, bottom_y + 1 - top_y); 2806 vwidth, bottom_y + 1 - top_y);
2807 if (top_p) 2807 if (top_p)
2808 corners |= 1 << CORNER_TOP_RIGHT; 2808 corners |= 1 << CORNER_TOP_RIGHT;
2809 if (bot_p) 2809 if (bot_p)
@@ -2813,25 +2813,25 @@ x_draw_relief_rect (struct frame *f,
2813 { 2813 {
2814 if (!right_p) 2814 if (!right_p)
2815 x_fill_rectangle (f, top_left_gc, left_x, top_y, 2815 x_fill_rectangle (f, top_left_gc, left_x, top_y,
2816 right_x + 1 - left_x, width); 2816 right_x + 1 - left_x, hwidth);
2817 else 2817 else
2818 x_fill_trapezoid_for_relief (f, top_left_gc, left_x, top_y, 2818 x_fill_trapezoid_for_relief (f, top_left_gc, left_x, top_y,
2819 right_x + 1 - left_x, width, 1); 2819 right_x + 1 - left_x, hwidth, 1);
2820 } 2820 }
2821 if (bot_p) 2821 if (bot_p)
2822 { 2822 {
2823 if (!left_p) 2823 if (!left_p)
2824 x_fill_rectangle (f, bottom_right_gc, left_x, bottom_y + 1 - width, 2824 x_fill_rectangle (f, bottom_right_gc, left_x, bottom_y + 1 - hwidth,
2825 right_x + 1 - left_x, width); 2825 right_x + 1 - left_x, hwidth);
2826 else 2826 else
2827 x_fill_trapezoid_for_relief (f, bottom_right_gc, 2827 x_fill_trapezoid_for_relief (f, bottom_right_gc,
2828 left_x, bottom_y + 1 - width, 2828 left_x, bottom_y + 1 - hwidth,
2829 right_x + 1 - left_x, width, 0); 2829 right_x + 1 - left_x, hwidth, 0);
2830 } 2830 }
2831 if (left_p && width != 1) 2831 if (left_p && vwidth > 1)
2832 x_fill_rectangle (f, bottom_right_gc, left_x, top_y, 2832 x_fill_rectangle (f, bottom_right_gc, left_x, top_y,
2833 1, bottom_y + 1 - top_y); 2833 1, bottom_y + 1 - top_y);
2834 if (top_p && width != 1) 2834 if (top_p && hwidth > 1)
2835 x_fill_rectangle (f, bottom_right_gc, left_x, top_y, 2835 x_fill_rectangle (f, bottom_right_gc, left_x, top_y,
2836 right_x + 1 - left_x, 1); 2836 right_x + 1 - left_x, 1);
2837 if (corners) 2837 if (corners)
@@ -2865,12 +2865,12 @@ x_draw_relief_rect (struct frame *f,
2865 /* Top. */ 2865 /* Top. */
2866 if (top_p) 2866 if (top_p)
2867 { 2867 {
2868 if (width == 1) 2868 if (hwidth == 1)
2869 XDrawLine (dpy, drawable, gc, 2869 XDrawLine (dpy, drawable, gc,
2870 left_x + left_p, top_y, 2870 left_x + left_p, top_y,
2871 right_x + !right_p, top_y); 2871 right_x + !right_p, top_y);
2872 2872
2873 for (i = 1; i < width; ++i) 2873 for (i = 1; i < hwidth; ++i)
2874 XDrawLine (dpy, drawable, gc, 2874 XDrawLine (dpy, drawable, gc,
2875 left_x + i * left_p, top_y + i, 2875 left_x + i * left_p, top_y + i,
2876 right_x + 1 - i * right_p, top_y + i); 2876 right_x + 1 - i * right_p, top_y + i);
@@ -2879,13 +2879,10 @@ x_draw_relief_rect (struct frame *f,
2879 /* Left. */ 2879 /* Left. */
2880 if (left_p) 2880 if (left_p)
2881 { 2881 {
2882 if (width == 1) 2882 if (vwidth == 1)
2883 XDrawLine (dpy, drawable, gc, left_x, top_y + 1, left_x, bottom_y); 2883 XDrawLine (dpy, drawable, gc, left_x, top_y + 1, left_x, bottom_y);
2884 2884
2885 x_clear_area(f, left_x, top_y, 1, 1); 2885 for (i = 1; i < vwidth; ++i)
2886 x_clear_area(f, left_x, bottom_y, 1, 1);
2887
2888 for (i = (width > 1 ? 1 : 0); i < width; ++i)
2889 XDrawLine (dpy, drawable, gc, 2886 XDrawLine (dpy, drawable, gc,
2890 left_x + i, top_y + (i + 1) * top_p, 2887 left_x + i, top_y + (i + 1) * top_p,
2891 left_x + i, bottom_y + 1 - (i + 1) * bot_p); 2888 left_x + i, bottom_y + 1 - (i + 1) * bot_p);
@@ -2898,26 +2895,25 @@ x_draw_relief_rect (struct frame *f,
2898 gc = f->output_data.x->white_relief.gc; 2895 gc = f->output_data.x->white_relief.gc;
2899 XSetClipRectangles (dpy, gc, 0, 0, clip_rect, 1, Unsorted); 2896 XSetClipRectangles (dpy, gc, 0, 0, clip_rect, 1, Unsorted);
2900 2897
2901 if (width > 1) 2898 /* Outermost top line. */
2902 { 2899 if (top_p && hwidth > 1)
2903 /* Outermost top line. */ 2900 XDrawLine (dpy, drawable, gc,
2904 if (top_p) 2901 left_x + left_p, top_y,
2905 XDrawLine (dpy, drawable, gc, 2902 right_x + !right_p, top_y);
2906 left_x + left_p, top_y,
2907 right_x + !right_p, top_y);
2908 2903
2909 /* Outermost left line. */ 2904 /* Outermost left line. */
2910 if (left_p) 2905 if (left_p && vwidth > 1)
2911 XDrawLine (dpy, drawable, gc, left_x, top_y + 1, left_x, bottom_y); 2906 XDrawLine (dpy, drawable, gc, left_x, top_y + 1, left_x, bottom_y);
2912 }
2913 2907
2914 /* Bottom. */ 2908 /* Bottom. */
2915 if (bot_p) 2909 if (bot_p)
2916 { 2910 {
2917 XDrawLine (dpy, drawable, gc, 2911 if (hwidth >= 1)
2918 left_x + left_p, bottom_y, 2912 XDrawLine (dpy, drawable, gc,
2919 right_x + !right_p, bottom_y); 2913 left_x + left_p, bottom_y,
2920 for (i = 1; i < width; ++i) 2914 right_x + !right_p, bottom_y);
2915
2916 for (i = 1; i < hwidth; ++i)
2921 XDrawLine (dpy, drawable, gc, 2917 XDrawLine (dpy, drawable, gc,
2922 left_x + i * left_p, bottom_y - i, 2918 left_x + i * left_p, bottom_y - i,
2923 right_x + 1 - i * right_p, bottom_y - i); 2919 right_x + 1 - i * right_p, bottom_y - i);
@@ -2926,9 +2922,7 @@ x_draw_relief_rect (struct frame *f,
2926 /* Right. */ 2922 /* Right. */
2927 if (right_p) 2923 if (right_p)
2928 { 2924 {
2929 x_clear_area(f, right_x, top_y, 1, 1); 2925 for (i = 0; i < vwidth; ++i)
2930 x_clear_area(f, right_x, bottom_y, 1, 1);
2931 for (i = 0; i < width; ++i)
2932 XDrawLine (dpy, drawable, gc, 2926 XDrawLine (dpy, drawable, gc,
2933 right_x - i, top_y + (i + 1) * top_p, 2927 right_x - i, top_y + (i + 1) * top_p,
2934 right_x - i, bottom_y + 1 - (i + 1) * bot_p); 2928 right_x - i, bottom_y + 1 - (i + 1) * bot_p);
@@ -2949,8 +2943,8 @@ x_draw_relief_rect (struct frame *f,
2949 2943
2950static void 2944static void
2951x_draw_box_rect (struct glyph_string *s, 2945x_draw_box_rect (struct glyph_string *s,
2952 int left_x, int top_y, int right_x, int bottom_y, int width, 2946 int left_x, int top_y, int right_x, int bottom_y, int hwidth,
2953 bool left_p, bool right_p, XRectangle *clip_rect) 2947 int vwidth, bool left_p, bool right_p, XRectangle *clip_rect)
2954{ 2948{
2955 Display *display = FRAME_X_DISPLAY (s->f); 2949 Display *display = FRAME_X_DISPLAY (s->f);
2956 XGCValues xgcv; 2950 XGCValues xgcv;
@@ -2961,21 +2955,21 @@ x_draw_box_rect (struct glyph_string *s,
2961 2955
2962 /* Top. */ 2956 /* Top. */
2963 x_fill_rectangle (s->f, s->gc, 2957 x_fill_rectangle (s->f, s->gc,
2964 left_x, top_y, right_x - left_x + 1, width); 2958 left_x, top_y, right_x - left_x + 1, hwidth);
2965 2959
2966 /* Left. */ 2960 /* Left. */
2967 if (left_p) 2961 if (left_p)
2968 x_fill_rectangle (s->f, s->gc, 2962 x_fill_rectangle (s->f, s->gc,
2969 left_x, top_y, width, bottom_y - top_y + 1); 2963 left_x, top_y, vwidth, bottom_y - top_y + 1);
2970 2964
2971 /* Bottom. */ 2965 /* Bottom. */
2972 x_fill_rectangle (s->f, s->gc, 2966 x_fill_rectangle (s->f, s->gc,
2973 left_x, bottom_y - width + 1, right_x - left_x + 1, width); 2967 left_x, bottom_y - hwidth + 1, right_x - left_x + 1, hwidth);
2974 2968
2975 /* Right. */ 2969 /* Right. */
2976 if (right_p) 2970 if (right_p)
2977 x_fill_rectangle (s->f, s->gc, 2971 x_fill_rectangle (s->f, s->gc,
2978 right_x - width + 1, top_y, width, bottom_y - top_y + 1); 2972 right_x - vwidth + 1, top_y, vwidth, bottom_y - top_y + 1);
2979 2973
2980 XSetForeground (display, s->gc, xgcv.foreground); 2974 XSetForeground (display, s->gc, xgcv.foreground);
2981 x_reset_clip_rectangles (s->f, s->gc); 2975 x_reset_clip_rectangles (s->f, s->gc);
@@ -2987,7 +2981,7 @@ x_draw_box_rect (struct glyph_string *s,
2987static void 2981static void
2988x_draw_glyph_string_box (struct glyph_string *s) 2982x_draw_glyph_string_box (struct glyph_string *s)
2989{ 2983{
2990 int width, left_x, right_x, top_y, bottom_y, last_x; 2984 int hwidth, vwidth, left_x, right_x, top_y, bottom_y, last_x;
2991 bool raised_p, left_p, right_p; 2985 bool raised_p, left_p, right_p;
2992 struct glyph *last_glyph; 2986 struct glyph *last_glyph;
2993 XRectangle clip_rect; 2987 XRectangle clip_rect;
@@ -3001,7 +2995,8 @@ x_draw_glyph_string_box (struct glyph_string *s)
3001 ? s->first_glyph 2995 ? s->first_glyph
3002 : s->first_glyph + s->nchars - 1); 2996 : s->first_glyph + s->nchars - 1);
3003 2997
3004 width = eabs (s->face->box_line_width); 2998 vwidth = eabs (s->face->box_vertical_line_width);
2999 hwidth = eabs (s->face->box_horizontal_line_width);
3005 raised_p = s->face->box == FACE_RAISED_BOX; 3000 raised_p = s->face->box == FACE_RAISED_BOX;
3006 left_x = s->x; 3001 left_x = s->x;
3007 right_x = (s->row->full_width_p && s->extends_to_end_of_line_p 3002 right_x = (s->row->full_width_p && s->extends_to_end_of_line_p
@@ -3022,13 +3017,13 @@ x_draw_glyph_string_box (struct glyph_string *s)
3022 get_glyph_string_clip_rect (s, &clip_rect); 3017 get_glyph_string_clip_rect (s, &clip_rect);
3023 3018
3024 if (s->face->box == FACE_SIMPLE_BOX) 3019 if (s->face->box == FACE_SIMPLE_BOX)
3025 x_draw_box_rect (s, left_x, top_y, right_x, bottom_y, width, 3020 x_draw_box_rect (s, left_x, top_y, right_x, bottom_y, hwidth,
3026 left_p, right_p, &clip_rect); 3021 vwidth, left_p, right_p, &clip_rect);
3027 else 3022 else
3028 { 3023 {
3029 x_setup_relief_colors (s); 3024 x_setup_relief_colors (s);
3030 x_draw_relief_rect (s->f, left_x, top_y, right_x, bottom_y, 3025 x_draw_relief_rect (s->f, left_x, top_y, right_x, bottom_y, hwidth,
3031 width, raised_p, true, true, left_p, right_p, 3026 vwidth, raised_p, true, true, left_p, right_p,
3032 &clip_rect); 3027 &clip_rect);
3033 } 3028 }
3034} 3029}
@@ -3086,7 +3081,7 @@ x_draw_image_foreground (struct glyph_string *s)
3086 if (s->face->box != FACE_NO_BOX 3081 if (s->face->box != FACE_NO_BOX
3087 && s->first_glyph->left_box_line_p 3082 && s->first_glyph->left_box_line_p
3088 && s->slice.x == 0) 3083 && s->slice.x == 0)
3089 x += eabs (s->face->box_line_width); 3084 x += max (s->face->box_vertical_line_width, 0);
3090 3085
3091 /* If there is a margin around the image, adjust x- and y-position 3086 /* If there is a margin around the image, adjust x- and y-position
3092 by that margin. */ 3087 by that margin. */
@@ -3205,7 +3200,7 @@ x_draw_image_relief (struct glyph_string *s)
3205 if (s->face->box != FACE_NO_BOX 3200 if (s->face->box != FACE_NO_BOX
3206 && s->first_glyph->left_box_line_p 3201 && s->first_glyph->left_box_line_p
3207 && s->slice.x == 0) 3202 && s->slice.x == 0)
3208 x += eabs (s->face->box_line_width); 3203 x += max (s->face->box_vertical_line_width, 0);
3209 3204
3210 /* If there is a margin around the image, adjust x- and y-position 3205 /* If there is a margin around the image, adjust x- and y-position
3211 by that margin. */ 3206 by that margin. */
@@ -3273,7 +3268,7 @@ x_draw_image_relief (struct glyph_string *s)
3273 3268
3274 x_setup_relief_colors (s); 3269 x_setup_relief_colors (s);
3275 get_glyph_string_clip_rect (s, &r); 3270 get_glyph_string_clip_rect (s, &r);
3276 x_draw_relief_rect (s->f, x, y, x1, y1, thick, raised_p, 3271 x_draw_relief_rect (s->f, x, y, x1, y1, thick, thick, raised_p,
3277 top_p, bot_p, left_p, right_p, &r); 3272 top_p, bot_p, left_p, right_p, &r);
3278} 3273}
3279 3274
@@ -3292,7 +3287,7 @@ x_draw_image_foreground_1 (struct glyph_string *s, Pixmap pixmap)
3292 if (s->face->box != FACE_NO_BOX 3287 if (s->face->box != FACE_NO_BOX
3293 && s->first_glyph->left_box_line_p 3288 && s->first_glyph->left_box_line_p
3294 && s->slice.x == 0) 3289 && s->slice.x == 0)
3295 x += eabs (s->face->box_line_width); 3290 x += max (s->face->box_vertical_line_width, 0);
3296 3291
3297 /* If there is a margin around the image, adjust x- and y-position 3292 /* If there is a margin around the image, adjust x- and y-position
3298 by that margin. */ 3293 by that margin. */
@@ -3394,8 +3389,8 @@ x_draw_glyph_string_bg_rect (struct glyph_string *s, int x, int y, int w, int h)
3394static void 3389static void
3395x_draw_image_glyph_string (struct glyph_string *s) 3390x_draw_image_glyph_string (struct glyph_string *s)
3396{ 3391{
3397 int box_line_hwidth = eabs (s->face->box_line_width); 3392 int box_line_hwidth = max (s->face->box_vertical_line_width, 0);
3398 int box_line_vwidth = max (s->face->box_line_width, 0); 3393 int box_line_vwidth = max (s->face->box_horizontal_line_width, 0);
3399 int height; 3394 int height;
3400#ifndef USE_CAIRO 3395#ifndef USE_CAIRO
3401 Display *display = FRAME_X_DISPLAY (s->f); 3396 Display *display = FRAME_X_DISPLAY (s->f);