summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonas Schäfer <j.wielicki@sotecware.net>2019-02-14 16:35:28 +0100
committerJonas Schäfer <j.wielicki@sotecware.net>2019-02-14 16:35:39 +0100
commit07606b0cd252fe2836120ed43abd169c9470ad0f (patch)
treea225b289c73ad9606e643ff7a8b4f34f8f379644
parent2b70b57f32d9ac83ed2ec29145f4422779b010ff (diff)
downloadpoezio-07606b0cd252fe2836120ed43abd169c9470ad0f.tar.gz
poezio-07606b0cd252fe2836120ed43abd169c9470ad0f.tar.bz2
poezio-07606b0cd252fe2836120ed43abd169c9470ad0f.tar.xz
poezio-07606b0cd252fe2836120ed43abd169c9470ad0f.zip
Embed hsluv
See: https://lab.louiz.org/poezio/poezio/merge_requests/13#note_7453
-rw-r--r--poezio/colors.py2
-rw-r--r--poezio/hsluv.py360
2 files changed, 361 insertions, 1 deletions
diff --git a/poezio/colors.py b/poezio/colors.py
index e8bbfa36..c1019145 100644
--- a/poezio/colors.py
+++ b/poezio/colors.py
@@ -3,7 +3,7 @@ import curses
import hashlib
import math
-import hsluv
+from . import hsluv
Palette = Dict[float, int]
diff --git a/poezio/hsluv.py b/poezio/hsluv.py
new file mode 100644
index 00000000..7dce5061
--- /dev/null
+++ b/poezio/hsluv.py
@@ -0,0 +1,360 @@
+# This file was taken from https://github.com/hsluv/hsluv-python
+#
+# Copyright (c) 2015 Alexei Boronine
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+""" This module is generated by transpiling Haxe into Python and cleaning
+the resulting code by hand, e.g. removing unused Haxe classes. To try it
+yourself, clone https://github.com/hsluv/hsluv and run:
+
+ haxe -cp haxe/src hsluv.Hsluv -python hsluv.py
+"""
+
+import math
+
+
+
+__version__ = '0.0.2'
+
+m = [[3.240969941904521, -1.537383177570093, -0.498610760293],
+ [-0.96924363628087, 1.87596750150772, 0.041555057407175],
+ [0.055630079696993, -0.20397695888897, 1.056971514242878]]
+minv = [[0.41239079926595, 0.35758433938387, 0.18048078840183],
+ [0.21263900587151, 0.71516867876775, 0.072192315360733],
+ [0.019330818715591, 0.11919477979462, 0.95053215224966]]
+refY = 1.0
+refU = 0.19783000664283
+refV = 0.46831999493879
+kappa = 903.2962962
+epsilon = 0.0088564516
+hex_chars = "0123456789abcdef"
+
+
+def _distance_line_from_origin(line):
+ v = math.pow(line['slope'], 2) + 1
+ return math.fabs(line['intercept']) / math.sqrt(v)
+
+
+def _length_of_ray_until_intersect(theta, line):
+ return line['intercept'] / (math.sin(theta) - line['slope'] * math.cos(theta))
+
+
+def _get_bounds(l):
+ result = []
+ sub1 = math.pow(l + 16, 3) / 1560896
+ if sub1 > epsilon:
+ sub2 = sub1
+ else:
+ sub2 = l / kappa
+ _g = 0
+ while _g < 3:
+ c = _g
+ _g = _g + 1
+ m1 = m[c][0]
+ m2 = m[c][1]
+ m3 = m[c][2]
+ _g1 = 0
+ while _g1 < 2:
+ t = _g1
+ _g1 = _g1 + 1
+ top1 = (284517 * m1 - 94839 * m3) * sub2
+ top2 = (838422 * m3 + 769860 * m2 + 731718 * m1) * l * sub2 - (769860 * t) * l
+ bottom = (632260 * m3 - 126452 * m2) * sub2 + 126452 * t
+ result.append({'slope': top1 / bottom, 'intercept': top2 / bottom})
+ return result
+
+
+def _max_safe_chroma_for_l(l):
+ bounds = _get_bounds(l)
+ _hx_min = 1.7976931348623157e+308
+ _g = 0
+ while _g < 2:
+ i = _g
+ _g = _g + 1
+ length = _distance_line_from_origin(bounds[i])
+ if math.isnan(_hx_min):
+ _hx_min = _hx_min
+ elif math.isnan(length):
+ _hx_min = length
+ else:
+ _hx_min = min(_hx_min, length)
+ return _hx_min
+
+
+def _max_chroma_for_lh(l, h):
+ hrad = h / 360 * math.pi * 2
+ bounds = _get_bounds(l)
+ _hx_min = 1.7976931348623157e+308
+ _g = 0
+ while _g < len(bounds):
+ bound = bounds[_g]
+ _g = (_g + 1)
+ length = _length_of_ray_until_intersect(hrad, bound)
+ if length >= 0:
+ if math.isnan(_hx_min):
+ _hx_min = _hx_min
+ elif math.isnan(length):
+ _hx_min = length
+ else:
+ _hx_min = min(_hx_min, length)
+ return _hx_min
+
+
+def _dot_product(a, b):
+ sum = 0
+ _g1 = 0
+ _g = len(a)
+ while _g1 < _g:
+ i = _g1
+ _g1 = _g1 + 1
+ sum += a[i] * b[i]
+ return sum
+
+
+def _from_linear(c):
+ if c <= 0.0031308:
+ return 12.92 * c
+ else:
+ return 1.055 * math.pow(c, 0.416666666666666685) - 0.055
+
+
+def _to_linear(c):
+ if c > 0.04045:
+ return math.pow((c + 0.055) / 1.055, 2.4)
+ else:
+ return c / 12.92
+
+
+def xyz_to_rgb(_hx_tuple):
+ return [
+ _from_linear(_dot_product(m[0], _hx_tuple)),
+ _from_linear(_dot_product(m[1], _hx_tuple)),
+ _from_linear(_dot_product(m[2], _hx_tuple))]
+
+
+def rgb_to_xyz(_hx_tuple):
+ rgbl = [_to_linear(_hx_tuple[0]),
+ _to_linear(_hx_tuple[1]),
+ _to_linear(_hx_tuple[2])]
+ return [_dot_product(minv[0], rgbl),
+ _dot_product(minv[1], rgbl),
+ _dot_product(minv[2], rgbl)]
+
+
+def _y_to_l(y):
+ if y <= epsilon:
+ return y / refY * kappa
+ else:
+ return 116 * math.pow(y / refY, 0.333333333333333315) - 16
+
+
+def _l_to_y(l):
+ if l <= 8:
+ return refY * l / kappa
+ else:
+ return refY * math.pow((l + 16) / 116, 3)
+
+
+def xyz_to_luv(_hx_tuple):
+ x = float(_hx_tuple[0])
+ y = float(_hx_tuple[1])
+ z = float(_hx_tuple[2])
+ divider = x + 15 * y + 3 * z
+ var_u = 4 * x
+ var_v = 9 * y
+ if divider != 0:
+ var_u = var_u / divider
+ var_v = var_v / divider
+ else:
+ var_u = float("nan")
+ var_v = float("nan")
+ l = _y_to_l(y)
+ if l == 0:
+ return [0, 0, 0]
+ u = 13 * l * (var_u - refU)
+ v = 13 * l * (var_v - refV)
+ return [l, u, v]
+
+
+def luv_to_xyz(_hx_tuple):
+ l = float(_hx_tuple[0])
+ u = float(_hx_tuple[1])
+ v = float(_hx_tuple[2])
+ if l == 0:
+ return [0, 0, 0]
+ var_u = u / (13 * l) + refU
+ var_v = v / (13 * l) + refV
+ y = _l_to_y(l)
+ x = 0 - ((9 * y * var_u) / (((var_u - 4) * var_v) - var_u * var_v))
+ z = (((9 * y) - (15 * var_v * y)) - (var_v * x)) / (3 * var_v)
+ return [x, y, z]
+
+
+def luv_to_lch(_hx_tuple):
+ l = float(_hx_tuple[0])
+ u = float(_hx_tuple[1])
+ v = float(_hx_tuple[2])
+ _v = (u * u) + (v * v)
+ if _v < 0:
+ c = float("nan")
+ else:
+ c = math.sqrt(_v)
+ if c < 0.00000001:
+ h = 0
+ else:
+ hrad = math.atan2(v, u)
+ h = hrad * 180.0 / 3.1415926535897932
+ if h < 0:
+ h = 360 + h
+ return [l, c, h]
+
+
+def lch_to_luv(_hx_tuple):
+ l = float(_hx_tuple[0])
+ c = float(_hx_tuple[1])
+ h = float(_hx_tuple[2])
+ hrad = h / 360.0 * 2 * math.pi
+ u = math.cos(hrad) * c
+ v = math.sin(hrad) * c
+ return [l, u, v]
+
+
+def hsluv_to_lch(_hx_tuple):
+ h = float(_hx_tuple[0])
+ s = float(_hx_tuple[1])
+ l = float(_hx_tuple[2])
+ if l > 99.9999999:
+ return [100, 0, h]
+ if l < 0.00000001:
+ return [0, 0, h]
+ _hx_max = _max_chroma_for_lh(l, h)
+ c = _hx_max / 100 * s
+ return [l, c, h]
+
+
+def lch_to_hsluv(_hx_tuple):
+ l = float(_hx_tuple[0])
+ c = float(_hx_tuple[1])
+ h = float(_hx_tuple[2])
+ if l > 99.9999999:
+ return [h, 0, 100]
+ if l < 0.00000001:
+ return [h, 0, 0]
+ _hx_max = _max_chroma_for_lh(l, h)
+ s = c / _hx_max * 100
+ return [h, s, l]
+
+
+def hpluv_to_lch(_hx_tuple):
+ h = float(_hx_tuple[0])
+ s = float(_hx_tuple[1])
+ l = float(_hx_tuple[2])
+ if l > 99.9999999:
+ return [100, 0, h]
+ if l < 0.00000001:
+ return [0, 0, h]
+ _hx_max = _max_safe_chroma_for_l(l)
+ c = _hx_max / 100 * s
+ return [l, c, h]
+
+
+def lch_to_hpluv(_hx_tuple):
+ l = float(_hx_tuple[0])
+ c = float(_hx_tuple[1])
+ h = float(_hx_tuple[2])
+ if l > 99.9999999:
+ return [h, 0, 100]
+ if l < 0.00000001:
+ return [h, 0, 0]
+ _hx_max = _max_safe_chroma_for_l(l)
+ s = c / _hx_max * 100
+ return [h, s, l]
+
+
+def rgb_to_hex(_hx_tuple):
+ h = "#"
+ _g = 0
+ while _g < 3:
+ i = _g
+ _g = _g + 1
+ chan = float(_hx_tuple[i])
+ c = math.floor(chan * 255 + 0.5)
+ digit2 = int(c % 16)
+ digit1 = int((c - digit2) / 16)
+
+ h += hex_chars[digit1] + hex_chars[digit2]
+ return h
+
+
+def hex_to_rgb(hex):
+ hex = hex.lower()
+ ret = []
+ _g = 0
+ while _g < 3:
+ i = _g
+ _g = _g + 1
+ index = i * 2 + 1
+ _hx_str = hex[index]
+ digit1 = hex_chars.find(_hx_str)
+ index1 = i * 2 + 2
+ str1 = hex[index1]
+ digit2 = hex_chars.find(str1)
+ n = digit1 * 16 + digit2
+ ret.append(n / 255.0)
+ return ret
+
+
+def lch_to_rgb(_hx_tuple):
+ return xyz_to_rgb(luv_to_xyz(lch_to_luv(_hx_tuple)))
+
+
+def rgb_to_lch(_hx_tuple):
+ return luv_to_lch(xyz_to_luv(rgb_to_xyz(_hx_tuple)))
+
+
+def hsluv_to_rgb(_hx_tuple):
+ return lch_to_rgb(hsluv_to_lch(_hx_tuple))
+
+
+def rgb_to_hsluv(_hx_tuple):
+ return lch_to_hsluv(rgb_to_lch(_hx_tuple))
+
+
+def hpluv_to_rgb(_hx_tuple):
+ return lch_to_rgb(hpluv_to_lch(_hx_tuple))
+
+
+def rgb_to_hpluv(_hx_tuple):
+ return lch_to_hpluv(rgb_to_lch(_hx_tuple))
+
+
+def hsluv_to_hex(_hx_tuple):
+ return rgb_to_hex(hsluv_to_rgb(_hx_tuple))
+
+
+def hpluv_to_hex(_hx_tuple):
+ return rgb_to_hex(hpluv_to_rgb(_hx_tuple))
+
+
+def hex_to_hsluv(s):
+ return rgb_to_hsluv(hex_to_rgb(s))
+
+
+def hex_to_hpluv(s):
+ return rgb_to_hpluv(hex_to_rgb(s))