617 {
618
619
620
622
623 auto result = iterateThroughShapingRegions(
624 [this, limitlessWidth]
626
627
630 if (shaper == nullptr) {
631
632 return false;
633 }
634
635 iterateThroughFontStyles(textRange, styleSpan,
636 [this, &shaper, defaultBidiLevel, limitlessWidth, &advanceX]
639
640
641 fHeight = block.fStyle.getHeightOverride() ? block.fStyle.getHeight() : 0;
642 fUseHalfLeading = block.fStyle.getHalfLeading();
643 fBaselineShift = block.fStyle.getBaselineShift();
645 fCurrentText = block.fRange;
646 fUnresolvedBlocks.emplace_back(RunBlock(block.fRange));
647
649
650
651 SkFont font(std::move(typeface), block.fStyle.getFontSize());
652 font.setEdging(SkFont::Edging::kAntiAlias);
653 font.setHinting(SkFontHinting::kSlight);
654 font.setSubpixel(true);
655
656
657
658 int wantedWeight = block.fStyle.getFontStyle().weight();
659 bool fakeBold =
660 wantedWeight >= SkFontStyle::kSemiBold_Weight &&
661 wantedWeight - font.getTypeface()->fontStyle().weight() >= 200;
662 bool fakeItalic =
663 block.fStyle.getFontStyle().slant() == SkFontStyle::kItalic_Slant &&
664 font.getTypeface()->fontStyle().slant() != SkFontStyle::kItalic_Slant;
665 font.setEmbolden(fakeBold);
666 font.setSkewX(fakeItalic ? -SK_Scalar1 / 4 : 0);
667
668
669
670 auto resolvedCount = fResolvedBlocks.size();
671 auto unresolvedCount = fUnresolvedBlocks.size();
672 while (unresolvedCount-- > 0) {
673 auto unresolvedRange = fUnresolvedBlocks.front().fText;
674 if (unresolvedRange == EMPTY_TEXT) {
675
676 fUnresolvedBlocks.pop_front();
677 continue;
678 }
679 auto unresolvedText = fParagraph->text(unresolvedRange);
680
681 SkShaper::TrivialFontRunIterator fontIter(font, unresolvedText.size());
682 LangIterator langIter(unresolvedText, blockSpan,
683 fParagraph->paragraphStyle().getTextStyle());
684 SkShaper::TrivialBiDiRunIterator bidiIter(defaultBidiLevel, unresolvedText.size());
685 auto scriptIter = SkShapers::HB::ScriptRunIterator(unresolvedText.begin(),
686 unresolvedText.size());
687 fCurrentText = unresolvedRange;
688
689
690 TArray<SkShaper::Feature> adjustedFeatures(features.size());
691 for (const SkShaper::Feature& feature : features) {
692 SkRange<size_t> featureRange(feature.start, feature.end);
693 if (unresolvedRange.intersects(featureRange)) {
694 SkRange<size_t> adjustedRange = unresolvedRange.intersection(featureRange);
695 adjustedRange.Shift(-static_cast<std::make_signed_t<size_t>>(unresolvedRange.start));
696 adjustedFeatures.push_back({feature.tag, feature.value, adjustedRange.start, adjustedRange.end});
697 }
698 }
699
700 shaper->shape(unresolvedText.begin(), unresolvedText.size(),
701 fontIter, bidiIter,*scriptIter, langIter,
702 adjustedFeatures.data(), adjustedFeatures.size(),
703 limitlessWidth, this);
704
705
706
707 fUnresolvedBlocks.pop_front();
708 }
709
710 if (fUnresolvedBlocks.empty()) {
711
712
713 return Resolved::Everything;
714 }
else if (resolvedCount < fResolvedBlocks.size()) {
715 return Resolved::Something;
716 } else {
717 return Resolved::Nothing;
718 }
719 });
720
721 this->finish(block, fHeight, advanceX);
722 });
723
724 return true;
725 });
726
728}
static sk_sp< SkFontMgr > RefEmpty()
static float max(float r, float g, float b)
SKSHAPER_API std::unique_ptr< SkShaper > ShapeDontWrapOrReorder(sk_sp< SkUnicode > unicode, sk_sp< SkFontMgr > fallback)
SkRange< size_t > TextRange