441 {
442
443
446
450 };
451
452
456 if (0 <= t && t < 1) {
457 expandGap(pts[0].fX + t * (pts[1].fX - pts[0].fX));
458 }
459 };
460
467 }
468 };
469
471 float intersectionStorage[3];
474
475 for(double intersection : intersections) {
476 expandGap(intersection);
477 }
478 };
479
480
481 auto addPts = [&expandGap, &pts, topOffset, bottomOffset](int ptCount) {
482 for (int i = 0; i < ptCount; ++i) {
483 if (topOffset < pts[i].fY && pts[i].fY < bottomOffset) {
484 expandGap(pts[i].fX);
485 }
486 }
487 };
488
492 switch (verb) {
494 break;
495 }
497 auto [lineTop, lineBottom] = std::minmax({pts[0].fY, pts[1].fY});
498
499
500 if (topOffset <= lineBottom && lineTop <= bottomOffset) {
501 addLine(topOffset);
502 addLine(bottomOffset);
503 addPts(2);
504 }
505 break;
506 }
508 auto [quadTop, quadBottom] = std::minmax({pts[0].fY, pts[1].fY, pts[2].fY});
509
510
511 if (topOffset <= quadBottom && quadTop <= bottomOffset) {
512 addQuad(topOffset);
513 addQuad(bottomOffset);
514 addPts(3);
515 }
516 break;
517 }
519 SkDEBUGFAIL(
"There should be no conic primitives in glyph outlines.");
520 break;
521 }
523 auto [cubicTop, cubicBottom] =
524 std::minmax({pts[0].fY, pts[1].fY, pts[2].fY, pts[3].fY});
525
526
527 if (topOffset <= cubicBottom && cubicTop <= bottomOffset) {
528 addCubic(topOffset);
529 addCubic(bottomOffset);
530 addPts(4);
531 }
532 break;
533 }
535 break;
536 }
537 default: {
538 SkDEBUGFAIL(
"Unknown path verb generating glyph underline.");
539 break;
540 }
541 }
542 }
543
545}
#define SkDEBUGFAIL(message)
static constexpr float sk_ieee_float_divide(float numer, float denom)
static bool left(const SkPoint &p0, const SkPoint &p1)
static bool right(const SkPoint &p0, const SkPoint &p1)
static SkSpan< const float > IntersectWithHorizontalLine(SkSpan< const SkPoint > controlPoints, float yIntercept, float intersectionStorage[3])
static SkSpan< const float > IntersectWithHorizontalLine(SkSpan< const SkPoint > controlPoints, float yIntercept, float intersectionStorage[2])