summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPo Lu <luangruo@yahoo.com>1970-01-01 00:00:00 +0000
committerPo Lu <luangruo@yahoo.com>2024-04-28 11:58:22 +0800
commit77a170a175dfeb17dab23e41668b8497b8b3b9d7 (patch)
tree91bfe9fde05be0246fae36ef9daa6a755bcef500 /src
parent4992df159157806bcbad87569f34dc5136c96601 (diff)
downloademacs-77a170a175dfeb17dab23e41668b8497b8b3b9d7.tar.gz
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.
Diffstat (limited to 'src')
-rw-r--r--src/androidterm.c66
-rw-r--r--src/haikuterm.c17
-rw-r--r--src/nsterm.m18
-rw-r--r--src/pgtkterm.c30
-rw-r--r--src/w32term.c38
-rw-r--r--src/xfaces.c22
-rw-r--r--src/xterm.c67
7 files changed, 181 insertions, 77 deletions
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. */