279 {
280 fHeight = 0;
283
284 auto span = parent->clusters();
285 if (span.empty()) {
286 return;
287 }
288 auto maxLines = parent->paragraphStyle().getMaxLines();
289 auto align = parent->paragraphStyle().effective_align();
292 auto hasEllipsis = parent->paragraphStyle().ellipsized();
293
296 bool firstLine = true;
297
298 SkScalar softLineMaxIntrinsicWidth = 0;
299 fEndLine = TextStretch(span.begin(), span.begin(), parent->strutForceHeight());
300 auto end = span.end() - 1;
301 auto start = span.begin();
302 InternalLineMetrics maxRunMetrics;
303 bool needEllipsis = false;
304 while (fEndLine.endCluster() != end) {
305
306 this->lookAhead(maxWidth, end, parent->getApplyRoundingHack());
307
308 auto lastLine = (hasEllipsis && unlimitedLines) || fLineNumber >= maxLines;
309 needEllipsis = hasEllipsis && !endlessLine && lastLine;
310
311 this->moveForward(needEllipsis);
312 needEllipsis &= fEndLine.endCluster() <
end - 1;
313
314
315 this->trimEndSpaces(align);
316
317
318 Cluster* startLine;
321 std::tie(startLine,
pos, widthWithSpaces) = this->trimStartSpaces(end);
322
323 if (needEllipsis && !fHardLineBreak) {
324
325 fEndLine.restoreBreak();
326 widthWithSpaces = fEndLine.widthWithGhostSpaces();
327 }
328
329
330 if (fEndLine.metrics().isClean()) {
331 fEndLine.setMetrics(parent->getEmptyMetrics());
332 }
333
334
335 Run* lastRun =
nullptr;
336 for (auto cluster = fEndLine.startCluster(); cluster <= fEndLine.endCluster(); ++cluster) {
337 auto r = cluster->runOrNull();
338 if (r == lastRun) {
339 continue;
340 }
341 lastRun = r;
342 if (lastRun->placeholderStyle() != nullptr) {
344
345
346 lastRun->updateMetrics(&fEndLine.metrics());
347 }
348 }
349
350
351
352 maxRunMetrics = fEndLine.metrics();
353 maxRunMetrics.fForceStrut = false;
354
355
356 TextRange textExcludingSpaces(fEndLine.startCluster()->textRange().start, fEndLine.endCluster()->textRange().end);
357 TextRange text(fEndLine.startCluster()->textRange().start, fEndLine.breakCluster()->textRange().start);
358 TextRange textIncludingNewlines(fEndLine.startCluster()->textRange().start, startLine->textRange().start);
359 if (startLine == end) {
360 textIncludingNewlines.end = parent->text().size();
361 text.end = parent->text().size();
362 }
363 ClusterRange clusters(fEndLine.startCluster() - start, fEndLine.endCluster() - start + 1);
364 ClusterRange clustersWithGhosts(fEndLine.startCluster() - start, startLine - start);
365
366 if (disableFirstAscent && firstLine) {
367 fEndLine.metrics().fAscent = fEndLine.metrics().fRawAscent;
368 }
369 if (disableLastDescent && (lastLine || (startLine == end && !fHardLineBreak ))) {
370 fEndLine.metrics().fDescent = fEndLine.metrics().fRawDescent;
371 }
372
373 if (parent->strutEnabled()) {
374
375 parent->strutMetrics().updateLineMetrics(fEndLine.metrics());
376 }
377
378 SkScalar lineHeight = fEndLine.metrics().height();
379 firstLine = false;
380
381 if (fEndLine.empty()) {
382
383 textExcludingSpaces.end = textExcludingSpaces.start;
384 clusters.end = clusters.start;
385 }
386
387
389
390 addLine(textExcludingSpaces,
392 textIncludingNewlines, clusters, clustersWithGhosts, widthWithSpaces,
393 fEndLine.startPos(),
394 fEndLine.endPos(),
397 fEndLine.metrics(),
398 needEllipsis && !fHardLineBreak);
399
400 softLineMaxIntrinsicWidth += widthWithSpaces;
401
402 fMaxIntrinsicWidth =
std::max(fMaxIntrinsicWidth, softLineMaxIntrinsicWidth);
403 if (fHardLineBreak) {
404 softLineMaxIntrinsicWidth = 0;
405 }
406
407 fHeight += lineHeight;
408 if (!fHardLineBreak || startLine != end) {
409 fEndLine.clean();
410 }
411 fEndLine.startFrom(startLine,
pos);
412 parent->fMaxWidthWithTrailingSpaces =
std::max(parent->fMaxWidthWithTrailingSpaces, widthWithSpaces);
413
414 if (hasEllipsis && unlimitedLines) {
415
416
417 if (!fHardLineBreak) {
418 break;
419 }
420 } else if (lastLine) {
421
422 fHardLineBreak = false;
423 break;
424 }
425
426 ++fLineNumber;
427 }
428
429
430
431 if (fEndLine.endCluster() != nullptr) {
432 auto lastWordLength = 0.0f;
433 auto cluster = fEndLine.endCluster();
434 while (cluster != end || cluster->endPos() <
end->endPos()) {
435 fExceededMaxLines = true;
436 if (cluster->isHardBreak()) {
437
438 fMaxIntrinsicWidth =
std::max(fMaxIntrinsicWidth, softLineMaxIntrinsicWidth);
439 softLineMaxIntrinsicWidth = 0;
440 fMinIntrinsicWidth =
std::max(fMinIntrinsicWidth, lastWordLength);
441 lastWordLength = 0;
442 } else if (cluster->isWhitespaceBreak()) {
443
444 softLineMaxIntrinsicWidth += cluster->width();
445 fMinIntrinsicWidth =
std::max(fMinIntrinsicWidth, lastWordLength);
446 lastWordLength = 0;
447 } else if (cluster->run().isPlaceholder()) {
448
449 fMinIntrinsicWidth =
std::max(fMinIntrinsicWidth, lastWordLength);
450
451 softLineMaxIntrinsicWidth += cluster->width();
452 fMinIntrinsicWidth =
std::max(fMinIntrinsicWidth, cluster->width());
453 lastWordLength = 0;
454 } else {
455
456 softLineMaxIntrinsicWidth += cluster->width();
457 lastWordLength += cluster->width();
458 }
459 ++cluster;
460 }
461 fMinIntrinsicWidth =
std::max(fMinIntrinsicWidth, lastWordLength);
462 fMaxIntrinsicWidth =
std::max(fMaxIntrinsicWidth, softLineMaxIntrinsicWidth);
463
464 if (parent->lines().empty()) {
465
466 if (disableFirstAscent) {
467 fEndLine.metrics().fAscent = fEndLine.metrics().fRawAscent;
468 }
469 if (disableLastDescent && !fHardLineBreak) {
470 fEndLine.metrics().fDescent = fEndLine.metrics().fRawDescent;
471 }
472 fHeight =
std::max(fHeight, fEndLine.metrics().height());
473 }
474 }
475
476 if (fHardLineBreak) {
477 if (disableLastDescent) {
478 fEndLine.metrics().fDescent = fEndLine.metrics().fRawDescent;
479 }
480
481
482 if (parent->strutEnabled()) {
483
484 parent->strutMetrics().updateLineMetrics(fEndLine.metrics());
485 }
486
487 ClusterRange clusters(fEndLine.breakCluster() - start, fEndLine.endCluster() - start);
488 addLine(fEndLine.breakCluster()->textRange(),
489 fEndLine.breakCluster()->textRange(),
490 fEndLine.endCluster()->textRange(),
491 clusters,
492 clusters,
493 0,
494 0,
495 0,
498 fEndLine.metrics(),
499 needEllipsis);
500 fHeight += fEndLine.metrics().height();
501 parent->lines().back().setMaxRunMetrics(maxRunMetrics);
502 }
503
504 if (parent->lines().empty()) {
505 return;
506 }
507
508 if (disableFirstAscent) {
510 }
511 if (disableLastDescent) {
513 }
514}
static bool SkIsFinite(T x, Pack... values)
static float max(float r, float g, float b)
static float min(float r, float g, float b)
SkRange< size_t > ClusterRange
SkRange< size_t > TextRange
static constexpr SkPoint Make(float x, float y)