From 9f1a2db7c5978820571e7a24915cce412e8750c1 Mon Sep 17 00:00:00 2001 From: bakkeby Date: Sat, 21 Mar 2020 16:41:43 +0100 Subject: [PATCH] Adding font2 patch as per request #3 --- README.md | 7 +++- config.def.h | 10 ++++- patch/font2.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++ patch/font2.h | 2 + patch/x_include.c | 3 ++ patch/x_include.h | 3 ++ patches.def.h | 8 ++++ st.c | 1 - x.c | 25 ++++++++----- 9 files changed, 140 insertions(+), 13 deletions(-) create mode 100644 patch/font2.c create mode 100644 patch/font2.h diff --git a/README.md b/README.md index c41a87b..215e09e 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -Similar to [dwm-flexipatch](https://github.com/bakkeby/dwm-flexipatch) this st 0.8.2 project has a different take on st patching. It uses preprocessor directives to decide whether or not to include a patch during build time. Essentially this means that this build, for better or worse, contains both the patched _and_ the original code. The aim being that you can select which patches to include and the build will contain that code and nothing more. +Similar to [dwm-flexipatch](https://github.com/bakkeby/dwm-flexipatch) this st 0.8.2 (ed68fe7dce2b21b4e0e595b99d47790e76812cb7) project has a different take on st patching. It uses preprocessor directives to decide whether or not to include a patch during build time. Essentially this means that this build, for better or worse, contains both the patched _and_ the original code. The aim being that you can select which patches to include and the build will contain that code and nothing more. For example to include the `alpha` patch then you would only need to flip this setting from 0 to 1 in [patches.h](https://github.com/bakkeby/st-flexipatch/blob/master/patches.h): ```c @@ -15,6 +15,8 @@ Refer to [https://st.suckless.org/](https://st.suckless.org/) for details on the ### Changelog: +2020-03-21 - Added font2 patch + 2020-01-07 - Added st embedder patch 2019-10-16 - Introduced [flexipatch-finalizer](https://github.com/bakkeby/flexipatch-finalizer) @@ -58,6 +60,9 @@ Refer to [https://st.suckless.org/](https://st.suckless.org/) for details on the - [fix-keyboard-input](https://st.suckless.org/patches/fix_keyboard_input/) - allows cli applications to use all the fancy key combinations that are available to GUI applications + - [font2](https://st.suckless.org/patches/font2/) + - allows you to add a spare font besides the default + - [hidecursor](https://st.suckless.org/patches/hidecursor/) - hides the X cursor whenever a key is pressed and show it back when the mouse is moved in the terminal window diff --git a/config.def.h b/config.def.h index ad5f055..d8092d5 100644 --- a/config.def.h +++ b/config.def.h @@ -6,6 +6,14 @@ * font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html */ static char *font = "Liberation Mono:pixelsize=12:antialias=true:autohint=true"; +#if FONT2_PATCH +/* Spare fonts */ +static char *font2[] = { +/* "Inconsolata for Powerline:pixelsize=12:antialias=true:autohint=true", */ +/* "Hack Nerd Font Mono:pixelsize=11:antialias=true:autohint=true", */ +}; +#endif // FONT2_PATCH + #if RELATIVEBORDER_PATCH /* borderperc: percentage of cell width to use as a border * 0 = no border, 100 = border width is same as cell width */ @@ -626,4 +634,4 @@ static char ascii_printable[] = * current selection and with cwd set to the cwd of the active shell */ static char *plumb_cmd = "plumb"; -#endif // RIGHTCLICKTOPLUMB_PATCH \ No newline at end of file +#endif // RIGHTCLICKTOPLUMB_PATCH diff --git a/patch/font2.c b/patch/font2.c new file mode 100644 index 0000000..7477ced --- /dev/null +++ b/patch/font2.c @@ -0,0 +1,94 @@ +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); + } +} \ No newline at end of file diff --git a/patch/font2.h b/patch/font2.h new file mode 100644 index 0000000..c0f9ff5 --- /dev/null +++ b/patch/font2.h @@ -0,0 +1,2 @@ +static int xloadsparefont(FcPattern *, int); +static void xloadsparefonts(void); \ No newline at end of file diff --git a/patch/x_include.c b/patch/x_include.c index af9596d..85bed54 100644 --- a/patch/x_include.c +++ b/patch/x_include.c @@ -11,6 +11,9 @@ #if FIXKEYBOARDINPUT_PATCH #include "fixkeyboardinput.c" #endif +#if FONT2_PATCH +#include "font2.c" +#endif #if KEYBOARDSELECT_PATCH #include "keyboardselect_x.c" #endif diff --git a/patch/x_include.h b/patch/x_include.h index 29852fe..8d01dfe 100644 --- a/patch/x_include.h +++ b/patch/x_include.h @@ -8,6 +8,9 @@ #if FIXIME_PATCH #include "fixime_x.h" #endif +#if FONT2_PATCH +#include "font2.h" +#endif #if KEYBOARDSELECT_PATCH #include "keyboardselect_x.h" #endif diff --git a/patches.def.h b/patches.def.h index 4338cab..566e3e5 100644 --- a/patches.def.h +++ b/patches.def.h @@ -79,6 +79,14 @@ */ #define FIXKEYBOARDINPUT_PATCH 0 +/* This patch allows you to add spare font besides the default. Some glyphs can be not present in + * the default font. For this glyphs st uses font-config and try to find them in font cache first. + * This patch append fonts defined in font2 variable to the beginning of the font cache. + * So they will be used first for glyphs that are absent in the default font. + * https://st.suckless.org/patches/font2/ + */ +#define FONT2_PATCH 0 + /* Hide the X cursor whenever a key is pressed and show it back when the mouse is moved in * the terminal window. * https://st.suckless.org/patches/hidecursor/ diff --git a/st.c b/st.c index 3557ace..1ed81ff 100644 --- a/st.c +++ b/st.c @@ -2468,7 +2468,6 @@ tputc(Rune u) goto check_control_code; } - if (IS_SET(MODE_SIXEL)) { /* TODO: implement sixel mode */ return; diff --git a/x.c b/x.c index a669bcb..2fa5094 100644 --- a/x.c +++ b/x.c @@ -254,8 +254,9 @@ typedef struct { } Fontcache; /* Fontcache is an array now. A new font will be appended to the array. */ -static Fontcache frc[16]; +static Fontcache *frc = NULL; static int frclen = 0; +static int frccap = 0; static char *usedfont = NULL; static double usedfontsize = 0; static double defaultfontsize = 0; @@ -331,6 +332,9 @@ zoomabs(const Arg *arg) { xunloadfonts(); xloadfonts(usedfont, arg->f); + #if FONT2_PATCH + xloadsparefonts(); + #endif // FONT2_PATCH cresize(0, 0); redraw(); xhints(); @@ -861,7 +865,6 @@ xsetcolorname(int x, const char *name) if (!BETWEEN(x, 0, dc.collen)) return 1; - if (!xloadcolor(x, name, &ncolor)) return 1; @@ -1163,6 +1166,11 @@ xinit(int cols, int rows) usedfont = (opt_font == NULL)? font : opt_font; xloadfonts(usedfont, 0); + #if FONT2_PATCH + /* spare fonts */ + xloadsparefonts(); + #endif // FONT2_PATCH + /* colors */ #if ALPHA_PATCH xw.cmap = XCreateColormap(xw.dpy, parent, xw.vis, None); @@ -1447,14 +1455,11 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x fontpattern = FcFontSetMatch(0, fcsets, 1, fcpattern, &fcres); - /* - * Overwrite or create the new cache entry. - */ - if (frclen >= LEN(frc)) { - frclen = LEN(frc) - 1; - XftFontClose(xw.dpy, frc[frclen].font); - frc[frclen].unicodep = 0; - } + /* Allocate memory for the new cache entry. */ + if (frclen >= frccap) { + frccap += 16; + frc = xrealloc(frc, frccap * sizeof(Fontcache)); + } frc[frclen].font = XftFontOpenPattern(xw.dpy, fontpattern);