OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2006 The Android Open Source Project | 2 * Copyright 2006 The Android Open Source Project |
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 "Sk4fLinearGradient.h" | 8 #include "Sk4fLinearGradient.h" |
9 #include "SkGradientShaderPriv.h" | 9 #include "SkGradientShaderPriv.h" |
10 #include "SkLinearGradient.h" | 10 #include "SkLinearGradient.h" |
(...skipping 737 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
748 SkASSERT(colorCount > 1); | 748 SkASSERT(colorCount > 1); |
749 | 749 |
750 desc->fColors = colors; | 750 desc->fColors = colors; |
751 desc->fPos = pos; | 751 desc->fPos = pos; |
752 desc->fCount = colorCount; | 752 desc->fCount = colorCount; |
753 desc->fTileMode = mode; | 753 desc->fTileMode = mode; |
754 desc->fGradFlags = flags; | 754 desc->fGradFlags = flags; |
755 desc->fLocalMatrix = localMatrix; | 755 desc->fLocalMatrix = localMatrix; |
756 } | 756 } |
757 | 757 |
758 static int simplify(SkScalar* pos, SkColor* colors, int colorCount, SkShader::Ti leMode mode) { | |
759 if (pos) { | |
760 if (3 == colorCount) { | |
761 // Left-edged hard stop gradients (0, 0, 1) can be simplified | |
762 // to a 2-color gradient if first two colors are the same | |
763 if (SkScalarNearlyEqual(pos[0], 0.0f) && | |
764 SkScalarNearlyEqual(pos[1], 0.0f) && | |
765 SkScalarNearlyEqual(pos[2], 1.0f)) { | |
766 | |
767 // If the tile mode is repeat or mirror, first color | |
768 // doesn't matter | |
769 if (SkShader::kRepeat_TileMode == mode || | |
770 SkShader::kMirror_TileMode == mode || | |
771 colors[0] == colors[1]) { | |
772 | |
773 pos[0] = 0.0f; | |
774 pos[1] = 1.0f; | |
775 | |
776 colors[0] = colors[1]; | |
777 colors[1] = colors[2]; | |
778 | |
779 colorCount = 2; | |
f(malita)
2016/08/18 22:54:17
If we fall through here, I think we'll also take t
| |
780 } | |
781 } | |
782 | |
783 // Right-edged hard stop gradients (0, 1, 1) can be simplified | |
784 // to a 2-color gradient if last two colors are the same | |
785 if (SkScalarNearlyEqual(pos[0], 0.0f) && | |
786 SkScalarNearlyEqual(pos[1], 1.0f) && | |
787 SkScalarNearlyEqual(pos[2], 1.0f)) { | |
788 | |
789 // If the tile mode is repeat or mirror, last color | |
790 // doesn't matter | |
791 if (SkShader::kRepeat_TileMode == mode || | |
792 SkShader::kMirror_TileMode == mode || | |
793 colors[1] == colors[2]) { | |
794 | |
795 colorCount = 2; | |
796 } | |
797 } | |
798 } | |
799 } | |
800 return colorCount; | |
801 } | |
802 | |
758 sk_sp<SkShader> SkGradientShader::MakeLinear(const SkPoint pts[2], | 803 sk_sp<SkShader> SkGradientShader::MakeLinear(const SkPoint pts[2], |
759 const SkColor colors[], | 804 const SkColor colors[], |
760 const SkScalar pos[], int colorCount, | 805 const SkScalar pos[], int colorCoun t, |
761 SkShader::TileMode mode, | 806 SkShader::TileMode mode, |
762 uint32_t flags, | 807 uint32_t flags, |
763 const SkMatrix* localMatrix) { | 808 const SkMatrix* localMatrix) { |
764 if (!pts || !SkScalarIsFinite((pts[1] - pts[0]).length())) { | 809 if (!pts || !SkScalarIsFinite((pts[1] - pts[0]).length())) { |
765 return nullptr; | 810 return nullptr; |
766 } | 811 } |
767 if (!valid_grad(colors, pos, colorCount, mode)) { | 812 if (!valid_grad(colors, pos, colorCount, mode)) { |
768 return nullptr; | 813 return nullptr; |
769 } | 814 } |
770 if (1 == colorCount) { | 815 if (1 == colorCount) { |
771 return SkShader::MakeColorShader(colors[0]); | 816 return SkShader::MakeColorShader(colors[0]); |
772 } | 817 } |
773 | 818 |
819 SkAutoTArray<SkScalar> simplifiedPos(colorCount); | |
820 SkAutoTArray<SkColor> simplifiedCol(colorCount); | |
821 for (int i = 0; i < colorCount; i++) { | |
822 simplifiedCol[i] = colors[i]; | |
823 } | |
824 if (pos) { | |
825 for (int i = 0; i < colorCount; i++) { | |
826 simplifiedPos[i] = pos[i]; | |
827 } | |
828 colorCount = simplify(simplifiedPos.get(), simplifiedCol.get(), colorCou nt, mode); | |
829 } else { | |
830 simplifiedPos.reset(0); | |
831 } | |
f(malita)
2016/08/18 22:54:17
It would be nice to
a) avoid these allocations an
| |
832 | |
774 SkGradientShaderBase::Descriptor desc; | 833 SkGradientShaderBase::Descriptor desc; |
775 desc_init(&desc, colors, pos, colorCount, mode, flags, localMatrix); | 834 desc_init(&desc, simplifiedCol.get(), simplifiedPos.get(), colorCount, mode, flags, localMatrix); |
776 return sk_make_sp<SkLinearGradient>(pts, desc); | 835 return sk_make_sp<SkLinearGradient>(pts, desc); |
777 } | 836 } |
778 | 837 |
779 sk_sp<SkShader> SkGradientShader::MakeRadial(const SkPoint& center, SkScalar rad ius, | 838 sk_sp<SkShader> SkGradientShader::MakeRadial(const SkPoint& center, SkScalar rad ius, |
780 const SkColor colors[], | 839 const SkColor colors[], |
781 const SkScalar pos[], int colorCount, | 840 const SkScalar pos[], int colorCount, |
782 SkShader::TileMode mode, | 841 SkShader::TileMode mode, |
783 uint32_t flags, | 842 uint32_t flags, |
784 const SkMatrix* localMatrix) { | 843 const SkMatrix* localMatrix) { |
785 if (radius <= 0) { | 844 if (radius <= 0) { |
786 return nullptr; | 845 return nullptr; |
787 } | 846 } |
788 if (!valid_grad(colors, pos, colorCount, mode)) { | 847 if (!valid_grad(colors, pos, colorCount, mode)) { |
789 return nullptr; | 848 return nullptr; |
790 } | 849 } |
791 if (1 == colorCount) { | 850 if (1 == colorCount) { |
792 return SkShader::MakeColorShader(colors[0]); | 851 return SkShader::MakeColorShader(colors[0]); |
793 } | 852 } |
794 | 853 |
854 SkAutoTArray<SkScalar> simplifiedPos(colorCount); | |
855 SkAutoTArray<SkColor> simplifiedCol(colorCount); | |
856 for (int i = 0; i < colorCount; i++) { | |
857 simplifiedCol[i] = colors[i]; | |
858 } | |
859 if (pos) { | |
860 for (int i = 0; i < colorCount; i++) { | |
861 simplifiedPos[i] = pos[i]; | |
862 } | |
863 colorCount = simplify(simplifiedPos.get(), simplifiedCol.get(), colorCou nt, mode); | |
864 } else { | |
865 simplifiedPos.reset(0); | |
866 } | |
867 | |
795 SkGradientShaderBase::Descriptor desc; | 868 SkGradientShaderBase::Descriptor desc; |
796 desc_init(&desc, colors, pos, colorCount, mode, flags, localMatrix); | 869 desc_init(&desc, simplifiedCol.get(), simplifiedPos.get(), colorCount, mode, flags, localMatrix); |
797 return sk_make_sp<SkRadialGradient>(center, radius, desc); | 870 return sk_make_sp<SkRadialGradient>(center, radius, desc); |
798 } | 871 } |
799 | 872 |
800 sk_sp<SkShader> SkGradientShader::MakeTwoPointConical(const SkPoint& start, | 873 sk_sp<SkShader> SkGradientShader::MakeTwoPointConical(const SkPoint& start, |
801 SkScalar startRadius, | 874 SkScalar startRadius, |
802 const SkPoint& end, | 875 const SkPoint& end, |
803 SkScalar endRadius, | 876 SkScalar endRadius, |
804 const SkColor colors[], | 877 const SkColor colors[], |
805 const SkScalar pos[], | 878 const SkScalar pos[], |
806 int colorCount, | 879 int colorCount, |
807 SkShader::TileMode mode, | 880 SkShader::TileMode mode, |
808 uint32_t flags, | 881 uint32_t flags, |
809 const SkMatrix* localMatrix) { | 882 const SkMatrix* localMatrix) { |
810 if (startRadius < 0 || endRadius < 0) { | 883 if (startRadius < 0 || endRadius < 0) { |
811 return nullptr; | 884 return nullptr; |
812 } | 885 } |
813 if (!valid_grad(colors, pos, colorCount, mode)) { | 886 if (!valid_grad(colors, pos, colorCount, mode)) { |
814 return nullptr; | 887 return nullptr; |
815 } | 888 } |
816 if (startRadius == endRadius) { | 889 if (startRadius == endRadius) { |
817 if (start == end || startRadius == 0) { | 890 if (start == end || startRadius == 0) { |
818 return SkShader::MakeEmptyShader(); | 891 return SkShader::MakeEmptyShader(); |
819 } | 892 } |
820 } | 893 } |
821 if (1 == colorCount) { | 894 if (1 == colorCount) { |
822 return SkShader::MakeColorShader(colors[0]); | 895 return SkShader::MakeColorShader(colors[0]); |
823 } | 896 } |
824 | 897 |
898 SkAutoTArray<SkScalar> simplifiedPos(colorCount); | |
899 SkAutoTArray<SkColor> simplifiedCol(colorCount); | |
900 for (int i = 0; i < colorCount; i++) { | |
901 simplifiedCol[i] = colors[i]; | |
902 } | |
903 if (pos) { | |
904 for (int i = 0; i < colorCount; i++) { | |
905 simplifiedPos[i] = pos[i]; | |
906 } | |
907 colorCount = simplify(simplifiedPos.get(), simplifiedCol.get(), colorCou nt, mode); | |
908 } else { | |
909 simplifiedPos.reset(0); | |
910 } | |
911 | |
825 bool flipGradient = startRadius > endRadius; | 912 bool flipGradient = startRadius > endRadius; |
826 | 913 |
827 SkGradientShaderBase::Descriptor desc; | 914 SkGradientShaderBase::Descriptor desc; |
828 | 915 |
829 if (!flipGradient) { | 916 if (!flipGradient) { |
830 desc_init(&desc, colors, pos, colorCount, mode, flags, localMatrix); | 917 desc_init(&desc, simplifiedCol.get(), simplifiedPos.get(), colorCount, m ode, flags, localMatrix); |
831 return sk_make_sp<SkTwoPointConicalGradient>(start, startRadius, end, en dRadius, | 918 return sk_make_sp<SkTwoPointConicalGradient>(start, startRadius, end, en dRadius, |
832 flipGradient, desc); | 919 flipGradient, desc); |
833 } else { | 920 } else { |
834 SkAutoSTArray<8, SkColor> colorsNew(colorCount); | 921 SkAutoSTArray<8, SkColor> colorsNew(colorCount); |
835 SkAutoSTArray<8, SkScalar> posNew(colorCount); | 922 SkAutoSTArray<8, SkScalar> posNew(colorCount); |
836 for (int i = 0; i < colorCount; ++i) { | 923 for (int i = 0; i < colorCount; ++i) { |
837 colorsNew[i] = colors[colorCount - i - 1]; | 924 colorsNew[i] = simplifiedCol[colorCount - i - 1]; |
838 } | 925 } |
839 | 926 |
840 if (pos) { | 927 if (pos) { |
841 for (int i = 0; i < colorCount; ++i) { | 928 for (int i = 0; i < colorCount; ++i) { |
842 posNew[i] = 1 - pos[colorCount - i - 1]; | 929 posNew[i] = 1 - simplifiedPos[colorCount - i - 1]; |
843 } | 930 } |
844 desc_init(&desc, colorsNew.get(), posNew.get(), colorCount, mode, fl ags, localMatrix); | 931 desc_init(&desc, colorsNew.get(), posNew.get(), colorCount, mode, fl ags, localMatrix); |
845 } else { | 932 } else { |
846 desc_init(&desc, colorsNew.get(), nullptr, colorCount, mode, flags, localMatrix); | 933 desc_init(&desc, colorsNew.get(), nullptr, colorCount, mode, flags, localMatrix); |
847 } | 934 } |
848 | 935 |
849 return sk_make_sp<SkTwoPointConicalGradient>(end, endRadius, start, star tRadius, | 936 return sk_make_sp<SkTwoPointConicalGradient>(end, endRadius, start, star tRadius, |
850 flipGradient, desc); | 937 flipGradient, desc); |
851 } | 938 } |
852 } | 939 } |
853 | 940 |
854 sk_sp<SkShader> SkGradientShader::MakeSweep(SkScalar cx, SkScalar cy, | 941 sk_sp<SkShader> SkGradientShader::MakeSweep(SkScalar cx, SkScalar cy, |
855 const SkColor colors[], | 942 const SkColor colors[], |
856 const SkScalar pos[], | 943 const SkScalar pos[], |
857 int colorCount, | 944 int colorCount, |
858 uint32_t flags, | 945 uint32_t flags, |
859 const SkMatrix* localMatrix) { | 946 const SkMatrix* localMatrix) { |
860 if (!valid_grad(colors, pos, colorCount, SkShader::kClamp_TileMode)) { | 947 if (!valid_grad(colors, pos, colorCount, SkShader::kClamp_TileMode)) { |
861 return nullptr; | 948 return nullptr; |
862 } | 949 } |
863 if (1 == colorCount) { | 950 if (1 == colorCount) { |
864 return SkShader::MakeColorShader(colors[0]); | 951 return SkShader::MakeColorShader(colors[0]); |
865 } | 952 } |
866 | 953 |
954 SkAutoTArray<SkScalar> simplifiedPos(colorCount); | |
955 SkAutoTArray<SkColor> simplifiedCol(colorCount); | |
956 for (int i = 0; i < colorCount; i++) { | |
957 simplifiedCol[i] = colors[i]; | |
958 } | |
959 auto mode = SkShader::kClamp_TileMode; // Bogus tilemode | |
960 if (pos) { | |
961 for (int i = 0; i < colorCount; i++) { | |
962 simplifiedPos[i] = pos[i]; | |
963 } | |
964 colorCount = simplify(simplifiedPos.get(), simplifiedCol.get(), colorCou nt, mode); | |
965 } else { | |
966 simplifiedPos.reset(0); | |
967 } | |
968 | |
867 SkGradientShaderBase::Descriptor desc; | 969 SkGradientShaderBase::Descriptor desc; |
868 desc_init(&desc, colors, pos, colorCount, SkShader::kClamp_TileMode, flags, localMatrix); | 970 desc_init(&desc, simplifiedCol.get(), simplifiedPos.get(), colorCount, mode, flags, localMatrix); |
869 return sk_make_sp<SkSweepGradient>(cx, cy, desc); | 971 return sk_make_sp<SkSweepGradient>(cx, cy, desc); |
870 } | 972 } |
871 | 973 |
872 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkGradientShader) | 974 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkGradientShader) |
873 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLinearGradient) | 975 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLinearGradient) |
874 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkRadialGradient) | 976 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkRadialGradient) |
875 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSweepGradient) | 977 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSweepGradient) |
876 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkTwoPointConicalGradient) | 978 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkTwoPointConicalGradient) |
877 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END | 979 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END |
878 | 980 |
(...skipping 543 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1422 (*stops)[i] = stop; | 1524 (*stops)[i] = stop; |
1423 stop = i < outColors - 1 ? stop + random->nextUScalar1() * (1.f - st op) : 1.f; | 1525 stop = i < outColors - 1 ? stop + random->nextUScalar1() * (1.f - st op) : 1.f; |
1424 } | 1526 } |
1425 } | 1527 } |
1426 *tm = static_cast<SkShader::TileMode>(random->nextULessThan(SkShader::kTileM odeCount)); | 1528 *tm = static_cast<SkShader::TileMode>(random->nextULessThan(SkShader::kTileM odeCount)); |
1427 | 1529 |
1428 return outColors; | 1530 return outColors; |
1429 } | 1531 } |
1430 | 1532 |
1431 #endif | 1533 #endif |
OLD | NEW |