[latex3-commits] [git/LaTeX3-latex3-luaotfload] dev: Add DVI support (7473c30)

Marcel Fabian Krüger tex at 2krueger.de
Thu Jul 9 22:14:06 CEST 2020


Repository : https://github.com/latex3/luaotfload
On branch  : dev
Link       : https://github.com/latex3/luaotfload/commit/7473c3013d955c86c4b82b06c876d464be503e81

>---------------------------------------------------------------

commit 7473c3013d955c86c4b82b06c876d464be503e81
Author: Marcel Fabian Krüger <tex at 2krueger.de>
Date:   Thu Jul 9 22:12:25 2020 +0200

    Add DVI support


>---------------------------------------------------------------

7473c3013d955c86c4b82b06c876d464be503e81
 src/luaotfload-dvi.lua      | 131 ++++++++++++++++++++++++++++++++++++++++++++
 src/luaotfload-filelist.lua |   1 +
 src/luaotfload-main.lua     |   3 +
 3 files changed, 135 insertions(+)

diff --git a/src/luaotfload-dvi.lua b/src/luaotfload-dvi.lua
new file mode 100644
index 0000000..b697174
--- /dev/null
+++ b/src/luaotfload-dvi.lua
@@ -0,0 +1,131 @@
+-------------------------------------------------------------------------------
+--         FILE:  luaotfload-dvi.lua
+--  DESCRIPTION:  part of luaotfload / DVI
+-------------------------------------------------------------------------------
+
+
+local ProvidesLuaModule = { 
+    name          = "luaotfload-dvi",
+    version       = "3.14",       --TAGVERSION
+    date          = "2020-05-06", --TAGDATE
+    description   = "luaotfload submodule / DVI",
+    license       = "GPL v2.0",
+    author        = "Marcel Krüger",
+    copyright     = "Luaotfload Development Team",  
+}
+
+if luatexbase and luatexbase.provides_module then
+  luatexbase.provides_module (ProvidesLuaModule)
+end  
+
+local getfont = font.getfont
+local setfont = node.direct.setfont
+local getdisc = node.direct.getdisc
+local traverse_glyph = node.direct.traverse_glyph
+local traverse_id = node.direct.traverse_id
+local uses_font = node.direct.uses_font
+local define_font = font.define
+local disc_t = node.id'disc'
+
+-- DVI output support
+--
+-- When writing DVI files, we can't assume that the DVI reader has access to our
+-- font dictionaries, so we need an independent representation for our glyphs. The
+-- approach we chose in coordination with the dvisvgm author is to create a DVI font
+-- name which indicates the font filename and some essential backend parameters
+-- (especially otential extend, shrink, embolden, etc. factors) and then use GIDs in
+-- the page stream.
+--
+-- Normally we could easily implement this using virtual fonts, but because we are
+-- dealing with DVI output, LuaTeX is not evaluating virtual fonts by itself.
+-- So instead, we process the shaped output and replace all glyph nodes with glyph
+-- nodes from special fonts which have the characteristics expected brom the DVI reader.
+
+-- mapped_fonts maps fontids from the user to fontids used in the DVI file
+local mapped_fonts = setmetatable({}, {__index = function(t, fid)
+  local font = getfont(fid)
+  local mapped = font.backend_font or false
+  t[fid] = mapped
+  return mapped
+end})
+
+local function process(head, font)
+  local mapping = mapped_fonts[font]
+  if not mapping then return head end
+  local mapped_font = mapping.font
+  for n, c, f in traverse_glyph(head) do if f == font then
+    local mapped = mapping[c]
+    if mapped then setfont(n, mapped_font, mapped) end
+  end end
+  for n in traverse_id(disc_t, head) do if uses_font(n, font) then
+    local pre, post, rep = getdisc(n)
+    for n, c, f in traverse_glyph(pre) do if f == font then
+      local mapped = mapping[c]
+      if mapped then setfont(n, mapped_font, mapped) end
+    end end
+    for n, c, f in traverse_glyph(post) do if f == font then
+      local mapped = mapping[c]
+      if mapped then setfont(n, mapped_font, mapped) end
+    end end
+    for n, c, f in traverse_glyph(rep) do if f == font then
+      local mapped = mapping[c]
+      if mapped then setfont(n, mapped_font, mapped) end
+    end end
+  end end
+end
+local function manipulate(tfmdata, _, dvi_kind)
+  if dvi_kind ~= 'dvisvgm' then
+    texio.write_nl(string.format('WARNING (luaotfload): Unsupported DVI backend %q, falling back to dvisvgm.', dvi_kind))
+  end
+  -- Legacy fonts can be written to the DVI file directly
+  if 2 ~= (tfmdata.encodingbytes or ((tfmdata.format == 'truetype' or tfmdata.format == 'opentype') and 2 or 1)) then
+    return
+  end
+  local newfont = {}
+  for k,v in pairs(tfmdata) do
+    newfont[k] = v
+  end
+  local newchars = {}
+  newfont.characters = newchars
+  local lookup = {}
+  for k,v in pairs(tfmdata.characters) do
+    local newchar = {
+      width = v.width, -- Only width should really be necessary
+      height = v.height,
+      depth = v.depth,
+    }
+    newchars[v.index or k] = newchar
+    lookup[k] = v.index or k
+  end
+  newfont.checksum = string.unpack('>I4', 'LuaF') -- Use a magic checksum such that the reader
+                                                  -- can uniquely identify these fonts.
+  local name = '[' .. newfont.name .. ']:' -- TODO: Why .name? I would have expected .filename
+  if newfont.subfont and newfont.subfont ~= 1 then
+    name = name .. 'index=' .. tostring(math.tointeger(newfont.subfont-1)) .. ';'
+  end
+  if newfont.extend and newfont.extend ~= 1000 then
+    name = name .. 'extend=' .. tostring(math.tointeger(math.round(newfont.extend*65.536))) .. ';'
+  end
+  if newfont.slant and newfont.slant ~= 0 then
+    name = name .. 'slant=' .. tostring(math.tointeger(math.round(newfont.slant*65.536))) .. ';'
+  end
+  if newfont.mode == 2 and newfont.width and newfont.width ~= 0 then
+    name = name .. 'embolden=' .. tostring(math.tointeger(math.round(newfont.width*65.78176))) .. ';'
+  end
+  newfont.name = name:sub(1,-2) -- Stri th trailing : or ;
+  tfmdata.backend_font = lookup
+  lookup.font = define_font(newfont)
+end
+
+fonts.constructors.features.otf.register {
+  name = "dvifont",
+  default = "dvisvgm",
+  manipulators = {
+    node = manipulate,
+    base = manipulate,
+  },
+  processors = {
+    node = process,
+    base = process,
+  },
+}
diff --git a/src/luaotfload-filelist.lua b/src/luaotfload-filelist.lua
index 1e3a4ff..941e3b9 100644
--- a/src/luaotfload-filelist.lua
+++ b/src/luaotfload-filelist.lua
@@ -259,6 +259,7 @@ luaotfload.filelist.data =
     { name = "resolvers"         ,kind = kind_library, ext =".lua", gitdir=gitdirsrc, texdir=texdirtex, gitpref = "luaotfload-" }, 
     { name = "unicode"           ,kind = kind_library, ext =".lua", gitdir=gitdirsrc, texdir=texdirtex, gitpref = "luaotfload-" },
     { name = "tounicode"         ,kind = kind_library, ext =".lua", gitdir=gitdirsrc, texdir=texdirtex, gitpref = "luaotfload-" },
+    { name = "dvi"               ,kind = kind_library, ext =".lua", gitdir=gitdirsrc, texdir=texdirtex, gitpref = "luaotfload-" },
 
     { name = "characters"        ,kind = kind_generated, ext =".lua", gitdir=gitdirgen, texdir=texdirtex, gitpref = "luaotfload-", script="mkcharacter" },
     { name = "glyphlist"         ,kind = kind_generated, ext =".lua", gitdir=gitdirgen, texdir=texdirtex, gitpref = "luaotfload-", script="mkglyphlist" },
diff --git a/src/luaotfload-main.lua b/src/luaotfload-main.lua
index 2d2e122..2a2f8a5 100644
--- a/src/luaotfload-main.lua
+++ b/src/luaotfload-main.lua
@@ -326,6 +326,9 @@ luaotfload.main = function ()
     loadmodule "szss"       --- missing glyph handling
     initialize "auxiliary"    --- additional high-level functionality
     loadmodule "tounicode"
+    if tex.outputmode == 0 then
+        loadmodule "dvi"          --- allow writing fonts to DVI files
+    end
 
     luaotfload.aux.start_rewrite_fontname () --- to be migrated to fontspec
 





More information about the latex3-commits mailing list.