const uint8_t * u8_grapheme_next (const uint8_t *s, const uint8_t *end) { ucs4_t prev; int mblen; if (s == end) return NULL; for (s += u8_mbtouc (&prev, s, end - s); s != end; s += mblen) { ucs4_t next; mblen = u8_mbtouc (&next, s, end - s); if (uc_is_grapheme_break (prev, next)) break; prev = next; } return s; }
const uint8_t * u8_grapheme_prev (const uint8_t *s, const uint8_t *start) { ucs4_t next; if (s == start) return NULL; s = u8_prev (&next, s, start); while (s != start) { const uint8_t *prev_s; ucs4_t prev; prev_s = u8_prev (&prev, s, start); if (prev_s == NULL) { /* Ill-formed UTF-8 encoding. */ return start; } if (uc_is_grapheme_break (prev, next)) break; s = prev_s; next = prev; } return s; }
const uint32_t * u32_grapheme_prev (const uint32_t *s, const uint32_t *start) { ucs4_t next; if (s == start) return NULL; u32_prev (&next, s, start); for (s--; s != start; s--) { ucs4_t prev; if (u32_prev (&prev, s, start) == NULL) { /* Ill-formed UTF-32 encoding. */ return start; } if (uc_is_grapheme_break (prev, next)) break; next = prev; } return s; }
void u16_grapheme_breaks (const uint16_t *s, size_t n, char *p) { ucs4_t prev; int mblen; prev = 0; for (; n > 0; s += mblen, p += mblen, n -= mblen) { ucs4_t next; mblen = u16_mbtouc (&next, s, n); p[0] = uc_is_grapheme_break (prev, next); if (mblen > 1) p[1] = 0; prev = next; } }
void u8_grapheme_breaks (const uint8_t *s, size_t n, char *p) { ucs4_t prev; int mblen; prev = 0; for (; n > 0; s += mblen, p += mblen, n -= mblen) { ucs4_t next; int i; mblen = u8_mbtouc (&next, s, n); p[0] = uc_is_grapheme_break (prev, next); for (i = 1; i < mblen; i++) p[i] = 0; prev = next; } }
const uint32_t * u32_grapheme_next (const uint32_t *s, const uint32_t *end) { ucs4_t prev; if (s == end) return NULL; u32_mbtouc (&prev, s, end - s); for (s++; s != end; s++) { ucs4_t next; u32_mbtouc (&next, s, end - s); if (uc_is_grapheme_break (prev, next)) break; prev = next; } return s; }