diff options
author | ZachIR <zachir@librem.one> | 2025-07-08 20:39:57 -0500 |
---|---|---|
committer | ZachIR <zachir@librem.one> | 2025-07-08 20:39:57 -0500 |
commit | 38d2f7ba589e8ee0ee5ded7915952ed094e3a51a (patch) | |
tree | b98c891bcd03dcbc6a9ebae038d154a472febe8a /patches/st-undercurl-0.8.4-20210822.diff | |
parent | 8cda47f8e8b2db37f5c69b4cdb748ac31a2e6e23 (diff) |
Start from scratch on version 0.9.2
Diffstat (limited to 'patches/st-undercurl-0.8.4-20210822.diff')
-rw-r--r-- | patches/st-undercurl-0.8.4-20210822.diff | 605 |
1 files changed, 0 insertions, 605 deletions
diff --git a/patches/st-undercurl-0.8.4-20210822.diff b/patches/st-undercurl-0.8.4-20210822.diff deleted file mode 100644 index fab2ddc..0000000 --- a/patches/st-undercurl-0.8.4-20210822.diff +++ /dev/null @@ -1,605 +0,0 @@ -diff --git a/config.def.h b/config.def.h -index 6f05dce..7ae1b92 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -470,3 +470,27 @@ static char ascii_printable[] = - " !\"#$%&'()*+,-./0123456789:;<=>?" - "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_" - "`abcdefghijklmnopqrstuvwxyz{|}~"; -+ -+/** -+ * Undercurl style. Set UNDERCURL_STYLE to one of the available styles. -+ * -+ * Curly: Dunno how to draw it *shrug* -+ * _ _ _ _ -+ * ( ) ( ) ( ) ( ) -+ * (_) (_) (_) (_) -+ * -+ * Spiky: -+ * /\ /\ /\ /\ -+ * \/ \/ \/ -+ * -+ * Capped: -+ * _ _ _ -+ * / \ / \ / \ -+ * \_/ \_/ -+ */ -+// Available styles -+#define UNDERCURL_CURLY 0 -+#define UNDERCURL_SPIKY 1 -+#define UNDERCURL_CAPPED 2 -+// Active style -+#define UNDERCURL_STYLE UNDERCURL_SPIKY -diff --git a/st.c b/st.c -index 76b7e0d..542ab3a 100644 ---- a/st.c -+++ b/st.c -@@ -33,6 +33,7 @@ - #define UTF_SIZ 4 - #define ESC_BUF_SIZ (128*UTF_SIZ) - #define ESC_ARG_SIZ 16 -+#define CAR_PER_ARG 4 - #define STR_BUF_SIZ ESC_BUF_SIZ - #define STR_ARG_SIZ ESC_ARG_SIZ - -@@ -139,6 +140,7 @@ typedef struct { - int arg[ESC_ARG_SIZ]; - int narg; /* nb of args */ - char mode[2]; -+ int carg[ESC_ARG_SIZ][CAR_PER_ARG]; /* colon args */ - } CSIEscape; - - /* STR Escape sequence structs */ -@@ -159,6 +161,7 @@ static void ttywriteraw(const char *, size_t); - - static void csidump(void); - static void csihandle(void); -+static void readcolonargs(char **, int, int[][CAR_PER_ARG]); - static void csiparse(void); - static void csireset(void); - static int eschandle(uchar); -@@ -1131,6 +1134,28 @@ tnewline(int first_col) - tmoveto(first_col ? 0 : term.c.x, y); - } - -+void -+readcolonargs(char **p, int cursor, int params[][CAR_PER_ARG]) -+{ -+ int i = 0; -+ for (; i < CAR_PER_ARG; i++) -+ params[cursor][i] = -1; -+ -+ if (**p != ':') -+ return; -+ -+ char *np = NULL; -+ i = 0; -+ -+ while (**p == ':' && i < CAR_PER_ARG) { -+ while (**p == ':') -+ (*p)++; -+ params[cursor][i] = strtol(*p, &np, 10); -+ *p = np; -+ i++; -+ } -+} -+ - void - csiparse(void) - { -@@ -1153,6 +1178,7 @@ csiparse(void) - v = -1; - csiescseq.arg[csiescseq.narg++] = v; - p = np; -+ readcolonargs(&p, csiescseq.narg-1, csiescseq.carg); - if (*p != ';' || csiescseq.narg == ESC_ARG_SIZ) - break; - p++; -@@ -1369,6 +1395,10 @@ tsetattr(int *attr, int l) - ATTR_STRUCK ); - term.c.attr.fg = defaultfg; - term.c.attr.bg = defaultbg; -+ term.c.attr.ustyle = -1; -+ term.c.attr.ucolor[0] = -1; -+ term.c.attr.ucolor[1] = -1; -+ term.c.attr.ucolor[2] = -1; - break; - case 1: - term.c.attr.mode |= ATTR_BOLD; -@@ -1380,7 +1410,14 @@ tsetattr(int *attr, int l) - term.c.attr.mode |= ATTR_ITALIC; - break; - case 4: -- term.c.attr.mode |= ATTR_UNDERLINE; -+ term.c.attr.ustyle = csiescseq.carg[i][0]; -+ -+ if (term.c.attr.ustyle != 0) -+ term.c.attr.mode |= ATTR_UNDERLINE; -+ else -+ term.c.attr.mode &= ~ATTR_UNDERLINE; -+ -+ term.c.attr.mode ^= ATTR_DIRTYUNDERLINE; - break; - case 5: /* slow blink */ - /* FALLTHROUGH */ -@@ -1431,6 +1468,18 @@ tsetattr(int *attr, int l) - case 49: - term.c.attr.bg = defaultbg; - break; -+ case 58: -+ term.c.attr.ucolor[0] = csiescseq.carg[i][1]; -+ term.c.attr.ucolor[1] = csiescseq.carg[i][2]; -+ term.c.attr.ucolor[2] = csiescseq.carg[i][3]; -+ term.c.attr.mode ^= ATTR_DIRTYUNDERLINE; -+ break; -+ case 59: -+ term.c.attr.ucolor[0] = -1; -+ term.c.attr.ucolor[1] = -1; -+ term.c.attr.ucolor[2] = -1; -+ term.c.attr.mode ^= ATTR_DIRTYUNDERLINE; -+ break; - default: - if (BETWEEN(attr[i], 30, 37)) { - term.c.attr.fg = attr[i] - 30; -diff --git a/st.h b/st.h -index 3d351b6..95bdcbd 100644 ---- a/st.h -+++ b/st.h -@@ -34,6 +34,7 @@ enum glyph_attribute { - ATTR_WIDE = 1 << 9, - ATTR_WDUMMY = 1 << 10, - ATTR_BOLD_FAINT = ATTR_BOLD | ATTR_FAINT, -+ ATTR_DIRTYUNDERLINE = 1 << 15, - }; - - enum selection_mode { -@@ -65,6 +66,8 @@ typedef struct { - ushort mode; /* attribute flags */ - uint32_t fg; /* foreground */ - uint32_t bg; /* background */ -+ int ustyle; /* underline style */ -+ int ucolor[3]; /* underline color */ - } Glyph; - - typedef Glyph *Line; -diff --git a/st.info b/st.info -index 8201ad6..659878c 100644 ---- a/st.info -+++ b/st.info -@@ -1,4 +1,5 @@ - st-mono| simpleterm monocolor, -+ Su, - acsc=+C\,D-A.B0E``aaffgghFiGjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~, - am, - bce, -diff --git a/x.c b/x.c -index 210f184..3a0e79e 100644 ---- a/x.c -+++ b/x.c -@@ -45,6 +45,14 @@ typedef struct { - signed char appcursor; /* application cursor */ - } Key; - -+/* Undercurl slope types */ -+enum undercurl_slope_type { -+ UNDERCURL_SLOPE_ASCENDING = 0, -+ UNDERCURL_SLOPE_TOP_CAP = 1, -+ UNDERCURL_SLOPE_DESCENDING = 2, -+ UNDERCURL_SLOPE_BOTTOM_CAP = 3 -+}; -+ - /* X modifiers */ - #define XK_ANY_MOD UINT_MAX - #define XK_NO_MOD 0 -@@ -1339,6 +1347,51 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x - return numspecs; - } - -+static int isSlopeRising (int x, int iPoint, int waveWidth) -+{ -+ // . . . . -+ // / \ / \ / \ / \ -+ // / \ / \ / \ / \ -+ // . . . . . -+ -+ // Find absolute `x` of point -+ x += iPoint * (waveWidth/2); -+ -+ // Find index of absolute wave -+ int absSlope = x / ((float)waveWidth/2); -+ -+ return (absSlope % 2); -+} -+ -+static int getSlope (int x, int iPoint, int waveWidth) -+{ -+ // Sizes: Caps are half width of slopes -+ // 1_2 1_2 1_2 1_2 -+ // / \ / \ / \ / \ -+ // / \ / \ / \ / \ -+ // 0 3_0 3_0 3_0 3_ -+ // <2-> <1> <---6----> -+ -+ // Find type of first point -+ int firstType; -+ x -= (x / waveWidth) * waveWidth; -+ if (x < (waveWidth * (2.f/6.f))) -+ firstType = UNDERCURL_SLOPE_ASCENDING; -+ else if (x < (waveWidth * (3.f/6.f))) -+ firstType = UNDERCURL_SLOPE_TOP_CAP; -+ else if (x < (waveWidth * (5.f/6.f))) -+ firstType = UNDERCURL_SLOPE_DESCENDING; -+ else -+ firstType = UNDERCURL_SLOPE_BOTTOM_CAP; -+ -+ // Find type of given point -+ int pointType = (iPoint % 4); -+ pointType += firstType; -+ pointType %= 4; -+ -+ return pointType; -+} -+ - void - xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, int y) - { -@@ -1461,8 +1514,357 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i - - /* Render underline and strikethrough. */ - if (base.mode & ATTR_UNDERLINE) { -- XftDrawRect(xw.draw, fg, winx, winy + dc.font.ascent + 1, -- width, 1); -+ // Underline Color -+ const int widthThreshold = 28; // +1 width every widthThreshold px of font -+ int wlw = (win.ch / widthThreshold) + 1; // Wave Line Width -+ int linecolor; -+ if ((base.ucolor[0] >= 0) && -+ !(base.mode & ATTR_BLINK && win.mode & MODE_BLINK) && -+ !(base.mode & ATTR_INVISIBLE) -+ ) { -+ // Special color for underline -+ // Index -+ if (base.ucolor[1] < 0) { -+ linecolor = dc.col[base.ucolor[0]].pixel; -+ } -+ // RGB -+ else { -+ XColor lcolor; -+ lcolor.red = base.ucolor[0] * 257; -+ lcolor.green = base.ucolor[1] * 257; -+ lcolor.blue = base.ucolor[2] * 257; -+ lcolor.flags = DoRed | DoGreen | DoBlue; -+ XAllocColor(xw.dpy, xw.cmap, &lcolor); -+ linecolor = lcolor.pixel; -+ } -+ } else { -+ // Foreground color for underline -+ linecolor = fg->pixel; -+ } -+ -+ XGCValues ugcv = { -+ .foreground = linecolor, -+ .line_width = wlw, -+ .line_style = LineSolid, -+ .cap_style = CapNotLast -+ }; -+ -+ GC ugc = XCreateGC(xw.dpy, XftDrawDrawable(xw.draw), -+ GCForeground | GCLineWidth | GCLineStyle | GCCapStyle, -+ &ugcv); -+ -+ // Underline Style -+ if (base.ustyle != 3) { -+ //XftDrawRect(xw.draw, fg, winx, winy + dc.font.ascent + 1, width, 1); -+ XFillRectangle(xw.dpy, XftDrawDrawable(xw.draw), ugc, winx, -+ winy + dc.font.ascent + 1, width, wlw); -+ } else if (base.ustyle == 3) { -+ int ww = win.cw;//width; -+ int wh = dc.font.descent - wlw/2 - 1;//r.height/7; -+ int wx = winx; -+ int wy = winy + win.ch - dc.font.descent; -+ -+#if UNDERCURL_STYLE == UNDERCURL_CURLY -+ // Draw waves -+ int narcs = charlen * 2 + 1; -+ XArc *arcs = xmalloc(sizeof(XArc) * narcs); -+ -+ int i = 0; -+ for (i = 0; i < charlen-1; i++) { -+ arcs[i*2] = (XArc) { -+ .x = wx + win.cw * i + ww / 4, -+ .y = wy, -+ .width = win.cw / 2, -+ .height = wh, -+ .angle1 = 0, -+ .angle2 = 180 * 64 -+ }; -+ arcs[i*2+1] = (XArc) { -+ .x = wx + win.cw * i + ww * 0.75, -+ .y = wy, -+ .width = win.cw/2, -+ .height = wh, -+ .angle1 = 180 * 64, -+ .angle2 = 180 * 64 -+ }; -+ } -+ // Last wave -+ arcs[i*2] = (XArc) {wx + ww * i + ww / 4, wy, ww / 2, wh, -+ 0, 180 * 64 }; -+ // Last wave tail -+ arcs[i*2+1] = (XArc) {wx + ww * i + ww * 0.75, wy, ceil(ww / 2.), -+ wh, 180 * 64, 90 * 64}; -+ // First wave tail -+ i++; -+ arcs[i*2] = (XArc) {wx - ww/4 - 1, wy, ceil(ww / 2.), wh, 270 * 64, -+ 90 * 64 }; -+ -+ XDrawArcs(xw.dpy, XftDrawDrawable(xw.draw), ugc, arcs, narcs); -+ -+ free(arcs); -+#elif UNDERCURL_STYLE == UNDERCURL_SPIKY -+ // Make the underline corridor larger -+ /* -+ wy -= wh; -+ */ -+ wh *= 2; -+ -+ // Set the angle of the slope to 45° -+ ww = wh; -+ -+ // Position of wave is independent of word, it's absolute -+ wx = (wx / (ww/2)) * (ww/2); -+ -+ int marginStart = winx - wx; -+ -+ // Calculate number of points with floating precision -+ float n = width; // Width of word in pixels -+ n = (n / ww) * 2; // Number of slopes (/ or \) -+ n += 2; // Add two last points -+ int npoints = n; // Convert to int -+ -+ // Total length of underline -+ float waveLength = 0; -+ -+ if (npoints >= 3) { -+ // We add an aditional slot in case we use a bonus point -+ XPoint *points = xmalloc(sizeof(XPoint) * (npoints + 1)); -+ -+ // First point (Starts with the word bounds) -+ points[0] = (XPoint) { -+ .x = wx + marginStart, -+ .y = (isSlopeRising(wx, 0, ww)) -+ ? (wy - marginStart + ww/2.f) -+ : (wy + marginStart) -+ }; -+ -+ // Second point (Goes back to the absolute point coordinates) -+ points[1] = (XPoint) { -+ .x = (ww/2.f) - marginStart, -+ .y = (isSlopeRising(wx, 1, ww)) -+ ? (ww/2.f - marginStart) -+ : (-ww/2.f + marginStart) -+ }; -+ waveLength += (ww/2.f) - marginStart; -+ -+ // The rest of the points -+ for (int i = 2; i < npoints-1; i++) { -+ points[i] = (XPoint) { -+ .x = ww/2, -+ .y = (isSlopeRising(wx, i, ww)) -+ ? wh/2 -+ : -wh/2 -+ }; -+ waveLength += ww/2; -+ } -+ -+ // Last point -+ points[npoints-1] = (XPoint) { -+ .x = ww/2, -+ .y = (isSlopeRising(wx, npoints-1, ww)) -+ ? wh/2 -+ : -wh/2 -+ }; -+ waveLength += ww/2; -+ -+ // End -+ if (waveLength < width) { // Add a bonus point? -+ int marginEnd = width - waveLength; -+ points[npoints] = (XPoint) { -+ .x = marginEnd, -+ .y = (isSlopeRising(wx, npoints, ww)) -+ ? (marginEnd) -+ : (-marginEnd) -+ }; -+ -+ npoints++; -+ } else if (waveLength > width) { // Is last point too far? -+ int marginEnd = waveLength - width; -+ points[npoints-1].x -= marginEnd; -+ if (isSlopeRising(wx, npoints-1, ww)) -+ points[npoints-1].y -= (marginEnd); -+ else -+ points[npoints-1].y += (marginEnd); -+ } -+ -+ // Draw the lines -+ XDrawLines(xw.dpy, XftDrawDrawable(xw.draw), ugc, points, npoints, -+ CoordModePrevious); -+ -+ // Draw a second underline with an offset of 1 pixel -+ if ( ((win.ch / (widthThreshold/2)) % 2)) { -+ points[0].x++; -+ -+ XDrawLines(xw.dpy, XftDrawDrawable(xw.draw), ugc, points, -+ npoints, CoordModePrevious); -+ } -+ -+ // Free resources -+ free(points); -+ } -+#else // UNDERCURL_CAPPED -+ // Cap is half of wave width -+ float capRatio = 0.5f; -+ -+ // Make the underline corridor larger -+ wh *= 2; -+ -+ // Set the angle of the slope to 45° -+ ww = wh; -+ ww *= 1 + capRatio; // Add a bit of width for the cap -+ -+ // Position of wave is independent of word, it's absolute -+ wx = (wx / ww) * ww; -+ -+ float marginStart; -+ switch(getSlope(winx, 0, ww)) { -+ case UNDERCURL_SLOPE_ASCENDING: -+ marginStart = winx - wx; -+ break; -+ case UNDERCURL_SLOPE_TOP_CAP: -+ marginStart = winx - (wx + (ww * (2.f/6.f))); -+ break; -+ case UNDERCURL_SLOPE_DESCENDING: -+ marginStart = winx - (wx + (ww * (3.f/6.f))); -+ break; -+ case UNDERCURL_SLOPE_BOTTOM_CAP: -+ marginStart = winx - (wx + (ww * (5.f/6.f))); -+ break; -+ } -+ -+ // Calculate number of points with floating precision -+ float n = width; // Width of word in pixels -+ // ._. -+ n = (n / ww) * 4; // Number of points (./ \.) -+ n += 2; // Add two last points -+ int npoints = n; // Convert to int -+ -+ // Position of the pen to draw the lines -+ float penX = 0; -+ float penY = 0; -+ -+ if (npoints >= 3) { -+ XPoint *points = xmalloc(sizeof(XPoint) * (npoints + 1)); -+ -+ // First point (Starts with the word bounds) -+ penX = winx; -+ switch (getSlope(winx, 0, ww)) { -+ case UNDERCURL_SLOPE_ASCENDING: -+ penY = wy + wh/2.f - marginStart; -+ break; -+ case UNDERCURL_SLOPE_TOP_CAP: -+ penY = wy; -+ break; -+ case UNDERCURL_SLOPE_DESCENDING: -+ penY = wy + marginStart; -+ break; -+ case UNDERCURL_SLOPE_BOTTOM_CAP: -+ penY = wy + wh/2.f; -+ break; -+ } -+ points[0].x = penX; -+ points[0].y = penY; -+ -+ // Second point (Goes back to the absolute point coordinates) -+ switch (getSlope(winx, 1, ww)) { -+ case UNDERCURL_SLOPE_ASCENDING: -+ penX += ww * (1.f/6.f) - marginStart; -+ penY += 0; -+ break; -+ case UNDERCURL_SLOPE_TOP_CAP: -+ penX += ww * (2.f/6.f) - marginStart; -+ penY += -wh/2.f + marginStart; -+ break; -+ case UNDERCURL_SLOPE_DESCENDING: -+ penX += ww * (1.f/6.f) - marginStart; -+ penY += 0; -+ break; -+ case UNDERCURL_SLOPE_BOTTOM_CAP: -+ penX += ww * (2.f/6.f) - marginStart; -+ penY += -marginStart + wh/2.f; -+ break; -+ } -+ points[1].x = penX; -+ points[1].y = penY; -+ -+ // The rest of the points -+ for (int i = 2; i < npoints; i++) { -+ switch (getSlope(winx, i, ww)) { -+ case UNDERCURL_SLOPE_ASCENDING: -+ case UNDERCURL_SLOPE_DESCENDING: -+ penX += ww * (1.f/6.f); -+ penY += 0; -+ break; -+ case UNDERCURL_SLOPE_TOP_CAP: -+ penX += ww * (2.f/6.f); -+ penY += -wh / 2.f; -+ break; -+ case UNDERCURL_SLOPE_BOTTOM_CAP: -+ penX += ww * (2.f/6.f); -+ penY += wh / 2.f; -+ break; -+ } -+ points[i].x = penX; -+ points[i].y = penY; -+ } -+ -+ // End -+ float waveLength = penX - winx; -+ if (waveLength < width) { // Add a bonus point? -+ int marginEnd = width - waveLength; -+ penX += marginEnd; -+ switch(getSlope(winx, npoints, ww)) { -+ case UNDERCURL_SLOPE_ASCENDING: -+ case UNDERCURL_SLOPE_DESCENDING: -+ //penY += 0; -+ break; -+ case UNDERCURL_SLOPE_TOP_CAP: -+ penY += -marginEnd; -+ break; -+ case UNDERCURL_SLOPE_BOTTOM_CAP: -+ penY += marginEnd; -+ break; -+ } -+ -+ points[npoints].x = penX; -+ points[npoints].y = penY; -+ -+ npoints++; -+ } else if (waveLength > width) { // Is last point too far? -+ int marginEnd = waveLength - width; -+ points[npoints-1].x -= marginEnd; -+ switch(getSlope(winx, npoints-1, ww)) { -+ case UNDERCURL_SLOPE_TOP_CAP: -+ points[npoints-1].y += marginEnd; -+ break; -+ case UNDERCURL_SLOPE_BOTTOM_CAP: -+ points[npoints-1].y -= marginEnd; -+ break; -+ default: -+ break; -+ } -+ } -+ -+ // Draw the lines -+ XDrawLines(xw.dpy, XftDrawDrawable(xw.draw), ugc, points, npoints, -+ CoordModeOrigin); -+ -+ // Draw a second underline with an offset of 1 pixel -+ if ( ((win.ch / (widthThreshold/2)) % 2)) { -+ for (int i = 0; i < npoints; i++) -+ points[i].x++; -+ -+ XDrawLines(xw.dpy, XftDrawDrawable(xw.draw), ugc, points, -+ npoints, CoordModeOrigin); -+ } -+ -+ // Free resources -+ free(points); -+ } -+#endif -+ } -+ -+ XFreeGC(xw.dpy, ugc); - } - - if (base.mode & ATTR_STRUCK) { |