summaryrefslogtreecommitdiff
path: root/include/term/unicode/width.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/term/unicode/width.h')
-rw-r--r--include/term/unicode/width.h21
1 files changed, 11 insertions, 10 deletions
diff --git a/include/term/unicode/width.h b/include/term/unicode/width.h
index 388ae6c..a7dfe66 100644
--- a/include/term/unicode/width.h
+++ b/include/term/unicode/width.h
@@ -11,17 +11,16 @@ struct unicode_range { uint32_t lo, hi; };
static inline bool in_ranges(const struct unicode_range *ranges, size_t count, uint32_t cp)
{
- size_t lo = 0, hi = count;
- while (lo < hi) {
- size_t mid = lo + (hi - lo) / 2;
- if (cp < ranges[mid].lo)
- hi = mid;
- else if (cp > ranges[mid].hi)
- lo = mid + 1;
- else
- return true;
+ if (count == 0 || cp < ranges[0].lo || cp > ranges[count - 1].hi)
+ return false;
+ const struct unicode_range *base = ranges;
+ size_t n = count;
+ while (n > 1) {
+ size_t half = n / 2;
+ base = (base[half].lo <= cp) ? base + half : base;
+ n -= half;
}
- return false;
+ return cp <= base->hi;
}
#define IN_TABLE(table, cp) in_ranges(table, sizeof(table) / sizeof(table[0]), cp)
@@ -47,6 +46,8 @@ static inline bool unicode_emoji_presentation(uint32_t cp)
static inline bool unicode_spacing_mark(uint32_t cp)
{
+ if (cp < 0x903 || ((cp - 0xABEDu) < (0x11000u - 0xABEDu)) || cp > 0x1D281)
+ return false;
return IN_TABLE(spacing_mark, cp);
}