summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpryazha <pryadeiniv@mail.ru>2025-07-01 08:36:48 +0500
committerpryazha <pryadeiniv@mail.ru>2025-07-01 08:36:48 +0500
commit7a35432782a8bb38429854180a7d16f82edec34a (patch)
tree85ba292c29cb28fa7e75dd65bb4b7f26102982f2
parentd18e6eb27e002872429d3f931bc08d6af816e1f7 (diff)
changes (apparently)HEADmaster
-rw-r--r--config.h8
-rwxr-xr-xstbin0 -> 106256 bytes
-rw-r--r--st.c3
-rw-r--r--st.h6
-rw-r--r--st.obin0 -> 78728 bytes
-rw-r--r--win.h2
-rw-r--r--x.c139
-rw-r--r--x.obin0 -> 73640 bytes
8 files changed, 85 insertions, 73 deletions
diff --git a/config.h b/config.h
index 415a66e..9f593eb 100644
--- a/config.h
+++ b/config.h
@@ -5,8 +5,9 @@
*
* font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html
*/
-static char *font = "Iosevka:pixelsize=20:style=regular";
-static int borderpx = 4;
+// static char *font = "Iosevka:pixelsize=20:antialias=true:autohint=true";
+static char *font = "FiraCode Nerd Font:pixelsize=16:antialias=true:autohint=true";
+static int borderpx = 2;
/*
* What program is execed by st depends of these precedence rules:
@@ -28,6 +29,9 @@ char *vtiden = "\033[?6c";
/* Kerning / character bounding-box multipliers */
static float cwscale = 1.0;
static float chscale = 1.0;
+/* Character rendering offsets in pixels */
+static short cxoffset = 0;
+static short cyoffset = 0;
/*
* word delimiter string
diff --git a/st b/st
new file mode 100755
index 0000000..68a0ee3
--- /dev/null
+++ b/st
Binary files differ
diff --git a/st.c b/st.c
index 7371554..0a894fc 100644
--- a/st.c
+++ b/st.c
@@ -2671,7 +2671,8 @@ draw(void)
drawregion(0, 0, term.col, term.row);
xdrawcursor(cx, term.c.y, term.line[term.c.y][cx],
- term.ocx, term.ocy, term.line[term.ocy][term.ocx]);
+ term.ocx, term.ocy, term.line[term.ocy][term.ocx],
+ term.line[term.ocy], term.col);
term.ocx = cx;
term.ocy = term.c.y;
xfinishdraw();
diff --git a/st.h b/st.h
index fd3b0d8..19d81b0 100644
--- a/st.h
+++ b/st.h
@@ -36,6 +36,12 @@ enum glyph_attribute {
ATTR_BOLD_FAINT = ATTR_BOLD | ATTR_FAINT,
};
+enum drawing_mode {
+ DRAW_NONE = 0,
+ DRAW_BG = 1 << 0,
+ DRAW_FG = 1 << 1,
+};
+
enum selection_mode {
SEL_IDLE = 0,
SEL_EMPTY = 1,
diff --git a/st.o b/st.o
new file mode 100644
index 0000000..6fd04d3
--- /dev/null
+++ b/st.o
Binary files differ
diff --git a/win.h b/win.h
index 6de960d..94679e4 100644
--- a/win.h
+++ b/win.h
@@ -25,7 +25,7 @@ enum win_mode {
void xbell(void);
void xclipcopy(void);
-void xdrawcursor(int, int, Glyph, int, int, Glyph);
+void xdrawcursor(int, int, Glyph, int, int, Glyph, Line, int);
void xdrawline(Line, int, int, int);
void xfinishdraw(void);
void xloadcols(void);
diff --git a/x.c b/x.c
index 677c806..bc1128f 100644
--- a/x.c
+++ b/x.c
@@ -143,7 +143,7 @@ typedef struct {
static inline ushort sixd_to_16bit(int);
static int xmakeglyphfontspecs(XftGlyphFontSpec *, const Glyph *, int, int, int);
-static void xdrawglyphfontspecs(const XftGlyphFontSpec *, Glyph, int, int, int);
+static void xdrawglyphfontspecs(const XftGlyphFontSpec *, Glyph, int, int, int, int);
static void xdrawglyph(Glyph, int, int);
static void xclear(int, int, int, int);
static int xgeommasktogravity(int);
@@ -1295,8 +1295,8 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x
if (glyphidx) {
specs[numspecs].font = font->match;
specs[numspecs].glyph = glyphidx;
- specs[numspecs].x = (short)xp;
- specs[numspecs].y = (short)yp;
+ specs[numspecs].x = (short)xp + cxoffset;
+ specs[numspecs].y = (short)yp + cyoffset;
xp += runewidth;
numspecs++;
continue;
@@ -1379,7 +1379,7 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x
}
void
-xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, int y)
+xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, int y, int dmode)
{
int charlen = len * ((base.mode & ATTR_WIDE) ? 2 : 1);
int winx = win.hborderpx + x * win.cw, winy = win.vborderpx + y * win.ch,
@@ -1469,48 +1469,40 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i
if (base.mode & ATTR_INVISIBLE)
fg = bg;
-
- /* Intelligent cleaning up of the borders. */
- if (x == 0) {
- xclear(0, (y == 0)? 0 : winy, win.vborderpx,
- winy + win.ch +
- ((winy + win.ch >= win.vborderpx + win.th)? win.h : 0));
- }
- if (winx + width >= win.hborderpx + win.tw) {
- xclear(winx + width, (y == 0)? 0 : winy, win.w,
- ((winy + win.ch >= win.vborderpx + win.th)? win.h : (winy + win.ch)));
- }
- if (y == 0)
- xclear(winx, 0, winx + width, win.hborderpx);
- if (winy + win.ch >= win.vborderpx + win.th)
- xclear(winx, winy + win.ch, winx + width, win.h);
-
- /* Clean up the region we want to draw to. */
- XftDrawRect(xw.draw, bg, winx, winy, width, win.ch);
-
- /* Set the clip region because Xft is sometimes dirty. */
- r.x = 0;
- r.y = 0;
- r.height = win.ch;
- r.width = width;
- XftDrawSetClipRectangles(xw.draw, winx, winy, &r, 1);
-
- /* Render the glyphs. */
- XftDrawGlyphFontSpec(xw.draw, fg, specs, len);
-
- /* Render underline and strikethrough. */
- if (base.mode & ATTR_UNDERLINE) {
- XftDrawRect(xw.draw, fg, winx, winy + dc.font.ascent * chscale + 1,
- width, 1);
+ if (dmode & DRAW_BG) {
+ /* Intelligent cleaning up of the borders. */
+ if (x == 0) {
+ xclear(0, (y == 0)? 0 : winy, borderpx,
+ winy + win.ch +
+ ((winy + win.ch >= borderpx + win.th)? win.h : 0));
+ }
+ if (winx + width >= borderpx + win.tw) {
+ xclear(winx + width, (y == 0)? 0 : winy, win.w,
+ ((winy + win.ch >= borderpx + win.th)? win.h : (winy + win.ch)));
+ }
+ if (y == 0)
+ xclear(winx, 0, winx + width, borderpx);
+ if (winy + win.ch >= borderpx + win.th)
+ xclear(winx, winy + win.ch, winx + width, win.h);
+ /* Fill the background */
+ XftDrawRect(xw.draw, bg, winx, winy, width, win.ch);
}
- if (base.mode & ATTR_STRUCK) {
- XftDrawRect(xw.draw, fg, winx, winy + 2 * dc.font.ascent * chscale / 3,
- width, 1);
- }
+ if (dmode & DRAW_FG) {
+ /* Render the glyphs. */
+ XftDrawGlyphFontSpec(xw.draw, fg, specs, len);
+
+ /* Render underline and strikethrough. */
+ if (base.mode & ATTR_UNDERLINE) {
+ XftDrawRect(xw.draw, fg, winx, winy + dc.font.ascent + 1,
+ width, 1);
+ }
- /* Reset clip to none. */
- XftDrawSetClip(xw.draw, 0);
+ if (base.mode & ATTR_STRUCK) {
+ XftDrawRect(xw.draw, fg, winx, winy + 2 * dc.font.ascent / 3,
+ width, 1);
+ }
+ }
}
void
@@ -1520,18 +1512,20 @@ xdrawglyph(Glyph g, int x, int y)
XftGlyphFontSpec spec;
numspecs = xmakeglyphfontspecs(&spec, &g, 1, x, y);
- xdrawglyphfontspecs(&spec, g, numspecs, x, y);
+ xdrawglyphfontspecs(&spec, g, numspecs, x, y, DRAW_BG | DRAW_FG);
}
void
-xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og)
+xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og, Line line, int len)
{
Color drawcol;
/* remove the old cursor */
if (selected(ox, oy))
og.mode ^= ATTR_REVERSE;
- xdrawglyph(og, ox, oy);
+ /* Redraw the line where cursor was previously.
+ * It will restore wide glyphs and ligatures broken by the cursor. */
+ xdrawline(line, 0, oy, len);
if (IS_SET(MODE_HIDE))
return;
@@ -1661,32 +1655,39 @@ xstartdraw(void)
void
xdrawline(Line line, int x1, int y1, int x2)
{
- int i, x, ox, numspecs;
+ int i, x, ox, numspecs, numspecs_cached;
Glyph base, new;
- XftGlyphFontSpec *specs = xw.specbuf;
-
- numspecs = xmakeglyphfontspecs(specs, &line[x1], x2 - x1, x1, y1);
- i = ox = 0;
- for (x = x1; x < x2 && i < numspecs; x++) {
- new = line[x];
- if (new.mode == ATTR_WDUMMY)
- continue;
- if (selected(x, y1))
- new.mode ^= ATTR_REVERSE;
- if (i > 0 && ATTRCMP(base, new)) {
- xdrawglyphfontspecs(specs, base, i, ox, y1);
- specs += i;
- numspecs -= i;
- i = 0;
- }
- if (i == 0) {
- ox = x;
- base = new;
+ XftGlyphFontSpec *specs;
+
+ numspecs_cached = xmakeglyphfontspecs(xw.specbuf, &line[x1], x2 - x1, x1, y1);
+
+ /* Draw line in 2 passes: background and foreground. This way wide glyphs
+ won't get truncated (#223) */
+ for (int dmode = DRAW_BG; dmode <= DRAW_FG; dmode <<= 1) {
+ specs = xw.specbuf;
+ numspecs = numspecs_cached;
+ i = ox = 0;
+ for (x = x1; x < x2 && i < numspecs; x++) {
+ new = line[x];
+ if (new.mode == ATTR_WDUMMY)
+ continue;
+ if (selected(x, y1))
+ new.mode ^= ATTR_REVERSE;
+ if (i > 0 && ATTRCMP(base, new)) {
+ xdrawglyphfontspecs(specs, base, i, ox, y1, dmode);
+ specs += i;
+ numspecs -= i;
+ i = 0;
+ }
+ if (i == 0) {
+ ox = x;
+ base = new;
+ }
+ i++;
}
- i++;
+ if (i > 0)
+ xdrawglyphfontspecs(specs, base, i, ox, y1, dmode);
}
- if (i > 0)
- xdrawglyphfontspecs(specs, base, i, ox, y1);
}
void
diff --git a/x.o b/x.o
new file mode 100644
index 0000000..79d8ad4
--- /dev/null
+++ b/x.o
Binary files differ