Add support for short/long colors

This adds support to gears.color.parse_color to parse things like "#fff" (one
character per color component, without alpha) and "#ffff0000ffff0000" (four
characters per component, with alpha).

This makes sense on its own, but should also help with
https://github.com/awesomeWM/awesome/issues/585.

Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
Uli Schlachter 2016-01-09 18:17:30 +01:00
parent 8b3087dc4e
commit 0956aa01d9
2 changed files with 63 additions and 12 deletions

View File

@ -28,13 +28,28 @@ local pattern_cache
-- @usage -- This will return 0, 1, 0, 1 -- @usage -- This will return 0, 1, 0, 1
-- gears.color.parse_color("#00ff00ff") -- gears.color.parse_color("#00ff00ff")
function color.parse_color(col) function color.parse_color(col)
-- Get all hex chars
local rgb = {} local rgb = {}
for pair in string.gmatch(col, "[^#].") do for char in string.gmatch(col, "[^#]") do
local i = tonumber(pair, 16) table.insert(rgb, tonumber(char, 16) / 0xf)
if i then
table.insert(rgb, i / 255)
end
end end
-- Merge consecutive values until we have at most four groups (rgba)
local factor = 0xf
while #rgb > 4 do
local merged = {}
local key, value = next(rgb, nil)
local next_factor = (factor + 1)*(factor + 1) - 1
while key do
local key2, value2 = next(rgb, key)
local v1, v2 = value * factor, value2 * factor
local new = v1 * (factor + 1) + v2
table.insert(merged, new / next_factor)
key, value = next(rgb, key2)
end
rgb = merged
factor = next_factor
end
-- Add missing groups (missing alpha)
while #rgb < 4 do while #rgb < 4 do
table.insert(rgb, 1) table.insert(rgb, 1)
end end

View File

@ -11,26 +11,62 @@ describe("gears.color", function()
describe("parse_color", function() describe("parse_color", function()
local function test(e_r, e_g, e_b, e_a, input) local function test(e_r, e_g, e_b, e_a, input)
local o_r, o_g, o_b, o_a, unused = color.parse_color(input) local o_r, o_g, o_b, o_a, unused = color.parse_color(input)
assert.is.same(o_r, e_r / 255) assert.is.same(o_r, e_r / 0xff)
assert.is.same(o_g, e_g / 255) assert.is.same(o_g, e_g / 0xff)
assert.is.same(o_b, e_b / 255) assert.is.same(o_b, e_b / 0xff)
assert.is.same(o_a, e_a / 0xff)
assert.is_nil(unused) assert.is_nil(unused)
end end
it("black", function() it("black", function()
test(0, 0, 0, 255, "#000000") test(0, 0, 0, 0xff, "#000000")
end) end)
it("opaque black", function() it("opaque black", function()
test(0, 0, 0, 255, "#000000ff") test(0, 0, 0, 0xff, "#000000ff")
end) end)
it("transparent gray", function() it("transparent gray", function()
test(128, 128, 128, 128, "#80808080") test(0x80, 0x80, 0x80, 0x80, "#80808080")
end) end)
it("transparent white", function() it("transparent white", function()
test(255, 255, 255, 127, "#ffffff7f") test(0xff, 0xff, 0xff, 0x7f, "#ffffff7f")
end)
describe("different lengths", function()
local function gray(e, e_a, input)
local o_r, o_g, o_b, o_a, unused = color.parse_color(input)
assert.is.same(o_r, e)
assert.is.same(o_g, e)
assert.is.same(o_b, e)
assert.is.same(o_a, e_a)
assert.is_nil(unused)
end
it("rgb", function()
gray(0x8/0xf, 1, "#888")
end)
it("rgba", function()
gray(0x8/0xf, 0x8/0xf, "#8888")
end)
it("rrggbb", function()
gray(0x80/0xff, 1, "#808080")
end)
it("rrggbbaa", function()
gray(0x80/0xff, 0x80/0xff, "#80808080")
end)
it("rrrrggggbbbb", function()
gray(0x8000/0xffff, 1, "#800080008000")
end)
it("rrrrggggbbbbaaaa", function()
gray(0x8000/0xffff, 0x8000/0xffff, "#8000800080008000")
end)
end) end)
end) end)