1 /*
2  * Copyright 2012 The Android Open Source Project
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #ifndef SkLightingImageFilter_DEFINED
9 #define SkLightingImageFilter_DEFINED
10 
11 #include "SkImageFilter.h"
12 #include "SkColor.h"
13 
14 class SK_API SkPoint3 {
15 public:
SkPoint3()16     SkPoint3() {}
SkPoint3(SkScalar x,SkScalar y,SkScalar z)17     SkPoint3(SkScalar x, SkScalar y, SkScalar z)
18       : fX(x), fY(y), fZ(z) {}
dot(const SkPoint3 & other)19     SkScalar dot(const SkPoint3& other) const {
20         return fX * other.fX + fY * other.fY + fZ * other.fZ;
21     }
maxComponent()22     SkScalar maxComponent() const {
23         return fX > fY ? (fX > fZ ? fX : fZ) : (fY > fZ ? fY : fZ);
24     }
normalize()25     void normalize() {
26         // Small epsilon is added to prevent division by 0.
27         SkScalar scale = SkScalarInvert(SkScalarSqrt(dot(*this)) + SK_ScalarNearlyZero);
28         fX = fX * scale;
29         fY = fY * scale;
30         fZ = fZ * scale;
31     }
32     SkPoint3 operator*(SkScalar scalar) const {
33         return SkPoint3(fX * scalar, fY * scalar, fZ * scalar);
34     }
35     SkPoint3 operator-(const SkPoint3& other) const {
36         return SkPoint3(fX - other.fX, fY - other.fY, fZ - other.fZ);
37     }
38     bool operator==(const SkPoint3& other) const {
39         return fX == other.fX && fY == other.fY && fZ == other.fZ;
40     }
41     SkScalar fX, fY, fZ;
42 };
43 
44 class SkLight;
45 
46 class SK_API SkLightingImageFilter : public SkImageFilter {
47 public:
48     static SkImageFilter* CreateDistantLitDiffuse(const SkPoint3& direction,
49         SkColor lightColor, SkScalar surfaceScale, SkScalar kd,
50         SkImageFilter* input = NULL, const CropRect* cropRect = NULL);
51     static SkImageFilter* CreatePointLitDiffuse(const SkPoint3& location,
52         SkColor lightColor, SkScalar surfaceScale, SkScalar kd,
53         SkImageFilter* input = NULL, const CropRect* cropRect = NULL);
54     static SkImageFilter* CreateSpotLitDiffuse(const SkPoint3& location,
55         const SkPoint3& target, SkScalar specularExponent, SkScalar cutoffAngle,
56         SkColor lightColor, SkScalar surfaceScale, SkScalar kd,
57         SkImageFilter* input = NULL, const CropRect* cropRect = NULL);
58     static SkImageFilter* CreateDistantLitSpecular(const SkPoint3& direction,
59         SkColor lightColor, SkScalar surfaceScale, SkScalar ks,
60         SkScalar shininess, SkImageFilter* input = NULL, const CropRect* cropRect = NULL);
61     static SkImageFilter* CreatePointLitSpecular(const SkPoint3& location,
62         SkColor lightColor, SkScalar surfaceScale, SkScalar ks,
63         SkScalar shininess, SkImageFilter* input = NULL, const CropRect* cropRect = NULL);
64     static SkImageFilter* CreateSpotLitSpecular(const SkPoint3& location,
65         const SkPoint3& target, SkScalar specularExponent, SkScalar cutoffAngle,
66         SkColor lightColor, SkScalar surfaceScale, SkScalar ks,
67         SkScalar shininess, SkImageFilter* input = NULL, const CropRect* cropRect = NULL);
68     ~SkLightingImageFilter();
69 
70     SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP()
71 
72 protected:
73     SkLightingImageFilter(SkLight* light,
74                           SkScalar surfaceScale,
75                           SkImageFilter* input,
76                           const CropRect* cropRect);
77     void flatten(SkWriteBuffer&) const override;
light()78     const SkLight* light() const { return fLight.get(); }
surfaceScale()79     SkScalar surfaceScale() const { return fSurfaceScale; }
80 
81 private:
82     typedef SkImageFilter INHERITED;
83     SkAutoTUnref<SkLight> fLight;
84     SkScalar fSurfaceScale;
85 };
86 
87 #endif
88