| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2012 The Android Open Source Project | 2 * Copyright 2012 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 "SkLightingImageFilter.h" | 8 #include "SkLightingImageFilter.h" |
| 9 #include "SkBitmap.h" | 9 #include "SkBitmap.h" |
| 10 #include "SkColorPriv.h" | 10 #include "SkColorPriv.h" |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 57 | 57 |
| 58 class DiffuseLightingType { | 58 class DiffuseLightingType { |
| 59 public: | 59 public: |
| 60 DiffuseLightingType(SkScalar kd) | 60 DiffuseLightingType(SkScalar kd) |
| 61 : fKD(kd) {} | 61 : fKD(kd) {} |
| 62 SkPMColor light(const SkPoint3& normal, const SkPoint3& surfaceTolight, cons
t SkPoint3& lightColor) const { | 62 SkPMColor light(const SkPoint3& normal, const SkPoint3& surfaceTolight, cons
t SkPoint3& lightColor) const { |
| 63 SkScalar colorScale = SkScalarMul(fKD, normal.dot(surfaceTolight)); | 63 SkScalar colorScale = SkScalarMul(fKD, normal.dot(surfaceTolight)); |
| 64 colorScale = SkScalarClampMax(colorScale, SK_Scalar1); | 64 colorScale = SkScalarClampMax(colorScale, SK_Scalar1); |
| 65 SkPoint3 color(lightColor * colorScale); | 65 SkPoint3 color(lightColor * colorScale); |
| 66 return SkPackARGB32(255, | 66 return SkPackARGB32(255, |
| 67 SkScalarFloorToInt(color.fX), | 67 SkClampMax(SkScalarFloorToInt(color.fX), 255), |
| 68 SkScalarFloorToInt(color.fY), | 68 SkClampMax(SkScalarFloorToInt(color.fY), 255), |
| 69 SkScalarFloorToInt(color.fZ)); | 69 SkClampMax(SkScalarFloorToInt(color.fZ), 255)); |
| 70 } | 70 } |
| 71 private: | 71 private: |
| 72 SkScalar fKD; | 72 SkScalar fKD; |
| 73 }; | 73 }; |
| 74 | 74 |
| 75 class SpecularLightingType { | 75 class SpecularLightingType { |
| 76 public: | 76 public: |
| 77 SpecularLightingType(SkScalar ks, SkScalar shininess) | 77 SpecularLightingType(SkScalar ks, SkScalar shininess) |
| 78 : fKS(ks), fShininess(shininess) {} | 78 : fKS(ks), fShininess(shininess) {} |
| 79 SkPMColor light(const SkPoint3& normal, const SkPoint3& surfaceTolight, cons
t SkPoint3& lightColor) const { | 79 SkPMColor light(const SkPoint3& normal, const SkPoint3& surfaceTolight, cons
t SkPoint3& lightColor) const { |
| 80 SkPoint3 halfDir(surfaceTolight); | 80 SkPoint3 halfDir(surfaceTolight); |
| 81 halfDir.fZ += SK_Scalar1; // eye position is always (0, 0, 1) | 81 halfDir.fZ += SK_Scalar1; // eye position is always (0, 0, 1) |
| 82 halfDir.normalize(); | 82 halfDir.normalize(); |
| 83 SkScalar colorScale = SkScalarMul(fKS, | 83 SkScalar colorScale = SkScalarMul(fKS, |
| 84 SkScalarPow(normal.dot(halfDir), fShininess)); | 84 SkScalarPow(normal.dot(halfDir), fShininess)); |
| 85 colorScale = SkScalarClampMax(colorScale, SK_Scalar1); | 85 colorScale = SkScalarClampMax(colorScale, SK_Scalar1); |
| 86 SkPoint3 color(lightColor * colorScale); | 86 SkPoint3 color(lightColor * colorScale); |
| 87 return SkPackARGB32(SkScalarFloorToInt(color.maxComponent()), | 87 return SkPackARGB32(SkClampMax(SkScalarFloorToInt(color.maxComponent()),
255), |
| 88 SkScalarFloorToInt(color.fX), | 88 SkClampMax(SkScalarFloorToInt(color.fX), 255), |
| 89 SkScalarFloorToInt(color.fY), | 89 SkClampMax(SkScalarFloorToInt(color.fY), 255), |
| 90 SkScalarFloorToInt(color.fZ)); | 90 SkClampMax(SkScalarFloorToInt(color.fZ), 255)); |
| 91 } | 91 } |
| 92 private: | 92 private: |
| 93 SkScalar fKS; | 93 SkScalar fKS; |
| 94 SkScalar fShininess; | 94 SkScalar fShininess; |
| 95 }; | 95 }; |
| 96 | 96 |
| 97 inline SkScalar sobel(int a, int b, int c, int d, int e, int f, SkScalar scale)
{ | 97 inline SkScalar sobel(int a, int b, int c, int d, int e, int f, SkScalar scale)
{ |
| 98 return SkScalarMul(SkIntToScalar(-a + b - 2 * c + 2 * d -e + f), scale); | 98 return SkScalarMul(SkIntToScalar(-a + b - 2 * c + 2 * d -e + f), scale); |
| 99 } | 99 } |
| 100 | 100 |
| (...skipping 565 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 666 }; | 666 }; |
| 667 | 667 |
| 668 /////////////////////////////////////////////////////////////////////////////// | 668 /////////////////////////////////////////////////////////////////////////////// |
| 669 | 669 |
| 670 class SkSpotLight : public SkLight { | 670 class SkSpotLight : public SkLight { |
| 671 public: | 671 public: |
| 672 SkSpotLight(const SkPoint3& location, const SkPoint3& target, SkScalar specu
larExponent, SkScalar cutoffAngle, SkColor color) | 672 SkSpotLight(const SkPoint3& location, const SkPoint3& target, SkScalar specu
larExponent, SkScalar cutoffAngle, SkColor color) |
| 673 : INHERITED(color), | 673 : INHERITED(color), |
| 674 fLocation(location), | 674 fLocation(location), |
| 675 fTarget(target), | 675 fTarget(target), |
| 676 fSpecularExponent(specularExponent) | 676 fSpecularExponent(SkScalarPin(specularExponent, kSpecularExponentMin, kSp
ecularExponentMax)) |
| 677 { | 677 { |
| 678 fS = target - location; | 678 fS = target - location; |
| 679 fS.normalize(); | 679 fS.normalize(); |
| 680 fCosOuterConeAngle = SkScalarCos(SkDegreesToRadians(cutoffAngle)); | 680 fCosOuterConeAngle = SkScalarCos(SkDegreesToRadians(cutoffAngle)); |
| 681 const SkScalar antiAliasThreshold = SkFloatToScalar(0.016f); | 681 const SkScalar antiAliasThreshold = SkFloatToScalar(0.016f); |
| 682 fCosInnerConeAngle = fCosOuterConeAngle + antiAliasThreshold; | 682 fCosInnerConeAngle = fCosOuterConeAngle + antiAliasThreshold; |
| 683 fConeScale = SkScalarInvert(antiAliasThreshold); | 683 fConeScale = SkScalarInvert(antiAliasThreshold); |
| 684 } | 684 } |
| 685 | 685 |
| 686 virtual SkLight* transform(const SkMatrix& matrix) const { | 686 virtual SkLight* transform(const SkMatrix& matrix) const { |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 771 | 771 |
| 772 const SkSpotLight& o = static_cast<const SkSpotLight&>(other); | 772 const SkSpotLight& o = static_cast<const SkSpotLight&>(other); |
| 773 return INHERITED::isEqual(other) && | 773 return INHERITED::isEqual(other) && |
| 774 fLocation == o.fLocation && | 774 fLocation == o.fLocation && |
| 775 fTarget == o.fTarget && | 775 fTarget == o.fTarget && |
| 776 fSpecularExponent == o.fSpecularExponent && | 776 fSpecularExponent == o.fSpecularExponent && |
| 777 fCosOuterConeAngle == o.fCosOuterConeAngle; | 777 fCosOuterConeAngle == o.fCosOuterConeAngle; |
| 778 } | 778 } |
| 779 | 779 |
| 780 private: | 780 private: |
| 781 static const SkScalar kSpecularExponentMin; |
| 782 static const SkScalar kSpecularExponentMax; |
| 783 |
| 781 typedef SkLight INHERITED; | 784 typedef SkLight INHERITED; |
| 782 SkPoint3 fLocation; | 785 SkPoint3 fLocation; |
| 783 SkPoint3 fTarget; | 786 SkPoint3 fTarget; |
| 784 SkScalar fSpecularExponent; | 787 SkScalar fSpecularExponent; |
| 785 SkScalar fCosOuterConeAngle; | 788 SkScalar fCosOuterConeAngle; |
| 786 SkScalar fCosInnerConeAngle; | 789 SkScalar fCosInnerConeAngle; |
| 787 SkScalar fConeScale; | 790 SkScalar fConeScale; |
| 788 SkPoint3 fS; | 791 SkPoint3 fS; |
| 789 }; | 792 }; |
| 790 | 793 |
| 794 // According to the spec, the specular term should be in the range [1, 128] : |
| 795 // http://www.w3.org/TR/SVG/filters.html#feSpecularLightingSpecularExponentAttri
bute |
| 796 const SkScalar SkSpotLight::kSpecularExponentMin = SkFloatToScalar(1.0f); |
| 797 const SkScalar SkSpotLight::kSpecularExponentMax = SkFloatToScalar(128.0f); |
| 798 |
| 791 /////////////////////////////////////////////////////////////////////////////// | 799 /////////////////////////////////////////////////////////////////////////////// |
| 792 | 800 |
| 793 SkLightingImageFilter::SkLightingImageFilter(SkLight* light, SkScalar surfaceSca
le, SkImageFilter* input, const SkIRect* cropRect) | 801 SkLightingImageFilter::SkLightingImageFilter(SkLight* light, SkScalar surfaceSca
le, SkImageFilter* input, const SkIRect* cropRect) |
| 794 : INHERITED(input, cropRect), | 802 : INHERITED(input, cropRect), |
| 795 fLight(light), | 803 fLight(light), |
| 796 fSurfaceScale(SkScalarDiv(surfaceScale, SkIntToScalar(255))) | 804 fSurfaceScale(SkScalarDiv(surfaceScale, SkIntToScalar(255))) |
| 797 { | 805 { |
| 798 SkASSERT(fLight); | 806 SkASSERT(fLight); |
| 799 // our caller knows that we take ownership of the light, so we don't | 807 // our caller knows that we take ownership of the light, so we don't |
| 800 // need to call ref() here. | 808 // need to call ref() here. |
| (...skipping 763 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1564 | 1572 |
| 1565 #endif | 1573 #endif |
| 1566 | 1574 |
| 1567 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkLightingImageFilter) | 1575 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkLightingImageFilter) |
| 1568 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDiffuseLightingImageFilter) | 1576 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDiffuseLightingImageFilter) |
| 1569 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSpecularLightingImageFilter) | 1577 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSpecularLightingImageFilter) |
| 1570 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDistantLight) | 1578 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDistantLight) |
| 1571 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPointLight) | 1579 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPointLight) |
| 1572 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSpotLight) | 1580 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSpotLight) |
| 1573 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END | 1581 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END |
| OLD | NEW |