OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "GrRRectEffect.h" | 8 #include "GrRRectEffect.h" |
9 | 9 |
10 #include "gl/GrGLEffect.h" | 10 #include "gl/GrGLEffect.h" |
11 #include "gl/GrGLSL.h" | 11 #include "gl/GrGLSL.h" |
| 12 #include "GrConvexPolyEffect.h" |
12 #include "GrTBackendEffectFactory.h" | 13 #include "GrTBackendEffectFactory.h" |
13 | 14 |
14 #include "SkRRect.h" | 15 #include "SkRRect.h" |
15 | 16 |
| 17 // The effects defined here only handle rrect radii >= kRadiusMin. |
| 18 static const SkScalar kRadiusMin = SK_ScalarHalf; |
| 19 |
| 20 ////////////////////////////////////////////////////////////////////////////// |
| 21 |
16 class GLCircularRRectEffect; | 22 class GLCircularRRectEffect; |
17 | 23 |
18 class CircularRRectEffect : public GrEffect { | 24 class CircularRRectEffect : public GrEffect { |
19 public: | 25 public: |
20 // This effect only supports circular corner rrects where the radius is >= k
RadiusMin. | |
21 static const SkScalar kRadiusMin; | |
22 | 26 |
23 enum CornerFlags { | 27 enum CornerFlags { |
24 kTopLeft_CornerFlag = (1 << SkRRect::kUpperLeft_Corner), | 28 kTopLeft_CornerFlag = (1 << SkRRect::kUpperLeft_Corner), |
25 kTopRight_CornerFlag = (1 << SkRRect::kUpperRight_Corner), | 29 kTopRight_CornerFlag = (1 << SkRRect::kUpperRight_Corner), |
26 kBottomRight_CornerFlag = (1 << SkRRect::kLowerRight_Corner), | 30 kBottomRight_CornerFlag = (1 << SkRRect::kLowerRight_Corner), |
27 kBottomLeft_CornerFlag = (1 << SkRRect::kLowerLeft_Corner), | 31 kBottomLeft_CornerFlag = (1 << SkRRect::kLowerLeft_Corner), |
28 | 32 |
29 kLeft_CornerFlags = kTopLeft_CornerFlag | kBottomLeft_CornerFlag, | 33 kLeft_CornerFlags = kTopLeft_CornerFlag | kBottomLeft_CornerFlag, |
30 kTop_CornerFlags = kTopLeft_CornerFlag | kTopRight_CornerFlag, | 34 kTop_CornerFlags = kTopLeft_CornerFlag | kTopRight_CornerFlag, |
31 kRight_CornerFlags = kTopRight_CornerFlag | kBottomRight_CornerFlag, | 35 kRight_CornerFlags = kTopRight_CornerFlag | kBottomRight_CornerFlag, |
32 kBottom_CornerFlags = kBottomLeft_CornerFlag | kBottomRight_CornerFlag, | 36 kBottom_CornerFlags = kBottomLeft_CornerFlag | kBottomRight_CornerFlag, |
33 | 37 |
34 kAll_CornerFlags = kTopLeft_CornerFlag | kTopRight_CornerFlag | | 38 kAll_CornerFlags = kTopLeft_CornerFlag | kTopRight_CornerFlag | |
35 kBottomLeft_CornerFlag | kBottomRight_CornerFlag, | 39 kBottomLeft_CornerFlag | kBottomRight_CornerFlag, |
36 | 40 |
| 41 kNone_CornerFlags = 0 |
37 }; | 42 }; |
38 | 43 |
39 // The flags are used to indicate which corners are circluar (unflagged corn
ers are assumed to | 44 // The flags are used to indicate which corners are circluar (unflagged corn
ers are assumed to |
40 // be square). | 45 // be square). |
41 static GrEffectRef* Create(GrEffectEdgeType, uint32_t circularCornerFlags, c
onst SkRRect&); | 46 static GrEffectRef* Create(GrEffectEdgeType, uint32_t circularCornerFlags, c
onst SkRRect&); |
42 | 47 |
43 virtual ~CircularRRectEffect() {}; | 48 virtual ~CircularRRectEffect() {}; |
44 static const char* Name() { return "CircularRRect"; } | 49 static const char* Name() { return "CircularRRect"; } |
45 | 50 |
46 const SkRRect& getRRect() const { return fRRect; } | 51 const SkRRect& getRRect() const { return fRRect; } |
(...skipping 15 matching lines...) Expand all Loading... |
62 | 67 |
63 SkRRect fRRect; | 68 SkRRect fRRect; |
64 GrEffectEdgeType fEdgeType; | 69 GrEffectEdgeType fEdgeType; |
65 uint32_t fCircularCornerFlags; | 70 uint32_t fCircularCornerFlags; |
66 | 71 |
67 GR_DECLARE_EFFECT_TEST; | 72 GR_DECLARE_EFFECT_TEST; |
68 | 73 |
69 typedef GrEffect INHERITED; | 74 typedef GrEffect INHERITED; |
70 }; | 75 }; |
71 | 76 |
72 const SkScalar CircularRRectEffect::kRadiusMin = 0.5f; | |
73 | |
74 GrEffectRef* CircularRRectEffect::Create(GrEffectEdgeType edgeType, | 77 GrEffectRef* CircularRRectEffect::Create(GrEffectEdgeType edgeType, |
75 uint32_t circularCornerFlags, | 78 uint32_t circularCornerFlags, |
76 const SkRRect& rrect) { | 79 const SkRRect& rrect) { |
77 SkASSERT(kFillAA_GrEffectEdgeType == edgeType || kInverseFillAA_GrEffectEdge
Type == edgeType); | 80 SkASSERT(kFillAA_GrEffectEdgeType == edgeType || kInverseFillAA_GrEffectEdge
Type == edgeType); |
78 return CreateEffectRef(AutoEffectUnref(SkNEW_ARGS(CircularRRectEffect, | 81 return CreateEffectRef(AutoEffectUnref(SkNEW_ARGS(CircularRRectEffect, |
79 (edgeType, circularCornerF
lags, rrect)))); | 82 (edgeType, circularCornerF
lags, rrect)))); |
80 } | 83 } |
81 | 84 |
82 void CircularRRectEffect::getConstantColorComponents(GrColor* color, uint32_t* v
alidFlags) const { | 85 void CircularRRectEffect::getConstantColorComponents(GrColor* color, uint32_t* v
alidFlags) const { |
83 *validFlags = 0; | 86 *validFlags = 0; |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
296 const GrDrawEffect& drawEffect) { | 299 const GrDrawEffect& drawEffect) { |
297 const CircularRRectEffect& crre = drawEffect.castEffect<CircularRRectEffect>
(); | 300 const CircularRRectEffect& crre = drawEffect.castEffect<CircularRRectEffect>
(); |
298 const SkRRect& rrect = crre.getRRect(); | 301 const SkRRect& rrect = crre.getRRect(); |
299 if (rrect != fPrevRRect) { | 302 if (rrect != fPrevRRect) { |
300 SkRect rect = rrect.getBounds(); | 303 SkRect rect = rrect.getBounds(); |
301 SkScalar radius = 0; | 304 SkScalar radius = 0; |
302 switch (crre.getCircularCornerFlags()) { | 305 switch (crre.getCircularCornerFlags()) { |
303 case CircularRRectEffect::kAll_CornerFlags: | 306 case CircularRRectEffect::kAll_CornerFlags: |
304 SkASSERT(rrect.isSimpleCircular()); | 307 SkASSERT(rrect.isSimpleCircular()); |
305 radius = rrect.getSimpleRadii().fX; | 308 radius = rrect.getSimpleRadii().fX; |
306 SkASSERT(radius >= CircularRRectEffect::kRadiusMin); | 309 SkASSERT(radius >= kRadiusMin); |
307 rect.inset(radius, radius); | 310 rect.inset(radius, radius); |
308 break; | 311 break; |
309 case CircularRRectEffect::kTopLeft_CornerFlag: | 312 case CircularRRectEffect::kTopLeft_CornerFlag: |
310 radius = rrect.radii(SkRRect::kUpperLeft_Corner).fX; | 313 radius = rrect.radii(SkRRect::kUpperLeft_Corner).fX; |
311 rect.fLeft += radius; | 314 rect.fLeft += radius; |
312 rect.fTop += radius; | 315 rect.fTop += radius; |
313 rect.fRight += 0.5f; | 316 rect.fRight += 0.5f; |
314 rect.fBottom += 0.5f; | 317 rect.fBottom += 0.5f; |
315 break; | 318 break; |
316 case CircularRRectEffect::kTopRight_CornerFlag: | 319 case CircularRRectEffect::kTopRight_CornerFlag: |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
370 fPrevRRect = rrect; | 373 fPrevRRect = rrect; |
371 } | 374 } |
372 } | 375 } |
373 | 376 |
374 ////////////////////////////////////////////////////////////////////////////// | 377 ////////////////////////////////////////////////////////////////////////////// |
375 | 378 |
376 class GLEllipticalRRectEffect; | 379 class GLEllipticalRRectEffect; |
377 | 380 |
378 class EllipticalRRectEffect : public GrEffect { | 381 class EllipticalRRectEffect : public GrEffect { |
379 public: | 382 public: |
380 // This effect only supports rrects where the radii are >= kRadiusMin. | |
381 static const SkScalar kRadiusMin; | |
382 | |
383 static GrEffectRef* Create(GrEffectEdgeType, const SkRRect&); | 383 static GrEffectRef* Create(GrEffectEdgeType, const SkRRect&); |
384 | 384 |
385 virtual ~EllipticalRRectEffect() {}; | 385 virtual ~EllipticalRRectEffect() {}; |
386 static const char* Name() { return "EllipticalRRect"; } | 386 static const char* Name() { return "EllipticalRRect"; } |
387 | 387 |
388 const SkRRect& getRRect() const { return fRRect; } | 388 const SkRRect& getRRect() const { return fRRect; } |
389 | 389 |
390 | 390 |
391 GrEffectEdgeType getEdgeType() const { return fEdgeType; } | 391 GrEffectEdgeType getEdgeType() const { return fEdgeType; } |
392 | 392 |
393 typedef GLEllipticalRRectEffect GLEffect; | 393 typedef GLEllipticalRRectEffect GLEffect; |
394 | 394 |
395 virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags
) const SK_OVERRIDE; | 395 virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags
) const SK_OVERRIDE; |
396 | 396 |
397 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE; | 397 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE; |
398 | 398 |
399 private: | 399 private: |
400 EllipticalRRectEffect(GrEffectEdgeType, const SkRRect&); | 400 EllipticalRRectEffect(GrEffectEdgeType, const SkRRect&); |
401 | 401 |
402 virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE; | 402 virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE; |
403 | 403 |
404 SkRRect fRRect; | 404 SkRRect fRRect; |
405 GrEffectEdgeType fEdgeType; | 405 GrEffectEdgeType fEdgeType; |
406 | 406 |
407 GR_DECLARE_EFFECT_TEST; | 407 GR_DECLARE_EFFECT_TEST; |
408 | 408 |
409 typedef GrEffect INHERITED; | 409 typedef GrEffect INHERITED; |
410 }; | 410 }; |
411 | 411 |
412 const SkScalar EllipticalRRectEffect::kRadiusMin = 0.5f; | |
413 | |
414 GrEffectRef* EllipticalRRectEffect::Create(GrEffectEdgeType edgeType, const SkRR
ect& rrect) { | 412 GrEffectRef* EllipticalRRectEffect::Create(GrEffectEdgeType edgeType, const SkRR
ect& rrect) { |
415 SkASSERT(kFillAA_GrEffectEdgeType == edgeType || kInverseFillAA_GrEffectEdge
Type == edgeType); | 413 SkASSERT(kFillAA_GrEffectEdgeType == edgeType || kInverseFillAA_GrEffectEdge
Type == edgeType); |
416 return CreateEffectRef(AutoEffectUnref(SkNEW_ARGS(EllipticalRRectEffect, (ed
geType, rrect)))); | 414 return CreateEffectRef(AutoEffectUnref(SkNEW_ARGS(EllipticalRRectEffect, (ed
geType, rrect)))); |
417 } | 415 } |
418 | 416 |
419 void EllipticalRRectEffect::getConstantColorComponents(GrColor* color, uint32_t*
validFlags) const { | 417 void EllipticalRRectEffect::getConstantColorComponents(GrColor* color, uint32_t*
validFlags) const { |
420 *validFlags = 0; | 418 *validFlags = 0; |
421 } | 419 } |
422 | 420 |
423 const GrBackendEffectFactory& EllipticalRRectEffect::getFactory() const { | 421 const GrBackendEffectFactory& EllipticalRRectEffect::getFactory() const { |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
589 return erre.getRRect().getType() | erre.getEdgeType() << 3; | 587 return erre.getRRect().getType() | erre.getEdgeType() << 3; |
590 } | 588 } |
591 | 589 |
592 void GLEllipticalRRectEffect::setData(const GrGLUniformManager& uman, | 590 void GLEllipticalRRectEffect::setData(const GrGLUniformManager& uman, |
593 const GrDrawEffect& drawEffect) { | 591 const GrDrawEffect& drawEffect) { |
594 const EllipticalRRectEffect& erre = drawEffect.castEffect<EllipticalRRectEff
ect>(); | 592 const EllipticalRRectEffect& erre = drawEffect.castEffect<EllipticalRRectEff
ect>(); |
595 const SkRRect& rrect = erre.getRRect(); | 593 const SkRRect& rrect = erre.getRRect(); |
596 if (rrect != fPrevRRect) { | 594 if (rrect != fPrevRRect) { |
597 SkRect rect = rrect.getBounds(); | 595 SkRect rect = rrect.getBounds(); |
598 const SkVector& r0 = rrect.radii(SkRRect::kUpperLeft_Corner); | 596 const SkVector& r0 = rrect.radii(SkRRect::kUpperLeft_Corner); |
599 SkASSERT(r0.fX >= EllipticalRRectEffect::kRadiusMin); | 597 SkASSERT(r0.fX >= kRadiusMin); |
600 SkASSERT(r0.fY >= EllipticalRRectEffect::kRadiusMin); | 598 SkASSERT(r0.fY >= kRadiusMin); |
601 switch (erre.getRRect().getType()) { | 599 switch (erre.getRRect().getType()) { |
602 case SkRRect::kSimple_Type: | 600 case SkRRect::kSimple_Type: |
603 rect.inset(r0.fX, r0.fY); | 601 rect.inset(r0.fX, r0.fY); |
604 uman.set2f(fInvRadiiSqdUniform, 1.f / (r0.fX * r0.fX), | 602 uman.set2f(fInvRadiiSqdUniform, 1.f / (r0.fX * r0.fX), |
605 1.f / (r0.fY * r0.fY)); | 603 1.f / (r0.fY * r0.fY)); |
606 break; | 604 break; |
607 case SkRRect::kNinePatch_Type: { | 605 case SkRRect::kNinePatch_Type: { |
608 const SkVector& r1 = rrect.radii(SkRRect::kLowerRight_Corner); | 606 const SkVector& r1 = rrect.radii(SkRRect::kLowerRight_Corner); |
609 SkASSERT(r1.fX >= EllipticalRRectEffect::kRadiusMin); | 607 SkASSERT(r1.fX >= kRadiusMin); |
610 SkASSERT(r1.fY >= EllipticalRRectEffect::kRadiusMin); | 608 SkASSERT(r1.fY >= kRadiusMin); |
611 rect.fLeft += r0.fX; | 609 rect.fLeft += r0.fX; |
612 rect.fTop += r0.fY; | 610 rect.fTop += r0.fY; |
613 rect.fRight -= r1.fX; | 611 rect.fRight -= r1.fX; |
614 rect.fBottom -= r1.fY; | 612 rect.fBottom -= r1.fY; |
615 uman.set4f(fInvRadiiSqdUniform, 1.f / (r0.fX * r0.fX), | 613 uman.set4f(fInvRadiiSqdUniform, 1.f / (r0.fX * r0.fX), |
616 1.f / (r0.fY * r0.fY), | 614 1.f / (r0.fY * r0.fY), |
617 1.f / (r1.fX * r1.fX), | 615 1.f / (r1.fX * r1.fX), |
618 1.f / (r1.fY * r1.fY)); | 616 1.f / (r1.fY * r1.fY)); |
619 break; | 617 break; |
620 } | 618 } |
621 default: | 619 default: |
622 GrCrash("RRect should always be simple or nine-patch."); | 620 GrCrash("RRect should always be simple or nine-patch."); |
623 } | 621 } |
624 uman.set4f(fInnerRectUniform, rect.fLeft, rect.fTop, rect.fRight, rect.f
Bottom); | 622 uman.set4f(fInnerRectUniform, rect.fLeft, rect.fTop, rect.fRight, rect.f
Bottom); |
625 fPrevRRect = rrect; | 623 fPrevRRect = rrect; |
626 } | 624 } |
627 } | 625 } |
628 | 626 |
629 ////////////////////////////////////////////////////////////////////////////// | 627 ////////////////////////////////////////////////////////////////////////////// |
630 | 628 |
631 GrEffectRef* GrRRectEffect::Create(GrEffectEdgeType edgeType, const SkRRect& rre
ct) { | 629 GrEffectRef* GrRRectEffect::Create(GrEffectEdgeType edgeType, const SkRRect& rre
ct) { |
632 if (kFillAA_GrEffectEdgeType != edgeType && kInverseFillAA_GrEffectEdgeType
!= edgeType) { | 630 if (kFillAA_GrEffectEdgeType != edgeType && kInverseFillAA_GrEffectEdgeType
!= edgeType) { |
633 return NULL; | 631 return NULL; |
634 } | 632 } |
635 uint32_t cornerFlags; | 633 |
| 634 if (rrect.isRect()) { |
| 635 return GrConvexPolyEffect::Create(edgeType, rrect.getBounds()); |
| 636 } |
| 637 |
636 if (rrect.isSimple()) { | 638 if (rrect.isSimple()) { |
| 639 if (rrect.getSimpleRadii().fX < kRadiusMin || rrect.getSimpleRadii().fY
< kRadiusMin) { |
| 640 // In this case the corners are extremely close to rectangular and w
e collapse the |
| 641 // clip to a rectangular clip. |
| 642 return GrConvexPolyEffect::Create(edgeType, rrect.getBounds()); |
| 643 } |
637 if (rrect.getSimpleRadii().fX == rrect.getSimpleRadii().fY) { | 644 if (rrect.getSimpleRadii().fX == rrect.getSimpleRadii().fY) { |
638 if (rrect.getSimpleRadii().fX < CircularRRectEffect::kRadiusMin) { | 645 return CircularRRectEffect::Create(edgeType, CircularRRectEffect::kA
ll_CornerFlags, |
639 return NULL; | 646 rrect); |
640 } | |
641 cornerFlags = CircularRRectEffect::kAll_CornerFlags; | |
642 } else { | 647 } else { |
643 if (rrect.getSimpleRadii().fX < EllipticalRRectEffect::kRadiusMin || | |
644 rrect.getSimpleRadii().fY < EllipticalRRectEffect::kRadiusMin) { | |
645 return NULL; | |
646 } | |
647 return EllipticalRRectEffect::Create(edgeType, rrect); | 648 return EllipticalRRectEffect::Create(edgeType, rrect); |
648 } | 649 } |
649 } else if (rrect.isComplex() || rrect.isNinePatch()) { | 650 } |
| 651 |
| 652 if (rrect.isComplex() || rrect.isNinePatch()) { |
650 // Check for the "tab" cases - two adjacent circular corners and two squ
are corners. | 653 // Check for the "tab" cases - two adjacent circular corners and two squ
are corners. |
651 SkScalar radius = 0; | 654 SkScalar circularRadius = 0; |
652 cornerFlags = 0; | 655 uint32_t cornerFlags = 0; |
| 656 |
| 657 SkVector radii[4]; |
| 658 bool squashedRadii = false; |
653 for (int c = 0; c < 4; ++c) { | 659 for (int c = 0; c < 4; ++c) { |
654 const SkVector& r = rrect.radii((SkRRect::Corner)c); | 660 radii[c] = rrect.radii((SkRRect::Corner)c); |
655 SkASSERT((0 == r.fX) == (0 == r.fY)); | 661 SkASSERT((0 == radii[c].fX) == (0 == radii[c].fY)); |
656 if (0 == r.fX) { | 662 if (0 == radii[c].fX) { |
| 663 // The corner is square, so no need to squash or flag as circula
r. |
657 continue; | 664 continue; |
658 } | 665 } |
659 if (r.fX != r.fY) { | 666 if (radii[c].fX < kRadiusMin || radii[c].fY < kRadiusMin) { |
| 667 radii[c].set(0, 0); |
| 668 squashedRadii = true; |
| 669 continue; |
| 670 } |
| 671 if (radii[c].fX != radii[c].fY) { |
660 cornerFlags = ~0U; | 672 cornerFlags = ~0U; |
661 break; | 673 break; |
662 } | 674 } |
663 if (!cornerFlags) { | 675 if (!cornerFlags) { |
664 radius = r.fX; | 676 circularRadius = radii[c].fX; |
665 if (radius < CircularRRectEffect::kRadiusMin) { | |
666 cornerFlags = ~0U; | |
667 break; | |
668 } | |
669 cornerFlags = 1 << c; | 677 cornerFlags = 1 << c; |
670 } else { | 678 } else { |
671 if (r.fX != radius) { | 679 if (radii[c].fX != circularRadius) { |
672 cornerFlags = ~0U; | 680 cornerFlags = ~0U; |
673 break; | 681 break; |
674 } | 682 } |
675 cornerFlags |= 1 << c; | 683 cornerFlags |= 1 << c; |
676 } | 684 } |
677 } | 685 } |
678 | 686 |
679 switch (cornerFlags) { | 687 switch (cornerFlags) { |
| 688 case CircularRRectEffect::kAll_CornerFlags: |
| 689 // This rrect should have been caught in the simple case above.
Though, it would |
| 690 // be correctly handled in the fallthrough code. |
| 691 SkASSERT(false); |
680 case CircularRRectEffect::kTopLeft_CornerFlag: | 692 case CircularRRectEffect::kTopLeft_CornerFlag: |
681 case CircularRRectEffect::kTopRight_CornerFlag: | 693 case CircularRRectEffect::kTopRight_CornerFlag: |
682 case CircularRRectEffect::kBottomRight_CornerFlag: | 694 case CircularRRectEffect::kBottomRight_CornerFlag: |
683 case CircularRRectEffect::kBottomLeft_CornerFlag: | 695 case CircularRRectEffect::kBottomLeft_CornerFlag: |
684 case CircularRRectEffect::kLeft_CornerFlags: | 696 case CircularRRectEffect::kLeft_CornerFlags: |
685 case CircularRRectEffect::kTop_CornerFlags: | 697 case CircularRRectEffect::kTop_CornerFlags: |
686 case CircularRRectEffect::kRight_CornerFlags: | 698 case CircularRRectEffect::kRight_CornerFlags: |
687 case CircularRRectEffect::kBottom_CornerFlags: | 699 case CircularRRectEffect::kBottom_CornerFlags: { |
688 case CircularRRectEffect::kAll_CornerFlags: | 700 SkTCopyOnFirstWrite<SkRRect> rr(rrect); |
689 break; | 701 if (squashedRadii) { |
690 default: | 702 rr.writable()->setRectRadii(rrect.getBounds(), radii); |
| 703 } |
| 704 return CircularRRectEffect::Create(edgeType, cornerFlags, *rr); |
| 705 } |
| 706 case CircularRRectEffect::kNone_CornerFlags: |
| 707 return GrConvexPolyEffect::Create(edgeType, rrect.getBounds()); |
| 708 default: { |
| 709 if (squashedRadii) { |
| 710 // If we got here then we squashed some but not all the radi
i to zero. (If all |
| 711 // had been squashed cornerFlags would be 0.) The elliptical
effect doesn't |
| 712 // support some rounded and some square corners. |
| 713 return NULL; |
| 714 } |
691 if (rrect.isNinePatch()) { | 715 if (rrect.isNinePatch()) { |
692 const SkVector& r0 = rrect.radii(SkRRect::kUpperLeft_Corner)
; | 716 return EllipticalRRectEffect::Create(edgeType, rrect); |
693 const SkVector& r1 = rrect.radii(SkRRect::kLowerRight_Corner
); | |
694 if (r0.fX >= EllipticalRRectEffect::kRadiusMin && | |
695 r0.fY >= EllipticalRRectEffect::kRadiusMin && | |
696 r1.fX >= EllipticalRRectEffect::kRadiusMin && | |
697 r1.fY >= EllipticalRRectEffect::kRadiusMin) { | |
698 return EllipticalRRectEffect::Create(edgeType, rrect); | |
699 } | |
700 } | 717 } |
701 return NULL; | 718 return NULL; |
| 719 } |
702 } | 720 } |
703 } else { | |
704 return NULL; | |
705 } | 721 } |
706 return CircularRRectEffect::Create(edgeType, cornerFlags, rrect); | 722 |
| 723 return NULL; |
707 } | 724 } |
OLD | NEW |