add font2 patch for nerdfont glyphs and terminus font, because the terminus nerd font is refarted

This commit is contained in:
lucy 2026-02-28 14:16:32 +01:00
parent 4c04bb3e66
commit 60de33724f
6 changed files with 250 additions and 121 deletions

View File

@ -6,6 +6,12 @@
* font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html
*/
static char *font = "Liberation Mono:pixelsize=12:antialias=true:autohint=true";
/* Spare fonts */
static char *font2[] = {
/* "Inconsolata for Powerline:pixelsize=12:antialias=true:autohint=true", */
/* "Hack Nerd Font Mono:pixelsize=11:antialias=true:autohint=true", */
};
static int borderpx = 2;
/*

View File

@ -6,6 +6,9 @@
* font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html
*/
static char *font = "Terminus:pixelsize=14";
static char *font2[] = {
"Symbols Nerd Font:pixelsize=14"
};
static int borderpx = 14;
/*

BIN
st

Binary file not shown.

101
x.c
View File

@ -160,6 +160,8 @@ static void xhints(void);
static int xloadcolor(int, const char *, Color *);
static int xloadfont(Font *, FcPattern *);
static void xloadfonts(const char *, double);
static int xloadsparefont(FcPattern *, int);
static void xloadsparefonts(void);
static void xunloadfont(Font *);
static void xunloadfonts(void);
static void xsetenv(void);
@ -309,6 +311,7 @@ zoomabs(const Arg *arg)
{
xunloadfonts();
xloadfonts(usedfont, arg->f);
xloadsparefonts();
cresize(0, 0);
redraw();
xhints();
@ -1063,6 +1066,101 @@ xloadfonts(const char *fontstr, double fontsize)
FcPatternDestroy(pattern);
}
int
xloadsparefont(FcPattern *pattern, int flags)
{
FcPattern *match;
FcResult result;
match = FcFontMatch(NULL, pattern, &result);
if (!match) {
return 1;
}
if (!(frc[frclen].font = XftFontOpenPattern(xw.dpy, match))) {
FcPatternDestroy(match);
return 1;
}
frc[frclen].flags = flags;
/* Believe U+0000 glyph will present in each default font */
frc[frclen].unicodep = 0;
frclen++;
return 0;
}
void
xloadsparefonts(void)
{
FcPattern *pattern;
double sizeshift, fontval;
int fc;
char **fp;
if (frclen != 0)
die("can't embed spare fonts. cache isn't empty");
/* Calculate count of spare fonts */
fc = sizeof(font2) / sizeof(*font2);
if (fc == 0)
return;
/* Allocate memory for cache entries. */
if (frccap < 4 * fc) {
frccap += 4 * fc - frccap;
frc = xrealloc(frc, frccap * sizeof(Fontcache));
}
for (fp = font2; fp - font2 < fc; ++fp) {
if (**fp == '-')
pattern = XftXlfdParse(*fp, False, False);
else
pattern = FcNameParse((FcChar8 *)*fp);
if (!pattern)
die("can't open spare font %s\n", *fp);
if (defaultfontsize > 0) {
sizeshift = usedfontsize - defaultfontsize;
if (sizeshift != 0 &&
FcPatternGetDouble(pattern, FC_PIXEL_SIZE, 0, &fontval) ==
FcResultMatch) {
fontval += sizeshift;
FcPatternDel(pattern, FC_PIXEL_SIZE);
FcPatternDel(pattern, FC_SIZE);
FcPatternAddDouble(pattern, FC_PIXEL_SIZE, fontval);
}
}
FcPatternAddBool(pattern, FC_SCALABLE, 1);
FcConfigSubstitute(NULL, pattern, FcMatchPattern);
XftDefaultSubstitute(xw.dpy, xw.scr, pattern);
if (xloadsparefont(pattern, FRC_NORMAL))
die("can't open spare font %s\n", *fp);
FcPatternDel(pattern, FC_SLANT);
FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ITALIC);
if (xloadsparefont(pattern, FRC_ITALIC))
die("can't open spare font %s\n", *fp);
FcPatternDel(pattern, FC_WEIGHT);
FcPatternAddInteger(pattern, FC_WEIGHT, FC_WEIGHT_BOLD);
if (xloadsparefont(pattern, FRC_ITALICBOLD))
die("can't open spare font %s\n", *fp);
FcPatternDel(pattern, FC_SLANT);
FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ROMAN);
if (xloadsparefont(pattern, FRC_BOLD))
die("can't open spare font %s\n", *fp);
FcPatternDestroy(pattern);
}
}
void
xunloadfont(Font *f)
{
@ -1177,6 +1275,9 @@ xinit(int cols, int rows)
usedfont = (opt_font == NULL)? font : opt_font;
xloadfonts(usedfont, 0);
/* spare fonts */
xloadsparefonts();
/* colors */
xw.cmap = XCreateColormap(xw.dpy, parent, xw.vis, None);
xloadcols();

133
x.c.orig
View File

@ -19,6 +19,7 @@ char *argv0;
#include "arg.h"
#include "st.h"
#include "win.h"
#include "hb.h"
/* types used in config.h */
typedef struct {
@ -142,8 +143,9 @@ typedef struct {
} DC;
static inline ushort sixd_to_16bit(int);
static void xresetfontsettings(ushort mode, Font **font, int *frcflags);
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);
@ -758,7 +760,7 @@ xresize(int col, int row)
xclear(0, 0, win.w, win.h);
/* resize to new width */
xw.specbuf = xrealloc(xw.specbuf, col * sizeof(GlyphFontSpec));
xw.specbuf = xrealloc(xw.specbuf, col * sizeof(GlyphFontSpec) * 4);
}
ushort
@ -1073,6 +1075,9 @@ xunloadfont(Font *f)
void
xunloadfonts(void)
{
/* Clear Harfbuzz font cache. */
hbunloadfonts();
/* Free the loaded fonts in the font cache. */
while (frclen > 0)
XftFontClose(xw.dpy, frc[--frclen].font);
@ -1210,7 +1215,7 @@ xinit(int cols, int rows)
XFillRectangle(xw.dpy, xw.buf, dc.gc, 0, 0, win.w, win.h);
/* font spec buffer */
xw.specbuf = xmalloc(cols * sizeof(GlyphFontSpec));
xw.specbuf = xmalloc(cols * sizeof(GlyphFontSpec) * 4);
/* Xft rendering context */
xw.draw = XftDrawCreate(xw.dpy, xw.buf, xw.vis, xw.cmap);
@ -1264,63 +1269,73 @@ xinit(int cols, int rows)
xsel.xtarget = XA_STRING;
}
void
xresetfontsettings(ushort mode, Font **font, int *frcflags)
{
*font = &dc.font;
if ((mode & ATTR_ITALIC) && (mode & ATTR_BOLD)) {
*font = &dc.ibfont;
*frcflags = FRC_ITALICBOLD;
} else if (mode & ATTR_ITALIC) {
*font = &dc.ifont;
*frcflags = FRC_ITALIC;
} else if (mode & ATTR_BOLD) {
*font = &dc.bfont;
*frcflags = FRC_BOLD;
}
}
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;
ushort mode, prevmode = USHRT_MAX;
ushort mode = glyphs[0].mode & ~ATTR_WRAP;
Font *font = &dc.font;
int frcflags = FRC_NORMAL;
float runewidth = win.cw;
float runewidth = win.cw * ((glyphs[0].mode & ATTR_WIDE) ? 2.0f : 1.0f);
Rune rune;
FT_UInt glyphidx;
FcResult fcres;
FcPattern *fcpattern, *fontpattern;
FcFontSet *fcsets[] = { NULL };
FcCharSet *fccharset;
int i, f, numspecs = 0;
int f, code_idx, numspecs = 0;
float cluster_xp = xp, cluster_yp = yp;
HbTransformData shaped = { 0 };
for (i = 0, xp = winx, yp = winy + font->ascent; i < len; ++i) {
/* Fetch rune and mode for current glyph. */
rune = glyphs[i].u;
mode = glyphs[i].mode;
/* Initial values. */
xresetfontsettings(mode, &font, &frcflags);
/* Skip dummy wide-character spacing. */
if (mode == ATTR_WDUMMY)
/* Shape the segment. */
hbtransform(&shaped, font->match, glyphs, 0, len);
xp = winx; yp = winy + font->ascent;
cluster_xp = xp; cluster_yp = yp;
for (code_idx = 0; code_idx < shaped.count; code_idx++) {
int idx = shaped.glyphs[code_idx].cluster;
if (glyphs[idx].mode & ATTR_WDUMMY)
continue;
/* Determine font for glyph if different from previous glyph. */
if (prevmode != mode) {
prevmode = mode;
font = &dc.font;
frcflags = FRC_NORMAL;
runewidth = win.cw * ((mode & ATTR_WIDE) ? 2.0f : 1.0f);
if ((mode & ATTR_ITALIC) && (mode & ATTR_BOLD)) {
font = &dc.ibfont;
frcflags = FRC_ITALICBOLD;
} else if (mode & ATTR_ITALIC) {
font = &dc.ifont;
frcflags = FRC_ITALIC;
} else if (mode & ATTR_BOLD) {
font = &dc.bfont;
frcflags = FRC_BOLD;
}
yp = winy + font->ascent;
}
/* Lookup character index with default font. */
glyphidx = XftCharIndex(xw.dpy, font->match, rune);
if (glyphidx) {
specs[numspecs].font = font->match;
specs[numspecs].glyph = glyphidx;
specs[numspecs].x = (short)xp;
specs[numspecs].y = (short)yp;
/* Advance the drawing cursor if we've moved to a new cluster */
if (code_idx > 0 && idx != shaped.glyphs[code_idx - 1].cluster) {
xp += runewidth;
numspecs++;
continue;
cluster_xp = xp;
cluster_yp = yp;
}
/* Fallback on font cache, search the font cache for match. */
if (shaped.glyphs[code_idx].codepoint != 0) {
/* If symbol is found, put it into the specs. */
specs[numspecs].font = font->match;
specs[numspecs].glyph = shaped.glyphs[code_idx].codepoint;
specs[numspecs].x = cluster_xp + (short)(shaped.positions[code_idx].x_offset / 64.);
specs[numspecs].y = cluster_yp - (short)(shaped.positions[code_idx].y_offset / 64.);
cluster_xp += shaped.positions[code_idx].x_advance / 64.;
cluster_yp += shaped.positions[code_idx].y_advance / 64.;
numspecs++;
} else {
/* If it's not found, try to fetch it through the font cache. */
rune = glyphs[idx].u;
for (f = 0; f < frclen; f++) {
glyphidx = XftCharIndex(xw.dpy, frc[f].font, rune);
/* Everything correct. */
@ -1389,17 +1404,18 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x
specs[numspecs].glyph = glyphidx;
specs[numspecs].x = (short)xp;
specs[numspecs].y = (short)yp;
xp += runewidth;
numspecs++;
}
}
/* Cleanup and get ready for next segment. */
hbcleanup(&shaped);
return numspecs;
}
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 charlen)
{
int charlen = len * ((base.mode & ATTR_WIDE) ? 2 : 1);
int winx = borderpx + x * win.cw, winy = borderpx + y * win.ch,
width = charlen * win.cw;
Color *fg, *bg, *temp, revfg, revbg, truefg, truebg;
@ -1535,21 +1551,24 @@ void
xdrawglyph(Glyph g, int x, int y)
{
int numspecs;
XftGlyphFontSpec spec;
XftGlyphFontSpec *specs = xw.specbuf;
numspecs = xmakeglyphfontspecs(&spec, &g, 1, x, y);
xdrawglyphfontspecs(&spec, g, numspecs, x, y);
numspecs = xmakeglyphfontspecs(specs, &g, 1, x, y);
xdrawglyphfontspecs(specs, g, numspecs, x, y, (g.mode & ATTR_WIDE) ? 2 : 1);
}
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 the ligatures broken by the cursor. */
xdrawline(line, 0, oy, len);
if (IS_SET(MODE_HIDE))
return;
@ -1683,18 +1702,16 @@ xdrawline(Line line, int x1, int y1, int x2)
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++) {
for (x = x1; x < x2; 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;
if ((i > 0) && ATTRCMP(base, new)) {
numspecs = xmakeglyphfontspecs(specs, &line[ox], x - ox, ox, y1);
xdrawglyphfontspecs(specs, base, numspecs, ox, y1, x - ox);
i = 0;
}
if (i == 0) {
@ -1703,8 +1720,10 @@ xdrawline(Line line, int x1, int y1, int x2)
}
i++;
}
if (i > 0)
xdrawglyphfontspecs(specs, base, i, ox, y1);
if (i > 0) {
numspecs = xmakeglyphfontspecs(specs, &line[ox], x2 - ox, ox, y1);
xdrawglyphfontspecs(specs, base, numspecs, ox, y1, x2 - ox);
}
}
void

BIN
x.o

Binary file not shown.