[svg] Implement feDiffuseLighting

https://www.w3.org/TR/SVG11/filters.html#feDiffuseLightingElement

- Add SkSVGFeDiffuseLighting node
- Move distant light source direction computation into a method on
  SkSVGFeDistantLight
- Implement distant and point light sources for feDiffuseLighting

Bug: skia:10841
Change-Id: I74b8b9e04be5d2c5ac9f912d015dce96367040a1
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/402645
Reviewed-by: Florin Malita <fmalita@chromium.org>
Commit-Queue: Tyler Denniston <tdenniston@google.com>
diff --git a/modules/svg/src/SkSVGFeLightSource.cpp b/modules/svg/src/SkSVGFeLightSource.cpp
index f1f74af..2f05957 100644
--- a/modules/svg/src/SkSVGFeLightSource.cpp
+++ b/modules/svg/src/SkSVGFeLightSource.cpp
@@ -9,6 +9,18 @@
 #include "modules/svg/include/SkSVGFeLightSource.h"
 #include "modules/svg/include/SkSVGValue.h"
 
+SkPoint3 SkSVGFeDistantLight::computeDirection() const {
+    // Computing direction from azimuth+elevation is two 3D rotations:
+    //  - Rotate [1,0,0] about y axis first (elevation)
+    //  - Rotate result about z axis (azimuth)
+    // Which is just the first column vector in the 3x3 matrix Rz*Ry.
+    const float azimuthRad = SkDegreesToRadians(fAzimuth);
+    const float elevationRad = SkDegreesToRadians(fElevation);
+    const float sinAzimuth = sinf(azimuthRad), cosAzimuth = cosf(azimuthRad);
+    const float sinElevation = sinf(elevationRad), cosElevation = cosf(elevationRad);
+    return SkPoint3::Make(cosAzimuth * cosElevation, sinAzimuth * cosElevation, sinElevation);
+}
+
 bool SkSVGFeDistantLight::parseAndSetAttribute(const char* n, const char* v) {
     return INHERITED::parseAndSetAttribute(n, v) ||
            this->setAzimuth(SkSVGAttributeParser::parse<SkSVGNumberType>("azimuth", n, v)) ||