Flutter Engine
The Flutter Engine
Functions
GrRRectEffect Namespace Reference

Functions

GrFPResult Make (std::unique_ptr< GrFragmentProcessor >, GrClipEdgeType, const SkRRect &, const GrShaderCaps &)
 

Function Documentation

◆ Make()

GrFPResult GrRRectEffect::Make ( std::unique_ptr< GrFragmentProcessor inputFP,
GrClipEdgeType  edgeType,
const SkRRect rrect,
const GrShaderCaps caps 
)

Creates an effect that performs anti-aliased clipping against a SkRRect. It doesn't support all varieties of SkRRect, so the caller must check success in the GrFPResult.

Definition at line 713 of file GrRRectEffect.cpp.

715 {
716 if (rrect.isRect()) {
717 auto fp = GrFragmentProcessor::Rect(std::move(inputFP), edgeType, rrect.getBounds());
718 return GrFPSuccess(std::move(fp));
719 }
720
721 if (rrect.isOval()) {
722 return GrOvalEffect::Make(std::move(inputFP), edgeType, rrect.getBounds(), caps);
723 }
724
725 if (rrect.isSimple()) {
728 // In this case the corners are extremely close to rectangular and we collapse the
729 // clip to a rectangular clip.
730 auto fp = GrFragmentProcessor::Rect(std::move(inputFP), edgeType, rrect.getBounds());
731 return GrFPSuccess(std::move(fp));
732 }
734 return CircularRRectEffect::Make(std::move(inputFP), edgeType,
735 CircularRRectEffect::kAll_CornerFlags, rrect);
736 } else {
737 return EllipticalRRectEffect::Make(std::move(inputFP), edgeType, rrect);
738 }
739 }
740
741 if (rrect.isComplex() || rrect.isNinePatch()) {
742 // Check for the "tab" cases - two adjacent circular corners and two square corners.
743 SkScalar circularRadius = 0;
744 uint32_t cornerFlags = 0;
745
746 SkVector radii[4];
747 bool squashedRadii = false;
748 for (int c = 0; c < 4; ++c) {
749 radii[c] = rrect.radii((SkRRect::Corner)c);
750 // This effect can't handle a corner with both zero and non-zero radii
751 if ((0 == radii[c].fX) != (0 == radii[c].fY)) {
752 return GrFPFailure(std::move(inputFP));
753 }
754 if (0 == radii[c].fX) {
755 // The corner is square, so no need to squash or flag as circular.
756 continue;
757 }
758 if (radii[c].fX < kRadiusMin || radii[c].fY < kRadiusMin) {
759 radii[c].set(0, 0);
760 squashedRadii = true;
761 continue;
762 }
763 if (radii[c].fX != radii[c].fY) {
764 cornerFlags = ~0U;
765 break;
766 }
767 if (!cornerFlags) {
768 circularRadius = radii[c].fX;
769 cornerFlags = 1 << c;
770 } else {
771 if (radii[c].fX != circularRadius) {
772 cornerFlags = ~0U;
773 break;
774 }
775 cornerFlags |= 1 << c;
776 }
777 }
778
779 switch (cornerFlags) {
780 case CircularRRectEffect::kAll_CornerFlags:
781 // This rrect should have been caught in the simple case above. Though, it would
782 // be correctly handled in the fallthrough code.
783 SkASSERT(false);
784 [[fallthrough]];
785 case CircularRRectEffect::kTopLeft_CornerFlag:
786 case CircularRRectEffect::kTopRight_CornerFlag:
787 case CircularRRectEffect::kBottomRight_CornerFlag:
788 case CircularRRectEffect::kBottomLeft_CornerFlag:
789 case CircularRRectEffect::kLeft_CornerFlags:
790 case CircularRRectEffect::kTop_CornerFlags:
791 case CircularRRectEffect::kRight_CornerFlags:
792 case CircularRRectEffect::kBottom_CornerFlags: {
794 if (squashedRadii) {
795 rr.writable()->setRectRadii(rrect.getBounds(), radii);
796 }
797 return CircularRRectEffect::Make(std::move(inputFP), edgeType, cornerFlags, *rr);
798 }
799 case CircularRRectEffect::kNone_CornerFlags: {
800 auto fp =
801 GrFragmentProcessor::Rect(std::move(inputFP), edgeType, rrect.getBounds());
802 return GrFPSuccess(std::move(fp));
803 }
804 default: {
807 if (rrect.isNinePatch() &&
808 ul.fX >= kRadiusMin &&
809 ul.fY >= kRadiusMin &&
810 lr.fX >= kRadiusMin &&
811 lr.fY >= kRadiusMin) {
812 return EllipticalRRectEffect::Make(std::move(inputFP), edgeType, rrect);
813 }
814 return GrFPFailure(std::move(inputFP));
815 }
816 }
817 }
818 return GrFPFailure(std::move(inputFP));
819}
static GrFPResult GrFPSuccess(std::unique_ptr< GrFragmentProcessor > fp)
static GrFPResult GrFPFailure(std::unique_ptr< GrFragmentProcessor > fp)
static const SkScalar kRadiusMin
#define SkASSERT(cond)
Definition: SkAssert.h:116
static std::unique_ptr< GrFragmentProcessor > Rect(std::unique_ptr< GrFragmentProcessor >, GrClipEdgeType, SkRect)
static bool IsSimpleCircular(const SkRRect &rr)
Definition: SkRRectPriv.h:27
static SkVector GetSimpleRadii(const SkRRect &rr)
Definition: SkRRectPriv.h:22
bool isOval() const
Definition: SkRRect.h:85
SkVector radii(Corner corner) const
Definition: SkRRect.h:271
@ kUpperLeft_Corner
index of top-left corner radii
Definition: SkRRect.h:252
@ kLowerRight_Corner
index of bottom-right corner radii
Definition: SkRRect.h:254
bool isNinePatch() const
Definition: SkRRect.h:87
bool isRect() const
Definition: SkRRect.h:84
const SkRect & getBounds() const
Definition: SkRRect.h:279
bool isSimple() const
Definition: SkRRect.h:86
bool isComplex() const
Definition: SkRRect.h:88
float SkScalar
Definition: extension.cpp:12
GrFPResult Make(std::unique_ptr< GrFragmentProcessor >, GrClipEdgeType, const SkRect &, const GrShaderCaps &)
SK_API sk_sp< SkDocument > Make(SkWStream *dst, const SkSerialProcs *=nullptr, std::function< void(const SkPicture *)> onEndPage=nullptr)
SkRRect rrect
Definition: SkRecords.h:232
const uint32_t fp
float fX
x-axis value
Definition: SkPoint_impl.h:164
void set(float x, float y)
Definition: SkPoint_impl.h:200
float fY
y-axis value
Definition: SkPoint_impl.h:165