Flutter Engine
The Flutter Engine
Classes | Public Member Functions | Static Public Member Functions | List of all members
SkIcuBreakIteratorCache Class Referencefinal

Public Member Functions

ICUBreakIterator makeBreakIterator (SkUnicode::BreakType type, const char *bcp47)
 

Static Public Member Functions

static SkIcuBreakIteratorCacheget ()
 

Detailed Description

Definition at line 149 of file SkUnicode_icu.cpp.

Member Function Documentation

◆ get()

static SkIcuBreakIteratorCache & SkIcuBreakIteratorCache::get ( )
inlinestatic

Definition at line 227 of file SkUnicode_icu.cpp.

227 {
229 return instance;
230 }
VkInstance instance
Definition: main.cc:48

◆ makeBreakIterator()

ICUBreakIterator SkIcuBreakIteratorCache::makeBreakIterator ( SkUnicode::BreakType  type,
const char *  bcp47 
)
inline

Definition at line 232 of file SkUnicode_icu.cpp.

232 {
233 SkAutoMutexExclusive lock(fCacheMutex);
234 UErrorCode status = U_ZERO_ERROR;
235
236 // Get ICU locale for BCP47 langtag
237 char localeIDStorage[ULOC_FULLNAME_CAPACITY];
238 const char* localeID = nullptr;
239 if (bcp47) {
240 sk_uloc_forLanguageTag(bcp47, localeIDStorage, ULOC_FULLNAME_CAPACITY, nullptr, &status);
241 if (U_FAILURE(status)) {
242 SkDEBUGF("Break error could not get language tag: %s", sk_u_errorName(status));
243 } else if (localeIDStorage[0]) {
244 localeID = localeIDStorage;
245 }
246 }
247 if (!localeID) {
248 localeID = sk_uloc_getDefault();
249 }
250
251 auto make = [](const Request& request) -> UBreakIterator* {
252 UErrorCode status = U_ZERO_ERROR;
253 UBreakIterator* bi = sk_ubrk_open(convertType(request.fType),
254 request.fIcuLocale.c_str(),
255 nullptr, 0, &status);
256 if (U_FAILURE(status)) {
257 SkDEBUGF("Break error: %s", sk_u_errorName(status));
258 }
259 return bi;
260 };
261
262 auto clone = [](const UBreakIterator* existing) -> ICUBreakIterator {
263 if (!existing) {
264 return nullptr;
265 }
266
267 UErrorCode status = U_ZERO_ERROR;
268 ICUBreakIterator clone(sk_ubrk_clone(existing, &status));
269 if (U_FAILURE(status)) {
270 SkDEBUGF("Break error: %s", sk_u_errorName(status));
271 }
272 return clone;
273 };
274
275 Request request(type, localeID);
276
277 // See if this request is already in the cache
278 const sk_sp<BreakIteratorRef>* ref = fRequestCache.find(request);
279 if (ref) {
280 // See if the breakIterator needs to be re-created
281 if (!(*ref)->breakIterator) {
282 (*ref)->breakIterator = make(request);
283 }
284 return clone((*ref)->breakIterator);
285 }
286
287 // This request was not in the cache, create an iterator.
288 ICUBreakIterator newIter(make(request));
289 if (!newIter) {
290 return nullptr;
291 }
292
294
295 // Check if the new iterator is a duplicate
296 // Android doesn't expose ubrk_getLocaleByType so there is no means of de-duplicating.
297 // ubrk_getAvailable seems like it should work, but the implementation is just every locale.
298 if (SkGetICULib()->f_ubrk_getLocaleByType) {
299 const char* actualLocale = SkGetICULib()->f_ubrk_getLocaleByType(
300 newIter.get(), ULOC_ACTUAL_LOCALE, &status);
301 // Android doesn't expose ubrk_getLocaleByType so a wrapper may return an error.
302 if (!U_FAILURE(status)) {
303 if (!actualLocale) {
304 actualLocale = "";
305 }
306 // If the actual locale is the same as the requested locale we know there is no entry.
307 if (strcmp(actualLocale, localeID) != 0) {
308 Request actualRequest(type, actualLocale);
309 const sk_sp<BreakIteratorRef>* actualRef = fRequestCache.find(actualRequest);
310 if (actualRef) {
311 if (!(*actualRef)->breakIterator) {
312 (*actualRef)->breakIterator = newIter.release();
313 }
314 actualRef = fRequestCache.set(request, *actualRef);
315 return clone((*actualRef)->breakIterator);
316 } else {
317 this->purgeIfNeeded();
318 newRef = sk_make_sp<BreakIteratorRef>(std::move(newIter));
319 fRequestCache.set(actualRequest, newRef);
320 }
321 }
322 }
323 }
324
325 if (!newRef) {
326 this->purgeIfNeeded();
327 newRef = sk_make_sp<BreakIteratorRef>(std::move(newIter));
328 }
329 fRequestCache.set(request, newRef);
330
331 return clone(newRef->breakIterator);
332 }
#define SkDEBUGF(...)
Definition: SkDebug.h:24
static SKICU_EMIT_FUNCS UBreakIterator * sk_ubrk_clone(const UBreakIterator *bi, UErrorCode *status)
const SkICULib * SkGetICULib()
std::unique_ptr< UBreakIterator, SkFunctionObject< ubrk_close_wrapper > > ICUBreakIterator
static UBreakIteratorType convertType(SkUnicode::BreakType type)
GLenum type
static void make(SkBitmap *bitmap, SkColorType colorType, SkAlphaType alphaType, sk_sp< SkColorSpace > colorSpace)
Definition: encode_srgb.cpp:35
const char *(* f_ubrk_getLocaleByType)(const UBreakIterator *, ULocDataLocaleType, UErrorCode *)

The documentation for this class was generated from the following file: