summaryrefslogtreecommitdiff
path: root/tex/context/modules/mkiv/m-punk.mkiv
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/modules/mkiv/m-punk.mkiv')
-rw-r--r--tex/context/modules/mkiv/m-punk.mkiv257
1 files changed, 257 insertions, 0 deletions
diff --git a/tex/context/modules/mkiv/m-punk.mkiv b/tex/context/modules/mkiv/m-punk.mkiv
new file mode 100644
index 000000000..331e90d2e
--- /dev/null
+++ b/tex/context/modules/mkiv/m-punk.mkiv
@@ -0,0 +1,257 @@
+%D \module
+%D [ file=m-punk,
+%D version=2008.04.15,
+%D title=\CONTEXT\ Modules,
+%D subtitle=Punk Support,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\ifx\luaversion\undefined \endinput \fi
+
+% At some point the font generation code will move into the
+% ConTeXt MkIV kernel.
+
+\startluacode
+local concat = table.concat
+local chardata = characters.data
+local fontdata = fonts.hashes.identifiers
+
+fonts.mp = fonts.mp or { }
+
+fonts.mp.version = fonts.mp.version or 1.15
+fonts.mp.inline = true
+fonts.mp.cache = containers.define("fonts", "mp", fonts.mp.version, true)
+
+metapost.characters = metapost.characters or { }
+
+-- todo: use table share as in otf
+
+local characters, descriptions = { }, { }
+local factor, l, n, w, h, d, total, variants = 100, { }, 0, 0, 0, 0, 0, 0, true
+
+-- A next version of mplib will provide the tfm font information which
+-- gives better glyph dimensions, plus additional kerning information.
+
+local flusher = {
+ startfigure = function(chrnum,llx,lly,urx,ury)
+ l, n = { }, chrnum
+ w, h, d = urx - llx, ury, -lly
+ total = total + 1
+ inline = fonts.mp.inline
+ end,
+ flushfigure = function(t)
+ for i=1, #t do
+ l[#l+1] = t[i]
+ end
+ end,
+ stopfigure = function()
+ local cd = chardata[n]
+ if inline then
+ descriptions[n] = {
+ -- unicode = n,
+ name = cd and cd.adobename,
+ width = w*100,
+ height = h*100,
+ depth = d*100,
+ boundingbox = { 0, -d, w, h },
+ }
+ characters[n] = {
+ commands = { -- todo: xforms, should happen in backend
+ { "special", "pdf: " .. concat(l," ") },
+ }
+ }
+ else
+ descriptions[n] = {
+ -- unicode = n,
+ name = cd and cd.adobename,
+ width = w*100,
+ height = h*100,
+ depth = d*100,
+ boundingbox = { 0, -d, w, h },
+ }
+ characters[n] = {
+ commands = {
+ { "image", { stream = concat(l," "), bbox = { 0, -d*65536, w*65536, h*65536 } } },
+ }
+ }
+ end
+ end
+}
+
+metapost.characters.instances = metapost.characters.instances or 10
+
+function metapost.characters.process(mpxformat, name, instances, scalefactor)
+ statistics.starttiming(metapost.characters)
+ scalefactor = scalefactor or 1
+ instances = instances or metapost.characters.instances or 10
+ local fontname = file.removesuffix(file.basename(name))
+ local hash = file.robustname(string.format("%s %05i %03i", fontname, scalefactor*1000, instances))
+ local lists = containers.read(fonts.mp.cache, hash)
+ if not lists then
+ statistics.starttiming(flusher)
+ -- we can use a format per font
+ local data = io.loaddata(resolvers.findfile(name))
+ metapost.reset(mpxformat)
+ metapost.setoutercolor(2) -- no outer color and no reset either
+ lists = { }
+ for i=1,instances do
+ characters = { }
+ descriptions = { }
+ metapost.process(
+ mpxformat,
+ {
+ "randomseed := " .. i*10 .. ";",
+ "scale_factor := " .. 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 = string.format("%s-%03i",hash,i),
+ virtualized = true,
+ spacer = "space",
+ }
+ }
+ end
+ metapost.reset(mpxformat) -- saves memory
+ lists = containers.write(fonts.mp.cache, hash, lists)
+ statistics.stoptiming(flusher)
+ end
+ variants = variants + #lists
+ statistics.stoptiming(metapost.characters)
+ return lists
+end
+
+function fonts.handlers.vf.combiner.commands.metafont(g,v)
+ local size = g.specification.size
+ local data = metapost.characters.process(v[2],v[3],v[4],size/655360)
+ local list, t = { }, { }
+ for d=1,#data do
+ t = data[d]
+ t = fonts.constructors.scale(t, -1000)
+ local id = font.nextid()
+ t.fonts = { { id = id } }
+ fontdata[id] = t
+ fonts.handlers.vf.helpers.composecharacters(t)
+ list[d] = font.define(t)
+ end
+ for k, v in next, t do
+ g[k] = v -- kind of replace, when not present, make nil
+ end
+ g.properties.virtualized = true
+ g.variants = list
+end
+
+fonts.definers.methods.install( "punk", {
+ { "metafont", "mfplain", "punkfont.mp", 10 },
+} )
+fonts.definers.methods.install( "punkbold", {
+ { "metafont", "mfplain", "punkfont-bold.mp", 10 },
+} )
+fonts.definers.methods.install( "punkslanted", {
+ { "metafont", "mfplain", "punkfont-slanted.mp", 10 },
+} )
+fonts.definers.methods.install( "punkboldslanted", {
+ { "metafont", "mfplain", "punkfont-boldslanted.mp", 10 },
+} )
+
+-- typesetters.cases.register("RandomPunk", function(current)
+-- local used = fontdata[current].variants
+-- if used then
+-- local f = math.random(1,#used)
+-- current.font = used[f]
+-- return current, true
+-- else
+-- return current, false
+-- end
+-- end)
+
+local getfont = nodes.nuts.getfont
+local setfield = nodes.nuts.setfield
+local random = math.random
+
+typesetters.cases.register("RandomPunk", function(start)
+ local used = fontdata[getfont(start)].variants
+ if used then
+ local f = random(1,#used)
+ setfield(start,"font",used[f])
+ return start, true
+ else
+ return start, false
+ end
+end)
+
+metapost.characters.flusher = flusher
+
+statistics.register("metapost font generation", function()
+ local time = statistics.elapsedtime(flusher)
+ if total > 0 then
+ return string.format("%i glyphs, %.3f seconds runtime, %i glyphs/second", total, time, total/time)
+ else
+ return string.format("%i glyphs, %.3f seconds runtime", total, time)
+ end
+end)
+
+statistics.register("metapost font loading",function()
+ local time = statistics.elapsedtime(metapost.characters)
+ if variants > 0 then
+ return string.format("%.3f seconds, %i instances, %0.3f instances/second", time, variants, variants/time)
+ else
+ return string.format("%.3f seconds, %i instances", time, variants)
+ end
+end)
+\stopluacode
+
+\unexpanded\def\EnableRandomPunk {\setcharactercasing[RandomPunk]}
+\unexpanded\def\RandomPunk {\groupedcommand\EnableRandomPunk\donothing}
+\unexpanded\def\StartRandomPunk {\begingroup\EnableRandomPunk}
+\unexpanded\def\StopRandomPunk {\endgroup}
+
+\starttypescript [serif] [punk]
+ \definefontsynonym [Serif] [demo@punk]
+ \definefontsynonym [SerifBold] [demobold@punkbold]
+ \definefontsynonym [SerifSlanted] [demoslanted@punkslanted]
+ \definefontsynonym [SerifBoldSlanted] [demoboldslanted@punkboldslanted]
+ \definefontsynonym [SerifItalic] [SerifSlanted]
+ \definefontsynonym [SerifBoldItalic] [SerifBoldSlanted]
+\stoptypescript
+
+\starttypescript [punk]
+ \definetypeface [punk] [rm] [serif] [punk] [default]
+\stoptypescript
+
+\endinput
+
+\usetypescript[punk]
+
+\setupbodyfont[punk,14pt]
+
+\starttext
+ \definedfont[demo@punk at 10pt]hello world\par
+ \definedfont[demo@punk at 12pt]hello world\par
+ \definedfont[demo@punk at 16pt]hello world\par
+ \definedfont[demo@punk at 20pt]hello world\par
+\stoptext
+