1/* 2 * Copyright 2019 Google LLC 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// Convert HSLA -> RGBA (including clamp and premul). 9// 10// Based on work by Sam Hocevar, Emil Persson, and Ian Taylor [1][2][3]. 11// 12// [1] http://lolengine.net/blog/2013/01/13/fast-rgb-to-hsv 13// [2] http://lolengine.net/blog/2013/07/27/rgb-to-hsv-in-glsl 14// [3] http://www.chilliant.com/rgb2hsv.html 15 16in fragmentProcessor? inputFP; 17 18void main() { 19 half4 inputColor = sample(inputFP); 20 half3 hsl = inputColor.rgb; 21 22 half C = (1 - abs(2 * hsl.z - 1)) * hsl.y; 23 half3 p = hsl.xxx + half3(0, 2/3.0, 1/3.0); 24 half3 q = saturate(abs(fract(p) * 6 - 3) - 1); 25 half3 rgb = (q - 0.5) * C + hsl.z; 26 27 sk_OutColor = saturate(half4(rgb, inputColor.a)); 28 sk_OutColor.rgb *= sk_OutColor.a; 29} 30 31@optimizationFlags { 32 (inputFP ? ProcessorOptimizationFlags(inputFP.get()) : kAll_OptimizationFlags) & 33 (kConstantOutputForConstantInput_OptimizationFlag | kPreservesOpaqueInput_OptimizationFlag) 34} 35 36@class { 37 #include "include/private/SkColorData.h" 38 #include "include/private/SkNx.h" 39 40 SkPMColor4f constantOutputForConstantInput(const SkPMColor4f& inColor) const override { 41 SkPMColor4f c = ConstantOutputForConstantInput(this->childProcessor(0), inColor); 42 const auto H = c[0], 43 S = c[1], 44 L = c[2], 45 C = (1 - std::abs(2 * L - 1)) * S; 46 47 const auto p = H + Sk4f(0, 2/3.f, 1/3.f, 0), 48 q = Sk4f::Min(Sk4f::Max(((p - p.floor()) * 6 - 3).abs() - 1, 0), 1), 49 rgb = (q - 0.5f) * C + L, 50 rgba = Sk4f::Min(Sk4f::Max(Sk4f(rgb[0], rgb[1], rgb[2], c.fA), 0), 1); 51 52 return SkColor4f{rgba[0], rgba[1], rgba[2], rgba[3]}.premul(); 53 } 54} 55