diff options
author | Taco Hoekwater <taco@elvenkind.com> | 2011-06-01 08:54:21 +0000 |
---|---|---|
committer | Taco Hoekwater <taco@elvenkind.com> | 2011-06-01 08:54:21 +0000 |
commit | d7ccb42582f85acf30568913610ccf4d602023fb (patch) | |
tree | 7292e3545a420676878e7451b68892d360c62cb6 /Master/texmf-dist/tex/context/base/colo-ini.lua | |
parent | 2d62a6fe9b80def59c392268022f1f9a2d6e358f (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.lua | 406 |
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 |