diff options
Diffstat (limited to 'src/width.c')
| -rw-r--r-- | src/width.c | 70 |
1 files changed, 0 insertions, 70 deletions
diff --git a/src/width.c b/src/width.c deleted file mode 100644 index 1e893f6..0000000 --- a/src/width.c +++ /dev/null @@ -1,70 +0,0 @@ -#include "vega.h" - -typedef struct { uint32_t first, last; } Range; - -/* Zero-width: combining marks, Hangul vowel and final jamo, joiners, - * variation selectors, format characters. */ -static const Range zero[] = { - {0x0300, 0x036F}, {0x0483, 0x0489}, {0x0591, 0x05BD}, {0x0610, 0x061A}, {0x064B, 0x065F}, {0x0E31, 0x0E31}, - {0x0E34, 0x0E3A}, {0x0E47, 0x0E4E}, {0x1160, 0x11FF}, {0x1AB0, 0x1AFF}, {0x1DC0, 0x1DFF}, {0x200B, 0x200F}, - {0x202A, 0x202E}, {0x2060, 0x2064}, {0x20D0, 0x20FF}, {0x302A, 0x302F}, {0x3099, 0x309A}, {0xD7B0, 0xD7FF}, - {0xFE00, 0xFE0F}, {0xFE20, 0xFE2F}, {0xFEFF, 0xFEFF}, {0x1F3FB, 0x1F3FF}, {0xE0000, 0xE0FFF}, -}; - -/* East Asian Wide and Fullwidth, and emoji shown as pictures. */ -static const Range wide[] = { - {0x1100, 0x115F}, {0x231A, 0x231B}, {0x2329, 0x232A}, {0x23E9, 0x23EC}, {0x23F0, 0x23F0}, {0x23F3, 0x23F3}, - {0x25FD, 0x25FE}, {0x2614, 0x2615}, {0x2648, 0x2653}, {0x267F, 0x267F}, {0x2693, 0x2693}, {0x26A1, 0x26A1}, - {0x26AA, 0x26AB}, {0x26BD, 0x26BE}, {0x26C4, 0x26C5}, {0x26CE, 0x26CE}, {0x26D4, 0x26D4}, {0x26EA, 0x26EA}, - {0x26F2, 0x26F3}, {0x26F5, 0x26F5}, {0x26FA, 0x26FA}, {0x26FD, 0x26FD}, {0x2705, 0x2705}, {0x270A, 0x270B}, - {0x2728, 0x2728}, {0x274C, 0x274C}, {0x274E, 0x274E}, {0x2753, 0x2755}, {0x2757, 0x2757}, {0x2795, 0x2797}, - {0x27B0, 0x27B0}, {0x27BF, 0x27BF}, {0x2B1B, 0x2B1C}, {0x2B50, 0x2B50}, {0x2B55, 0x2B55}, {0x2E80, 0x303E}, - {0x3041, 0x33FF}, {0x3400, 0x4DBF}, {0x4E00, 0x9FFF}, {0xA000, 0xA4CF}, {0xA960, 0xA97F}, {0xAC00, 0xD7A3}, - {0xF900, 0xFAFF}, {0xFE10, 0xFE19}, {0xFE30, 0xFE6F}, {0xFF00, 0xFF60}, {0xFFE0, 0xFFE6}, {0x16FE0, 0x16FE4}, - {0x17000, 0x18CFF}, {0x1B000, 0x1B2FF}, {0x1F004, 0x1F004}, {0x1F0CF, 0x1F0CF}, {0x1F18E, 0x1F18E}, - {0x1F191, 0x1F19A}, {0x1F200, 0x1F251}, {0x1F300, 0x1F64F}, {0x1F680, 0x1F6FF}, {0x1F7E0, 0x1F7EB}, - {0x1F90C, 0x1F9FF}, {0x1FA70, 0x1FAFF}, {0x20000, 0x2FFFD}, {0x30000, 0x3FFFD}, -}; - -static bool in(const Range *ranges, size_t count, uint32_t codepoint) { - size_t low = 0, high = count; - while (low < high) { - size_t middle = (low + high) / 2; - if (codepoint < ranges[middle].first) high = middle; - else if (codepoint > ranges[middle].last) low = middle + 1; - else return true; - } - return false; -} - -unsigned vega_width(uint32_t codepoint) { - if (in(zero, sizeof(zero) / sizeof(*zero), codepoint)) return 0; - return in(wide, sizeof(wide) / sizeof(*wide), codepoint) ? 2 : 1; -} - -uint32_t vega_visible(uint32_t codepoint) { - if (codepoint < 0x20) return 0x2400 + codepoint; - if (codepoint == 0x7F) return 0x2421; - if (codepoint >= 0x80 && codepoint < 0xA0) return 0xFFFD; - return codepoint; -} - -size_t vega_decode(const char *text, size_t length, size_t at, uint32_t *codepoint) { - const unsigned char *p = (const unsigned char *)text + at; - size_t left = length - at, need = p[0] < 0x80 ? 1 : p[0] < 0xE0 ? 2 : p[0] < 0xF0 ? 3 : 4; - if (need > left) { *codepoint = 0xFFFD; return left; } - uint32_t value = need == 1 ? p[0] : need == 2 ? p[0] & 0x1Fu : need == 3 ? p[0] & 0x0Fu : p[0] & 0x07u; - for (size_t i = 1; i < need; ++i) value = value << 6 | (p[i] & 0x3Fu); - *codepoint = value; - return need; -} - -unsigned vega_text_width(const char *text, size_t length) { - unsigned width = 0; - for (size_t at = 0; at < length;) { - uint32_t codepoint; - at += vega_decode(text, length, at, &codepoint); - width += vega_width(vega_visible(codepoint)); - } - return width; -} |
