summaryrefslogtreecommitdiff
path: root/tex/context/base/mkiv/meta-fnt.lua
diff options
context:
space:
mode:
authorContext Git Mirror Bot <phg42.2a@gmail.com>2016-01-12 17:15:07 +0100
committerContext Git Mirror Bot <phg42.2a@gmail.com>2016-01-12 17:15:07 +0100
commit8d8d528d2ad52599f11250cfc567fea4f37f2a8b (patch)
tree94286bc131ef7d994f9432febaf03fe23d10eef8 /tex/context/base/mkiv/meta-fnt.lua
parentf5aed2e51223c36c84c5f25a6cad238b2af59087 (diff)
downloadcontext-8d8d528d2ad52599f11250cfc567fea4f37f2a8b.tar.gz
2016-01-12 16:26:00
Diffstat (limited to 'tex/context/base/mkiv/meta-fnt.lua')
-rw-r--r--tex/context/base/mkiv/meta-fnt.lua266
1 files changed, 266 insertions, 0 deletions
diff --git a/tex/context/base/mkiv/meta-fnt.lua b/tex/context/base/mkiv/meta-fnt.lua
new file mode 100644
index 000000000..95bdfa6d9
--- /dev/null
+++ b/tex/context/base/mkiv/meta-fnt.lua
@@ -0,0 +1,266 @@
+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 { }
+
+local function unicodetoactualtext(...)
+ unicodetoactualtext = backends.codeinjections.unicodetoactualtext
+ return unicodetoactualtext(...)
+end
+
+-- 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
+
+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]
+ local code = unicodetoactualtext(slot,concat(code," ")) or ""
+ 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:" .. code },
+ }
+ }
+ else
+ characters[slot] = {
+ commands = {
+ {
+ "image",
+ {
+ stream = code,
+ bbox = { 0, -depth * 65536, width * 65536, height * 65536 }
+ },
+ },
+ }
+ }
+ end
+ code = nil -- no need to keep that
+ 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
+
+interfaces.implement {
+ name = "definemetafont",
+ actions = metapost.fonts.define,
+ arguments = {
+ {
+ { "fontname" },
+ { "filename" },
+ }
+ }
+}
+
+-- metapost.fonts.define {
+-- fontname = "bidi",
+-- filename = "bidi-symbols.mp",
+-- }