• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 * Copyright 2025 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 #include "modules/skunicode/include/SkUnicode_bidi.h"
8 
9 #include "include/core/SkSpan.h"
10 #include "include/core/SkString.h"
11 #include "include/core/SkTypes.h"
12 #include "include/private/base/SkTArray.h"
13 #include "include/private/base/SkTo.h"
14 #include "modules/skunicode/include/SkUnicode.h"
15 #include "modules/skunicode/src/SkBidiFactory_icu_subset.h"
16 #include "modules/skunicode/src/SkUnicode_hardcoded.h"
17 #include "modules/skunicode/src/SkUnicode_icu_bidi.h"
18 #include "src/base/SkBitmaskEnum.h"
19 #include "src/base/SkUTF.h"
20 
21 #include <algorithm>
22 #include <cstdint>
23 #include <memory>
24 #include <string>
25 #include <utility>
26 #include <vector>
27 #include <array>
28 #include <unicode/ubidi.h>
29 #include <unicode/ubrk.h>
30 #include <unicode/uchar.h>
31 #include <unicode/uloc.h>
32 #include <unicode/uscript.h>
33 #include <unicode/ustring.h>
34 #include <unicode/utext.h>
35 #include <unicode/utypes.h>
36 
37 using namespace skia_private;
38 
39 class SkUnicode_bidi : public SkUnicodeHardCodedCharProperties {
40 public:
SkUnicode_bidi()41     SkUnicode_bidi() {}
42     ~SkUnicode_bidi() override = default;
43 
makeBidiIterator(const uint16_t text[],int count,SkBidiIterator::Direction dir)44     std::unique_ptr<SkBidiIterator> makeBidiIterator(const uint16_t text[], int count,
45                                                      SkBidiIterator::Direction dir) override {
46         return fBidiFact->MakeIterator(text, count, dir);
47     }
makeBidiIterator(const char text[],int count,SkBidiIterator::Direction dir)48     std::unique_ptr<SkBidiIterator> makeBidiIterator(const char text[],
49                                                      int count,
50                                                      SkBidiIterator::Direction dir) override {
51         SkDEBUGF("Method 'makeBidiIterator' is not implemented\n");
52         return nullptr;
53     }
makeBreakIterator(const char locale[],BreakType breakType)54     std::unique_ptr<SkBreakIterator> makeBreakIterator(const char locale[],
55                                                        BreakType breakType) override {
56         SkDEBUGF("Method 'makeBreakIterator' is not implemented\n");
57         return nullptr;
58     }
makeBreakIterator(BreakType breakType)59     std::unique_ptr<SkBreakIterator> makeBreakIterator(BreakType breakType) override {
60         SkDEBUGF("Method 'makeBreakIterator' is not implemented\n");
61         return nullptr;
62     }
63 
getBidiRegions(const char utf8[],int utf8Units,TextDirection dir,std::vector<BidiRegion> * results)64     bool getBidiRegions(const char utf8[],
65                         int utf8Units,
66                         TextDirection dir,
67                         std::vector<BidiRegion>* results) override {
68         return fBidiFact->ExtractBidi(utf8, utf8Units, dir, results);
69     }
70 
getUtf8Words(const char utf8[],int utf8Units,const char * locale,std::vector<Position> * results)71     bool getUtf8Words(const char utf8[],
72                       int utf8Units,
73                       const char* locale,
74                       std::vector<Position>* results) override {
75         SkDEBUGF("Method 'getUtf8Words' is not implemented\n");
76         return false;
77     }
78 
getSentences(const char utf8[],int utf8Units,const char * locale,std::vector<SkUnicode::Position> * results)79     bool getSentences(const char utf8[],
80                       int utf8Units,
81                       const char* locale,
82                       std::vector<SkUnicode::Position>* results) override {
83         SkDEBUGF("Method 'getSentences' is not implemented\n");
84         return false;
85     }
86 
computeCodeUnitFlags(char utf8[],int utf8Units,bool replaceTabs,TArray<SkUnicode::CodeUnitFlags,true> * results)87     bool computeCodeUnitFlags(char utf8[],
88                               int utf8Units,
89                               bool replaceTabs,
90                               TArray<SkUnicode::CodeUnitFlags, true>* results) override {
91         SkDEBUGF("Method 'computeCodeUnitFlags' is not implemented\n");
92         return false;
93     }
94 
computeCodeUnitFlags(char16_t utf16[],int utf16Units,bool replaceTabs,TArray<SkUnicode::CodeUnitFlags,true> * results)95     bool computeCodeUnitFlags(char16_t utf16[], int utf16Units, bool replaceTabs,
96                           TArray<SkUnicode::CodeUnitFlags, true>* results) override {
97         results->clear();
98         results->push_back_n(utf16Units + 1, CodeUnitFlags::kNoCodeUnitFlag);
99         for (auto i = 0; i < utf16Units; ++i) {
100             auto unichar = utf16[i];
101             if (this->isSpace(unichar)) {
102                 results->at(i) |= SkUnicode::kPartOfIntraWordBreak;
103             }
104             if (this->isWhitespace(unichar)) {
105                 results->at(i) |= SkUnicode::kPartOfWhiteSpaceBreak;
106             }
107             if (this->isControl(unichar)) {
108                 results->at(i) |= SkUnicode::kControl;
109             }
110             if (this->isIdeographic(unichar)) {
111                 results->at(i) |= SkUnicode::kIdeographic;
112             }
113         }
114         return true;
115     }
116 
getWords(const char utf8[],int utf8Units,const char * locale,std::vector<Position> * results)117     bool getWords(const char utf8[], int utf8Units, const char* locale, std::vector<Position>* results) override {
118         SkDEBUGF("Method 'getWords' is not implemented\n");
119         return false;
120     }
121 
toUpper(const SkString & str)122     SkString toUpper(const SkString& str) override {
123         SkDEBUGF("Method 'toUpper' is not implemented\n");
124         return SkString();
125     }
126 
toUpper(const SkString & str,const char * locale)127     SkString toUpper(const SkString& str, const char* locale) override {
128         SkDEBUGF("Method 'toUpper' is not implemented\n");
129         return SkString();
130     }
131 
reorderVisual(const BidiLevel runLevels[],int levelsCount,int32_t logicalFromVisual[])132     void reorderVisual(const BidiLevel runLevels[],
133                        int levelsCount,
134                        int32_t logicalFromVisual[]) override {
135         fBidiFact->bidi_reorderVisual(runLevels, levelsCount, logicalFromVisual);
136     }
137 
138 private:
139     sk_sp<SkBidiFactory> fBidiFact = sk_make_sp<SkBidiSubsetFactory>();
140 };
141 
142 namespace SkUnicodes::Bidi {
Make()143     sk_sp<SkUnicode> Make() {
144         return sk_make_sp<SkUnicode_bidi>();
145     }
146 }
147