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 749 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
760 SkColor tmp[2]; \ | 760 SkColor tmp[2]; \ |
761 do { \ | 761 do { \ |
762 if (1 == count) { \ | 762 if (1 == count) { \ |
763 tmp[0] = tmp[1] = colors[0]; \ | 763 tmp[0] = tmp[1] = colors[0]; \ |
764 colors = tmp; \ | 764 colors = tmp; \ |
765 pos = nullptr; \ | 765 pos = nullptr; \ |
766 count = 2; \ | 766 count = 2; \ |
767 } \ | 767 } \ |
768 } while (0) | 768 } while (0) |
769 | 769 |
770 struct ColorStopOptimizer { | |
771 ColorStopOptimizer(const SkColor* colors, const SkScalar* pos, | |
772 int count, SkShader::TileMode mode) | |
773 : fColors(colors) | |
774 , fPos(pos) | |
775 , fCount(count) { | |
776 | |
777 if (count != 3) { | |
f(malita)
2016/08/19 15:26:20
We should also bail here if pos is null (which I t
| |
778 return; | |
779 } | |
780 | |
781 if (SkScalarNearlyEqual(pos[0], 0.0f) && | |
782 SkScalarNearlyEqual(pos[1], 0.0f) && | |
783 SkScalarNearlyEqual(pos[2], 1.0f)) { | |
784 | |
785 if (SkShader::kRepeat_TileMode == mode || | |
786 SkShader::kMirror_TileMode == mode || | |
787 colors[0] == colors[1]) { | |
788 | |
789 fColorStorage[0] = colors[1]; | |
790 fColorStorage[1] = colors[2]; | |
791 fPosStorage[0] = 0.0f; | |
792 fPosStorage[1] = 1.0f; | |
793 | |
794 fColors = fColorStorage; | |
795 fPos = fPosStorage; | |
796 fCount = 2; | |
797 } | |
798 } else if (SkScalarNearlyEqual(pos[0], 0.0f) && | |
799 SkScalarNearlyEqual(pos[1], 1.0f) && | |
800 SkScalarNearlyEqual(pos[2], 1.0f)) { | |
801 | |
802 if (SkShader::kRepeat_TileMode == mode || | |
803 SkShader::kMirror_TileMode == mode || | |
804 colors[1] == colors[2]) { | |
805 | |
806 fCount = 2; | |
807 } | |
808 } | |
809 } | |
810 | |
811 const SkColor* fColors; | |
812 const SkScalar* fPos; | |
813 int fCount; | |
814 | |
815 SkColor fColorStorage[2]; | |
816 SkScalar fPosStorage[2]; | |
817 }; | |
818 | |
770 sk_sp<SkShader> SkGradientShader::MakeLinear(const SkPoint pts[2], | 819 sk_sp<SkShader> SkGradientShader::MakeLinear(const SkPoint pts[2], |
771 const SkColor colors[], | 820 const SkColor colors[], |
772 const SkScalar pos[], int colorCount, | 821 const SkScalar pos[], int colorCoun t, |
773 SkShader::TileMode mode, | 822 SkShader::TileMode mode, |
774 uint32_t flags, | 823 uint32_t flags, |
775 const SkMatrix* localMatrix) { | 824 const SkMatrix* localMatrix) { |
776 if (!pts || !SkScalarIsFinite((pts[1] - pts[0]).length())) { | 825 if (!pts || !SkScalarIsFinite((pts[1] - pts[0]).length())) { |
777 return nullptr; | 826 return nullptr; |
778 } | 827 } |
779 if (!valid_grad(colors, pos, colorCount, mode)) { | 828 if (!valid_grad(colors, pos, colorCount, mode)) { |
780 return nullptr; | 829 return nullptr; |
781 } | 830 } |
782 if (1 == colorCount) { | 831 if (1 == colorCount) { |
783 return SkShader::MakeColorShader(colors[0]); | 832 return SkShader::MakeColorShader(colors[0]); |
784 } | 833 } |
785 | 834 |
835 ColorStopOptimizer opt(colors, pos, colorCount, mode); | |
836 | |
786 SkGradientShaderBase::Descriptor desc; | 837 SkGradientShaderBase::Descriptor desc; |
787 desc_init(&desc, colors, pos, colorCount, mode, flags, localMatrix); | 838 desc_init(&desc, opt.fColors, opt.fPos, opt.fCount, mode, flags, localMatrix ); |
788 return sk_make_sp<SkLinearGradient>(pts, desc); | 839 return sk_make_sp<SkLinearGradient>(pts, desc); |
789 } | 840 } |
790 | 841 |
791 sk_sp<SkShader> SkGradientShader::MakeRadial(const SkPoint& center, SkScalar rad ius, | 842 sk_sp<SkShader> SkGradientShader::MakeRadial(const SkPoint& center, SkScalar rad ius, |
792 const SkColor colors[], | 843 const SkColor colors[], |
793 const SkScalar pos[], int colorCount, | 844 const SkScalar pos[], int colorCount, |
794 SkShader::TileMode mode, | 845 SkShader::TileMode mode, |
795 uint32_t flags, | 846 uint32_t flags, |
796 const SkMatrix* localMatrix) { | 847 const SkMatrix* localMatrix) { |
797 if (radius <= 0) { | 848 if (radius <= 0) { |
798 return nullptr; | 849 return nullptr; |
799 } | 850 } |
800 if (!valid_grad(colors, pos, colorCount, mode)) { | 851 if (!valid_grad(colors, pos, colorCount, mode)) { |
801 return nullptr; | 852 return nullptr; |
802 } | 853 } |
803 if (1 == colorCount) { | 854 if (1 == colorCount) { |
804 return SkShader::MakeColorShader(colors[0]); | 855 return SkShader::MakeColorShader(colors[0]); |
805 } | 856 } |
806 | 857 |
858 ColorStopOptimizer opt(colors, pos, colorCount, mode); | |
859 | |
807 SkGradientShaderBase::Descriptor desc; | 860 SkGradientShaderBase::Descriptor desc; |
808 desc_init(&desc, colors, pos, colorCount, mode, flags, localMatrix); | 861 desc_init(&desc, opt.fColors, opt.fPos, opt.fCount, mode, flags, localMatrix ); |
809 return sk_make_sp<SkRadialGradient>(center, radius, desc); | 862 return sk_make_sp<SkRadialGradient>(center, radius, desc); |
810 } | 863 } |
811 | 864 |
812 sk_sp<SkShader> SkGradientShader::MakeTwoPointConical(const SkPoint& start, | 865 sk_sp<SkShader> SkGradientShader::MakeTwoPointConical(const SkPoint& start, |
813 SkScalar startRadius, | 866 SkScalar startRadius, |
814 const SkPoint& end, | 867 const SkPoint& end, |
815 SkScalar endRadius, | 868 SkScalar endRadius, |
816 const SkColor colors[], | 869 const SkColor colors[], |
817 const SkScalar pos[], | 870 const SkScalar pos[], |
818 int colorCount, | 871 int colorCount, |
819 SkShader::TileMode mode, | 872 SkShader::TileMode mode, |
820 uint32_t flags, | 873 uint32_t flags, |
821 const SkMatrix* localMatrix) { | 874 const SkMatrix* localMatrix) { |
822 if (startRadius < 0 || endRadius < 0) { | 875 if (startRadius < 0 || endRadius < 0) { |
823 return nullptr; | 876 return nullptr; |
824 } | 877 } |
825 if (!valid_grad(colors, pos, colorCount, mode)) { | 878 if (!valid_grad(colors, pos, colorCount, mode)) { |
826 return nullptr; | 879 return nullptr; |
827 } | 880 } |
828 if (startRadius == endRadius) { | 881 if (startRadius == endRadius) { |
829 if (start == end || startRadius == 0) { | 882 if (start == end || startRadius == 0) { |
830 return SkShader::MakeEmptyShader(); | 883 return SkShader::MakeEmptyShader(); |
831 } | 884 } |
832 } | 885 } |
833 EXPAND_1_COLOR(colorCount); | 886 EXPAND_1_COLOR(colorCount); |
834 | 887 |
888 ColorStopOptimizer opt(colors, pos, colorCount, mode); | |
889 | |
835 bool flipGradient = startRadius > endRadius; | 890 bool flipGradient = startRadius > endRadius; |
836 | 891 |
837 SkGradientShaderBase::Descriptor desc; | 892 SkGradientShaderBase::Descriptor desc; |
838 | 893 |
839 if (!flipGradient) { | 894 if (!flipGradient) { |
840 desc_init(&desc, colors, pos, colorCount, mode, flags, localMatrix); | 895 desc_init(&desc, opt.fColors, opt.fPos, opt.fCount, mode, flags, localMa trix); |
841 return sk_make_sp<SkTwoPointConicalGradient>(start, startRadius, end, en dRadius, | 896 return sk_make_sp<SkTwoPointConicalGradient>(start, startRadius, end, en dRadius, |
842 flipGradient, desc); | 897 flipGradient, desc); |
843 } else { | 898 } else { |
844 SkAutoSTArray<8, SkColor> colorsNew(colorCount); | 899 SkAutoSTArray<8, SkColor> colorsNew(colorCount); |
845 SkAutoSTArray<8, SkScalar> posNew(colorCount); | 900 SkAutoSTArray<8, SkScalar> posNew(colorCount); |
846 for (int i = 0; i < colorCount; ++i) { | 901 for (int i = 0; i < colorCount; ++i) { |
847 colorsNew[i] = colors[colorCount - i - 1]; | 902 colorsNew[i] = opt.fColors[colorCount - i - 1]; |
848 } | 903 } |
849 | 904 |
850 if (pos) { | 905 if (pos) { |
851 for (int i = 0; i < colorCount; ++i) { | 906 for (int i = 0; i < colorCount; ++i) { |
852 posNew[i] = 1 - pos[colorCount - i - 1]; | 907 posNew[i] = 1 - opt.fPos[colorCount - i - 1]; |
853 } | 908 } |
854 desc_init(&desc, colorsNew.get(), posNew.get(), colorCount, mode, fl ags, localMatrix); | 909 desc_init(&desc, colorsNew.get(), posNew.get(), colorCount, mode, fl ags, localMatrix); |
855 } else { | 910 } else { |
856 desc_init(&desc, colorsNew.get(), nullptr, colorCount, mode, flags, localMatrix); | 911 desc_init(&desc, colorsNew.get(), nullptr, colorCount, mode, flags, localMatrix); |
857 } | 912 } |
858 | 913 |
859 return sk_make_sp<SkTwoPointConicalGradient>(end, endRadius, start, star tRadius, | 914 return sk_make_sp<SkTwoPointConicalGradient>(end, endRadius, start, star tRadius, |
860 flipGradient, desc); | 915 flipGradient, desc); |
861 } | 916 } |
862 } | 917 } |
863 | 918 |
864 sk_sp<SkShader> SkGradientShader::MakeSweep(SkScalar cx, SkScalar cy, | 919 sk_sp<SkShader> SkGradientShader::MakeSweep(SkScalar cx, SkScalar cy, |
865 const SkColor colors[], | 920 const SkColor colors[], |
866 const SkScalar pos[], | 921 const SkScalar pos[], |
867 int colorCount, | 922 int colorCount, |
868 uint32_t flags, | 923 uint32_t flags, |
869 const SkMatrix* localMatrix) { | 924 const SkMatrix* localMatrix) { |
870 if (!valid_grad(colors, pos, colorCount, SkShader::kClamp_TileMode)) { | 925 if (!valid_grad(colors, pos, colorCount, SkShader::kClamp_TileMode)) { |
871 return nullptr; | 926 return nullptr; |
872 } | 927 } |
873 if (1 == colorCount) { | 928 if (1 == colorCount) { |
874 return SkShader::MakeColorShader(colors[0]); | 929 return SkShader::MakeColorShader(colors[0]); |
875 } | 930 } |
876 | 931 |
932 auto mode = SkShader::kClamp_TileMode; | |
933 | |
934 ColorStopOptimizer opt(colors, pos, colorCount, mode); | |
935 | |
877 SkGradientShaderBase::Descriptor desc; | 936 SkGradientShaderBase::Descriptor desc; |
878 desc_init(&desc, colors, pos, colorCount, SkShader::kClamp_TileMode, flags, localMatrix); | 937 desc_init(&desc, opt.fColors, opt.fPos, opt.fCount, mode, flags, localMatrix ); |
879 return sk_make_sp<SkSweepGradient>(cx, cy, desc); | 938 return sk_make_sp<SkSweepGradient>(cx, cy, desc); |
880 } | 939 } |
881 | 940 |
882 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkGradientShader) | 941 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkGradientShader) |
883 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLinearGradient) | 942 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLinearGradient) |
884 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkRadialGradient) | 943 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkRadialGradient) |
885 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSweepGradient) | 944 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSweepGradient) |
886 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkTwoPointConicalGradient) | 945 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkTwoPointConicalGradient) |
887 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END | 946 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END |
888 | 947 |
(...skipping 543 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1432 (*stops)[i] = stop; | 1491 (*stops)[i] = stop; |
1433 stop = i < outColors - 1 ? stop + random->nextUScalar1() * (1.f - st op) : 1.f; | 1492 stop = i < outColors - 1 ? stop + random->nextUScalar1() * (1.f - st op) : 1.f; |
1434 } | 1493 } |
1435 } | 1494 } |
1436 *tm = static_cast<SkShader::TileMode>(random->nextULessThan(SkShader::kTileM odeCount)); | 1495 *tm = static_cast<SkShader::TileMode>(random->nextULessThan(SkShader::kTileM odeCount)); |
1437 | 1496 |
1438 return outColors; | 1497 return outColors; |
1439 } | 1498 } |
1440 | 1499 |
1441 #endif | 1500 #endif |
OLD | NEW |