summaryrefslogtreecommitdiffstats
path: root/util.c
diff options
context:
space:
mode:
authorSquibby <34315567+squibbysquibby@users.noreply.github.com>2017-12-06 20:56:00 +0100
committerSquibby <34315567+squibbysquibby@users.noreply.github.com>2017-12-07 00:39:07 +0100
commiteb96c7172555f96b07969c6abf74740bb03e36f9 (patch)
tree8fb39b0c1a3ee8adc46e13315409e341e2d5c028 /util.c
parentf02661879ff0efefc6751d927c2e721e64ad79f0 (diff)
downloadnsxiv-eb96c7172555f96b07969c6abf74740bb03e36f9.tar.zst
Try to match a fallback font if needed
Fixes #276 Instead of rendering the entire filename at once, Xft will let us do it character by character. This will allow sxiv to query fontconfig for a font that can provide any missing codepoints, if needed. A known issue of this patch is that the "..." dots rendering will not work properly for very long multibyte filenames. That is because we cannot easily predict the final width of the rendered filename before drawing it. I couldn't figure out a clean way to deal with this, so I ended up just truncating the offending filenames.
Diffstat (limited to 'util.c')
-rw-r--r--util.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/util.c b/util.c
index 6a236c6..973bc80 100644
--- a/util.c
+++ b/util.c
@@ -204,3 +204,32 @@ int r_mkdir(char *path)
}
return 0;
}
+
+/* copied from sheredom's utf8.h (public domain) https://github.com/sheredom/utf8.h */
+
+void* utf8codepoint(const void* __restrict__ str, long* __restrict__ out_codepoint)
+{
+ const char *s = (const char *)str;
+
+ if (0xf0 == (0xf8 & s[0])) {
+ // 4 byte utf8 codepoint
+ *out_codepoint = ((0x07 & s[0]) << 18) | ((0x3f & s[1]) << 12) |
+ ((0x3f & s[2]) << 6) | (0x3f & s[3]);
+ s += 4;
+ } else if (0xe0 == (0xf0 & s[0])) {
+ // 3 byte utf8 codepoint
+ *out_codepoint = ((0x0f & s[0]) << 12) | ((0x3f & s[1]) << 6) | (0x3f & s[2]);
+ s += 3;
+ } else if (0xc0 == (0xe0 & s[0])) {
+ // 2 byte utf8 codepoint
+ *out_codepoint = ((0x1f & s[0]) << 6) | (0x3f & s[1]);
+ s += 2;
+ } else {
+ // 1 byte utf8 codepoint otherwise
+ *out_codepoint = s[0];
+ s += 1;
+ }
+
+ return (void *)s;
+}
+