]> git.eshelyaron.com Git - emacs.git/commitdiff
Allow negative line width for :box face attribute
authorAlexandre Adolphe <alexandre.adolphe@gmail.com>
Sat, 10 Aug 2019 20:57:24 +0000 (22:57 +0200)
committerNoam Postavsky <npostavs@gmail.com>
Wed, 1 Apr 2020 22:02:55 +0000 (18:02 -0400)
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.

doc/lispref/display.texi
lisp/cus-face.el
src/dispextern.h
src/nsfont.m
src/nsterm.m
src/w32term.c
src/xdisp.c
src/xfaces.c
src/xterm.c

index 9fbf995d7e48c5d4b24bf0d7c762a6f58e294b7b..132a3c8535476808b393147a1839ead08cd707f2 100644 (file)
@@ -2444,12 +2444,15 @@ Draw a box with lines of width 1, in the foreground color.
 @item @var{color}
 Draw a box with lines of width 1, in color @var{color}.
 
-@item @code{(:line-width @var{width} :color @var{color} :style @var{style})}
-This way you can explicitly specify all aspects of the box.  The value
-@var{width} specifies the width of the lines to draw; it defaults to
-1.  A negative width @minus{}@var{n} means to draw a line of width @var{n}
-whose top and bottom parts occupy the space of the underlying text,
-thus avoiding any increase in the character height.
+@item @code{(:line-width (@var{vwidth} . @var{hwidth}) :color @var{color} :style @var{style})}
+This way you can explicitly specify all aspects of the box.  The values
+@var{vwidth} and @var{hwidth} specifies respectively the width of the
+vertical and horizontal lines to draw; they default to (1 . 1).
+A negative horizontal or vertical width @minus{}@var{n} means to draw a line
+of width @var{n} that occupies the space of the underlying text, thus
+avoiding any increase in the character height or width. For simplification
+the width could be specified with only a single number @var{n} instead
+of a list, such case is equivalent to @code{((abs @var{n}) . @var{n})}.
 
 The value @var{color} specifies the color to draw with.  The default is
 the foreground color of the face for simple boxes, and the background
index ed4cf046fcf3379b57b4bc24eb1e86ad2b63dd6c..cc766aa4509c359d1985977992426c3d101dc68f 100644 (file)
             :help-echo "Control box around text."
             (const :tag "Off" nil)
             (list :tag "Box"
-                  :value (:line-width 2 :color "grey75" :style released-button)
-                  (const :format "" :value :line-width)
-                  (integer :tag "Width")
+                   :value (:line-width (2 . 2) :color "grey75" :style released-button)
+                   (const :format "" :value :line-width)
+                   (cons :tag "Width" :extra-offset 2
+                         (integer :tag "Vertical")
+                         (integer :tag "Horizontal"))
                   (const :format "" :value :color)
                   (choice :tag "Color" (const :tag "*" nil) color)
                   (const :format "" :value :style)
        (and real-value
            (let ((lwidth
                   (or (and (consp real-value)
-                           (plist-get real-value :line-width))
+                            (if (listp (cdr real-value))
+                                (plist-get real-value :line-width)
+                              real-value))
                       (and (integerp real-value) real-value)
-                      1))
+                       '(1 . 1)))
                  (color
                   (or (and (consp real-value) (plist-get real-value :color))
                       (and (stringp real-value) real-value)
                       nil))
                  (style
                   (and (consp real-value) (plist-get real-value :style))))
+              (if (integerp lwidth)
+                  (setq lwidth (cons (abs lwidth) lwidth)))
              (list :line-width lwidth :color color :style style))))
      ;; filter to make customized-value suitable for storing
      (lambda (cus-value)
index 08380f1f17fe9acf220d2a4b7d7198d8e53edaa5..555946f84cba4914f127db492e9fdc0479cf665b 100644 (file)
@@ -1693,12 +1693,17 @@ struct face
   int fontset;
 
   /* Non-zero means characters in this face have a box of that
-     thickness around them.  If this value is negative, its absolute
-     value indicates the thickness, and the horizontal (top and
-     bottom) borders of box are drawn inside of the character glyphs'
-     area.  The vertical (left and right) borders of the box are drawn
-     in the same way as when this value is positive.  */
-  int box_line_width;
+     thickness around them. Vertical (left and right) and horizontal
+     (top and bottom) borders size can be set separatedly using an
+     associated list of two ints in the form
+     (vertical_size . horizontal_size). In case one of the value is
+     negative, its absolute value indicates the thickness, and the
+     borders of box are drawn inside of the character glyphs' area
+     potentially over the glyph itself but the glyph drawing size is
+     not increase. If a (signed) int N is use instead of a list, it
+     is the same as setting ( abs(N) . N ) values. */
+  int box_vertical_line_width;
+  int box_horizontal_line_width;
 
   /* Type of box drawn.  A value of FACE_NO_BOX means no box is drawn
      around text in this face.  A value of FACE_SIMPLE_BOX means a box
index 9bec36917862e03573313887d6b49c25ddcbf216..e41a698a2ff0876efba9a4d36afcca2abc3bb36c 100644 (file)
@@ -1043,7 +1043,7 @@ nsfont_draw (struct glyph_string *s, int from, int to, int x, int y,
 
   r.origin.x = s->x;
   if (s->face->box != FACE_NO_BOX && s->first_glyph->left_box_line_p)
-    r.origin.x += abs (s->face->box_line_width);
+    r.origin.x += max (s->face->box_vertical_line_width, 0);
 
   r.origin.y = s->y;
   r.size.height = FONT_HEIGHT (font);
@@ -1105,7 +1105,7 @@ nsfont_draw (struct glyph_string *s, int from, int to, int x, int y,
     {
       NSRect br = r;
       int fibw = FRAME_INTERNAL_BORDER_WIDTH (s->f);
-      int mbox_line_width = max (s->face->box_line_width, 0);
+      int mbox_line_width = max (s->face->box_vertical_line_width, 0);
 
       if (s->row->full_width_p)
         {
@@ -1129,9 +1129,10 @@ nsfont_draw (struct glyph_string *s, int from, int to, int x, int y,
         }
       else
         {
-          int correction = abs (s->face->box_line_width)+1;
+          int correction = abs (s->face->box_horizontal_line_width)+1;
           br.origin.y += correction;
           br.size.height -= 2*correction;
+          correction = abs (s->face->box_vertical_line_width)+1;
           br.origin.x += correction;
           br.size.width -= 2*correction;
         }
index 04fc0512234b796bb5fdd0809d1cf8cd48880196..3ce223307badd69cf313ec53b4f41b5cbb6303fa 100644 (file)
@@ -3639,8 +3639,8 @@ ns_draw_text_decoration (struct glyph_string *s, struct face *face,
 }
 
 static void
-ns_draw_box (NSRect r, CGFloat thickness, NSColor *col,
-             char left_p, char right_p)
+ns_draw_box (NSRect r, CGFloat hthickness, CGFloat vthickness,
+             NSColor *col, char left_p, char right_p)
 /* --------------------------------------------------------------------------
     Draw an unfilled rect inside r, optionally leaving left and/or right open.
     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,
   [col set];
 
   /* top, bottom */
-  s.size.height = thickness;
+  s.size.height = hthickness;
   NSRectFill (s);
-  s.origin.y += r.size.height - thickness;
+  s.origin.y += r.size.height - hthickness;
   NSRectFill (s);
 
   s.size.height = r.size.height;
   s.origin.y = r.origin.y;
 
   /* left, right (optional) */
-  s.size.width = thickness;
+  s.size.width = vthickness;
   if (left_p)
     NSRectFill (s);
   if (right_p)
     {
-      s.origin.x += r.size.width - thickness;
+      s.origin.x += r.size.width - vthickness;
       NSRectFill (s);
     }
 }
 
 
 static void
