diff options
Diffstat (limited to 'Master/texmf-dist/tex/context/base/meta-fnt.lua')
-rw-r--r-- | Master/texmf-dist/tex/context/base/meta-fnt.lua | 269 |
1 files changed, 269 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/context/base/meta-fnt.lua b/Master/texmf-dist/tex/context/base/meta-fnt.lua new file mode 100644 index 00000000000..596d0f45669 --- /dev/null +++ b/Master/texmf-dist/tex/context/base/meta-fnt.lua @@ -0,0 +1,269 @@ +if not modules then modules = { } end modules ['meta-fnt'] = { + version = 1.001, + comment = "companion to meta-fnt.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local concat = table.concat +local format = string.format +local formatters = string.formatters +local chardata = characters.data +local fontdata = fonts.hashes.identifiers + +local vffonts = fonts.handlers.vf + +local mpfonts = fonts.mp or { } +fonts.mp = mpfonts + +mpfonts.version = mpfonts.version or 1.20 +mpfonts.inline = true +mpfonts.cache = containers.define("fonts", "mp", mpfonts.version, true) + +metapost.fonts = metapost.fonts or { } + +-- a few glocals + +local characters, descriptions = { }, { } +local factor, code, slot, width, height, depth, total, variants, bbox, llx, lly, urx, ury = 100, { }, 0, 0, 0, 0, 0, 0, true, 0, 0, 0, 0 + +-- The next variant of ActualText is what Taco and I could come up with +-- eventually. As of September 2013 Acrobat copies okay, Sumatra copies a +-- question mark, pdftotext injects an extra space and Okular adds a +-- newline plus space. + +-- return formatters["BT /Span << /ActualText (CONTEXT) >> BDC [<feff>] TJ % t EMC ET"](code) + +local function topdf(n,code) + if n < 0x10000 then + return formatters["BT /Span << /ActualText <feff%04x> >> BDC [<feff>] TJ % t EMC ET"](n,code) + else + return formatters["BT /Span << /ActualText <feff%04x%04x> >> BDC [<feff>] TJ % t EMC ET"](n/1024+0xD800,n%1024+0xDC00,code) + end +end + +-- local function topdf(n,code) +-- return formatters["/Span << /ActualText (CTX) >> BDC % t EMC"](code) +-- end + +local flusher = { + startfigure = function(_chr_,_llx_,_lly_,_urx_,_ury_) + code = { } + slot = _chr_ + llx = _llx_ + lly = _lly_ + urx = _urx_ + ury = _ury_ + width = urx - llx + height = ury + depth = -lly + total = total + 1 + inline = mpfonts.inline + end, + flushfigure = function(t) + for i=1,#t do + code[#code+1] = t[i] + end + end, + stopfigure = function() + local cd = chardata[n] + descriptions[slot] = { + -- unicode = slot, + name = cd and cd.adobename, + width = width * 100, + height = height * 100, + depth = depth * 100, + boundingbox = { llx, lly, urx, ury }, + } + if inline then + characters[slot] = { + commands = { + { "special", "pdf:" .. topdf(slot,code) }, + } + } + else + characters[slot] = { + commands = { + { + "image", + { + stream = topdf(slot,code), + bbox = { 0, -depth * 65536, width * 65536, height * 65536 } + }, + }, + } + } + end + end +} + +local function process(mpxformat,name,instances,scalefactor) + local filename = resolvers.findfile(name) + local attributes = filename and lfs.isfile(filename) and lfs.attributes(filename) + if attributes then + statistics.starttiming(metapost.fonts) + scalefactor = scalefactor or 1 + instances = instances or metapost.fonts.instances or 1 -- maybe store in liost too + local fontname = file.removesuffix(file.basename(name)) + local modification = attributes.modification + local filesize = attributes.size + local hash = file.robustname(formatters["%s %05i %03i"](fontname,scalefactor*1000,instances)) + local lists = containers.read(mpfonts.cache,hash) + if not lists or lists.modification ~= modification or lists.filesize ~= filesize or lists.instances ~= instances or lists.scalefactor ~= scalefactor then + statistics.starttiming(flusher) + local data = io.loaddata(filename) + metapost.reset(mpxformat) + metapost.setoutercolor(2) -- no outer color and no reset either + lists = { } + for i=1,instances do + characters = { } + descriptions = { } + metapost.process( + mpxformat, + { + formatters["randomseed := %s ;"](i*10), + formatters["charscale := %s ;"](scalefactor), + data, + }, + false, + flusher, + false, + false, + "all" + ) + lists[i] = { + characters = characters, + descriptions = descriptions, + parameters = { + designsize = 655360, + slant = 0, + space = 333 * scalefactor, + space_stretch = 166.5 * scalefactor, + space_shrink = 111 * scalefactor, + x_height = 431 * scalefactor, + quad = 1000 * scalefactor, + extra_space = 0, + }, + properties = { + name = formatters["%s-%03i"](hash,i), + virtualized = true, + spacer = "space", + } + } + end + lists.version = metapost.variables.fontversion or "1.000" + lists.modification = modification + lists.filesize = filesize + lists.instances = instances + lists.scalefactor = scalefactor + metapost.reset(mpxformat) -- saves memory + lists = containers.write(mpfonts.cache, hash, lists) + statistics.stoptiming(flusher) + end + variants = variants + #lists + statistics.stoptiming(metapost.fonts) + return lists + else + return { } + end +end + +metapost.fonts.flusher = flusher +metapost.fonts.instances = 1 +metapost.fonts.process = process + +local function build(g,v) + local size = g.specification.size + local data = process(v[2],v[3],v[4],size/655360,v[6]) + local list = { } + local t = { } + for d=1,#data do + t = fonts.constructors.scale(data[d],-1000) + local id = font.nextid() + t.fonts = { { id = id } } + fontdata[id] = t + if v[5] then + vffonts.helpers.composecharacters(t) + end + list[d] = font.define(t) + end + for k, v in next, t do -- last t + g[k] = v -- kind of replace, when not present, make nil + end + g.properties.virtualized = true + g.variants = list +end + +vffonts.combiner.commands.metapost = build +vffonts.combiner.commands.metafont = build + +statistics.register("metapost font generation", function() + if total > 0 then + local time = statistics.elapsedtime(flusher) + if total > 0 then + return format("%i glyphs, %.3f seconds runtime, %i glyphs/second", total, time, total/time) + else + return format("%i glyphs, %.3f seconds runtime", total, time) + end + end +end) + +statistics.register("metapost font loading",function() + if variants > 0 then + local time = statistics.elapsedtime(metapost.fonts) + if variants > 0 then + return format("%.3f seconds, %i instances, %0.3f instances/second", time, variants, variants/time) + else + return format("%.3f seconds, %i instances", time, variants) + end + end +end) + +-- fonts.definers.methods.install( "bidi", { +-- { +-- "metapost", -- method +-- "metafun", -- format +-- "fontoeps.mp", -- filename +-- 1, -- instances +-- false, -- compose +-- }, +-- } ) + +local report = logs.reporter("metapost","fonts") + +function metapost.fonts.define(specification) + local fontname = specification.fontname or "" + local filename = specification.filename or "" + local format = specification.format or "metafun" + if fontname == "" then + report("no fontname given") + return + end + if filename == "" then + report("no filename given for %a",fontname) + return + end + local fullname = resolvers.findfile(filename) + if fullname == "" then + report("unable to locate file %a",filename) + return + end + report("generating font %a using format %a and file %a",fontname,format,filename) + fonts.definers.methods.install(fontname, { + { + specification.engine or "metapost", + format, + filename, + specification.instances or 1, + specification.compose or false, + }, + } ) +end + +commands.definemetafont = metapost.fonts.define + +-- metapost.fonts.define { +-- fontname = "bidi", +-- filename = "bidi-symbols.mp", +-- } |