| 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 (!pos || count != 3) { |
| 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 |