diff options
Diffstat (limited to 'Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ocl.lua')
-rw-r--r-- | Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ocl.lua | 210 |
1 files changed, 137 insertions, 73 deletions
diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ocl.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ocl.lua index b2aba7ac7fe..65a1c63427c 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ocl.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ocl.lua @@ -8,34 +8,86 @@ if not modules then modules = { } end modules ['font-ocl'] = { -- todo : user list of colors -local tostring, next = tostring, next +local tostring, next, format = tostring, next, string.format +local round, max = math.round, math.round local formatters = string.formatters +local tounicode = fonts.mappings.tounicode -local otf = fonts.handlers.otf +local otf = fonts.handlers.otf -local f_color_start = formatters["pdf:direct: %f %f %f rg"] -local s_color_stop = "pdf:direct:" +local f_color = formatters["pdf:direct:%f %f %f rg"] +local f_gray = formatters["pdf:direct:%f g"] +local s_black = "pdf:direct:0 g" if context then local startactualtext = nil local stopactualtext = nil - function otf.getactualtext(n) + function otf.getactualtext(s) if not startactualtext then - startactualtext = backends.codeinjections.startunicodetoactualtext - stopactualtext = backends.codeinjections.stopunicodetoactualtext + startactualtext = backends.codeinjections.startunicodetoactualtextdirect + stopactualtext = backends.codeinjections.stopunicodetoactualtextdirect end - return startactualtext(n), stopactualtext() + return startactualtext(s), stopactualtext() end else local tounicode = fonts.mappings.tounicode16 - function otf.getactualtext(n) - return "/Span << /ActualText <feff" .. tounicode(n) .. "> >> BDC", "EMC" + function otf.getactualtext(s) + return + "/Span << /ActualText <feff" .. n .. "> >> BDC", + "EMC" + end + +end + +local sharedpalettes = { } + +if context then + + local graytorgb = attributes.colors.graytorgb + local cmyktorgb = attributes.colors.cmyktorgb + + function otf.registerpalette(name,values) + sharedpalettes[name] = values + for i=1,#values do + local v = values[i] + local r, g, b + local s = v.s + if s then + r, g, b = graytorgb(s) + else + local c, m, y, k = v.c, v.m, v.y, v.k + if c or m or y or k then + r, g, b = cmyktorgb(c or 0,m or 0,y or 0,k or 0) + else + r, g, b = v.r, v.g, v.b + end + end + values[i] = { + max(r and round(r*255) or 0,255), + max(g and round(g*255) or 0,255), + max(b and round(b*255) or 0,255) + } + end + end + +else -- for generic + + function otf.registerpalette(name,values) + sharedpalettes[name] = values + for i=1,#values do + local v = values[i] + values[i] = { + max(round((v.r or 0)*255),255), + max(round((v.g or 0)*255),255), + max(round((v.b or 0)*255),255) + } + end end end @@ -45,7 +97,7 @@ local function initializecolr(tfmdata,kind,value) -- hm, always value local palettes = tfmdata.resources.colorpalettes if palettes then -- - local palette = palettes[tonumber(value) or 1] or palettes[1] or { } + local palette = sharedpalettes[value] or palettes[tonumber(value) or 1] or palettes[1] or { } local classes = #palette if classes == 0 then return @@ -63,7 +115,12 @@ local function initializecolr(tfmdata,kind,value) -- hm, always value -- for i=1,classes do local p = palette[i] - colorvalues[i] = { "special", f_color_start(p[1]/255,p[2]/255,p[3]/255) } + local r, g, b = p[1], p[2], p[3] + if r == g and g == b then + colorvalues[i] = { "special", f_gray(r/255) } + else + colorvalues[i] = { "special", f_color(r/255,g/255,b/255) } + end end -- local getactualtext = otf.getactualtext @@ -73,22 +130,30 @@ local function initializecolr(tfmdata,kind,value) -- hm, always value if description then local colorlist = description.colors if colorlist then - local b, e = getactualtext(unicode) + local b, e = getactualtext(tounicode(characters[unicode].unicode or 0xFFFD)) local w = character.width or 0 local s = #colorlist - local n = 1 local t = { - { "special", "pdf:direct: q " .. b } + -- We need to force page first because otherwise the q's get outside + -- the font switch and as a consequence the next character has no font + -- set (well, it has: the preceding one). As a consequence these fonts + -- are somewhat inefficient as each glyph gets the font set. It's a + -- side effect of the fact that a font is handled when a character gets + -- flushed. + { "special", "pdf:page:q" }, + { "special", "pdf:raw:" .. b } } + local n = #t for i=1,s do local entry = colorlist[i] - n = n + 1 t[n] = colorvalues[entry.class] + n = n + 1 t[n] = colorvalues[entry.class] or s_black n = n + 1 t[n] = { "char", entry.slot } if s > 1 and i < s and w ~= 0 then n = n + 1 t[n] = { "right", -w } end end - n = n + 1 t[n] = { "special", "pdf:direct:" .. e .. " Q" } + n = n + 1 t[n] = { "special", "pdf:page:" .. e } + n = n + 1 t[n] = { "special", "pdf:raw:Q" } character.commands = t end end @@ -166,34 +231,56 @@ do end -if context and xml.convert then + +do local report_svg = logs.reporter("fonts","svg conversion") - local xmlconvert = xml.convert - local xmlfirst = xml.first local loaddata = io.loaddata local savedata = io.savedata local remove = os.remove + if context and xml.convert then + + local xmlconvert = xml.convert + local xmlfirst = xml.first + + function otfsvg.filterglyph(entry,index) + local svg = xmlconvert(entry.data) + local root = svg and xmlfirst(svg,"/svg[@id='glyph"..index.."']") + local data = root and tostring(root) + -- report_svg("data for glyph %04X: %s",index,data) + return data + end + + else + + function otfsvg.filterglyph(entry,index) -- can be overloaded + return entry.data + end + + end + -- function otfsvg.topdf(svgshapes) - -- local svgfile = "temp-otf-svg-shape.svg" - -- local pdffile = "temp-otf-svg-shape.pdf" - -- local command = "inkscape " .. svgfile .. " --export-pdf=" .. pdffile - -- local testrun = false - -- local pdfshapes = { } - -- local nofshapes = #svgshapes + -- local svgfile = "temp-otf-svg-shape.svg" + -- local pdffile = "temp-otf-svg-shape.pdf" + -- local command = "inkscape " .. svgfile .. " --export-pdf=" .. pdffile + -- local testrun = false + -- local pdfshapes = { } + -- local nofshapes = #svgshapes + -- local filterglyph = otfsvg.filterglyph -- report_svg("processing %i svg containers",nofshapes) -- statistics.starttiming() -- for i=1,nofshapes do -- local entry = svgshapes[i] - -- for j=entry.first,entry.last do - -- local svg = xmlconvert(entry.data) - -- local data = xmlfirst(svg,"/svg[@id='glyph"..j.."']") + -- for index=entry.first,entry.last do + -- local data = filterglyph(entry,index) -- savedata(svgfile,tostring(data)) - -- report_svg("processing svg shape of glyph %i in container %i",j,i) - -- os.execute(command) - -- pdfshapes[j] = loaddata(pdffile) + -- if data and data ~= "" then + -- report_svg("processing svg shape of glyph %i in container %i",index,i) + -- os.execute(command) + -- pdfshapes[index] = loaddata(pdffile) + -- end -- end -- if testrun and i > testrun then -- report_svg("quiting test run") @@ -207,26 +294,25 @@ if context and xml.convert then -- end function otfsvg.topdf(svgshapes) - local inkscape = io.popen("inkscape --shell 2>&1","w") - local pdfshapes = { } - local nofshapes = #svgshapes - local f_svgfile = formatters["temp-otf-svg-shape-%i.svg"] - local f_pdffile = formatters["temp-otf-svg-shape-%i.pdf"] - local f_convert = formatters["%s --export-pdf=%s\n"] + local inkscape = io.popen("inkscape --shell > temp-otf-svg-shape.log","w") + local pdfshapes = { } + local nofshapes = #svgshapes + local f_svgfile = formatters["temp-otf-svg-shape-%i.svg"] + local f_pdffile = formatters["temp-otf-svg-shape-%i.pdf"] + local f_convert = formatters["%s --export-pdf=%s\n"] + local filterglyph = otfsvg.filterglyph report_svg("processing %i svg containers",nofshapes) statistics.starttiming() for i=1,nofshapes do local entry = svgshapes[i] - for j=entry.first,entry.last do - local svg = xmlconvert(entry.data) - local root = svg and xmlfirst(svg,"/svg[@id='glyph"..j.."']") - local data = root and tostring(root) + for index=entry.first,entry.last do + local data = filterglyph(entry,index) if data and data ~= "" then - local svgfile = f_svgfile(j) - local pdffile = f_pdffile(j) + local svgfile = f_svgfile(index) + local pdffile = f_pdffile(index) savedata(svgfile,data) inkscape:write(f_convert(svgfile,pdffile)) - pdfshapes[j] = true + pdfshapes[index] = true end end end @@ -236,39 +322,17 @@ if context and xml.convert then -- end inkscape:close() report_svg("processing %i pdf results",nofshapes) - for i in next, pdfshapes do - local svgfile = f_svgfile(i) - local pdffile = f_pdffile(i) - pdfshapes[i] = loaddata(pdffile) + for index in next, pdfshapes do + local svgfile = f_svgfile(index) + local pdffile = f_pdffile(index) + pdfshapes[index] = loaddata(pdffile) remove(svgfile) remove(pdffile) end statistics.stoptiming() - report_svg("conversion time: %0.3f",statistics.elapsedtime()) - return pdfshapes - end - -else - - function otfsvg.topdf(svgshapes) - local svgfile = "temp-otf-svg-shape.svg" - local pdffile = "temp-otf-svg-shape.pdf" - local command = "inkscape " .. svgfile .. " --export-pdf=" .. pdffile - local pdfshapes = { } - local nofshapes = #svgshapes - texio.write(formatters["[converting %i svg glyphs to pdf using command %q : "](nofshapes,command)) - for i=1,nofshapes do - local entry = svgshapes[i] - for j=entry.first,entry.last do - -- cross our fingers .. some, day i will filter - texio.write(formatters["%i "](j)) - io.savedata(svgfile,tostring(entry.data)) - os.execute(command) - pdfshapes[j] = io.loaddata(pdffile) - end + if statistics.elapsedseconds then + report_svg("svg conversion time %s",statistics.elapsedseconds()) end - os.remove(svgfile) - texio.write("done]") return pdfshapes end |