-ns_draw_relief (NSRect r, int thickness, char raised_p,
+ns_draw_relief (NSRect r, int hthickness, int vthickness, char raised_p,
                char top_p, char bottom_p, char left_p, char right_p,
                struct glyph_string *s)
 /* --------------------------------------------------------------------------
@@ -3722,27 +3722,27 @@ ns_draw_relief (NSRect r, int thickness, char raised_p,
   /* TODO: mitering. Using NSBezierPath doesn't work because of color switch.  */
 
   /* top */
-  sr.size.height = thickness;
+  sr.size.height = hthickness;
   if (top_p) NSRectFill (sr);
 
   /* left */
   sr.size.height = r.size.height;
-  sr.size.width = thickness;
+  sr.size.width = vthickness;
   if (left_p) NSRectFill (sr);
 
   [(raised_p ? darkCol : lightCol) set];
 
   /* bottom */
   sr.size.width = r.size.width;
-  sr.size.height = thickness;
-  sr.origin.y += r.size.height - thickness;
+  sr.size.height = hthickness;
+  sr.origin.y += r.size.height - hthickness;
   if (bottom_p) NSRectFill (sr);
 
   /* right */
   sr.size.height = r.size.height;
   sr.origin.y = r.origin.y;
-  sr.size.width = thickness;
-  sr.origin.x += r.size.width - thickness;
+  sr.size.width = vthickness;
+  sr.origin.x += r.size.width - vthickness;
   if (right_p) NSRectFill (sr);
 }
 
@@ -3758,7 +3758,7 @@ ns_dumpglyphs_box_or_relief (struct glyph_string *s)
   char left_p, right_p;
   struct glyph *last_glyph;
   NSRect r;
-  int thickness;
+  int hthickness, vthickness;
   struct face *face;
 
   if (s->hl == DRAW_MOUSE_FACE)
@@ -3771,7 +3771,8 @@ ns_dumpglyphs_box_or_relief (struct glyph_string *s)
   else
     face = s->face;
 
-  thickness = face->box_line_width;
+  vthickness = face->box_vertical_line_width;
+  hthickness = face->box_horizontal_line_width;
 
   NSTRACE ("ns_dumpglyphs_box_or_relief");
 
@@ -3796,14 +3797,15 @@ ns_dumpglyphs_box_or_relief (struct glyph_string *s)
   /* TODO: Sometimes box_color is 0 and this seems wrong; should investigate.  */
   if (s->face->box == FACE_SIMPLE_BOX && s->face->box_color)
     {
-      ns_draw_box (r, abs (thickness),
+      ns_draw_box (r, abs (hthickness), abs (vthickness),
                    ns_lookup_indexed_color (face->box_color, s->f),
-                  left_p, right_p);
+                   left_p, right_p);
     }
   else
     {
-      ns_draw_relief (r, abs (thickness), s->face->box == FACE_RAISED_BOX,
-                     1, 1, left_p, right_p, s);
+      ns_draw_relief (r, abs (hthickness), abs (vthickness),
+                      s->face->box == FACE_RAISED_BOX,
+                      1, 1, left_p, right_p, s);
     }
 }
 
