hsl.go 3.9 KB

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