287 {
288 if (fLines.empty()) {
289 return {0, 0};
290 }
291
292 if (
pos.fParagraphIndex >= fLines.size()) {
293 pos.fParagraphIndex = fLines.size() - 1;
294 pos.fTextByteIndex = fLines[
pos.fParagraphIndex].fText.size();
295 } else {
297 }
298
300 SkASSERT(
pos.fTextByteIndex <= fLines[
pos.fParagraphIndex].fText.size());
301
302 SkASSERT(
pos.fTextByteIndex == fLines[
pos.fParagraphIndex].fText.size() ||
304
307 break;
309 if (0 ==
pos.fTextByteIndex) {
310 if (
pos.fParagraphIndex > 0) {
311 --
pos.fParagraphIndex;
312 pos.fTextByteIndex = fLines[
pos.fParagraphIndex].fText.size();
313 }
314 } else {
315 const auto& str = fLines[
pos.fParagraphIndex].fText;
318 }
319 break;
321 if (fLines[
pos.fParagraphIndex].fText.size() ==
pos.fTextByteIndex) {
322 if (
pos.fParagraphIndex + 1 < fLines.size()) {
323 ++
pos.fParagraphIndex;
324 pos.fTextByteIndex = 0;
325 }
326 } else {
327 const auto& str = fLines[
pos.fParagraphIndex].fText;
330 }
331 break;
333 {
334 const std::vector<size_t>& list = fLines[
pos.fParagraphIndex].fLineEndOffsets;
336 pos.fTextByteIndex =
f > 0 ? list[
f - 1] : 0;
337 }
338 break;
340 {
341 const std::vector<size_t>& list = fLines[
pos.fParagraphIndex].fLineEndOffsets;
343 if (
f < list.size()) {
344 pos.fTextByteIndex = list[
f] > 0 ? list[
f] - 1 : 0;
345 } else {
346 pos.fTextByteIndex = fLines[
pos.fParagraphIndex].fText.size();
347 }
348 }
349 break;
351 {
352 SkASSERT(
pos.fTextByteIndex < fLines[
pos.fParagraphIndex].fCursorPos.size());
353 float x = fLines[
pos.fParagraphIndex].fCursorPos[
pos.fTextByteIndex].left();
354 const std::vector<size_t>& list = fLines[
pos.fParagraphIndex].fLineEndOffsets;
356
358
360 (
f == 1) ? 0 : list[
f - 2],
362 }
else if (
pos.fParagraphIndex > 0) {
363 --
pos.fParagraphIndex;
364 const auto& newLine = fLines[
pos.fParagraphIndex];
365 size_t r = newLine.fLineEndOffsets.size();
366 if (r > 0) {
368 newLine.fLineEndOffsets[r - 1],
369 newLine.fCursorPos.size());
370 } else {
372 newLine.fCursorPos.size());
373 }
374 }
377 }
378 break;
380 {
381 const std::vector<size_t>& list = fLines[
pos.fParagraphIndex].fLineEndOffsets;
382 float x = fLines[
pos.fParagraphIndex].fCursorPos[
pos.fTextByteIndex].left();
383
385 if (
f < list.size()) {
386 const auto&
bounds = fLines[
pos.fParagraphIndex].fCursorPos;
388 f + 1 < list.size() ? list[
f + 1]
390 }
else if (
pos.fParagraphIndex + 1 < fLines.size()) {
391 ++
pos.fParagraphIndex;
392 const auto&
bounds = fLines[
pos.fParagraphIndex].fCursorPos;
393 const std::vector<size_t>& l2 = fLines[
pos.fParagraphIndex].fLineEndOffsets;
395 l2.size() > 0 ? l2[0] :
bounds.size());
396 } else {
397 pos.fTextByteIndex = fLines[
pos.fParagraphIndex].fText.size();
398 }
401 }
402 break;
404 {
405 if (
pos.fTextByteIndex == 0) {
407 break;
408 }
409 const std::vector<bool>& words = fLines[
pos.fParagraphIndex].fWordBoundaries;
410 SkASSERT(words.size() == fLines[
pos.fParagraphIndex].fText.size());
411 do {
412 --
pos.fTextByteIndex;
413 }
while (
pos.fTextByteIndex > 0 && !words[
pos.fTextByteIndex]);
414 }
415 break;
417 {
419 if (
pos.fTextByteIndex ==
text.size()) {
421 break;
422 }
423 const std::vector<bool>& words = fLines[
pos.fParagraphIndex].fWordBoundaries;
425 do {
426 ++
pos.fTextByteIndex;
427 }
while (
pos.fTextByteIndex <
text.size() && !words[
pos.fTextByteIndex]);
428 }
429 break;
430
431 }
433}
static size_t find_first_larger(const std::vector< T > &list, T value)
static const char * prev_utf8(const char *p, const char *begin)
static const char * begin(const StringSlice &s)
static size_t align_column(const StringSlice &str, size_t p)
static const char * next_utf8(const char *p, const char *end)
static bool is_utf8_continuation(char v)
static size_t find_closest_x(const std::vector< SkRect > &bounds, float x, size_t b, size_t e)
Optional< SkRect > bounds