@@ -3819,7 +3821,7 @@ ns_maybe_dumpglyphs_background (struct glyph_string *s, char force_p)
 
   if (!s->background_filled_p/* || s->hl == DRAW_MOUSE_FACE*/)
     {
-      int box_line_width = max (s->face->box_line_width, 0);
+      int box_line_width = max (s->face->box_horizontal_line_width, 0);
       if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width
          /* When xdisp.c ignores FONT_HEIGHT, we cannot trust font
             dimensions, since the actual glyphs might be much
@@ -3870,7 +3872,7 @@ ns_dumpglyphs_image (struct glyph_string *s, NSRect r)
    -------------------------------------------------------------------------- */
 {
   EmacsImage *img = s->img->pixmap;
-  int box_line_vwidth = max (s->face->box_line_width, 0);
+  int box_line_vwidth = max (s->face->box_horizontal_line_width, 0);
   int x = s->x, y = s->ybase - image_ascent (s->img, s->face, &s->slice);
   int bg_x, bg_y, bg_height;
   int th;
@@ -3883,7 +3885,7 @@ ns_dumpglyphs_image (struct glyph_string *s, NSRect r)
 
   if (s->face->box != FACE_NO_BOX
       && s->first_glyph->left_box_line_p && s->slice.x == 0)
-    x += abs (s->face->box_line_width);
+    x += max (s->face->box_vertical_line_width, 0);
 
   bg_x = x;
   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)
       r.origin.y = y - th;
       r.size.width = s->slice.width + 2*th-1;
       r.size.height = s->slice.height + 2*th-1;
-      ns_draw_relief (r, th, raised_p,
+      ns_draw_relief (r, th, th, raised_p,
                       s->slice.y == 0,
                       s->slice.y + s->slice.height == s->img->height,
                       s->slice.x == 0,
@@ -4017,7 +4019,7 @@ ns_dumpglyphs_image (struct glyph_string *s, NSRect r)
     {
       int thickness = abs (s->img->relief);
       if (thickness == 0) thickness = 1;
-      ns_draw_box (br, thickness, FRAME_CURSOR_COLOR (s->f), 1, 1);
+      ns_draw_box (br, thickness, thickness, FRAME_CURSOR_COLOR (s->f), 1, 1);
     }
 }
 
@@ -4100,7 +4102,7 @@ ns_draw_glyph_string_foreground (struct glyph_string *s)
      of S to the right of that box line.  */
   if (s->face && s->face->box != FACE_NO_BOX
       && s->first_glyph->left_box_line_p)
-    x = s->x + eabs (s->face->box_line_width);
+    x = s->x + max (s->face->box_vertical_line_width, 0);
   else
     x = s->x;
 
@@ -4126,7 +4128,7 @@ ns_draw_composite_glyph_string_foreground (struct glyph_string *s)
      of S to the right of that box line.  */
   if (s->face && s->face->box != FACE_NO_BOX
       && s->first_glyph->left_box_line_p)
-    x = s->x + eabs (s->face->box_line_width);
+    x = s->x + max (s->face->box_vertical_line_width, 0);
   else
     x = s->x;
 
@@ -4142,7 +4144,7 @@ ns_draw_composite_glyph_string_foreground (struct glyph_string *s)
       if (s->cmp_from == 0)
         {
           NSRect r = NSMakeRect (s->x, s->y, s->width-1, s->height -1);
-          ns_draw_box (r, 1, FRAME_CURSOR_COLOR (s->f), 1, 1);
+          ns_draw_box (r, 1, 1, FRAME_CURSOR_COLOR (s->f), 1, 1);
         }
     }
   else if (! s->first_glyph->u.cmp.automatic)
index 76cf6bd6964a842f2d76cb70a41232428690243d..5fa77d58e10bc95bca6e2a40e9cb68204185b5d5 100644 (file)
@@ -888,10 +888,10 @@ static void w32_draw_image_foreground_1 (struct glyph_string *, HBITMAP);
 static void w32_clear_glyph_string_rect (struct glyph_string *, int,
                                          int, int, int);
 static void w32_draw_relief_rect (struct frame *, int, int, int, int,
-                                  int, int, int, int, int, int,
+                                  int, int, int, int, int, int, int,
                                   RECT *);
 static void w32_draw_box_rect (struct glyph_string *, int, int, int, int,
-                               int, bool, bool, RECT *);
+                               int, int, bool, bool, RECT *);
 
 
 /* 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)
      shouldn't be drawn in the first place.  */
   if (!s->background_filled_p)
     {
-      int box_line_width = max (s->face->box_line_width, 0);
+      int box_line_width = max (s->face->box_horizontal_line_width, 0);
 
 #if 0 /* TODO: stipple */
       if (s->stippled_p)
@@ -1206,7 +1206,7 @@ w32_draw_glyph_string_foreground (struct glyph_string *s)
      of S to the right of that box line.  */
   if (s->face->box != FACE_NO_BOX
       && s->first_glyph->left_box_line_p)
-    x = s->x + eabs (s->face->box_line_width);
+    x = s->x + max (s->face->box_vertical_line_width, 0);
   else
     x = s->x;
 
@@ -1264,7 +1264,7 @@ w32_draw_composite_glyph_string_foreground (struct glyph_string *s)
      of S to the right of that box line.  */
   if (s->face && s->face->box != FACE_NO_BOX
       && s->first_glyph->left_box_line_p)
-    x = s->x + eabs (s->face->box_line_width);
+    x = s->x + max (s->face->box_vertical_line_width, 0);
   else
     x = s->x;
 
@@ -1361,7 +1361,7 @@ w32_draw_glyphless_glyph_string_foreground (struct glyph_string *s)
      of S to the right of that box line.  */
   if (s->face->box != FACE_NO_BOX
       && s->first_glyph->left_box_line_p)
-    x = s->x + eabs (s->face->box_line_width);
+    x = s->x + max (s->face->box_vertical_line_width, 0);
   else
     x = s->x;
 
@@ -1617,7 +1617,7 @@ w32_setup_relief_colors (struct glyph_string *s)
 static void
 w32_draw_relief_rect (struct frame *f,
                      int left_x, int top_y, int right_x, int bottom_y,
-                     int width, int raised_p,
+                     int hwidth, int vwidth, int raised_p,
                      int top_p, int bot_p, int left_p, int right_p,
                      RECT *clip_rect)
 {
@@ -1634,14 +1634,14 @@ w32_draw_relief_rect (struct frame *f,
 
   /* Top.  */
   if (top_p)
-    for (i = 0; i < width; ++i)
+    for (i = 0; i < hwidth; ++i)
       w32_fill_area (f, hdc, gc.foreground,
                     left_x + i * left_p, top_y + i,
                     right_x - left_x - i * (left_p + right_p ) + 1, 1);
 
   /* Left.  */
   if (left_p)
-    for (i = 0; i < width; ++i)
+    for (i = 0; i < vwidth; ++i)
       w32_fill_area (f, hdc, gc.foreground,
                     left_x + i, top_y + (i + 1) * top_p, 1,
                     bottom_y - top_y - (i + 1) * (bot_p + top_p) + 1);
@@ -1653,14 +1653,14 @@ w32_draw_relief_rect (struct frame *f,
 
   /* Bottom.  */
   if (bot_p)
-    for (i = 0; i < width; ++i)
+    for (i = 0; i < hwidth; ++i)
       w32_fill_area (f, hdc, gc.foreground,
                     left_x + i * left_p, bottom_y - i,
                     right_x - left_x - i * (left_p + right_p) + 1, 1);
 
   /* Right.  */
   if (right_p)
-    for (i = 0; i < width; ++i)
+    for (i = 0; i < vwidth; ++i)
       w32_fill_area (f, hdc, gc.foreground,
                     right_x - i, top_y + (i + 1) * top_p, 1,
                     bottom_y - top_y - (i + 1) * (bot_p + top_p) + 1);
@@ -1680,31 +1680,31 @@ w32_draw_relief_rect (struct frame *f,
 
 static void
 w32_draw_box_rect (struct glyph_string *s,
-                  int left_x, int top_y, int right_x, int bottom_y, int width,
-                   bool left_p, bool right_p, RECT *clip_rect)
+                  int left_x, int top_y, int right_x, int bottom_y, int hwidth,
+                  int vwidth, bool left_p, bool right_p, RECT *clip_rect)
 {
   w32_set_clip_rectangle (s->hdc, clip_rect);
 
   /* Top.  */
   w32_fill_area (s->f, s->hdc, s->face->box_color,
-                 left_x, top_y, right_x - left_x + 1, width);
+                 left_x, top_y, right_x - left_x + 1, hwidth);
 
   /* Left.  */
   if (left_p)
     {
       w32_fill_area (s->f, s->hdc, s->face->box_color,
-                     left_x, top_y, width, bottom_y - top_y + 1);
+                     left_x, top_y, vwidth, bottom_y - top_y + 1);
     }
 
   /* Bottom.  */
   w32_fill_area (s->f, s->hdc, s->face->box_color,
-                 left_x, bottom_y - width + 1, right_x - left_x + 1, width);
+                 left_x, bottom_y - hwidth + 1, right_x - left_x + 1, hwidth);
 
   /* Right.  */
   if (right_p)
     {
       w32_fill_area (s->f, s->hdc, s->face->box_color,
-                     right_x - width + 1, top_y, width, bottom_y - top_y + 1);
+                     right_x - vwidth + 1, top_y, vwidth, bottom_y - top_y + 1);
     }
 
   w32_set_clip_rectangle (s->hdc, NULL);
@@ -1716,7 +1716,7 @@ w32_draw_box_rect (struct glyph_string *s,
 static void
 w32_draw_glyph_string_box (struct glyph_string *s)
 {
-  int width, left_x, right_x, top_y, bottom_y, last_x;
+  int hwidth, vwidth, left_x, right_x, top_y, bottom_y, last_x;
   bool left_p, right_p, raised_p;
   struct glyph *last_glyph;
   RECT clip_rect;
@@ -1730,7 +1730,8 @@ w32_draw_glyph_string_box (struct glyph_string *s)
                ? s->first_glyph
                : s->first_glyph + s->nchars - 1);
 
-  width = eabs (s->face->box_line_width);
+  vwidth = eabs (s->face->box_vertical_line_width);
+  hwidth = eabs (s->face->box_horizontal_line_width);
   raised_p = s->face->box == FACE_RAISED_BOX;
   left_x = s->x;
   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)
   get_glyph_string_clip_rect (s, &clip_rect);
 
   if (s->face->box == FACE_SIMPLE_BOX)
-    w32_draw_box_rect (s, left_x, top_y, right_x, bottom_y, width,
-                       left_p, right_p, &clip_rect);
+    w32_draw_box_rect (s, left_x, top_y, right_x, bottom_y, hwidth,
+                       vwidth, left_p, right_p, &clip_rect);
   else
     {
       w32_setup_relief_colors (s);
-      w32_draw_relief_rect (s->f, left_x, top_y, right_x, bottom_y,
-                            width, raised_p, 1, 1, left_p, right_p, &clip_rect);
+      w32_draw_relief_rect (s->f, left_x, top_y, right_x, bottom_y, hwidth,
+                            vwidth, raised_p, 1, 1, left_p, right_p, &clip_rect);
     }
 }
 
