sites

public wiki contents of suckless.org
git clone git://git.suckless.org/sites
Log | Files | Refs

st-undercurl-0.8.4.diff (6335B)


      1 diff --git a/st.c b/st.c
      2 index 76b7e0d..542ab3a 100644
      3 --- a/st.c
      4 +++ b/st.c
      5 @@ -33,6 +33,7 @@
      6  #define UTF_SIZ       4
      7  #define ESC_BUF_SIZ   (128*UTF_SIZ)
      8  #define ESC_ARG_SIZ   16
      9 +#define CAR_PER_ARG   4
     10  #define STR_BUF_SIZ   ESC_BUF_SIZ
     11  #define STR_ARG_SIZ   ESC_ARG_SIZ
     12  
     13 @@ -139,6 +140,7 @@ typedef struct {
     14  	int arg[ESC_ARG_SIZ];
     15  	int narg;              /* nb of args */
     16  	char mode[2];
     17 +	int carg[ESC_ARG_SIZ][CAR_PER_ARG]; /* colon args */
     18  } CSIEscape;
     19  
     20  /* STR Escape sequence structs */
     21 @@ -159,6 +161,7 @@ static void ttywriteraw(const char *, size_t);
     22  
     23  static void csidump(void);
     24  static void csihandle(void);
     25 +static void readcolonargs(char **, int, int[][CAR_PER_ARG]);
     26  static void csiparse(void);
     27  static void csireset(void);
     28  static int eschandle(uchar);
     29 @@ -1131,6 +1134,28 @@ tnewline(int first_col)
     30  	tmoveto(first_col ? 0 : term.c.x, y);
     31  }
     32  
     33 +void
     34 +readcolonargs(char **p, int cursor, int params[][CAR_PER_ARG])
     35 +{
     36 +	int i = 0;
     37 +	for (; i < CAR_PER_ARG; i++)
     38 +		params[cursor][i] = -1;
     39 +
     40 +	if (**p != ':')
     41 +		return;
     42 +
     43 +	char *np = NULL;
     44 +	i = 0;
     45 +
     46 +	while (**p == ':' && i < CAR_PER_ARG) {
     47 +		while (**p == ':')
     48 +			(*p)++;
     49 +		params[cursor][i] = strtol(*p, &np, 10);
     50 +		*p = np;
     51 +		i++;
     52 +	}
     53 +}
     54 +
     55  void
     56  csiparse(void)
     57  {
     58 @@ -1153,6 +1178,7 @@ csiparse(void)
     59  			v = -1;
     60  		csiescseq.arg[csiescseq.narg++] = v;
     61  		p = np;
     62 +		readcolonargs(&p, csiescseq.narg-1, csiescseq.carg);
     63  		if (*p != ';' || csiescseq.narg == ESC_ARG_SIZ)
     64  			break;
     65  		p++;
     66 @@ -1369,6 +1395,10 @@ tsetattr(int *attr, int l)
     67  				ATTR_STRUCK     );
     68  			term.c.attr.fg = defaultfg;
     69  			term.c.attr.bg = defaultbg;
     70 +			term.c.attr.ustyle = -1;
     71 +			term.c.attr.ucolor[0] = -1;
     72 +			term.c.attr.ucolor[1] = -1;
     73 +			term.c.attr.ucolor[2] = -1;
     74  			break;
     75  		case 1:
     76  			term.c.attr.mode |= ATTR_BOLD;
     77 @@ -1380,7 +1410,14 @@ tsetattr(int *attr, int l)
     78  			term.c.attr.mode |= ATTR_ITALIC;
     79  			break;
     80  		case 4:
     81 -			term.c.attr.mode |= ATTR_UNDERLINE;
     82 +			term.c.attr.ustyle = csiescseq.carg[i][0];
     83 +
     84 +			if (term.c.attr.ustyle != 0)
     85 +				term.c.attr.mode |= ATTR_UNDERLINE;
     86 +			else
     87 +				term.c.attr.mode &= ~ATTR_UNDERLINE;
     88 +
     89 +			term.c.attr.mode ^= ATTR_DIRTYUNDERLINE;
     90  			break;
     91  		case 5: /* slow blink */
     92  			/* FALLTHROUGH */
     93 @@ -1431,6 +1468,18 @@ tsetattr(int *attr, int l)
     94  		case 49:
     95  			term.c.attr.bg = defaultbg;
     96  			break;
     97 +		case 58:
     98 +			term.c.attr.ucolor[0] = csiescseq.carg[i][1];
     99 +			term.c.attr.ucolor[1] = csiescseq.carg[i][2];
    100 +			term.c.attr.ucolor[2] = csiescseq.carg[i][3];
    101 +			term.c.attr.mode ^= ATTR_DIRTYUNDERLINE;
    102 +			break;
    103 +		case 59:
    104 +			term.c.attr.ucolor[0] = -1;
    105 +			term.c.attr.ucolor[1] = -1;
    106 +			term.c.attr.ucolor[2] = -1;
    107 +			term.c.attr.mode ^= ATTR_DIRTYUNDERLINE;
    108 +			break;
    109  		default:
    110  			if (BETWEEN(attr[i], 30, 37)) {
    111  				term.c.attr.fg = attr[i] - 30;
    112 diff --git a/st.h b/st.h
    113 index 3d351b6..2cfac88 100644
    114 --- a/st.h
    115 +++ b/st.h
    116 @@ -34,6 +34,7 @@ enum glyph_attribute {
    117  	ATTR_WIDE       = 1 << 9,
    118  	ATTR_WDUMMY     = 1 << 10,
    119  	ATTR_BOLD_FAINT = ATTR_BOLD | ATTR_FAINT,
    120 +	ATTR_DIRTYUNDERLINE = 1 << 15,
    121  };
    122  
    123  enum selection_mode {
    124 @@ -65,6 +66,8 @@ typedef struct {
    125  	ushort mode;      /* attribute flags */
    126  	uint32_t fg;      /* foreground  */
    127  	uint32_t bg;      /* background  */
    128 +	int ustyle;	  /* underline style */
    129 +	int ucolor[3];    /* underline color */
    130  } Glyph;
    131  
    132  typedef Glyph *Line;
    133 diff --git a/st.info b/st.info
    134 index 8201ad6..659878c 100644
    135 --- a/st.info
    136 +++ b/st.info
    137 @@ -1,4 +1,5 @@
    138  st-mono| simpleterm monocolor,
    139 +	Su,
    140  	acsc=+C\,D-A.B0E``aaffgghFiGjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~,
    141  	am,
    142  	bce,
    143 diff --git a/x.c b/x.c
    144 index 210f184..9a6a2bd 100644
    145 --- a/x.c
    146 +++ b/x.c
    147 @@ -1461,8 +1461,95 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i
    148  
    149  	/* Render underline and strikethrough. */
    150  	if (base.mode & ATTR_UNDERLINE) {
    151 -		XftDrawRect(xw.draw, fg, winx, winy + dc.font.ascent + 1,
    152 -				width, 1);
    153 +		// Underline Color
    154 +		int wlw = 1; // Wave Line Width
    155 +		int linecolor;
    156 +		if ((base.ucolor[0] >= 0) &&
    157 +			!(base.mode & ATTR_BLINK && win.mode & MODE_BLINK) &&
    158 +			!(base.mode & ATTR_INVISIBLE)
    159 +		) {
    160 +			// Special color for underline
    161 +			// Index
    162 +			if (base.ucolor[1] < 0) {
    163 +				linecolor = dc.col[base.ucolor[0]].pixel;
    164 +			}
    165 +			// RGB
    166 +			else {
    167 +				XColor lcolor;
    168 +				lcolor.red = base.ucolor[0] * 257;
    169 +				lcolor.green = base.ucolor[1] * 257;
    170 +				lcolor.blue = base.ucolor[2] * 257;
    171 +				lcolor.flags = DoRed | DoGreen | DoBlue;
    172 +				XAllocColor(xw.dpy, xw.cmap, &lcolor);
    173 +				linecolor = lcolor.pixel;
    174 +			}
    175 +		} else {
    176 +			// Foreground color for underline
    177 +			linecolor = fg->pixel;
    178 +		}
    179 +
    180 +		XGCValues ugcv = {
    181 +			.foreground = linecolor,
    182 +			.line_width = wlw,
    183 +			.line_style = LineSolid,
    184 +			.cap_style = CapNotLast
    185 +		};
    186 +
    187 +		GC ugc = XCreateGC(xw.dpy, XftDrawDrawable(xw.draw),
    188 +			GCForeground | GCLineWidth | GCLineStyle | GCCapStyle,
    189 +			&ugcv);
    190 +
    191 +		// Underline Style
    192 +		if (base.ustyle != 3) {
    193 +			//XftDrawRect(xw.draw, fg, winx, winy + dc.font.ascent + 1, width, 1);
    194 +			XFillRectangle(xw.dpy, XftDrawDrawable(xw.draw), ugc, winx,
    195 +				winy + dc.font.ascent + 1, width, wlw);
    196 +		} else if (base.ustyle == 3) {
    197 +			int ww = win.cw;//width;
    198 +			int wh = dc.font.descent - wlw/2 - 1;//r.height/7;
    199 +			int wx = winx;
    200 +			int wy = winy + win.ch - dc.font.descent;
    201 +
    202 +			// Draw waves
    203 +			int narcs = charlen * 2 + 1;
    204 +			XArc *arcs = xmalloc(sizeof(XArc) * narcs);
    205 +
    206 +			int i = 0;
    207 +			for (i = 0; i < charlen-1; i++) {
    208 +				arcs[i*2] = (XArc) {
    209 +					.x = wx + win.cw * i + ww / 4,
    210 +					.y = wy,
    211 +					.width = win.cw / 2,
    212 +					.height = wh,
    213 +					.angle1 = 0,
    214 +					.angle2 = 180 * 64
    215 +				};
    216 +				arcs[i*2+1] = (XArc) {
    217 +					.x = wx + win.cw * i + ww * 0.75,
    218 +					.y = wy,
    219 +					.width = win.cw/2,
    220 +					.height = wh,
    221 +					.angle1 = 180 * 64,
    222 +					.angle2 = 180 * 64
    223 +				};
    224 +			}
    225 +			// Last wave
    226 +			arcs[i*2] = (XArc) {wx + ww * i + ww / 4, wy, ww / 2, wh,
    227 +			0, 180 * 64 };
    228 +			// Last wave tail
    229 +			arcs[i*2+1] = (XArc) {wx + ww * i + ww * 0.75, wy, ceil(ww / 2.),
    230 +			wh, 180 * 64, 90 * 64};
    231 +			// First wave tail
    232 +			i++;
    233 +			arcs[i*2] = (XArc) {wx - ww/4 - 1, wy, ceil(ww / 2.), wh, 270 * 64,
    234 +			90 * 64 };
    235 +
    236 +			XDrawArcs(xw.dpy, XftDrawDrawable(xw.draw), ugc, arcs, narcs);
    237 +
    238 +			free(arcs);
    239 +		}
    240 +
    241 +		XFreeGC(xw.dpy, ugc);
    242  	}
    243  
    244  	if (base.mode & ATTR_STRUCK) {