From a9a14ff85b28de498b5ebd4ba6077b1c3cbcd6da Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Sun, 14 Jul 2024 16:30:43 +0800 Subject: [PATCH] feat(cpicker): add hwb color space --- bundle/cpicker.nvim/lua/cpicker.lua | 2 +- .../cpicker.nvim/lua/cpicker/formats/hwb.lua | 112 ++++++++++++++++++ .../cpicker.nvim/syntax/spacevim_cpicker.vim | 2 +- lua/spacevim/api/color.lua | 73 +++++++++++- 4 files changed, 182 insertions(+), 7 deletions(-) create mode 100644 bundle/cpicker.nvim/lua/cpicker/formats/hwb.lua diff --git a/bundle/cpicker.nvim/lua/cpicker.lua b/bundle/cpicker.nvim/lua/cpicker.lua index e236d1f5a..c3a15d57b 100644 --- a/bundle/cpicker.nvim/lua/cpicker.lua +++ b/bundle/cpicker.nvim/lua/cpicker.lua @@ -74,7 +74,7 @@ end local function copy_color() local from, to = vim - .regex([[#[0123456789ABCDEF]\+\|rgb(\d\+,\s\d\+,\s\d\+)\|hsl(\d\+,\s\d\+%,\s\d\+%)\|hsv(\d\+,\s\d\+%,\s\d\+%)\|cmyk(\d\+%,\s\d\+%,\s\d\+%,\s\d\+%)]]) + .regex([[#[0123456789ABCDEF]\+\|rgb(\d\+,\s\d\+,\s\d\+)\|hsl(\d\+,\s\d\+%,\s\d\+%)\|hsv(\d\+,\s\d\+%,\s\d\+%)\|cmyk(\d\+%,\s\d\+%,\s\d\+%,\s\d\+%)\|hwb(\d\+,\s\d\+%,\s\d\+%)]]) :match_str(vim.fn.getline('.')) if from then vim.fn.setreg('+', string.sub(vim.fn.getline('.'), from, to + 1)) diff --git a/bundle/cpicker.nvim/lua/cpicker/formats/hwb.lua b/bundle/cpicker.nvim/lua/cpicker/formats/hwb.lua new file mode 100644 index 000000000..44cf5ea5c --- /dev/null +++ b/bundle/cpicker.nvim/lua/cpicker/formats/hwb.lua @@ -0,0 +1,112 @@ +--============================================================================= +-- hwb.lua +-- Copyright (c) 2019-2024 Wang Shidong & Contributors +-- Author: Wang Shidong < wsdjeg@outlook.com > +-- URL: https://spacevim.org +-- License: GPLv3 +--============================================================================= +local M = {} + +local color = require('spacevim.api.color') +local util = require('cpicker.util') + +local hue = 0 -- [0, 360] +local whiteness = 0 -- [0, 100%] +local blackness = 0 -- [0, 100%] + +local function on_change_argv() + return 'hwb', { hue, whiteness, blackness } +end + +function M.buf_text() + local rst = {} + local h_bar = util.generate_bar(hue, '+', 360) + local w_bar = util.generate_bar(whiteness, '+') + local b_bar = util.generate_bar(blackness, '+') + table.insert(rst, 'HWB: H: ' .. string.format('%4s', math.floor(hue + 0.5)) .. ' ' .. h_bar) + table.insert( + rst, + ' W: ' .. string.format('%3s', math.floor(whiteness * 100 + 0.5)) .. '% ' .. w_bar + ) + table.insert( + rst, + ' B: ' .. string.format('%3s', math.floor(blackness * 100 + 0.5)) .. '% ' .. b_bar + ) + return rst +end + +function M.color_code() + return + ' =========' .. string.format( + ' hwb(%s, %s%%, %s%%)', + math.floor(hue + 0.5), + math.floor(whiteness * 100 + 0.5), + math.floor(blackness * 100 + 0.5) + ) +end + +local function increase_hwb_h() + if hue <= 359 then + hue = hue + 1 + elseif hue < 360 then + hue = 360 + end + return on_change_argv() +end +local function reduce_hwb_h() + if hue >= 1 then + hue = hue - 1 + elseif hue > 0 then + hue = 0 + end + return on_change_argv() +end +local function increase_hwb_w() + if whiteness <= 0.99 then + whiteness = whiteness + 0.01 + elseif whiteness < 1 then + whiteness = 1 + end + return on_change_argv() +end +local function reduce_hwb_w() + if whiteness >= 0.01 then + whiteness = whiteness - 0.01 + elseif whiteness > 0 and whiteness < 0.01 then + whiteness = 0 + end + return on_change_argv() +end +local function increase_hwb_b() + if blackness <= 0.99 then + blackness = blackness + 0.01 + elseif blackness < 1 then + blackness = 1 + end + return on_change_argv() +end +local function reduce_hwb_b() + if blackness >= 0.01 then + blackness = blackness - 0.01 + elseif blackness > 0 and blackness < 0.01 then + blackness = 0 + end + return on_change_argv() +end +function M.increase_reduce_functions() + return { + { increase_hwb_h, reduce_hwb_h }, + { increase_hwb_w, reduce_hwb_w }, + { increase_hwb_b, reduce_hwb_b }, + } +end + +function M.on_change(f, code) + if f == 'hwb' then + return + end + hue, whiteness, blackness = color[f .. '2hwb'](unpack(code)) +end + +return M + diff --git a/bundle/cpicker.nvim/syntax/spacevim_cpicker.vim b/bundle/cpicker.nvim/syntax/spacevim_cpicker.vim index 015ae2545..805983ed7 100644 --- a/bundle/cpicker.nvim/syntax/spacevim_cpicker.vim +++ b/bundle/cpicker.nvim/syntax/spacevim_cpicker.vim @@ -5,7 +5,7 @@ let b:current_syntax = 'spacevim_cpicker' syntax case ignore syn match ProcessBar /[?=+]\+/ -syn match SpaceVimPickerCode /#[0123456789ABCDEF]\+\|rgb(\d\+,\s\d\+,\s\d\+)\|hsl(\d\+,\s\d\+%,\s\d\+%)\|hsv(\d\+,\s\d\+%,\s\d\+%)\|cmyk(\d\+%,\s\d\+%,\s\d\+%,\s\d\+%)/ +syn match SpaceVimPickerCode /#[0123456789ABCDEF]\+\|rgb(\d\+,\s\d\+,\s\d\+)\|hsl(\d\+,\s\d\+%,\s\d\+%)\|hsv(\d\+,\s\d\+%,\s\d\+%)\|cmyk(\d\+%,\s\d\+%,\s\d\+%,\s\d\+%)\|hwb(\d\+,\s\d\+%,\s\d\+%)/ syn match SpaceVimPickerBackground /=\+/ highlight ProcessBar ctermfg=Gray ctermbg=Gray guifg=Gray guibg=Gray diff --git a/lua/spacevim/api/color.lua b/lua/spacevim/api/color.lua index d68e7b94c..2bbf4c4f4 100644 --- a/lua/spacevim/api/color.lua +++ b/lua/spacevim/api/color.lua @@ -84,9 +84,9 @@ color.rgb2cmyk = function(r, g, b) local c, m, y, k k = 1 - math.max(r, g, b) if k ~= 1 then - c = (1 - r - k) / (1 - k) - m = (1 - g - k) / (1 - k) - y = (1 - b - k) / (1 - k) + c = (1 - r - k) / (1 - k) + m = (1 - g - k) / (1 - k) + y = (1 - b - k) / (1 - k) else c, m, y = 0, 0, 0 end @@ -160,10 +160,10 @@ end color.hsl2hsv = function(h, s, l) return color.rgb2hsv(color.hsl2rgb(h, s, l)) end -color.hsl2cmyk = function (h, s, l) +color.hsl2cmyk = function(h, s, l) return color.rgb2cmyk(color.hsl2rgb(h, s, l)) end -color.hsv2cmyk = function (h, s, v) +color.hsv2cmyk = function(h, s, v) return color.rgb2cmyk(color.hsv2rgb(h, s, v)) end color.cmyk2hsv = function(c, m, y, k) @@ -174,6 +174,65 @@ color.cmyk2hsl = function(c, m, y, k) return color.rgb2hsl(color.cmyk2rgb(c, m, y, k)) end +color.hwb2rgb = function(h, w, b) + if w + b >= 1 then + local gray = w / (w + b) + return gray, gray, gray + end + local r, g, b = color.hsl2rgb(h, 1, 0.5) + r = r * (1 - w - b) + w + if r > 1 then + r = 1 + elseif r < 0 then + r = 0 + end + g = g * (1 - w - b) + w + if g > 1 then + g = 1 + elseif g < 0 then + g = 0 + end + b = b * (1 - w - b) + w + if b > 1 then + b = 1 + elseif b < 0 then + b = 0 + end + return r, g, b +end + +color.rgb2hwb = function(r, g, b) + local h = color.rgb2hsl(r, g, b) + local w = math.min(r, g, b) + b = 1 - math.max(r, g, b) + return h, w, b +end + +color.hsv2hwb = function(h, s, v) + return color.rgb2hwb(color.hsv2rgb(h, s, v)) +end + +color.hsl2hwb = function(h, s, l) + return color.rgb2hwb(color.hsl2rgb(h, s, l)) +end + +color.cmyk2hwb = function(c, m, y, k) + return color.rgb2hwb(color.cmyk2rgb(c, m, y, k)) +end + +color.hwb2hsl = function(h, w, b) + return color.rgb2hwb(color.hwb2rgb(h, w, b)) +end + +color.hwb2hsv = function(h, w, b) + + return color.rgb2hsv(color.hwb2rgb(h, w, b)) +end + +color.hwb2cmyk = function(h, w, b) + return color.rgb2cmyk(color.hwb2rgb(h, w, b)) +end + local function decimalToHex(decimal) local hex = '' local hexChars = '0123456789ABCDEF' @@ -206,4 +265,8 @@ color.cmyk2hex = function(c, y, m, k) return color.rgb2hex(color.cmyk2rgb(c, y, m, k)) end +color.hwb2hex = function(h, w, b) + return color.rgb2hex(color.hwb2rgb(h, w, b)) +end + return color