@@ -1795,7 +1796,7 @@ w32_draw_image_foreground (struct glyph_string *s)
   if (s->face->box != FACE_NO_BOX
       && s->first_glyph->left_box_line_p
       && s->slice.x == 0)
-    x += eabs (s->face->box_line_width);
+    x += max (s->face->box_vertical_line_width, 0);
 
   /* If there is a margin around the image, adjust x- and y-position
      by that margin.  */
@@ -1982,7 +1983,7 @@ w32_draw_image_relief (struct glyph_string *s)
   if (s->face->box != FACE_NO_BOX
       && s->first_glyph->left_box_line_p
       && s->slice.x == 0)
-    x += eabs (s->face->box_line_width);
+    x += max (s->face->box_vertical_line_width, 0);
 
   /* If there is a margin around the image, adjust x- and y-position
      by that margin.  */
@@ -2034,7 +2035,7 @@ w32_draw_image_relief (struct glyph_string *s)
 
   w32_setup_relief_colors (s);
   get_glyph_string_clip_rect (s, &r);
-  w32_draw_relief_rect (s->f, x, y, x1, y1, thick, raised_p,
+  w32_draw_relief_rect (s->f, x, y, x1, y1, thick, thick, raised_p,
                        top_p, bot_p, left_p, right_p, &r);
 }
 
@@ -2054,7 +2055,7 @@ w32_draw_image_foreground_1 (struct glyph_string *s, HBITMAP pixmap)
   if (s->face->box != FACE_NO_BOX
       && s->first_glyph->left_box_line_p
       && s->slice.x == 0)
-    x += eabs (s->face->box_line_width);
+    x += max (s->face->box_vertical_line_width, 0);
 
   /* If there is a margin around the image, adjust x- and y-position
      by that margin.  */
@@ -2167,8 +2168,8 @@ static void
 w32_draw_image_glyph_string (struct glyph_string *s)
 {
   int x, y;
-  int box_line_hwidth = eabs (s->face->box_line_width);
-  int box_line_vwidth = max (s->face->box_line_width, 0);
+  int box_line_hwidth = max (s->face->box_vertical_line_width, 0);
+  int box_line_vwidth = max (s->face->box_horizontal_line_width, 0);
   int height, width;
   HBITMAP pixmap = 0;
 
index 61c798c59e80f4f1eb68f759d4162df91e5e83f3..cbdef7ad11821f54efc247f33d07a04f670c26e4 100644 (file)
@@ -2061,8 +2061,8 @@ estimate_mode_line_height (struct frame *f, enum face_id face_id)
            {
              if (face->font)
                height = normal_char_height (face->font, -1);
-             if (face->box_line_width > 0)
-               height += 2 * face->box_line_width;
+             if (face->box_horizontal_line_width > 0)
+               height += 2 * face->box_horizontal_line_width;
            }
        }
 
