1/*
2 * Copyright 2022 Google LLC
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "modules/skunicode/include/SkUnicode.h"
9
10#include "include/private/SkBitmaskEnum.h"
11#include "include/private/SkTemplates.h"
12
13
14std::unique_ptr<SkUnicode> SkUnicode::Make() {
15#ifdef SK_UNICODE_ICU_IMPLEMENTATION
16    std::unique_ptr<SkUnicode> unicode = SkUnicode::MakeIcuBasedUnicode();
17    if (unicode) {
18        return unicode;
19    }
20#endif
21    return nullptr;
22}
23
24std::unique_ptr<SkUnicode> MakeClientBasedUnicode(
25        SkSpan<char> text,
26        std::vector<SkUnicode::Position> words,
27        std::vector<SkUnicode::Position> graphemeBreaks,
28        std::vector<SkUnicode::LineBreakBefore> lineBreaks) {
29#ifdef SK_UNICODE_CLIENT_IMPLEMENTATION
30    std::unique_ptr<SkUnicode> unicode =
31            SkUnicode::MakeClientBasedUnicode(text, words, graphemeBreaks, lineBreaks);
32    if (unicode) {
33        return unicode;
34    }
35#endif
36    return nullptr;
37}
38
39SkString SkUnicode::convertUtf16ToUtf8(const char16_t* utf16, int utf16Units) {
40
41    int utf8Units = SkUTF::UTF16ToUTF8(nullptr, 0, (uint16_t*)utf16, utf16Units);
42    if (utf8Units < 0) {
43        SkDEBUGF("Convert error: Invalid utf16 input");
44        return SkString();
45    }
46    SkAutoTArray<char> utf8(utf8Units);
47    SkDEBUGCODE(int dstLen =) SkUTF::UTF16ToUTF8(utf8.data(), utf8Units, (uint16_t*)utf16, utf16Units);
48    SkASSERT(dstLen == utf8Units);
49
50    return SkString(utf8.data(), utf8Units);
51}
52
53SkString SkUnicode::convertUtf16ToUtf8(const std::u16string& utf16) {
54    return convertUtf16ToUtf8(utf16.c_str(), utf16.size());
55}
56
57std::u16string SkUnicode::convertUtf8ToUtf16(const char* utf8, int utf8Units) {
58
59    int utf16Units = SkUTF::UTF8ToUTF16(nullptr, 0, utf8, utf8Units);
60    if (utf16Units < 0) {
61        SkDEBUGF("Convert error: Invalid utf8 input");
62        return std::u16string();
63    }
64
65    SkAutoTArray<uint16_t> utf16(utf16Units);
66    SkDEBUGCODE(int dstLen =) SkUTF::UTF8ToUTF16(utf16.data(), utf16Units, utf8, utf8Units);
67    SkASSERT(dstLen == utf16Units);
68
69    return std::u16string((char16_t *)utf16.data(), utf16Units);
70}
71
72std::u16string SkUnicode::convertUtf8ToUtf16(const SkString& utf8) {
73    return convertUtf8ToUtf16(utf8.c_str(), utf8.size());
74}
75
76bool SkUnicode::isTabulation(SkUnicode::CodeUnitFlags flags) {
77    return (flags & SkUnicode::kTabulation) == SkUnicode::kTabulation;
78}
79
80bool SkUnicode::isHardLineBreak(SkUnicode::CodeUnitFlags flags) {
81    return (flags & SkUnicode::kHardLineBreakBefore) == SkUnicode::kHardLineBreakBefore;
82}
83
84bool SkUnicode::isSoftLineBreak(SkUnicode::CodeUnitFlags flags) {
85    return (flags & SkUnicode::kSoftLineBreakBefore) == SkUnicode::kSoftLineBreakBefore;
86}
87
88bool SkUnicode::isGraphemeStart(SkUnicode::CodeUnitFlags flags) {
89    return (flags & SkUnicode::kGraphemeStart) == SkUnicode::kGraphemeStart;
90}
91
92bool SkUnicode::isControl(SkUnicode::CodeUnitFlags flags) {
93    return (flags & SkUnicode::kControl) == SkUnicode::kControl;
94}
95
96bool SkUnicode::isPartOfWhiteSpaceBreak(SkUnicode::CodeUnitFlags flags) {
97    return (flags & SkUnicode::kPartOfWhiteSpaceBreak) == SkUnicode::kPartOfWhiteSpaceBreak;
98}
99