diff --git a/lib/gears/color.lua.in b/lib/gears/color.lua.in index 99bff83a..662da69e 100644 --- a/lib/gears/color.lua.in +++ b/lib/gears/color.lua.in @@ -170,6 +170,36 @@ color.types = { radial = color.create_radial_pattern } +--- Create a pattern from a given string. +-- For full documentation of this function, please refer to create_pattern(). +-- This difference between create_pattern() and this function is that this +-- function does not insert the generated objects into the pattern cache. Thus, +-- you are allowed to modify the returned object. +-- @see create_pattern +-- @param col The string describing the pattern. +-- @return a cairo pattern object +function color.create_pattern_uncached(col) + -- If it already is a cairo pattern, just leave it as that + if cairo.Pattern:is_type_of(col) then + return col + end + local col = col or "#000000" + if type(col) == "string" then + local t = string.match(col, "[^:]+") + if color.types[t] then + local pos = string.len(t) + local arg = string.sub(col, pos + 2) + return color.types[t](arg) + end + elseif type(col) == "table" then + local t = col.type + if color.types[t] then + return color.types[t](col) + end + end + return color.create_solid_pattern(col) +end + --- Create a pattern from a given string. -- This function can create solid, linear, radial and png patterns. In general, -- patterns are specified as strings formatted as"type:arguments". "arguments" @@ -180,8 +210,13 @@ color.types = { -- { type = "radial", from = { 50, 50, 10 }, to = { 55, 55, 30 }, -- stops = { { 0, "#ff0000" }, { 0.5, "#00ff00" }, { 1, "#0000ff" } } } -- Any argument that cannot be understood is passed to create_solid_pattern(). --- @see create_solid_pattern, create_png_pattern, create_linear_pattern, --- create_radial_pattern +-- +-- Please note that you MUST NOT modify the returned pattern, for example by +-- calling :set_matrix() on it, because this function uses a cache and your +-- changes could thus have unintended side effects. Use create_pattern_uncached +-- if you need to modify the returned pattern. +-- @see create_pattern_uncached, create_solid_pattern, create_png_pattern, +-- create_linear_pattern, create_radial_pattern -- @param col The string describing the pattern. -- @return a cairo pattern object function color.create_pattern(col) @@ -191,26 +226,10 @@ function color.create_pattern(col) end local col = col or "#000000" local result = pattern_cache[col] - if result then - return result - end - if type(col) == "string" then - local t = string.match(col, "[^:]+") - if color.types[t] then - local pos = string.len(t) - local arg = string.sub(col, pos + 2) - result = color.types[t](arg) - end - elseif type(col) == "table" then - local t = col.type - if color.types[t] then - result = color.types[t](col) - end - end if not result then - result = color.create_solid_pattern(col) + result = color.create_pattern_uncached(col) + pattern_cache[col] = result end - pattern_cache[col] = result return result end diff --git a/spec/gears/color_spec.lua b/spec/gears/color_spec.lua index bf95c5a6..a6c823cb 100644 --- a/spec/gears/color_spec.lua +++ b/spec/gears/color_spec.lua @@ -151,17 +151,14 @@ describe("gears.color", function() end) it("with NONE repeat", function() - -- XXX: Can't use color() here because else the returned object - -- ends up in the pattern cache. What should we do about that? - local pattern = color.create_linear_pattern("0,0:0,10:0,#00ff00ff:1,#ff00ffff") + local pattern = color.create_pattern_uncached("linear:0,0:0,10:0,#00ff00ff:1,#ff00ffff") pattern:set_extend("NONE") assert.is_not.opaque(pattern) end) end) it("opaque linear pattern", function() - local pattern = color("linear:0,0:0,10:0,#00ff00ff:1,#ff00ffff") - assert.is.opaque(pattern) + assert.is.opaque("linear:0,0:0,10:0,#00ff00ff:1,#ff00ffff") end) it("opaque surface pattern", function() @@ -196,6 +193,18 @@ describe("gears.color", function() pending("unsupported pattern type") end end) + + describe("pattern cache", function() + it("caching works", function() + assert.is.equal(color("#00ff00"), color("#00ff00")) + end) + + it("create_pattern_uncached does not cache", function() + -- Since tests run in order, the above test already inserted + -- "#00ff00" into the cache + assert.is_not.equal(color.create_pattern_uncached("#00ff00"), color.create_pattern_uncached("#00ff00")) + end) + end) end) -- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80