summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/context/base/colo-ini.lua
diff options
context:
space:
mode:
authorTaco Hoekwater <taco@elvenkind.com>2011-06-01 08:54:21 +0000
committerTaco Hoekwater <taco@elvenkind.com>2011-06-01 08:54:21 +0000
commitd7ccb42582f85acf30568913610ccf4d602023fb (patch)
tree7292e3545a420676878e7451b68892d360c62cb6 /Master/texmf-dist/tex/context/base/colo-ini.lua
parent2d62a6fe9b80def59c392268022f1f9a2d6e358f (diff)
commit context 2011.05.18
git-svn-id: svn://tug.org/texlive/trunk@22719 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/context/base/colo-ini.lua')
-rw-r--r--Master/texmf-dist/tex/context/base/colo-ini.lua406
1 files changed, 337 insertions, 69 deletions
diff --git a/Master/texmf-dist/tex/context/base/colo-ini.lua b/Master/texmf-dist/tex/context/base/colo-ini.lua
index 342d6110dca..c4e802ff587 100644
--- a/Master/texmf-dist/tex/context/base/colo-ini.lua
+++ b/Master/texmf-dist/tex/context/base/colo-ini.lua
@@ -6,25 +6,31 @@ if not modules then modules = { } end modules ['colo-ini'] = {
license = "see context related readme files"
}
-local type = type
+local type, tonumber = type, tonumber
local concat = table.concat
local format, gmatch, gsub, lower, match, find = string.format, string.gmatch, string.gsub, string.lower, string.match, string.find
-local texsprint = tex.sprint
-local ctxcatcodes = tex.ctxcatcodes
+local P, R, C, Cc = lpeg.P, lpeg.R, lpeg.C, lpeg.Cc
+local lpegmatch, lpegpatterns = lpeg.match, lpeg.patterns
local trace_define = false trackers.register("colors.define",function(v) trace_define = v end)
-local settings_to_hash_strict = aux.settings_to_hash_strict
+local report_colors = logs.reporter("colors","defining")
-colors = colors or { }
-transparencies = transparencies or { }
+local attributes, context, commands = attributes, context, commands
-local registrations = backends.registrations
+local settings_to_hash_strict = utilities.parsers.settings_to_hash_strict
-local a_color = attributes.private('color')
-local a_transparency = attributes.private('transparency')
-local a_colorspace = attributes.private('colormodel')
-local a_background = attributes.private('background')
+local colors = attributes.colors
+local transparencies = attributes.transparencies
+local colorintents = attributes.colorintents
+local registrations = backends.registrations
+local settexattribute = tex.setattribute
+local gettexattribute = tex.getattribute
+
+local a_color = attributes.private('color')
+local a_transparency = attributes.private('transparency')
+local a_colorspace = attributes.private('colormodel')
+local a_background = attributes.private('background')
local register_color = colors.register
local attributes_list = attributes.list
@@ -33,12 +39,12 @@ local function definecolor(name, ca, global)
if ca and ca > 0 then
if global then
if trace_define then
- commands.writestatus("color","define global color '%s' with attribute: %s",name,ca)
+ report_colors("define global color '%s' with attribute: %s",name,ca)
end
context.colordefagc(name,ca)
else
if trace_define then
- commands.writestatus("color","define local color '%s' with attribute: %s",name,ca)
+ report_colors("define local color '%s' with attribute: %s",name,ca)
end
context.colordefalc(name,ca)
end
@@ -55,12 +61,12 @@ local function inheritcolor(name, ca, global)
if ca and ca ~= "" then
if global then
if trace_define then
- commands.writestatus("color","inherit global color '%s' with attribute: %s",name,ca)
+ report_colors("inherit global color '%s' with attribute: %s",name,ca)
end
- context.colordeffgc(name,ca)
+ context.colordeffgc(name,ca) -- some day we will set the macro directly
else
if trace_define then
- commands.writestatus("color","inherit local color '%s' with attribute: %s",name,ca)
+ report_colors("inherit local color '%s' with attribute: %s",name,ca)
end
context.colordefflc(name,ca)
end
@@ -77,12 +83,12 @@ local function definetransparent(name, ta, global)
if ta and ta > 0 then
if global then
if trace_define then
- commands.writestatus("color","define global transparency '%s' with attribute: %s",name,ta)
+ report_colors("define global transparency '%s' with attribute: %s",name,ta)
end
context.colordefagt(name,ta)
else
if trace_define then
- commands.writestatus("color","define local transparency '%s' with attribute: %s",name,ta)
+ report_colors("define local transparency '%s' with attribute: %s",name,ta)
end
context.colordefalt(name,ta)
end
@@ -99,12 +105,12 @@ local function inherittransparent(name, ta, global)
if ta and ta ~= "" then
if global then
if trace_define then
- commands.writestatus("color","inherit global transparency '%s' with attribute: %s",name,ta)
+ report_colors("inherit global transparency '%s' with attribute: %s",name,ta)
end
context.colordeffgt(name,ta)
else
if trace_define then
- commands.writestatus("color","inherit local transparency '%s' with attribute: %s",name,ta)
+ report_colors("inherit local transparency '%s' with attribute: %s",name,ta)
end
context.colordefflt(name,ta)
end
@@ -133,6 +139,60 @@ local transparent = {
exclusion = 12,
}
+-- backend driven limitations
+
+colors.supported = true -- always true
+transparencies.supported = true
+
+local gray_okay, rgb_okay, cmyk_okay, spot_okay, multichannel_okay, forced = true, true, true, true, true, false
+
+function colors.forcesupport(gray,rgb,cmyk,spot,multichannel) -- pdfx driven
+ gray_okay, rgb_okay, cmyk_okay, spot_okay, multichannel_okay, forced = gray, rgb, cmyk, spot, multichannel, true
+ report_colors("supported models: gray=%s, rgb=%s, cmyk=%s, spot=%s", -- multichannel=%s
+ tostring(gray), tostring(rgb), tostring(cmyk), tostring(spot)) -- tostring(multichannel)
+end
+
+local function forcedmodel(model) -- delayed till the backend but mp directly
+ if not forced then
+ return model
+ elseif model == 2 then -- gray
+ if gray_okay then
+ -- okay
+ elseif cmyk_okay then
+ return 4
+ elseif rgb_okay then
+ return 3
+ end
+ elseif model == 3 then -- rgb
+ if rgb_okay then
+ -- okay
+ elseif cmyk_okay then
+ return 4
+ elseif gray_okay then
+ return 2
+ end
+ elseif model == 4 then -- cmyk
+ if cmyk_okay then
+ -- okay
+ elseif rgb_okay then
+ return 3
+ elseif gray_okay then
+ return 2
+ end
+ elseif model == 5 then -- spot
+ if cmyk_okay then
+ return 4
+ elseif rgb_okay then
+ return 3
+ elseif gray_okay then
+ return 2
+ end
+ end
+ return model
+end
+
+colors.forcedmodel = forcedmodel
+
-- By coupling we are downward compatible. When we decouple we need to do more tricky
-- housekeeping (e.g. persist color independent transparencies when color bound ones
-- are nil.)
@@ -146,41 +206,43 @@ end
local registered = { }
local function do_registerspotcolor(parent,name,parentnumber,e,f,d,p)
- if not registered[parentnumber] then
+ if not registered[parent] then
+--~ print("!!!1",parent)
local v = colors.values[parentnumber]
if v then
- local kind = colors.default -- else problems with shading etc
- if kind == 1 then kind = v[1] end
+ local model = colors.default -- else problems with shading etc
+ if model == 1 then model = v[1] end
if e and e ~= "" then
registrations.spotcolorname(parent,e) -- before registration of the color
end
- if kind == 2 then -- name noffractions names p's r g b
+ if model == 2 then -- name noffractions names p's r g b
registrations.grayspotcolor(parent,f,d,p,v[2])
- elseif kind == 3 then
+ elseif model == 3 then
registrations.rgbspotcolor (parent,f,d,p,v[3],v[4],v[5])
- elseif kind == 4 then
+ elseif model == 4 then
registrations.cmykspotcolor(parent,f,d,p,v[6],v[7],v[8],v[9])
end
end
- registered[parentnumber] = true
+ registered[parent] = true
end
end
local function do_registermultitonecolor(parent,name,parentnumber,e,f,d,p) -- same as spot but different template
- if not registered[parentnumber] then
+ if not registered[parent] then
+--~ print("!!!2",parent)
local v = colors.values[parentnumber]
if v then
- local kind = colors.default -- else problems with shading etc
- if kind == 1 then kind = v[1] end
- if kind == 2 then
+ local model = colors.default -- else problems with shading etc
+ if model == 1 then model = v[1] end
+ if model == 2 then
registrations.grayindexcolor(parent,f,d,p,v[2])
- elseif kind == 3 then
+ elseif model == 3 then
registrations.rgbindexcolor (parent,f,d,p,v[3],v[4],v[5])
- elseif kind == 4 then
+ elseif model == 4 then
registrations.cmykindexcolor(parent,f,d,p,v[6],v[7],v[8],v[9])
end
end
- registered[parentnumber] = true
+ registered[parent] = true
end
end
@@ -188,16 +250,53 @@ function colors.definesimplegray(name,s)
return register_color(name,'gray',s) -- we still need to get rid of 'color'
end
+local hexdigit = R("09","AF","af")
+local hexnumber = hexdigit * hexdigit / function(s) return tonumber(s,16)/255 end + Cc(0)
+local hexpattern = hexnumber^-3 * P(-1)
+local hexcolor = Cc("H") * P("#") * hexpattern
+
+local left = P("(")
+local right = P(")")
+local comma = P(",")
+local mixnumber = lpegpatterns.number / tonumber
+local mixname = C(P(1-left-right-comma)^1)
+local mixcolor = Cc("M") * mixnumber * left * mixname * (comma * mixname)^-1 * right * P(-1)
+
+local exclamation = P("!")
+local pgfnumber = lpegpatterns.digit^0 / function(s) return tonumber(s)/100 end
+local pgfname = C(P(1-exclamation)^1)
+local pgfcolor = Cc("P") * pgfname * exclamation * pgfnumber * (exclamation * pgfname)^-1 * P(-1)
+
+local specialcolor = hexcolor + mixcolor
+
+local l_color = attributes.list[a_color]
+local l_transparency = attributes.list[a_transparency]
+
+directives.register("colors.pgf",function(v)
+ if v then
+ specialcolor = hexcolor + mixcolor + pgfcolor
+ else
+ specialcolor = hexcolor + mixcolor
+ end
+end)
+
function colors.defineprocesscolor(name,str,global,freeze) -- still inconsistent color vs transparent
- local x = match(str,"^#(.+)$") -- for old times sake (if we need to feed from xml or so)
- if x then
- local r, g, b = match(x .. "000000","(..)(..)(..)") -- watch the 255
- definecolor(name, register_color(name,'rgb',(tonumber(r,16) or 0)/255,(tonumber(g,16) or 0)/255,(tonumber(b,16) or 0)/255), global)
+ local what, one, two, three = lpegmatch(specialcolor,str)
+ if what == "H" then
+ -- for old times sake (if we need to feed from xml or so)
+ definecolor(name, register_color(name,'rgb',one,two,three),global)
+ elseif what == "M" then
+ -- intermediate
+ return colors.defineintermediatecolor(name,one,l_color[two],l_color[three],l_transparency[two],l_transparency[three],"",global,freeze)
+ elseif what == "P" then
+ -- pgf for tikz
+ return colors.defineintermediatecolor(name,two,l_color[one],l_color[three],l_transparency[one],l_transparency[three],"",global,freeze)
else
local settings = settings_to_hash_strict(str)
if settings then
local r, g, b = settings.r, settings.g, settings.b
if r or g or b then
+ -- we can consider a combined rgb cmyk s definition
definecolor(name, register_color(name,'rgb', tonumber(r) or 0, tonumber(g) or 0, tonumber(b) or 0), global)
else
local c, m, y, k = settings.c, settings.m, settings.y, settings.k
@@ -211,8 +310,8 @@ function colors.defineprocesscolor(name,str,global,freeze) -- still inconsistent
else
local x = settings.x or h
if x then
- r, g, b = match(x .. "000000","(..)(..)(..)") -- watch the 255
- definecolor(name, register_color(name,'rgb',(tonumber(r,16) or 0)/255,(tonumber(g,16) or 0)/255,(tonumber(b,16) or 0)/255), global)
+ r, g, b = lpegmatch(hexpattern,x) -- can be inlined
+ definecolor(name, register_color(name,'rgb',r,g,b), global)
else
definecolor(name, register_color(name,'gray',tonumber(s) or 0), global)
end
@@ -289,24 +388,36 @@ function colors.registerspotcolor(parent, str)
end
function colors.definemultitonecolor(name,multispec,colorspec,selfspec)
- local dd, pp, nn = { }, { }, { }
- for k,v in gmatch(multispec,"(%a+)=([^%,]*)") do
- dd[#dd+1] = k
- pp[#pp+1] = v
- nn[#nn+1] = k
- nn[#nn+1] = format("%1.3g",tonumber(v) or 0) -- 0 can't happen
+ local dd, pp, nn, max = { }, { }, { }, 0
+ for k,v in gmatch(multispec,"(%a+)=([^%,]*)") do -- use settings_to_array
+ max = max + 1
+ dd[max] = k
+ pp[max] = v
+ nn[max] = format("%s_%1.3g",k,tonumber(v) or 0) -- 0 can't happen
end
---~ v = tonumber(v) * p
- local nof = #dd
- if nof > 0 then
- dd, pp, nn = concat(dd,','), concat(pp,','), concat(nn,'_')
+ if max > 0 then
+ nn = concat(nn,'_')
local parent = gsub(lower(nn),"[^%d%a%.]+","_")
- colors.defineprocesscolor(parent,colorspec..","..selfspec,true,true)
+--~ if max == 2 and (not colorspec or colorspec == "") then
+--~ colors.defineduocolor(parent,pp[1],l_color[dd[1]],pp[2],l_color[dd[2]],true,true)
+--~ elseif (not colorspec or colorspec == "") then
+ if not colorspec or colorspec == "" then
+ local cc = { } for i=1,max do cc[i] = l_color[dd[i]] end
+ colors.definemixcolor(parent,pp,cc,global,freeze) -- can become local
+ else
+ if selfspec ~= "" then
+ colorspec = colorspec .. "," .. selfspec
+ end
+ colors.defineprocesscolor(parent,colorspec,true,true)
+ end
local cp = attributes_list[a_color][parent]
+ dd, pp = concat(dd,','), concat(pp,',')
+--~ print(name,multispec,colorspec,selfspec)
+--~ print(parent,max,cp)
if cp then
- do_registerspotcolor(parent, name, cp, "", nof, dd, pp)
- do_registermultitonecolor(parent, name, cp, "", nof, dd, pp)
- definecolor(name, register_color(name, 'spot', parent, nof, dd, pp), true)
+ do_registerspotcolor(parent, name, cp, "", max, dd, pp)
+--~ do_registermultitonecolor(parent, name, cp, "", max, dd, pp) -- done in previous ... check it
+ definecolor(name, register_color(name, 'spot', parent, max, dd, pp), true)
local t = settings_to_hash_strict(selfspec)
if t and t.a and t.t then
definetransparent(name, transparencies.register(name,transparent[t.a] or tonumber(t.a) or 1,tonumber(t.t) or 1), global)
@@ -318,13 +429,14 @@ function colors.definemultitonecolor(name,multispec,colorspec,selfspec)
end
end
-function colors.mp(model,ca,ta,default)
- local cv = colors.value(ca) -- faster when direct colors.values[ca]
+function colors.mpcolor(model,ca,ta,default) -- will move to mlib-col
+ local cv = colors.supported and colors.value(ca) -- faster when direct colors.values[ca]
if cv then
- local tv = transparencies.value(ta)
+ local tv = transparencies.supported and transparencies.value(ta)
if model == 1 then
model = cv[1]
end
+ model = forcedmodel(model)
if tv then
if model == 2 then
return format("transparent(%s,%s,(%s,%s,%s))",tv[1],tv[2],cv[3],cv[4],cv[5])
@@ -355,7 +467,7 @@ end
function colors.formatcolor(ca,separator)
local cv = colors.value(ca)
if cv then
- local c, f, t, model = { }, 13, 13, cv[1]
+ local c, cn, f, t, model = { }, 0, 13, 13, cv[1]
if model == 2 then
f, t = 2, 2
elseif model == 3 then
@@ -364,7 +476,8 @@ function colors.formatcolor(ca,separator)
f, t = 6, 9
end
for i=f,t do
- c[#c+1] = format("%0.3f",cv[i])
+ cn = cn + 1
+ c[cn] = format("%0.3f",cv[i])
end
return concat(c,separator)
else
@@ -451,20 +564,45 @@ end
function colors.defineintermediatecolor(name,fraction,c_one,c_two,a_one,a_two,specs,global,freeze)
fraction = tonumber(fraction) or 1
local one, two = colors.value(c_one), colors.value(c_two)
- if one and two then
- local csone, cstwo = one[1], two[1]
- if csone == cstwo then
- -- actually we can set all 8 values at once here but this is cleaner as we avoid
- -- problems with weighted gray conversions and work with original values
+ if one then
+ if two then
+ local csone, cstwo = one[1], two[1]
+ -- if csone == cstwo then
+ -- actually we can set all 8 values at once here but this is cleaner as we avoid
+ -- problems with weighted gray conversions and work with original values
+ local ca
+ if csone == 2 then
+ ca = register_color(name,'gray',f(one,two,2,fraction))
+ elseif csone == 3 then
+ ca = register_color(name,'rgb', f(one,two,3,fraction),
+ f(one,two,4,fraction),
+ f(one,two,5,fraction))
+ elseif csone == 4 then
+ ca = register_color(name,'cmyk',f(one,two,6,fraction),
+ f(one,two,7,fraction),
+ f(one,two,8,fraction),
+ f(one,two,9,fraction))
+ else
+ ca = register_color(name,'gray',f(one,two,2,fraction))
+ end
+ definecolor(name,ca,global,freeze)
+ -- end
+ else
+ local csone = one[1]
local ca
if csone == 2 then
- ca = register_color(name,'gray',f(one,two,2,fraction))
+ ca = register_color(name,'gray',fraction*one[2])
elseif csone == 3 then
- ca = register_color(name,'rgb',f(one,two,3,fraction),f(one,two,4,fraction),f(one,two,5,fraction))
+ ca = register_color(name,'rgb', fraction*one[3],
+ fraction*one[4],
+ fraction*one[5])
elseif csone == 4 then
- ca = register_color(name,'cmyk',f(one,two,6,fraction),f(one,two,7,fraction),f(one,two,8,fraction),f(one,two,9,fraction))
+ ca = register_color(name,'cmyk',fraction*one[6],
+ fraction*one[7],
+ fraction*one[8],
+ fraction*one[9])
else
- ca = register_color(name,'gray',f(one,two,2,fraction))
+ ca = register_color(name,'gray',fraction*one[2])
end
definecolor(name,ca,global,freeze)
end
@@ -474,7 +612,137 @@ function colors.defineintermediatecolor(name,fraction,c_one,c_two,a_one,a_two,sp
local ta = tonumber((t and t.a) or (one and one[1]) or (two and two[1]))
local tt = tonumber((t and t.t) or (one and two and f(one,two,2,fraction)))
if ta and tt then
---~ print(ta,tt)
definetransparent(name,transparencies.register(name,ta,tt),global)
end
end
+
+--~ local function f(one,two,i,fraction_one,fraction_two)
+--~ local otf = fraction_one * one[i] + fraction_two * two[i]
+--~ if otf > 1 then
+--~ otf = 1
+--~ end
+--~ return otf
+--~ end
+
+--~ function colors.defineduocolor(name,fraction_one,c_one,fraction_two,c_two,global,freeze)
+--~ local one, two = colors.value(c_one), colors.value(c_two)
+--~ if one and two then
+--~ fraction_one = tonumber(fraction_one) or 1
+--~ fraction_two = tonumber(fraction_two) or 1
+--~ local csone, cstwo = one[1], two[1]
+--~ local ca
+--~ if csone == 2 then
+--~ ca = register_color(name,'gray',f(one,two,2,fraction_one,fraction_two))
+--~ elseif csone == 3 then
+--~ ca = register_color(name,'rgb', f(one,two,3,fraction_one,fraction_two),
+--~ f(one,two,4,fraction_one,fraction_two),
+--~ f(one,two,5,fraction_one,fraction_two))
+--~ elseif csone == 4 then
+--~ ca = register_color(name,'cmyk',f(one,two,6,fraction_one,fraction_two),
+--~ f(one,two,7,fraction_one,fraction_two),
+--~ f(one,two,8,fraction_one,fraction_two),
+--~ f(one,two,9,fraction_one,fraction_two))
+--~ else
+--~ ca = register_color(name,'gray',f(one,two,2,fraction_one,fraction_two))
+--~ end
+--~ definecolor(name,ca,global,freeze)
+--~ end
+--~ end
+
+ local function f(i,colors,fraction)
+ local otf = 0
+ for c=1,#colors do
+ otf = otf + (tonumber(fraction[c]) or 1) * colors[c][i]
+ end
+ if otf > 1 then
+ otf = 1
+ end
+ return otf
+ end
+
+ function colors.definemixcolor(name,fractions,cs,global,freeze)
+ local values = { }
+ for i=1,#cs do -- do fraction in here
+ local v = colors.value(cs[i])
+ if not v then
+ return
+ end
+ values[i] = v
+ end
+ local csone = values[1][1]
+ local ca
+ if csone == 2 then
+ ca = register_color(name,'gray',f(2,values,fractions))
+ elseif csone == 3 then
+ ca = register_color(name,'rgb', f(3,values,fractions),
+ f(4,values,fractions),
+ f(5,values,fractions))
+ elseif csone == 4 then
+ ca = register_color(name,'cmyk',f(6,values,fractions),
+ f(7,values,fractions),
+ f(8,values,fractions),
+ f(9,values,fractions))
+ else
+ ca = register_color(name,'gray',f(2,values,fractions))
+ end
+ definecolor(name,ca,global,freeze)
+ end
+
+-- for the moment downward compatible
+
+local patterns = { "colo-imp-%s.mkiv", "colo-imp-%s.tex", "colo-%s.mkiv", "colo-%s.tex" }
+
+function colors.usecolors(name)
+ commands.uselibrary(name,patterns,function(name,foundname)
+ context.startreadingfile()
+ context.input(foundname)
+ context.showcolormessage("colors",4,name)
+ context.stopreadingfile()
+ end, function(name)
+ context.showcolormessage("colors",5,name)
+ end)
+end
+
+-- interface
+
+local setcolormodel = colors.setmodel
+
+function commands.setcolormodel(model,weight)
+ settexattribute(a_colorspace,setcolormodel(model,weight))
+end
+
+function commands.setrastercolor(name,s)
+ settexattribute(a_color,colors.definesimplegray(name,s))
+end
+
+function commands.registermaintextcolor(a)
+ colors.main = a
+end
+
+commands.defineprocesscolor = colors.defineprocesscolor
+commands.definespotcolor = colors.definespotcolor
+commands.definemultitonecolor = colors.definemultitonecolor
+commands.definetransparency = colors.definetransparency
+commands.defineintermediatecolor = colors.defineintermediatecolor
+
+function commands.spotcolorname (a) context(colors.spotcolorname (a)) end
+function commands.spotcolorparent (a) context(colors.spotcolorparent (a)) end
+function commands.spotcolorvalue (a) context(colors.spotcolorvalue (a)) end
+function commands.colorcomponents (a) context(colors.colorcomponents (a)) end
+function commands.transparencycomponents(a) context(colors.transparencycomponents(a)) end
+function commands.formatcolor (...) context(colors.formatcolor (...)) end
+function commands.formatgray (...) context(colors.formatgray (...)) end
+
+function commands.mpcolor(model,ca,ta,default)
+ context(colors.mpcolor(model,ca,ta,default))
+end
+
+function commands.doifblackelse(a)
+ commands.doifelse(colors.isblack(a))
+end
+
+function commands.doifdrawingblackelse()
+ commands.doifelse(colors.isblack(gettexattribute(a_color)))
+end
+
+commands.usecolors = colors.usecolors