summaryrefslogtreecommitdiff
path: root/src/fontloader/misc/fontloader-font-ocl.lua
diff options
context:
space:
mode:
Diffstat (limited to 'src/fontloader/misc/fontloader-font-ocl.lua')
-rw-r--r--src/fontloader/misc/fontloader-font-ocl.lua297
1 files changed, 297 insertions, 0 deletions
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 <feff" .. tounicode(n) .. "> >> 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,
+ }
+}