summaryrefslogtreecommitdiff
path: root/files/config/suckless/st/x.c.rej
blob: fe46ef1022eff2319513c9949cf7fb08bbe4f0bf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
--- x.c
+++ x.c
@@ -1322,12 +1404,15 @@ xinit(int cols, int rows)
 	xsel.xtarget = XInternAtom(xw.dpy, "UTF8_STRING", 0);
 	if (xsel.xtarget == None)
 		xsel.xtarget = XA_STRING;
+
+	// Initialize the graphics (image display) module.
+	gr_init(xw.dpy, xw.vis, xw.cmap);
 }
 
 int
 xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x, int y)
 {
-	float winx = borderpx + x * win.cw, winy = borderpx + y * win.ch, xp, yp;
+	float winx = win.hborderpx + x * win.cw, winy = win.vborderpx + y * win.ch, xp, yp;
 	ushort mode, prevmode = USHRT_MAX;
 	Font *font = &dc.font;
 	int frcflags = FRC_NORMAL;
@@ -1628,18 +1768,68 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i
 	r.width = width;
 	XftDrawSetClipRectangles(xw.draw, winx, winy, &r, 1);
 
-	/* Render the glyphs. */
-	XftDrawGlyphFontSpec(xw.draw, fg, specs, len);
-
-	/* Render underline and strikethrough. */
+	/* Decoration color. */
+	Color decor;
+	uint32_t decorcolor = tgetdecorcolor(&base);
+	if (decorcolor == DECOR_DEFAULT_COLOR) {
+		decor = *fg;
+	} else if (IS_TRUECOL(decorcolor)) {
+		colfg.alpha = 0xffff;
+		colfg.red = TRUERED(decorcolor);
+		colfg.green = TRUEGREEN(decorcolor);
+		colfg.blue = TRUEBLUE(decorcolor);
+		XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &colfg, &decor);
+	} else {
+		decor = dc.col[decorcolor];
+	}
+	decor.color.alpha = 0xffff;
+	decor.pixel |= 0xff << 24;
+
+	/* Float thickness, used as a base to compute other values. */
+	float fthick = dc.font.height / 18.0;
+	/* Integer thickness in pixels. Must not be 0. */
+	int thick = MAX(1, roundf(fthick));
+	/* The default gap between the baseline and a single underline. */
+	int gap = roundf(fthick * 2);
+	/* The total thickness of a double underline. */
+	int doubleh = thick * 2 + ceilf(fthick * 0.5);
+	/* The total thickness of an undercurl. */
+	int curlh = thick * 2 + roundf(fthick * 0.75);
+
+	/* Render the underline before the glyphs. */
 	if (base.mode & ATTR_UNDERLINE) {
-		XftDrawRect(xw.draw, fg, winx, winy + dc.font.ascent * chscale + 1,
-				width, 1);
+		uint32_t style = tgetdecorstyle(&base);
+		int liney = winy + dc.font.ascent + gap;
+		/* Adjust liney to guarantee that a single underline fits. */
+		liney -= MAX(0, liney + thick - (winy + win.ch));
+		if (style == UNDERLINE_DOUBLE) {
+			liney -= MAX(0, liney + doubleh - (winy + win.ch));
+			XftDrawRect(xw.draw, &decor, winx, liney, width, thick);
+			XftDrawRect(xw.draw, &decor, winx,
+				    liney + doubleh - thick, width, thick);
+		} else if (style == UNDERLINE_DOTTED) {
+			xdrawunderdashed(xw.draw, &decor, winx, liney, width,
+					 thick * 2, 0.5, thick);
+		} else if (style == UNDERLINE_DASHED) {
+			int wavelen = MAX(2, win.cw * 0.9);
+			xdrawunderdashed(xw.draw, &decor, winx, liney, width,
+					 wavelen, 0.65, thick);
+		} else if (style == UNDERLINE_CURLY) {
+			liney -= MAX(0, liney + curlh - (winy + win.ch));
+			xdrawundercurl(xw.draw, &decor, winx, liney, width,
+				       curlh, thick);
+		} else {
+			XftDrawRect(xw.draw, &decor, winx, liney, width, thick);
+		}
 	}
 
+	/* Render the glyphs. */
+	XftDrawGlyphFontSpec(xw.draw, fg, specs, len);
+
+	/* Render strikethrough. Alway use the fg color. */
 	if (base.mode & ATTR_STRUCK) {
-		XftDrawRect(xw.draw, fg, winx, winy + 2 * dc.font.ascent * chscale / 3,
-				width, 1);
+		XftDrawRect(xw.draw, fg, winx, winy + 2 * dc.font.ascent / 3,
+			    width, thick);
 	}
 
 	/* Reset clip to none. */