From 0956aa01d9e664a1eed3088312ee130b07f103c6 Mon Sep 17 00:00:00 2001 From: Uli Schlachter Date: Sat, 9 Jan 2016 18:17:30 +0100 Subject: [PATCH 1/2] 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 --- lib/gears/color.lua | 25 ++++++++++++++++---- spec/gears/color_spec.lua | 50 +++++++++++++++++++++++++++++++++------ 2 files changed, 63 insertions(+), 12 deletions(-) diff --git a/lib/gears/color.lua b/lib/gears/color.lua index 132d1d3e0..db347c662 100644 --- a/lib/gears/color.lua +++ b/lib/gears/color.lua @@ -28,13 +28,28 @@ local pattern_cache -- @usage -- This will return 0, 1, 0, 1 -- gears.color.parse_color("#00ff00ff") function color.parse_color(col) + -- Get all hex chars local rgb = {} - for pair in string.gmatch(col, "[^#].") do - local i = tonumber(pair, 16) - if i then - table.insert(rgb, i / 255) - end + for char in string.gmatch(col, "[^#]") do + table.insert(rgb, tonumber(char, 16) / 0xf) 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 table.insert(rgb, 1) end diff --git a/spec/gears/color_spec.lua b/spec/gears/color_spec.lua index 66fcfdce6..2098e6307 100644 --- a/spec/gears/color_spec.lua +++ b/spec/gears/color_spec.lua @@ -11,26 +11,62 @@ describe("gears.color", function() describe("parse_color", function() 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) - assert.is.same(o_r, e_r / 255) - assert.is.same(o_g, e_g / 255) - assert.is.same(o_b, e_b / 255) + assert.is.same(o_r, e_r / 0xff) + assert.is.same(o_g, e_g / 0xff) + assert.is.same(o_b, e_b / 0xff) + assert.is.same(o_a, e_a / 0xff) assert.is_nil(unused) end it("black", function() - test(0, 0, 0, 255, "#000000") + test(0, 0, 0, 0xff, "#000000") end) it("opaque black", function() - test(0, 0, 0, 255, "#000000ff") + test(0, 0, 0, 0xff, "#000000ff") end) it("transparent gray", function() - test(128, 128, 128, 128, "#80808080") + test(0x80, 0x80, 0x80, 0x80, "#80808080") end) 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) From 79d3dc003a34bf6828784480949ada273bca2be0 Mon Sep 17 00:00:00 2001 From: Uli Schlachter Date: Sun, 17 Jan 2016 14:27:29 +0100 Subject: [PATCH 2/2] gears.color: Add support for named colors Oh hey, Pango exports an API that allows to query for named colors based on the famous rgb.txt! Let's use that! Signed-off-by: Uli Schlachter --- lib/gears/color.lua | 55 +++++++++++++++++++++++++-------------- spec/gears/color_spec.lua | 8 ++++++ 2 files changed, 43 insertions(+), 20 deletions(-) diff --git a/lib/gears/color.lua b/lib/gears/color.lua index db347c662..63533c48d 100644 --- a/lib/gears/color.lua +++ b/lib/gears/color.lua @@ -13,14 +13,16 @@ local tonumber = tonumber local ipairs = ipairs local pairs = pairs local type = type -local cairo = require("lgi").cairo +local lgi = require("lgi") +local cairo = lgi.cairo +local Pango = lgi.Pango local surface = require("gears.surface") local color = { mt = {} } local pattern_cache --- Parse a HTML-color. --- This function can parse colors like `#rrggbb` and `#rrggbbaa`. +-- This function can parse colors like `#rrggbb` and `#rrggbbaa` and also `red`. -- Thanks to #lua for this. :) -- -- @param col The color to parse @@ -28,26 +30,39 @@ local pattern_cache -- @usage -- This will return 0, 1, 0, 1 -- gears.color.parse_color("#00ff00ff") function color.parse_color(col) - -- Get all hex chars local rgb = {} - for char in string.gmatch(col, "[^#]") do - table.insert(rgb, tonumber(char, 16) / 0xf) - 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) + -- Is it a HTML-style color? + if string.match(col, "^#%x+$") then + -- Get all hex chars + for char in string.gmatch(col, "[^#]") do + table.insert(rgb, tonumber(char, 16) / 0xf) + 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 + else + -- Let's ask Pango for its opinion (but this doesn't support alpha!) + local c = Pango.Color() + if c:parse(col) then + rgb = { + c.red / 0xffff, + c.green / 0xffff, + c.blue / 0xffff, + } end - rgb = merged - factor = next_factor end -- Add missing groups (missing alpha) while #rgb < 4 do diff --git a/spec/gears/color_spec.lua b/spec/gears/color_spec.lua index 2098e6307..e7694e349 100644 --- a/spec/gears/color_spec.lua +++ b/spec/gears/color_spec.lua @@ -22,6 +22,10 @@ describe("gears.color", function() test(0, 0, 0, 0xff, "#000000") end) + it("black", function() + test(0, 0, 0, 0xff, "black") + end) + it("opaque black", function() test(0, 0, 0, 0xff, "#000000ff") end) @@ -34,6 +38,10 @@ describe("gears.color", function() test(0xff, 0xff, 0xff, 0x7f, "#ffffff7f") end) + it("chartreuse", function() + test(0x7f, 0xff, 0x00, 0xff, "chartreuse") + 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)