blob: 6be3deec0ea0147217f5723af9155810758c4e71 [file] [log] [blame]
/*
* Copyright 2022 Rive
*/
#include "utils/rive_utf.hpp"
#include "rive/core/type_conversions.hpp"
using namespace rive;
int UTF::CountUTF8Length(const uint8_t utf8[]) {
unsigned lead = *utf8;
assert(lead != 0xFF);
assert((lead & 0xC0) != 0x80); // 10xxxxxx is not a legal lead byte
if ((lead & 0x80) == 0) {
return 1;
}
int n = 1;
lead <<= 1;
while (lead & 0x80) {
n += 1;
lead <<= 1;
}
assert(n >= 1 && n <= 4);
return n;
}
// Return the unichar pointed to by the utf8 pointer, and then
// update the pointer to point to the next sequence.
Unichar UTF::NextUTF8(const uint8_t** utf8Ptr) {
const uint8_t* text = *utf8Ptr;
uint32_t c = 0;
int n = CountUTF8Length(text);
assert(n >= 1 && n <= 4);
unsigned first = *text++;
if (n == 1) {
c = first;
} else {
c = first & ((unsigned)0xFF >> n);
--n;
do {
c = (c << 6) | (*text++ & 0x3F);
} while (--n);
}
*utf8Ptr = text; // update the pointer
return c;
}
int UTF::ToUTF16(Unichar uni, uint16_t utf16[]) {
if (uni > 0xFFFF) {
utf16[0] = castTo<uint16_t>((0xD800 - 64) | (uni >> 10));
utf16[1] = castTo<uint16_t>(0xDC00 | (uni & 0x3FF));
return 2;
}
utf16[0] = castTo<uint16_t>(uni);
return 1;
}