From f167b470d1831575735694406eca44963f76cb3f Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Sun, 12 Jun 2016 18:18:43 +0200 Subject: [fontloader] import font-ocl Some of the more absurd aspects of fonts ;) This will fork inkscape for the actual SVG processing. --- doc/filegraph.dot | 3 + doc/luaotfload-main.tex | 1 + scripts/mkimport | 19 +- scripts/mkstatus | 1 + src/fontloader/misc/fontloader-font-ocl.lua | 297 ++++++++++++++++++++++++++++ src/luaotfload-init.lua | 2 + 6 files changed, 315 insertions(+), 8 deletions(-) create mode 100644 src/fontloader/misc/fontloader-font-ocl.lua diff --git a/doc/filegraph.dot b/doc/filegraph.dot index 0c2dad1..34c462a 100644 --- a/doc/filegraph.dot +++ b/doc/filegraph.dot @@ -385,6 +385,9 @@ strict digraph luaotfload_files { //looks weird with circo ... font-xtx.lua font-gbn.lua + + font-ocl.lua + >, ] diff --git a/doc/luaotfload-main.tex b/doc/luaotfload-main.tex index bebb7df..e238901 100644 --- a/doc/luaotfload-main.tex +++ b/doc/luaotfload-main.tex @@ -1293,6 +1293,7 @@ grouped twofold as below: \beginaltitem{font-ota.lua} \endaltitem \beginaltitem{font-ots.lua} \endaltitem \beginaltitem{font-osd.lua} \endaltitem + \beginaltitem{font-ocl.lua} \endaltitem \beginaltitem{font-lua.lua} \endaltitem \beginaltitem{font-def.lua} \endaltitem \beginaltitem{font-xtx.lua} \endaltitem diff --git a/scripts/mkimport b/scripts/mkimport index 93f4b89..1dc0a29 100755 --- a/scripts/mkimport +++ b/scripts/mkimport @@ -237,6 +237,7 @@ local imports = { { name = "font-ini" , ours = "font-ini" , kind = kind_merged }, { name = "font-lua" , ours = "font-lua" , kind = kind_merged }, { name = "font-map" , ours = "font-map" , kind = kind_merged }, + { name = "font-ocl" , ours = "font-ocl" , kind = kind_merged }, { name = "font-onr" , ours = "font-onr" , kind = kind_merged }, { name = "font-one" , ours = "font-one" , kind = kind_merged }, { name = "font-osd" , ours = "font-osd" , kind = kind_merged }, @@ -307,14 +308,15 @@ local package = { --- [32] font-ota.lua --- [33] font-ots.lua --- [34] font-osd.lua ---- [35] font-onr.lua ---- [36] font-one.lua ---- [37] font-afk.lua ---- [38] font-lua.lua ---- [39] font-def.lua ---- [40] font-xtx.lua ---- [41] luatex-fonts-ext.lua ---- [42] font-gbn.lua +--- [35] font-ocl.lua +--- [36] font-onr.lua +--- [37] font-one.lua +--- [38] font-afk.lua +--- [39] font-lua.lua +--- [40] font-def.lua +--- [41] font-xtx.lua +--- [42] luatex-fonts-ext.lua +--- [43] font-gbn.lua --- --- Of these, nos. 01--11 are provided by the Lualibs. Keeping them --- around in the Luaotfload fontloader is therefore unnecessary. @@ -372,6 +374,7 @@ local package = { "font-ota", "font-ots", "font-osd", + "font-ocl", "font-onr", "font-one", "font-afk", diff --git a/scripts/mkstatus b/scripts/mkstatus index 5b29913..10f6680 100755 --- a/scripts/mkstatus +++ b/scripts/mkstatus @@ -113,6 +113,7 @@ local names = { { miscdir, "fontloader-font-ota.lua", }, { miscdir, "fontloader-font-ots.lua", }, { miscdir, "fontloader-font-osd.lua", }, + { miscdir, "fontloader-font-ocl.lua", }, --- lua libraries { miscdir, "fontloader-languages.lua", }, diff --git a/src/fontloader/misc/fontloader-font-ocl.lua b/src/fontloader/misc/fontloader-font-ocl.lua new file mode 100644 index 0000000..9661083 --- /dev/null +++ b/src/fontloader/misc/fontloader-font-ocl.lua @@ -0,0 +1,297 @@ +if not modules then modules = { } end modules ['font-ocl'] = { + version = 1.001, + comment = "companion to font-otf.lua (context)", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- todo : user list of colors + +local formatters = string.formatters + +local otf = fonts.handlers.otf + +local f_color_start = formatters["pdf:direct: %f %f %f rg"] +local s_color_stop = "pdf:direct:" + +if context then + + local startactualtext = nil + local stopactualtext = nil + + function otf.getactualtext(n) + if not startactualtext then + startactualtext = backends.codeinjections.startunicodetoactualtext + stopactualtext = backends.codeinjections.stopunicodetoactualtext + end + return startactualtext(n), stopactualtext() + end + +else + + local tounicode = fonts.mappings.tounicode16 + + function otf.getactualtext(n) + return "/Span << /ActualText >> BDC", "EMC" + end + +end + +local function initializecolr(tfmdata,kind,value) -- hm, always value + if value then + local palettes = tfmdata.resources.colorpalettes + if palettes then + -- + local palette = palettes[tonumber(value) or 1] or palettes[1] or { } + local classes = #palette + if classes == 0 then + return + end + -- + local characters = tfmdata.characters + local descriptions = tfmdata.descriptions + local properties = tfmdata.properties + local colorvalues = { } + -- + properties.virtualized = true + tfmdata.fonts = { + { id = 0 } + } + -- + for i=1,classes do + local p = palette[i] + colorvalues[i] = { "special", f_color_start(p[1]/255,p[2]/255,p[3]/255) } + end + -- + local getactualtext = otf.getactualtext + -- + for unicode, character in next, characters do + local description = descriptions[unicode] + if description then + local colorlist = description.colors + if colorlist then + local b, e = getactualtext(unicode) + local w = character.width or 0 + local s = #colorlist + local n = 1 + local t = { + { "special", "pdf:direct: q " .. b } + } + for i=1,s do + local entry = colorlist[i] + n = n + 1 t[n] = colorvalues[entry.class] + 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" } + character.commands = t + end + end + end + end + end +end + +fonts.handlers.otf.features.register { + name = "colr", + description = "color glyphs", + manipulators = { + base = initializecolr, + node = initializecolr, + } +} + +local otfsvg = otf.svg or { } +otf.svg = otfsvg +otf.svgenabled = true + +do + + local nofstreams = 0 + + -- local f_setstream = formatters[ [[io.savedata("svg-glyph-%05i",%q)]] ] + -- local f_getstream = formatters[ [[svg-glyph-%05i]] ] + + -- function otfsvg.storepdfdata(pdf) + -- nofstreams = nofstreams + 1 + -- storepdfdata = function(pdf) + -- nofstreams = nofstreams + 1 + -- return f_setstream(nofstreams,pdf), f_getstream(nofstreams) + -- end + -- end + + local f_name = formatters[ [[svg-glyph-%05i]] ] + local f_used = context and formatters[ [[original:///%s]] ] or formatters[ [[%s]] ] + + local cache = { } + + function otfsvg.storepdfdata(pdf) + nofstreams = nofstreams + 1 + local o, n = epdf.openMemStream(pdf,#pdf,f_name(nofstreams)) + cache[n] = o -- we need to keep in mem + return nil, f_used(n), nil + end + + if context then + + local storepdfdata = otfsvg.storepdfdata + local initialized = false + + function otfsvg.storepdfdata(pdf) + if not initialized then + if resolvers.setmemstream then + local f_setstream = formatters[ [[resolvers.setmemstream("svg-glyph-%05i",%q,true)]] ] + local f_getstream = formatters[ [[memstream:///svg-glyph-%05i]] ] + local f_nilstream = formatters[ [[resolvers.resetmemstream("svg-glyph-%05i",true)]] ] + storepdfdata = function(pdf) + nofstreams = nofstreams + 1 + return + f_setstream(nofstreams,pdf), + f_getstream(nofstreams), + f_nilstream(nofstreams) + end + otfsvg.storepdfdata = storepdfdata + end + initialized = true + end + return storepdfdata(pdf) + end + + end + +end + +if context and xml.convert then + + local report_svg = logs.reporter("fonts","svg conversion") + + 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 command = [[python "c:\Users\Hans Hagen\AppData\Roaming\Python\Scripts\cairosvg" -f pdf ]] .. svgfile .. " -o " .. pdffile + local testrun = false + local pdfshapes = { } + local nofshapes = #svgshapes + report_svg("processing %i svg containers",nofshapes) + for i=1,nofshapes do + local entry = svgshapes[i] + for j=entry.first,entry.last do + local svg = xml.convert(entry.data) + local data = xml.first(svg,"/svg[@id='glyph"..j.."']") + io.savedata(svgfile,tostring(data)) + report_svg("processing svg shape of glyph %i in container %i",j,i) + os.execute(command) + pdfshapes[j] = io.loaddata(pdffile) + end + if testrun and i > testrun then + report_svg("quiting test run") + break + end + end + os.remove(svgfile) + 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 + end + os.remove(svgfile) + texio.write("done]") + return pdfshapes + end + +end + +local function initializesvg(tfmdata,kind,value) -- hm, always value + if value and otf.svgenabled then + local characters = tfmdata.characters + local descriptions = tfmdata.descriptions + local properties = tfmdata.properties + -- + local svg = properties.svg + local hash = svg and svg.hash + local timestamp = svg and svg.timestamp + if not hash then + return + end + -- + local pdffile = containers.read(otf.pdfcache,hash) + local pdfshapes = pdffile and pdffile.pdfshapes + if not pdfshapes or pdffile.timestamp ~= timestamp then + local svgfile = containers.read(otf.svgcache,hash) + local svgshapes = svgfile and svgfile.svgshapes + pdfshapes = svgshapes and otfsvg.topdf(svgshapes) or { } + containers.write(otf.pdfcache, hash, { + pdfshapes = pdfshapes, + timestamp = timestamp, + }) + end + if not pdfshapes or not next(pdfshapes) then + return + end + -- + properties.virtualized = true + tfmdata.fonts = { + { id = 0 } + } + -- + local getactualtext = otf.getactualtext + local storepdfdata = otfsvg.storepdfdata + -- + local nop = { "nop" } + -- + for unicode, character in next, characters do + local index = character.index + if index then + local pdf = pdfshapes[index] + if pdf then + local setcode, name, nilcode = storepdfdata(pdf) + if name then + local bt, et = getactualtext(unicode) + local wd = character.width or 0 + local ht = character.height or 0 + local dp = character.depth or 0 + character.commands = { + { "special", "pdf:direct:" .. bt }, + { "down", dp }, + setcode and { "lua", setcode } or nop, + { "image", { filename = name, width = wd, height = ht, depth = dp } }, + nilcode and { "lua", nilcode } or nop, + { "special", "pdf:direct:" .. et }, + } + character.svg = true + end + end + end + end + end +end + +fonts.handlers.otf.features.register { + name = "svg", + description = "svg glyphs", + manipulators = { + base = initializesvg, + node = initializesvg, + } +} diff --git a/src/luaotfload-init.lua b/src/luaotfload-init.lua index 3c0b622..c977b49 100644 --- a/src/luaotfload-init.lua +++ b/src/luaotfload-init.lua @@ -264,6 +264,7 @@ local context_modules = { { ctx, "font-ota" }, { ctx, "font-ots" }, { ctx, "font-osd" }, + { ctx, "font-ocl" }, { ctx, "font-onr" }, { ctx, "font-one" }, { ctx, "font-afk" }, @@ -543,6 +544,7 @@ local init_main = function () load_fontloader_module "font-ota" load_fontloader_module "font-ots" load_fontloader_module "font-osd" + load_fontloader_module "font-ocl" load_fontloader_module "font-onr" load_fontloader_module "font-one" load_fontloader_module "font-afk" -- cgit v1.2.3