18a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/* 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2006 The Android Open Source Project 38a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 68a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 78a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifndef SkUtils_DEFINED 98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkUtils_DEFINED 108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkTypes.h" 12d1c8e56423f4d1a879f3a7bcd24e2725d9b690a7Hal Canary#include "SkMath.h" 1387db00111596d432908882a13982adde79793a7cMike Klein#include "SkOpts.h" 14bdb34d0345748f424e3c787ad9bbef04134c7e3bmtklein 1557bc1e7bc804be4779dd09409046f62c4d43e3cdMike Klein/** Similar to memset(), but it assigns a 16, 32, or 64-bit value into the buffer. 168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @param buffer The memory to have value copied into it 1757bc1e7bc804be4779dd09409046f62c4d43e3cdMike Klein @param value The value to be copied into buffer 188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @param count The number of times value should be copied into the buffer. 198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 2087db00111596d432908882a13982adde79793a7cMike Kleinstatic inline void sk_memset16(uint16_t buffer[], uint16_t value, int count) { 2187db00111596d432908882a13982adde79793a7cMike Klein SkOpts::memset16(buffer, value, count); 2287db00111596d432908882a13982adde79793a7cMike Klein} 2387db00111596d432908882a13982adde79793a7cMike Kleinstatic inline void sk_memset32(uint32_t buffer[], uint32_t value, int count) { 2487db00111596d432908882a13982adde79793a7cMike Klein SkOpts::memset32(buffer, value, count); 2587db00111596d432908882a13982adde79793a7cMike Klein} 2687db00111596d432908882a13982adde79793a7cMike Kleinstatic inline void sk_memset64(uint64_t buffer[], uint64_t value, int count) { 2787db00111596d432908882a13982adde79793a7cMike Klein SkOpts::memset64(buffer, value, count); 2887db00111596d432908882a13982adde79793a7cMike Klein} 294e1d3acc16edb0b502cff157978235f5af627a5amike@reedtribe.org/////////////////////////////////////////////////////////////////////////////// 308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define kMaxBytesInUTF8Sequence 4 328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_DEBUG 348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int SkUTF8_LeadByteToCount(unsigned c); 358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#else 368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define SkUTF8_LeadByteToCount(c) ((((0xE5 << 24) >> ((unsigned)c >> 4 << 1)) & 3) + 1) 378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 394e1d3acc16edb0b502cff157978235f5af627a5amike@reedtribe.orginline int SkUTF8_CountUTF8Bytes(const char utf8[]) { 408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(utf8); 418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return SkUTF8_LeadByteToCount(*(const uint8_t*)utf8); 428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkUTF8_CountUnichars(const char utf8[]); 45d1c8e56423f4d1a879f3a7bcd24e2725d9b690a7Hal Canary 46889d521d8715f4934accb630097bc09bf7ad1a32Mike Reed/** These functions are safe: invalid sequences will return -1; */ 47889d521d8715f4934accb630097bc09bf7ad1a32Mike Reedint SkUTF8_CountUnichars(const void* utf8, size_t byteLength); 48889d521d8715f4934accb630097bc09bf7ad1a32Mike Reedint SkUTF16_CountUnichars(const void* utf16, size_t byteLength); 49889d521d8715f4934accb630097bc09bf7ad1a32Mike Reedint SkUTF32_CountUnichars(const void* utf32, size_t byteLength); 50d1c8e56423f4d1a879f3a7bcd24e2725d9b690a7Hal Canary 51d1c8e56423f4d1a879f3a7bcd24e2725d9b690a7Hal Canary/** This function is safe: invalid UTF8 sequences will return -1 52d1c8e56423f4d1a879f3a7bcd24e2725d9b690a7Hal Canary * When -1 is returned, ptr is unchanged. 53d1c8e56423f4d1a879f3a7bcd24e2725d9b690a7Hal Canary * Precondition: *ptr < end; 54d1c8e56423f4d1a879f3a7bcd24e2725d9b690a7Hal Canary */ 55d1c8e56423f4d1a879f3a7bcd24e2725d9b690a7Hal CanarySkUnichar SkUTF8_NextUnicharWithError(const char** ptr, const char* end); 56d1c8e56423f4d1a879f3a7bcd24e2725d9b690a7Hal Canary 57d1c8e56423f4d1a879f3a7bcd24e2725d9b690a7Hal Canary/** this version replaces invalid utf-8 sequences with code point U+FFFD. */ 58d1c8e56423f4d1a879f3a7bcd24e2725d9b690a7Hal Canaryinline SkUnichar SkUTF8_NextUnichar(const char** ptr, const char* end) { 59d1c8e56423f4d1a879f3a7bcd24e2725d9b690a7Hal Canary SkUnichar val = SkUTF8_NextUnicharWithError(ptr, end); 60d1c8e56423f4d1a879f3a7bcd24e2725d9b690a7Hal Canary if (val < 0) { 61d1c8e56423f4d1a879f3a7bcd24e2725d9b690a7Hal Canary *ptr = end; 62d1c8e56423f4d1a879f3a7bcd24e2725d9b690a7Hal Canary return 0xFFFD; // REPLACEMENT CHARACTER 63d1c8e56423f4d1a879f3a7bcd24e2725d9b690a7Hal Canary } 64d1c8e56423f4d1a879f3a7bcd24e2725d9b690a7Hal Canary return val; 65d1c8e56423f4d1a879f3a7bcd24e2725d9b690a7Hal Canary} 66d1c8e56423f4d1a879f3a7bcd24e2725d9b690a7Hal Canary 678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkUnichar SkUTF8_ToUnichar(const char utf8[]); 688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkUnichar SkUTF8_NextUnichar(const char**); 698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkUnichar SkUTF8_PrevUnichar(const char**); 708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** Return the number of bytes need to convert a unichar 728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com into a utf8 sequence. Will be 1..kMaxBytesInUTF8Sequence, 738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com or 0 if uni is illegal. 748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 75a93a14a99816d25b773f0b12868143702baf44bfBen Wagnersize_t SkUTF8_FromUnichar(SkUnichar uni, char utf8[] = nullptr); 768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkUTF16_IsHighSurrogate(c) (((c) & 0xFC00) == 0xD800) 808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkUTF16_IsLowSurrogate(c) (((c) & 0xFC00) == 0xDC00) 818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkUTF16_CountUnichars(const uint16_t utf16[]); 838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// returns the current unichar and then moves past it (*p++) 848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkUnichar SkUTF16_NextUnichar(const uint16_t**); 858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// this guy backs up to the previus unichar value, and returns it (*--p) 868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkUnichar SkUTF16_PrevUnichar(const uint16_t**); 87a93a14a99816d25b773f0b12868143702baf44bfBen Wagnersize_t SkUTF16_FromUnichar(SkUnichar uni, uint16_t utf16[] = nullptr); 888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comsize_t SkUTF16_ToUTF8(const uint16_t utf16[], int numberOf16BitValues, 90a93a14a99816d25b773f0b12868143702baf44bfBen Wagner char utf8[] = nullptr); 918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 92cf4b8181c9bbeb0273dc7459163552bd42a6518dreed@google.cominline bool SkUnichar_IsVariationSelector(SkUnichar uni) { 93419f43348ab6c9226b82490d41c736230ae3bf41reed@google.com/* The 'true' ranges are: 94419f43348ab6c9226b82490d41c736230ae3bf41reed@google.com * 0x180B <= uni <= 0x180D 95419f43348ab6c9226b82490d41c736230ae3bf41reed@google.com * 0xFE00 <= uni <= 0xFE0F 96419f43348ab6c9226b82490d41c736230ae3bf41reed@google.com * 0xE0100 <= uni <= 0xE01EF 97419f43348ab6c9226b82490d41c736230ae3bf41reed@google.com */ 98419f43348ab6c9226b82490d41c736230ae3bf41reed@google.com if (uni < 0x180B || uni > 0xE01EF) { 99419f43348ab6c9226b82490d41c736230ae3bf41reed@google.com return false; 100419f43348ab6c9226b82490d41c736230ae3bf41reed@google.com } 101419f43348ab6c9226b82490d41c736230ae3bf41reed@google.com if ((uni > 0x180D && uni < 0xFE00) || (uni > 0xFE0F && uni < 0xE0100)) { 102419f43348ab6c9226b82490d41c736230ae3bf41reed@google.com return false; 103419f43348ab6c9226b82490d41c736230ae3bf41reed@google.com } 104419f43348ab6c9226b82490d41c736230ae3bf41reed@google.com return true; 105419f43348ab6c9226b82490d41c736230ae3bf41reed@google.com} 106d6e6e6699a85c6ed79e7d3b01e30d19e361ae049Hal Canary 107d6e6e6699a85c6ed79e7d3b01e30d19e361ae049Hal Canarynamespace SkHexadecimalDigits { 108d6e6e6699a85c6ed79e7d3b01e30d19e361ae049Hal Canary extern const char gUpper[16]; // 0-9A-F 109d6e6e6699a85c6ed79e7d3b01e30d19e361ae049Hal Canary extern const char gLower[16]; // 0-9a-f 110d6e6e6699a85c6ed79e7d3b01e30d19e361ae049Hal Canary} 111d6e6e6699a85c6ed79e7d3b01e30d19e361ae049Hal Canary 1128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 113