From f167b470d1831575735694406eca44963f76cb3f Mon Sep 17 00:00:00 2001
From: Philipp Gesang <phg@phi-gamma.net>
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.
---
 src/fontloader/misc/fontloader-font-ocl.lua | 297 ++++++++++++++++++++++++++++
 1 file changed, 297 insertions(+)
 create mode 100644 src/fontloader/misc/fontloader-font-ocl.lua

(limited to 'src/fontloader/misc')

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,
+    }
+}
-- 
cgit v1.2.3