OSDN Git Service

Comments style changed.
[excelize/excelize.git] / hsl.go
1 // Copyright (c) 2012 Rodrigo Moraes. All rights reserved.
2 //
3 // Redistribution and use in source and binary forms, with or without
4 // modification, are permitted provided that the following conditions are
5 // met:
6 //
7 //       * Redistributions of source code must retain the above copyright
8 // notice, this list of conditions and the following disclaimer.
9 //       * Redistributions in binary form must reproduce the above
10 // copyright notice, this list of conditions and the following disclaimer
11 // in the documentation and/or other materials provided with the
12 // distribution.
13 //       * Neither the name of Google Inc. nor the names of its
14 // contributors may be used to endorse or promote products derived from
15 // this software without specific prior written permission.
16 //
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
29 package excelize
30
31 import (
32         "image/color"
33         "math"
34 )
35
36 // HSLModel converts any color.Color to a HSL color.
37 var HSLModel = color.ModelFunc(hslModel)
38
39 // HSL represents a cylindrical coordinate of points in an RGB color model.
40 //
41 // Values are in the range 0 to 1.
42 type HSL struct {
43         H, S, L float64
44 }
45
46 // RGBA returns the alpha-premultiplied red, green, blue and alpha values
47 // for the HSL.
48 func (c HSL) RGBA() (uint32, uint32, uint32, uint32) {
49         r, g, b := HSLToRGB(c.H, c.S, c.L)
50         return uint32(r) * 0x101, uint32(g) * 0x101, uint32(b) * 0x101, 0xffff
51 }
52
53 // hslModel converts a color.Color to HSL.
54 func hslModel(c color.Color) color.Color {
55         if _, ok := c.(HSL); ok {
56                 return c
57         }
58         r, g, b, _ := c.RGBA()
59         h, s, l := RGBToHSL(uint8(r>>8), uint8(g>>8), uint8(b>>8))
60         return HSL{h, s, l}
61 }
62
63 // RGBToHSL converts an RGB triple to a HSL triple.
64 func RGBToHSL(r, g, b uint8) (h, s, l float64) {
65         fR := float64(r) / 255
66         fG := float64(g) / 255
67         fB := float64(b) / 255
68         max := math.Max(math.Max(fR, fG), fB)
69         min := math.Min(math.Min(fR, fG), fB)
70         l = (max + min) / 2
71         if max == min {
72                 // Achromatic.
73                 h, s = 0, 0
74         } else {
75                 // Chromatic.
76                 d := max - min
77                 if l > 0.5 {
78                         s = d / (2.0 - max - min)
79                 } else {
80                         s = d / (max + min)
81                 }
82                 switch max {
83                 case fR:
84                         h = (fG - fB) / d
85                         if fG < fB {
86                                 h += 6
87                         }
88                 case fG:
89                         h = (fB-fR)/d + 2
90                 case fB:
91                         h = (fR-fG)/d + 4
92                 }
93                 h /= 6
94         }
95         return
96 }
97
98 // HSLToRGB converts an HSL triple to a RGB triple.
99 func HSLToRGB(h, s, l float64) (r, g, b uint8) {
100         var fR, fG, fB float64
101         if s == 0 {
102                 fR, fG, fB = l, l, l
103         } else {
104                 var q float64
105                 if l < 0.5 {
106                         q = l * (1 + s)
107                 } else {
108                         q = l + s - s*l
109                 }
110                 p := 2*l - q
111                 fR = hueToRGB(p, q, h+1.0/3)
112                 fG = hueToRGB(p, q, h)
113                 fB = hueToRGB(p, q, h-1.0/3)
114         }
115         r = uint8((fR * 255) + 0.5)
116         g = uint8((fG * 255) + 0.5)
117         b = uint8((fB * 255) + 0.5)
118         return
119 }
120
121 // hueToRGB is a helper function for HSLToRGB.
122 func hueToRGB(p, q, t float64) float64 {
123         if t < 0 {
124                 t++
125         }
126         if t > 1 {
127                 t--
128         }
129         if t < 1.0/6 {
130                 return p + (q-p)*6*t
131         }
132         if t < 0.5 {
133                 return q
134         }
135         if t < 2.0/3 {
136                 return p + (q-p)*(2.0/3-t)*6
137         }
138         return p
139 }