From: Po Lu Date: Thu, 1 Jan 1970 00:00:00 +0000 (+0000) Subject: Port double-line underlines to GUI systems X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=97f2d7dfac56cd571c371876a4a988b981572ffb;p=emacs.git Port double-line underlines to GUI systems * src/xterm.c (x_get_scale_factor): Replace display in first argument with a pointer to dpyinfo. (x_draw_underwave): Adjust to match. (x_draw_glyph_string): Implement double-line underlines. * src/androidterm.c (android_get_scale_factor) (android_draw_glyph_string): * src/haikuterm.c (haiku_draw_text_decoration): * src/nsterm.m (ns_draw_text_decoration): * src/pgtkterm.c (pgtk_draw_glyph_string): * src/w32term.c (w32_draw_glyph_string): Synchronize with X. * src/xfaces.c (realize_gui_face): Enable `double-line' on window systems. (cherry picked from commit 77a170a175dfeb17dab23e41668b8497b8b3b9d7) --- diff --git a/src/androidterm.c b/src/androidterm.c index f5173168785..9f25c507a23 100644 --- a/src/androidterm.c +++ b/src/androidterm.c @@ -3740,19 +3740,15 @@ static void android_get_scale_factor (int *scale_x, int *scale_y) { /* This is 96 everywhere else, but 160 on Android. */ - const int base_res = 160; - struct android_display_info *dpyinfo; + int base_res = 160; - dpyinfo = x_display_list; *scale_x = *scale_y = 1; + eassert (x_display_list); - if (dpyinfo) - { - if (dpyinfo->resx > base_res) - *scale_x = floor (dpyinfo->resx / base_res); - if (dpyinfo->resy > base_res) - *scale_y = floor (dpyinfo->resy / base_res); - } + if (x_display_list->resx > base_res) + *scale_x = floor (x_display_list->resx / base_res); + if (x_display_list->resy > base_res) + *scale_y = floor (x_display_list->resy / base_res); } static void @@ -4171,13 +4167,16 @@ android_draw_glyph_string (struct glyph_string *s) android_set_foreground (s->gc, xgcv.foreground); } } - else if (s->face->underline == FACE_UNDERLINE_SINGLE) + else if (s->face->underline == FACE_UNDERLINE_SINGLE + || s->face->underline == FACE_UNDERLINE_DOUBLE_LINE) { unsigned long thickness, position; int y; if (s->prev - && s->prev->face->underline == FACE_UNDERLINE_SINGLE + && ((s->prev->face->underline == FACE_UNDERLINE_SINGLE) + || (s->prev->face->underline + == FACE_UNDERLINE_DOUBLE_LINE)) && (s->prev->face->underline_at_descent_line_p == s->face->underline_at_descent_line_p) && (s->prev->face->underline_pixels_above_descent_line @@ -4254,19 +4253,38 @@ android_draw_glyph_string (struct glyph_string *s) thickness = (s->y + s->height) - (s->ybase + position); s->underline_thickness = thickness; s->underline_position = position; - y = s->ybase + position; - if (s->face->underline_defaulted_p) - android_fill_rectangle (FRAME_ANDROID_DRAWABLE (s->f), s->gc, - s->x, y, decoration_width, thickness); - else - { - struct android_gc_values xgcv; - android_get_gc_values (s->gc, ANDROID_GC_FOREGROUND, &xgcv); - android_set_foreground (s->gc, s->face->underline_color); - android_fill_rectangle (FRAME_ANDROID_DRAWABLE (s->f), s->gc, + + { + struct android_gc_values xgcv; + + y = s->ybase + position; + if (s->face->underline_defaulted_p) + android_fill_rectangle (FRAME_ANDROID_DRAWABLE (s->f), s->gc, s->x, y, decoration_width, thickness); - android_set_foreground (s->gc, xgcv.foreground); - } + else + { + android_get_gc_values (s->gc, ANDROID_GC_FOREGROUND, &xgcv); + android_set_foreground (s->gc, s->face->underline_color); + android_fill_rectangle (FRAME_ANDROID_DRAWABLE (s->f), s->gc, + s->x, y, decoration_width, thickness); + } + + /* Place a second underline above the first if this was + requested in the face specification. */ + + if (s->face->underline == FACE_UNDERLINE_DOUBLE_LINE) + { + /* Compute the position of the second underline. */ + position = position - thickness - 1; + y = s->ybase + position; + android_fill_rectangle (FRAME_ANDROID_DRAWABLE (s->f), + s->gc, s->x, y, decoration_width, + thickness, false); + } + + if (!s->face->underline_defaulted_p) + android_set_foreground (s->gc, xgcv.foreground); + } } } /* Draw overline. */ diff --git a/src/haikuterm.c b/src/haikuterm.c index c3971bf6fe4..4a03c4cb2d5 100644 --- a/src/haikuterm.c +++ b/src/haikuterm.c @@ -829,13 +829,15 @@ haiku_draw_text_decoration (struct glyph_string *s, struct face *face, if (face->underline == FACE_UNDERLINE_WAVE) haiku_draw_underwave (s, width, x); - else if (face->underline == FACE_UNDERLINE_SINGLE) + else if (face->underline == FACE_UNDERLINE_SINGLE + || face->underline == FACE_UNDERLINE_DOUBLE_LINE)) { unsigned long thickness, position; int y; if (s->prev - && s->prev->face->underline == FACE_UNDERLINE_SINGLE + && (s->prev->face->underline == FACE_UNDERLINE_SINGLE + || s->prev->face->underline == FACE_UNDERLINE_DOUBLE_LINE) && (s->prev->face->underline_at_descent_line_p == s->face->underline_at_descent_line_p) && (s->prev->face->underline_pixels_above_descent_line @@ -911,6 +913,17 @@ haiku_draw_text_decoration (struct glyph_string *s, struct face *face, y = s->ybase + position; BView_FillRectangle (view, s->x, y, s->width, thickness); + + /* Place a second underline above the first if this was + requested in the face specification. */ + + if (s->face->underline == FACE_UNDERLINE_DOUBLE_LINE) + { + /* Compute the position of the second underline. */ + position = position - thickness - 1; + y = s->ybase + position; + BView_FillRectangle (view, s->x, y, s->width, thickness); + } } } diff --git a/src/nsterm.m b/src/nsterm.m index 84d94b5be74..bd4010f2844 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -3337,7 +3337,8 @@ ns_draw_text_decoration (struct glyph_string *s, struct face *face, ns_draw_underwave (s, width, x); } - else if (s->face->underline == FACE_UNDERLINE_SINGLE) + else if (s->face->underline == FACE_UNDERLINE_SINGLE + || s->face->underline == FACE_UNDERLINE_DOUBLE_LINE) { NSRect r; @@ -3345,7 +3346,9 @@ ns_draw_text_decoration (struct glyph_string *s, struct face *face, /* If the prev was underlined, match its appearance. */ if (s->prev - && s->prev->face->underline == FACE_UNDERLINE_SINGLE + && ((s->prev->face->underline == FACE_UNDERLINE_SINGLE) + || (s->prev->face->underline + == FACE_UNDERLINE_DOUBLE_LINE)) && s->prev->underline_thickness > 0 && (s->prev->face->underline_at_descent_line_p == s->face->underline_at_descent_line_p) @@ -3417,6 +3420,17 @@ ns_draw_text_decoration (struct glyph_string *s, struct face *face, [[NSColor colorWithUnsignedLong:face->underline_color] set]; NSRectFill (r); + + /* Place a second underline above the first if this was + requested in the face specification. */ + + if (s->face->underline == FACE_UNDERLINE_DOUBLE_LINE) + { + /* Compute the position of the second underline. */ + position = position - thickness - 1; + r = NSMakeRect (x, s->ybase + position, width, thickness); + NSRectFill (r); + } } } /* Do overline. We follow other terms in using a thickness of 1 diff --git a/src/pgtkterm.c b/src/pgtkterm.c index e08e4b2b230..8441189ab8d 100644 --- a/src/pgtkterm.c +++ b/src/pgtkterm.c @@ -2553,13 +2553,17 @@ pgtk_draw_glyph_string (struct glyph_string *s) else pgtk_draw_underwave (s, s->face->underline_color); } - else if (s->face->underline == FACE_UNDERLINE_SINGLE) + else if (s->face->underline == FACE_UNDERLINE_SINGLE + || s->face->underline == FACE_UNDERLINE_DOUBLE_LINE) { unsigned long thickness, position; int y; + unsigned long foreground; if (s->prev - && s->prev->face->underline == FACE_UNDERLINE_SINGLE + && ((s->prev->face->underline == FACE_UNDERLINE_SINGLE) + || (s->prev->face->underline + == FACE_UNDERLINE_DOUBLE_LINE)) && (s->prev->face->underline_at_descent_line_p == s->face->underline_at_descent_line_p) && (s->prev->face->underline_pixels_above_descent_line @@ -2616,15 +2620,25 @@ pgtk_draw_glyph_string (struct glyph_string *s) s->underline_thickness = thickness; s->underline_position = position; y = s->ybase + position; + if (s->face->underline_defaulted_p) - pgtk_fill_rectangle (s->f, s->xgcv.foreground, - s->x, y, s->width, thickness, - false); + foreground = s->xgcv.foreground; else + foreground = s->face->underline_color; + + pgtk_fill_rectangle (s->f, foreground, s->x, y, s->width, + thickness, false); + + /* Place a second underline above the first if this was + requested in the face specification. */ + + if (s->face->underline == FACE_UNDERLINE_DOUBLE_LINE) { - pgtk_fill_rectangle (s->f, s->face->underline_color, - s->x, y, s->width, thickness, - false); + /* Compute the position of the second underline. */ + position = position - thickness - 1; + y = s->ybase + position; + pgtk_fill_rectangle (s->f, foreground, s->x, y, s->width, + thickness, false); } } } diff --git a/src/w32term.c b/src/w32term.c index 20ea346c8aa..a0037e6e090 100644 --- a/src/w32term.c +++ b/src/w32term.c @@ -2652,13 +2652,16 @@ w32_draw_glyph_string (struct glyph_string *s) w32_draw_underwave (s, color); } - else if (s->face->underline == FACE_UNDERLINE_SINGLE) + else if (s->face->underline == FACE_UNDERLINE_SINGLE + || s->face->underline == FACE_UNDERLINE_DOUBLE_LINE) { unsigned long thickness, position; int y; if (s->prev - && s->prev->face->underline == FACE_UNDERLINE_SINGLE + && ((s->prev->face->underline == FACE_UNDERLINE_SINGLE) + || (s->prev->face->underline + == FACE_UNDERLINE_DOUBLE_LINE)) && (s->prev->face->underline_at_descent_line_p == s->face->underline_at_descent_line_p) && (s->prev->face->underline_pixels_above_descent_line @@ -2676,6 +2679,7 @@ w32_draw_glyph_string (struct glyph_string *s) BOOL use_underline_position_properties; Lisp_Object val = (WINDOW_BUFFER_LOCAL_VALUE (Qunderline_minimum_offset, s->w)); + COLORREF foreground; if (FIXNUMP (val)) minimum_offset = max (0, XFIXNUM (val)); @@ -2734,18 +2738,28 @@ w32_draw_glyph_string (struct glyph_string *s) if (s->y + s->height < s->ybase + position + thickness) thickness = (s->y + s->height) - (s->ybase + position); s->underline_thickness = thickness; - s->underline_position = position; + s->underline_position = position; y = s->ybase + position; + if (s->face->underline_defaulted_p) - { - w32_fill_area (s->f, s->hdc, s->gc->foreground, s->x, - y, s->width, 1); - } - else - { - w32_fill_area (s->f, s->hdc, s->face->underline_color, s->x, - y, s->width, 1); - } + foreground = s->gc->foreground; + else + foreground = s->face->underline_color; + + w32_fill_area (s->f, s->hdc, foreground, s->x, y, + s->width, thickness); + + /* Place a second underline above the first if this was + requested in the face specification. */ + + if (s->face->underline == FACE_UNDERLINE_DOUBLE_LINE) + { + /* Compute the position of the second underline. */ + position = position - thickness - 1; + y = s->ybase + position; + w32_fill_area (s->f, s->hdc, foreground, s->x, y, + s->width, thickness); + } } } /* Draw overline. */ diff --git a/src/xfaces.c b/src/xfaces.c index 07e198974fa..d9ee82c8e7f 100644 --- a/src/xfaces.c +++ b/src/xfaces.c @@ -6398,13 +6398,21 @@ realize_gui_face (struct face_cache *cache, Lisp_Object attrs[LFACE_VECTOR_SIZE] } else if (EQ (keyword, QCstyle)) { - if (EQ (value, Qline)) - face->underline = FACE_UNDERLINE_SINGLE; - else if (EQ (value, Qwave)) - face->underline = FACE_UNDERLINE_WAVE; - else - face->underline = FACE_UNDERLINE_SINGLE; - } + if (EQ (value, Qline)) + face->underline = FACE_UNDERLINE_SINGLE; + else if (EQ (value, Qdouble_line)) + face->underline = FACE_UNDERLINE_DOUBLE_LINE; + else if (EQ (value, Qwave)) + face->underline = FACE_UNDERLINE_WAVE; +#if 0 + else if (EQ (value, Qdots)) + face->underline = FACE_UNDERLINE_DOTS; + else if (EQ (value, Qdashes)) + face->underline = FACE_UNDERLINE_DASHES; +#endif /* 0 */ + else + face->underline = FACE_UNDERLINE_SINGLE; + } else if (EQ (keyword, QCposition)) { face->underline_at_descent_line_p = !NILP (value); diff --git a/src/xterm.c b/src/xterm.c index 360541ac0b9..9b014a7d0e4 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -10735,10 +10735,10 @@ x_draw_stretch_glyph_string (struct glyph_string *s) } static void -x_get_scale_factor (Display *disp, int *scale_x, int *scale_y) +x_get_scale_factor (struct x_display_info *dpyinfo, + int *scale_x, int *scale_y) { - const int base_res = 96; - struct x_display_info * dpyinfo = x_display_info_for_display (disp); + int base_res = 96; *scale_x = *scale_y = 1; @@ -10764,12 +10764,14 @@ x_get_scale_factor (Display *disp, int *scale_x, int *scale_y) static void x_draw_underwave (struct glyph_string *s, int decoration_width) { - Display *display = FRAME_X_DISPLAY (s->f); - + Display *display; + struct x_display_info *dpyinfo; /* Adjust for scale/HiDPI. */ int scale_x, scale_y; - x_get_scale_factor (display, &scale_x, &scale_y); + dpyinfo = FRAME_DISPLAY_INFO (s->f); + display = dpyinfo->display; + x_get_scale_factor (dpyinfo, &scale_x, &scale_y); int wave_height = 3 * scale_y, wave_length = 2 * scale_x; @@ -10971,13 +10973,16 @@ x_draw_glyph_string (struct glyph_string *s) XSetForeground (display, s->gc, xgcv.foreground); } } - else if (s->face->underline == FACE_UNDERLINE_SINGLE) + else if (s->face->underline == FACE_UNDERLINE_SINGLE + || s->face->underline == FACE_UNDERLINE_DOUBLE_LINE) { unsigned long thickness, position; int y; if (s->prev - && s->prev->face->underline == FACE_UNDERLINE_SINGLE + && ((s->prev->face->underline == FACE_UNDERLINE_SINGLE) + || (s->prev->face->underline + == FACE_UNDERLINE_DOUBLE_LINE)) && (s->prev->face->underline_at_descent_line_p == s->face->underline_at_descent_line_p) && (s->prev->face->underline_pixels_above_descent_line @@ -11054,22 +11059,40 @@ x_draw_glyph_string (struct glyph_string *s) thickness = (s->y + s->height) - (s->ybase + position); s->underline_thickness = thickness; s->underline_position = position; - y = s->ybase + position; - if (s->face->underline_defaulted_p) - x_fill_rectangle (s->f, s->gc, - s->x, y, decoration_width, thickness, - false); - else - { - Display *display = FRAME_X_DISPLAY (s->f); - XGCValues xgcv; - XGetGCValues (display, s->gc, GCForeground, &xgcv); - XSetForeground (display, s->gc, s->face->underline_color); - x_fill_rectangle (s->f, s->gc, + + { + Display *display = FRAME_X_DISPLAY (s->f); + XGCValues xgcv; + + y = s->ybase + position; + if (s->face->underline_defaulted_p) + x_fill_rectangle (s->f, s->gc, s->x, y, decoration_width, thickness, false); - XSetForeground (display, s->gc, xgcv.foreground); - } + else + { + XGetGCValues (display, s->gc, GCForeground, &xgcv); + XSetForeground (display, s->gc, s->face->underline_color); + x_fill_rectangle (s->f, s->gc, + s->x, y, decoration_width, thickness, + false); + } + + /* Place a second underline above the first if this was + requested in the face specification. */ + + if (s->face->underline == FACE_UNDERLINE_DOUBLE_LINE) + { + /* Compute the position of the second underline. */ + position = position - thickness - 1; + y = s->ybase + position; + x_fill_rectangle (s->f, s->gc, s->x, y, decoration_width, + thickness, false); + } + + if (!s->face->underline_defaulted_p) + XSetForeground (display, s->gc, xgcv.foreground); + } } } /* Draw overline. */