luametalatex/luametalatex-font-t2-opt.lua

169 lines
4.9 KiB
Lua

-- This is optimizet2.lua.
-- Copyright 2019 Marcel Krüger <tex@2krueger.de>
--
-- This work may be distributed and/or modified under the
-- conditions of the LaTeX Project Public License version 1.3c.
-- The full text of this version can be found at
-- http://www.latex-project.org/lppl/lppl-1-3c.txt
--
-- This work has the LPPL maintenance status `maintained'
--
-- The Current Maintainer of this work is Marcel Krüger.
--
-- This work consists of the files buildcffwrapper.lua, buildotfwrapper.lua,
-- finish_pdffont.lua, finisht3.lua, glyph2char.lua, libSfnt.lua,
-- luaglyphlist.lua, luaotfprovider.lua, make_extensible_per_char.lua,
-- mpfont.lua, mplibtolist.lua, mplibtot2.lua, mpnodelib.lua,
-- mt1_fontloader.lua, nodebuilder.lua, optimizet2.lua, serializet2.lua.
return function(cs)
-- cs might contain some false entries, delete them
do
local j=1
for i = 1,#cs do
if cs[i] then
if i ~= j then
cs[j] = cs[i]
end
j = j+1
end
end
for i = j,#cs do
cs[i] = nil
end
end
-- First some easy replacements:
local use_hintmask
for i, v in ipairs(cs) do
if v[1] == 19 then
-- If this happens only one time, we do not want masks
use_hintmask = use_hintmask ~= nil
elseif v[1] == 21 then -- rmoveto
if v[2] == 0 then
v[1] = 4
v[2] = v[3]
v[3] = nil
elseif v[3] == 0 then
v[1] = 22
v[3] = nil
end
elseif v[1] == 5 then -- rlineto
if v[2] == 0 then
v[1] = 7
v[2] = v[3]
v[3] = nil
elseif v[3] == 0 then
v[1] = 6
v[3] = nil
end
elseif v[1] == 8 then -- rrcurveto
if v[2] == 0 then
if v[6] == 0 then
v[1] = 26 -- vvcurveto (even argument case)
table.remove(v, 6)
table.remove(v, 2)
else
v[1] = 30 -- vhcurveto
table.remove(v, 2)
if v[6] == 0 then table.remove(v, 6) end
end
elseif v[3] == 0 then
if v[7] == 0 then
v[1] = 27 -- hhcurveto (even argument case)
table.remove(v, 7)
table.remove(v, 3)
else
v[1] = 31 -- hvcurveto
table.remove(v, 3)
local t = v[5]
table.remove(v, 5)
if t ~= 0 then table.insert(v, t) end
end
elseif v[6] == 0 then
v[1] = 26 -- vvcurveto (odd argument case)
table.remove(v, 6)
elseif v[7] == 0 then
v[1] = 27 -- hhcurveto (odd argument case)
table.remove(v, 7)
local t = v[2]
v[2] = v[3]
v[3] = t
end
end
end
if not use_hintmask then
for i, v in ipairs(cs) do
if v[1] == 18 then
v[1] = 1
elseif not v[1] and cs[i+1] and cs[i+1][1] == 19 then
v[1] = 3
elseif v[1] == 19 then
table.remove(cs, i)
break
end
end
end
-- Try combining lineto segments. We could try harder, but this should
-- never be triggered anyway.
for i, v in ipairs(cs) do
if v[1] == 6 or v[1] == 7 then
while cs[i+1] and v[1] == cs[i+1][1] do
v[2] = v[2] + cs[i+1][2]
table.remove(cs, i+1)
end
end
end
-- Now use the variable argument versions of most commands
for i, v in ipairs(cs) do
if v[1] == 5 then -- rlineto
while cs[i+1] and 5 == cs[i+1][1] do
table.insert(v, cs[i+1][2])
table.insert(v, cs[i+1][3])
table.remove(cs, i+1)
end
if cs[i+1] and 8 == cs[i+1][1] then -- rrcurveto
v[1] = 25 -- rlinecurveto
for j=2,7 do table.insert(v, cs[i+1][j]) end
table.remove(cs, i+1)
end
elseif v[1] == 6 or v[1] == 7 then
local next_cmd = (v[1]-5)%2+6
while cs[i+1][1] == next_cmd do
next_cmd = (cs[i+1][1]-5)%2+6
table.insert(v, cs[i+1][2])
table.remove(cs, i+1)
end
elseif v[1] == 8 then
while cs[i+1] and 8 == cs[i+1][1] do -- rrcurveto
for j=2,7 do table.insert(v, cs[i+1][j]) end
table.remove(cs, i+1)
end
if cs[i+1] and 5 == cs[i+1][1] then -- rlineto
v[1] = 24 -- rcurveline
table.insert(v, cs[i+1][2])
table.insert(v, cs[i+1][3])
table.remove(cs, i+1)
end
elseif v[1] == 27 then
while cs[i+1] and 27 == cs[i+1][1] and #cs[i+1] == 5 do -- hhcurveto
for j=2,5 do table.insert(v, cs[i+1][j]) end
table.remove(cs, i+1)
end
elseif v[1] == 26 then
while cs[i+1] and 26 == cs[i+1][1] and #cs[i+1] == 5 do -- vvcurveto
for j=2,5 do table.insert(v, cs[i+1][j]) end
table.remove(cs, i+1)
end
elseif v[1] == 30 or v[1] == 31 then
local next_cmd = (v[1]-29)%2+30
while #v % 2 == 1 and cs[i+1] and next_cmd == cs[i+1][1] do -- [vh|hv]curveto
local next_cmd = (cs[i+1][1]-29)%2+30
for j=2,#cs[i+1] do table.insert(v, cs[i+1][j]) end
table.remove(cs, i+1)
end
elseif false then
-- TODO: More commands
end
end
end