@@ -28900,18 +28900,21 @@ produce_image_glyph (struct it *it)
 
   if (face->box != FACE_NO_BOX)
     {
-      if (face->box_line_width > 0)
+      if (face->box_horizontal_line_width > 0)
        {
          if (slice.y == 0)
-           it->ascent += face->box_line_width;
+           it->ascent += face->box_horizontal_line_width;
          if (slice.y + slice.height == img->height)
-           it->descent += face->box_line_width;
+           it->descent += face->box_horizontal_line_width;
        }
 
-      if (it->start_of_box_run_p && slice.x == 0)
-       it->pixel_width += eabs (face->box_line_width);
-      if (it->end_of_box_run_p && slice.x + slice.width == img->width)
-       it->pixel_width += eabs (face->box_line_width);
+      if (face->box_vertical_line_width > 0)
+       {
+         if (it->start_of_box_run_p && slice.x == 0)
+           it->pixel_width += face->box_vertical_line_width;
+         if (it->end_of_box_run_p && slice.x + slice.width == img->width)
+           it->pixel_width += face->box_vertical_line_width;
+       }
     }
 
   take_vertical_position_into_account (it);
@@ -29009,15 +29012,18 @@ produce_xwidget_glyph (struct it *it)
 
   if (face->box != FACE_NO_BOX)
     {
-      if (face->box_line_width > 0)
+      if (face->box_horizontal_line_width > 0)
        {
-         it->ascent += face->box_line_width;
-         it->descent += face->box_line_width;
+         it->ascent += face->box_horizontal_line_width;
+         it->descent += face->box_horizontal_line_width;
        }
 
-      if (it->start_of_box_run_p)
-       it->pixel_width += eabs (face->box_line_width);
-      it->pixel_width += eabs (face->box_line_width);
+      if (face->box_vertical_line_width > 0)
+       {
+         if (it->start_of_box_run_p)
+           it->pixel_width += face->box_vertical_line_width;
+         it->pixel_width += face->box_vertical_line_width;
+       }
     }
 
   take_vertical_position_into_account (it);
@@ -29780,6 +29786,31 @@ produce_glyphless_glyph (struct it *it, bool for_no_font, Lisp_Object acronym)
 }
 
 
+/* If face has a box, add the box thickness to the character
+   height.  If character has a box line to the left and/or
+   right, add the box line width to the character's width.  */
+#define IT_APPLY_FACE_BOX(it, face)                            \
+  do {                                                         \
+    if (face->box != FACE_NO_BOX)                              \
+      {                                                                \
+       int thick = face->box_horizontal_line_width;            \
+       if (thick > 0)                                          \
+         {                                                     \
+           it->ascent += thick;                                \
+           it->descent += thick;                               \
+         }                                                     \
+                                                               \
+       thick = face->box_vertical_line_width;                  \
+       if (thick > 0)                                          \
+         {                                                     \
+           if (it->start_of_box_run_p)                         \
+             it->pixel_width += thick;                         \
+           if (it->end_of_box_run_p)                           \
+             it->pixel_width += thick;                         \
+         }                                                     \
+      }                                                                \
+    } while (false)
+
 /* RIF:
    Produce glyphs/get display metrics for the display element IT is
    loaded with.  See the description of struct it in dispextern.h
@@ -29895,26 +29926,7 @@ gui_produce_glyphs (struct it *it)
          if (stretched_p)
            it->pixel_width *= XFLOATINT (it->space_width);
 
-         /* If face has a box, add the box thickness to the character
-            height.  If character has a box line to the left and/or
-            right, add the box line width to the character's width.  */
-         if (face->box != FACE_NO_BOX)
-           {
-             int thick = face->box_line_width;
-
-             if (thick > 0)
-               {
-                 it->ascent += thick;
-                 it->descent += thick;
-               }
-             else
-               thick = -thick;
-
-             if (it->start_of_box_run_p)
-               it->pixel_width += thick;
-             if (it->end_of_box_run_p)
-               it->pixel_width += thick;
-           }
+         IT_APPLY_FACE_BOX(it, face);
 
          /* If face has an overline, add the height of the overline
             (1 pixel) and a 1 pixel margin to the character height.  */
@@ -30029,10 +30041,10 @@ gui_produce_glyphs (struct it *it)
 
              if ((it->max_ascent > 0 || it->max_descent > 0)
                  && face->box != FACE_NO_BOX
-                 && face->box_line_width > 0)
+                 && face->box_horizontal_line_width > 0)
                {
-                 it->ascent += face->box_line_width;
-                 it->descent += face->box_line_width;
+                 it->ascent += face->box_horizontal_line_width;
+                 it->descent += face->box_horizontal_line_width;
                }
              if (!NILP (height)
                  && XFIXNUM (height) > it->ascent + it->descent)
@@ -30439,23 +30451,7 @@ gui_produce_glyphs (struct it *it)
       it->pixel_width = cmp->pixel_width;
       it->ascent = it->phys_ascent = cmp->ascent;
       it->descent = it->phys_descent = cmp->descent;
-      if (face->box != FACE_NO_BOX)
-       {
-         int thick = face->box_line_width;
-
-         if (thick > 0)
-           {
-             it->ascent += thick;
-             it->descent += thick;
-           }
-         else
-           thick = - thick;
-
-         if (it->start_of_box_run_p)
-           it->pixel_width += thick;
-         if (it->end_of_box_run_p)
-           it->pixel_width += thick;
-       }
+      IT_APPLY_FACE_BOX(it, face);
 
       /* If face has an overline, add the height of the overline
         (1 pixel) and a 1 pixel margin to the character height.  */
@@ -30489,23 +30485,8 @@ gui_produce_glyphs (struct it *it)
        it->glyph_row->contains_overlapping_glyphs_p = true;
       it->ascent = it->phys_ascent = metrics.ascent;
       it->descent = it->phys_descent = metrics.descent;
-      if (face->box != FACE_NO_BOX)
-       {
-         int thick = face->box_line_width;
+      IT_APPLY_FACE_BOX(it, face);
 
-         if (thick > 0)
-           {
-             it->ascent += thick;
-             it->descent += thick;
-           }
-         else
-           thick = - thick;
-
-         if (it->start_of_box_run_p)
-           it->pixel_width += thick;
-         if (it->end_of_box_run_p)
-           it->pixel_width += thick;
-       }
       /* If face has an overline, add the height of the overline
         (1 pixel) and a 1 pixel margin to the character height.  */
       if (face->overline_p)
index 711ec48bbdd60d4673f8f1434a9c6924c493959c..bab142ade0fdfcc5e0df68a0ee4699af0af3d758 100644 (file)
@@ -3128,6 +3128,8 @@ FRAME 0 means change the face on all frames, and change the default
        valid_p = XFIXNUM (value) != 0;
       else if (STRINGP (value))
        valid_p = SCHARS (value) > 0;
+      else if (CONSP (value) && FIXNUMP (XCAR (value)) && FIXNUMP (XCDR (value)))
+       valid_p = true;
       else if (CONSP (value))
        {
          Lisp_Object tem;
@@ -3146,7 +3148,9 @@ FRAME 0 means change the face on all frames, and change the default
 
              if (EQ (k, QCline_width))
                {
-                 if (!FIXNUMP (v) || XFIXNUM (v) == 0)
+                 if ((!CONSP(v) || !FIXNUMP (XCAR (v)) || XFIXNUM (XCAR (v)) == 0
+                                || !FIXNUMP (XCDR (v)) || XFIXNUM (XCDR (v)) == 0)
+                     && (!FIXNUMP (v) || XFIXNUM (v) == 0))
                    break;
                }
              else if (EQ (k, QCcolor))
@@ -5815,7 +5819,7 @@ realize_gui_face (struct face_cache *cache, Lisp_Object attrs[LFACE_VECTOR_SIZE]
       face->box_color = load_color (f, face, attrs[LFACE_BOX_INDEX],
                                    LFACE_BOX_INDEX);
       face->box = FACE_SIMPLE_BOX;
-      face->box_line_width = 1;
+      face->box_vertical_line_width = face->box_horizontal_line_width = 1;
     }
   else if (FIXNUMP (box))
     {
@@ -5823,9 +5827,19 @@ realize_gui_face (struct face_cache *cache, Lisp_Object attrs[LFACE_VECTOR_SIZE]
         face.  */
       eassert (XFIXNUM (box) != 0);
       face->box = FACE_SIMPLE_BOX;
-      face->box_line_width = XFIXNUM (box);
+      face->box_vertical_line_width = eabs(XFIXNUM (box));
+      face->box_horizontal_line_width = XFIXNUM (box);
+      face->box_color = face->foreground;
+      face->box_color_defaulted_p = true;
+    }
+  else if (CONSP (box) && FIXNUMP (XCAR (box)) && FIXNUMP (XCDR (box)))
+    {
+       /* `(VWIDTH . HWIDTH)'.  */
+      face->box = FACE_SIMPLE_BOX;
       face->box_color = face->foreground;
       face->box_color_defaulted_p = true;
+      face->box_vertical_line_width = XFIXNUM (XCAR (box));
+      face->box_horizontal_line_width = XFIXNUM (XCDR (box));
     }
   else if (CONSP (box))
     {
@@ -5834,7 +5848,7 @@ realize_gui_face (struct face_cache *cache, Lisp_Object attrs[LFACE_VECTOR_SIZE]
       face->box = FACE_SIMPLE_BOX;
       face->box_color = face->foreground;
       face->box_color_defaulted_p = true;
-      face->box_line_width = 1;
+      face->box_vertical_line_width = face->box_horizontal_line_width = 1;
 
       while (CONSP (box))
        {
@@ -5850,8 +5864,14 @@ realize_gui_face (struct face_cache *cache, Lisp_Object attrs[LFACE_VECTOR_SIZE]
 
          if (EQ (keyword, QCline_width))
            {
-             if (FIXNUMP (value) && XFIXNUM (value) != 0)
-               face->box_line_width = XFIXNUM (value);
+             if (CONSP (value) && FIXNUMP (XCAR (value)) && FIXNUMP (XCDR (value))) {
+                 face->box_vertical_line_width = XFIXNUM (XCAR (value));
+                 face->box_horizontal_line_width = XFIXNUM (XCDR (value));
+             }
+             else if (FIXNUMP (value) && XFIXNUM (value) != 0) {
+               face->box_vertical_line_width = eabs (XFIXNUM (value));
+               face->box_horizontal_line_width = XFIXNUM (value);
+             }
            }
          else if (EQ (keyword, QCcolor))
            {
index d7d992c91b29abf92e6f7f54ecc54d384619bf08..fc68c77048fabfee080f5484365da447d2b0e4c7 100644 (file)
@@ -1754,7 +1754,7 @@ x_draw_glyph_string_background (struct glyph_string *s, bool force_p)
      shouldn't be drawn in the first place.  */
   if (!s->background_filled_p)
     {
-      int box_line_width = max (s->face->box_line_width, 0);
+      int box_line_width = max (s->face->box_horizontal_line_width, 0);
 
       if (s->stippled_p)
        {
@@ -1799,7 +1799,7 @@ x_draw_glyph_string_foreground (struct glyph_string *s)
      of S to the right of that box line.  */
   if (s->face->box != FACE_NO_BOX
       && s->first_glyph->left_box_line_p)
-    x = s->x + eabs (s->face->box_line_width);
+    x = s->x + max (s->face->box_vertical_line_width, 0);
   else
     x = s->x;
 
@@ -1849,7 +1849,7 @@ x_draw_glyph_string_foreground (struct glyph_string *s)
          if (!(s->for_overlaps
                || (s->background_filled_p && s->hl != DRAW_CURSOR)))
            {
-             int box_line_width = max (s->face->box_line_width, 0);
+             int box_line_width = max (s->face->box_horizontal_line_width, 0);
 
              if (s->stippled_p)
                {
@@ -1893,7 +1893,7 @@ x_draw_composite_glyph_string_foreground (struct glyph_string *s)
      of S to the right of that box line.  */
   if (s->face && s->face->box != FACE_NO_BOX
       && s->first_glyph->left_box_line_p)
-    x = s->x + eabs (s->face->box_line_width);
+    x = s->x + max (s->face->box_vertical_line_width, 0);
   else
     x = s->x;
 
@@ -2004,7 +2004,7 @@ x_draw_glyphless_glyph_string_foreground (struct glyph_string *s)
      of S to the right of that box line.  */
   if (s->face && s->face->box != FACE_NO_BOX
       && s->first_glyph->left_box_line_p)
-    x = s->x + eabs (s->face->box_line_width);
+    x = s->x + max (s->face->box_vertical_line_width, 0);
   else
     x = s->x;
 
@@ -2769,7 +2769,7 @@ x_setup_relief_colors (struct glyph_string *s)
 static void
 x_draw_relief_rect (struct frame *f,
                    int left_x, int top_y, int right_x, int bottom_y,
-                   int width, bool raised_p, bool top_p, bool bot_p,
+                   int hwidth, int vwidth, bool raised_p, bool top_p, bool bot_p,
                    bool left_p, bool right_p,
                    XRectangle *clip_rect)
 {
@@ -2794,7 +2794,7 @@ x_draw_relief_rect (struct frame *f,
   if (left_p)
     {
       x_fill_rectangle (f, top_left_gc, left_x, top_y,
-                       width, bottom_y + 1 - top_y);
+                       vwidth, bottom_y + 1 - top_y);
       if (top_p)
        corners |= 1 << CORNER_TOP_LEFT;
       if (bot_p)
@@ -2802,8 +2802,8 @@ x_draw_relief_rect (struct frame *f,
     }
   if (right_p)
     {
-      x_fill_rectangle (f, bottom_right_gc, right_x + 1 - width, top_y,
-                       width, bottom_y + 1 - top_y);
+      x_fill_rectangle (f, bottom_right_gc, right_x + 1 - vwidth, top_y,
+                       vwidth, bottom_y + 1 - top_y);
       if (top_p)
        corners |= 1 << CORNER_TOP_RIGHT;
       if (bot_p)
@@ -2813,25 +2813,25 @@ x_draw_relief_rect (struct frame *f,
     {
       if (!right_p)
        x_fill_rectangle (f, top_left_gc, left_x, top_y,
-                         right_x + 1 - left_x, width);
+                         right_x + 1 - left_x, hwidth);
       else
        x_fill_trapezoid_for_relief (f, top_left_gc, left_x, top_y,
-                                    right_x + 1 - left_x, width, 1);
+                                    right_x + 1 - left_x, hwidth, 1);
     }
   if (bot_p)
     {
       if (!left_p)
-       x_fill_rectangle (f, bottom_right_gc, left_x, bottom_y + 1 - width,
-                         right_x + 1 - left_x, width);
+       x_fill_rectangle (f, bottom_right_gc, left_x, bottom_y + 1 - hwidth,
+                         right_x + 1 - left_x, hwidth);
       else
        x_fill_trapezoid_for_relief (f, bottom_right_gc,
-                                    left_x, bottom_y + 1 - width,
-                                    right_x + 1 - left_x, width, 0);
+                                    left_x, bottom_y + 1 - hwidth,
+                                    right_x + 1 - left_x, hwidth, 0);
     }
-  if (left_p && width != 1)
+  if (left_p && vwidth > 1)
     x_fill_rectangle (f, bottom_right_gc, left_x, top_y,
                      1, bottom_y + 1 - top_y);
-  if (top_p && width != 1)
+  if (top_p && hwidth > 1)
     x_fill_rectangle (f, bottom_right_gc, left_x, top_y,
                      right_x + 1 - left_x, 1);
   if (corners)
@@ -2865,12 +2865,12 @@ x_draw_relief_rect (struct frame *f,
   /* Top.  */
   if (top_p)
     {
-      if (width == 1)
+      if (hwidth == 1)
         XDrawLine (dpy, drawable, gc,
                   left_x + left_p, top_y,
                   right_x + !right_p, top_y);
 
-      for (i = 1; i < width; ++i)
+      for (i = 1; i < hwidth; ++i)
         XDrawLine (dpy, drawable, gc,
                   left_x  + i * left_p, top_y + i,
                   right_x + 1 - i * right_p, top_y + i);
@@ -2879,13 +2879,10 @@ x_draw_relief_rect (struct frame *f,
   /* Left.  */
   if (left_p)
     {
-      if (width == 1)
+      if (vwidth == 1)
         XDrawLine (dpy, drawable, gc, left_x, top_y + 1, left_x, bottom_y);
 
-      x_clear_area(f, left_x, top_y, 1, 1);
-      x_clear_area(f, left_x, bottom_y, 1, 1);
-
-      for (i = (width > 1 ? 1 : 0); i < width; ++i)
+      for (i = 1; i < vwidth; ++i)
         XDrawLine (dpy, drawable, gc,
                   left_x + i, top_y + (i + 1) * top_p,
                   left_x + i, bottom_y + 1 - (i + 1) * bot_p);
@@ -2898,26 +2895,25 @@ x_draw_relief_rect (struct frame *f,
     gc = f->output_data.x->white_relief.gc;
   XSetClipRectangles (dpy, gc, 0, 0, clip_rect, 1, Unsorted);
 
-  if (width > 1)
-    {
-      /* Outermost top line.  */
-      if (top_p)
-        XDrawLine (dpy, drawable, gc,
-                  left_x  + left_p, top_y,
-                  right_x + !right_p, top_y);
+  /* Outermost top line.  */
+  if (top_p && hwidth > 1)
+    XDrawLine (dpy, drawable, gc,
+              left_x  + left_p, top_y,
+              right_x + !right_p, top_y);
 
-      /* Outermost left line.  */
-      if (left_p)
-        XDrawLine (dpy, drawable, gc, left_x, top_y + 1, left_x, bottom_y);
-    }
+  /* Outermost left line.  */
+  if (left_p && vwidth > 1)
+    XDrawLine (dpy, drawable, gc, left_x, top_y + 1, left_x, bottom_y);
 
   /* Bottom.  */
   if (bot_p)
     {
-      XDrawLine (dpy, drawable, gc,
-                left_x + left_p, bottom_y,
-                right_x + !right_p, bottom_y);
-      for (i = 1; i < width; ++i)
+      if (hwidth >= 1)
+        XDrawLine (dpy, drawable, gc,
+                  left_x + left_p, bottom_y,
+                  right_x + !right_p, bottom_y);
+
+      for (i = 1; i < hwidth; ++i)
         XDrawLine (dpy, drawable, gc,
                   left_x  + i * left_p, bottom_y - i,
                   right_x + 1 - i * right_p, bottom_y - i);
@@ -2926,9 +2922,7 @@ x_draw_relief_rect (struct frame *f,
   /* Right.  */
   if (right_p)
     {
-      x_clear_area(f, right_x, top_y, 1, 1);
-      x_clear_area(f, right_x, bottom_y, 1, 1);
-      for (i = 0; i < width; ++i)
+      for (i = 0; i < vwidth; ++i)
         XDrawLine (dpy, drawable, gc,
                   right_x - i, top_y + (i + 1) * top_p,
                   right_x - i, bottom_y + 1 - (i + 1) * bot_p);
@@ -2949,8 +2943,8 @@ x_draw_relief_rect (struct frame *f,
 
 static void
 x_draw_box_rect (struct glyph_string *s,
-                int left_x, int top_y, int right_x, int bottom_y, int width,
-                bool left_p, bool right_p, XRectangle *clip_rect)
+                int left_x, int top_y, int right_x, int bottom_y, int hwidth,
+                int vwidth, bool left_p, bool right_p, XRectangle *clip_rect)
 {
   Display *display = FRAME_X_DISPLAY (s->f);
   XGCValues xgcv;
@@ -2961,21 +2955,21 @@ x_draw_box_rect (struct glyph_string *s,
 
   /* Top.  */
   x_fill_rectangle (s->f, s->gc,
-                 left_x, top_y, right_x - left_x + 1, width);
+                 left_x, top_y, right_x - left_x + 1, hwidth);
 
   /* Left.  */
   if (left_p)
     x_fill_rectangle (s->f, s->gc,
-                   left_x, top_y, width, bottom_y - top_y + 1);
+                   left_x, top_y, vwidth, bottom_y - top_y + 1);
 
   /* Bottom.  */
   x_fill_rectangle (s->f, s->gc,
-                 left_x, bottom_y - width + 1, right_x - left_x + 1, width);
+                 left_x, bottom_y - hwidth + 1, right_x - left_x + 1, hwidth);
 
   /* Right.  */
   if (right_p)
     x_fill_rectangle (s->f, s->gc,
-                   right_x - width + 1, top_y, width, bottom_y - top_y + 1);
+                   right_x - vwidth + 1, top_y, vwidth, bottom_y - top_y + 1);
 
   XSetForeground (display, s->gc, xgcv.foreground);
   x_reset_clip_rectangles (s->f, s->gc);
@@ -2987,7 +2981,7 @@ x_draw_box_rect (struct glyph_string *s,
 static void
 x_draw_glyph_string_box (struct glyph_string *s)
 {
-  int width, left_x, right_x, top_y, bottom_y, last_x;
+  int hwidth, vwidth, left_x, right_x, top_y, bottom_y, last_x;
   bool raised_p, left_p, right_p;
   struct glyph *last_glyph;
   XRectangle clip_rect;
@@ -3001,7 +2995,8 @@ x_draw_glyph_string_box (struct glyph_string *s)
                ? s->first_glyph
                : s->first_glyph + s->nchars - 1);
 
-  width = eabs (s->face->box_line_width);
+  vwidth = eabs (s->face->box_vertical_line_width);
+  hwidth = eabs (s->face->box_horizontal_line_width);
   raised_p = s->face->box == FACE_RAISED_BOX;
   left_x = s->x;
   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)
   get_glyph_string_clip_rect (s, &clip_rect);
 
   if (s->face->box == FACE_SIMPLE_BOX)
-    x_draw_box_rect (s, left_x, top_y, right_x, bottom_y, width,
-                    left_p, right_p, &clip_rect);
+    x_draw_box_rect (s, left_x, top_y, right_x, bottom_y, hwidth,
+                    vwidth, left_p, right_p, &clip_rect);
   else
     {
       x_setup_relief_colors (s);
-      x_draw_relief_rect (s->f, left_x, top_y, right_x, bottom_y,
-                         width, raised_p, true, true, left_p, right_p,
+      x_draw_relief_rect (s->f, left_x, top_y, right_x, bottom_y, hwidth,
+                         vwidth, raised_p, true, true, left_p, right_p,
                          &clip_rect);
     }
 }
@@ -3086,7 +3081,7 @@ x_draw_image_foreground (struct glyph_string *s)
   if (s->face->box != FACE_NO_BOX
       && s->first_glyph->left_box_line_p
       && s->slice.x == 0)
-    x += eabs (s->face->box_line_width);
+    x += max (s->face->box_vertical_line_width, 0);
 
   /* If there is a margin around the image, adjust x- and y-position
      by that margin.  */
@@ -3205,7 +3200,7 @@ x_draw_image_relief (struct glyph_string *s)
   if (s->face->box != FACE_NO_BOX
       && s->first_glyph->left_box_line_p
       && s->slice.x == 0)
-    x += eabs (s->face->box_line_width);
+    x += max (s->face->box_vertical_line_width, 0);
 
   /* If there is a margin around the image, adjust x- and y-position
      by that margin.  */
@@ -3273,7 +3268,7 @@ x_draw_image_relief (struct glyph_string *s)
 
   x_setup_relief_colors (s);
   get_glyph_string_clip_rect (s, &r);
-  x_draw_relief_rect (s->f, x, y, x1, y1, thick, raised_p,
+  x_draw_relief_rect (s->f, x, y, x1, y1, thick, thick, raised_p,
                      top_p, bot_p, left_p, right_p, &r);
 }
 
@@ -3292,7 +3287,7 @@ x_draw_image_foreground_1 (struct glyph_string *s, Pixmap pixmap)
   if (s->face->box != FACE_NO_BOX
       && s->first_glyph->left_box_line_p
       && s->slice.x == 0)
-    x += eabs (s->face->box_line_width);
+    x += max (s->face->box_vertical_line_width, 0);
 
   /* If there is a margin around the image, adjust x- and y-position
      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)
 static void
 x_draw_image_glyph_string (struct glyph_string *s)
 {
-  int box_line_hwidth = eabs (s->face->box_line_width);
-  int box_line_vwidth = max (s->face->box_line_width, 0);
+  int box_line_hwidth = max (s->face->box_vertical_line_width, 0);
+  int box_line_vwidth = max (s->face->box_horizontal_line_width, 0);
   int height;
 #ifndef USE_CAIRO
   Display *display = FRAME_X_DISPLAY (s->f);