232 {
234 UErrorCode status = U_ZERO_ERROR;
235
236
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
263 if (!existing) {
264 return nullptr;
265 }
266
267 UErrorCode status = U_ZERO_ERROR;
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
279 if (ref) {
280
281 if (!(*ref)->breakIterator) {
282 (*ref)->breakIterator =
make(request);
283 }
284 return clone((*ref)->breakIterator);
285 }
286
287
289 if (!newIter) {
290 return nullptr;
291 }
292
294
295
296
297
300 newIter.get(), ULOC_ACTUAL_LOCALE, &status);
301
302 if (!U_FAILURE(status)) {
303 if (!actualLocale) {
304 actualLocale = "";
305 }
306
307 if (strcmp(actualLocale, localeID) != 0) {
308 Request actualRequest(
type, actualLocale);
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 }
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)
static void make(SkBitmap *bitmap, SkColorType colorType, SkAlphaType alphaType, sk_sp< SkColorSpace > colorSpace)
const char *(* f_ubrk_getLocaleByType)(const UBreakIterator *, ULocDataLocaleType, UErrorCode *)