summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-harf-var-t2-writer.lua
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/luatex/luaotfload/luaotfload-harf-var-t2-writer.lua')
-rw-r--r--Master/texmf-dist/tex/luatex/luaotfload/luaotfload-harf-var-t2-writer.lua120
1 files changed, 120 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-harf-var-t2-writer.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-harf-var-t2-writer.lua
new file mode 100644
index 00000000000..f10bf6d860e
--- /dev/null
+++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-harf-var-t2-writer.lua
@@ -0,0 +1,120 @@
+-----------------------------------------------------------------------
+-- FILE: luaotfload-harf-var-t2-writer.lua
+-- DESCRIPTION: part of luaotfload / HarfBuzz / Serialize Type 2 charstrings
+-----------------------------------------------------------------------
+do
+ assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
+ name = "luaotfload-harf-var-t2-writer",
+ version = "3.19", --TAGVERSION
+ date = "2022-02-24", --TAGDATE
+ description = "luaotfload submodule / Type 2 charstring writer",
+ license = "GPL v2.0",
+ author = "Marcel Krüger",
+ copyright = "Luaotfload Development Team",
+ }
+end
+
+local pack = string.pack
+local function numbertot2(n)
+ if math.abs(n) > 2^15 then
+ error[[Number too big]]
+ end
+ local num = math.floor(n + .5)
+ if n ~= 0 and math.abs((num-n)/n) > 0.001 then
+ num = math.floor(n * 2^16 + 0.5)
+ return pack(">Bi4", 255, math.floor(n * 2^16 + 0.5))
+ elseif num >= -107 and num <= 107 then
+ return string.char(num + 139)
+ elseif num >= 108 and num <= 1131 then
+ return pack(">I2", num+0xF694) -- -108+(247*0x100)
+ elseif num >= -1131 and num <= -108 then
+ return pack(">I2", -num+0xFA94) -- -108+(251*0x100)
+ else
+ return pack(">Bi2", 28, num)
+ end
+end
+local function convert_cs(cs, upem)
+ local cs_parts = {}
+ local function add(cmd, first, ...)
+ if cmd == 19 or cmd == 20 then
+ cs_parts[#cs_parts+1] = string.char(cmd)
+ cs_parts[#cs_parts+1] = first
+ return
+ end
+ if first then
+ cs_parts[#cs_parts+1] = numbertot2(first*upem/1000)
+ return add(cmd, ...)
+ end
+ if cmd then
+ if cmd < 0 then
+ cs_parts[#cs_parts+1] = string.char(12, -cmd-1)
+ else
+ cs_parts[#cs_parts+1] = string.char(cmd)
+ end
+ end
+ end
+ for _, args in ipairs(cs) do
+ if args then
+ local cmd = args[1]
+ local height = #args - 1
+ local i = 2
+ while height > 48 do
+ -- Special cases: hhcurveto, vvcurveto, rcurveline, rlinecurve
+ -- hhvurveto/vvcurveto: In odd argument case, the first argument must be
+ -- followed by a multiple of four arguments.
+ if cmd == 27 and i == 2 and height % 4 == 1 then -- hhcurveto
+ add(cmd, table.unpack(args, i, i + 44))
+ height = height - 45
+ i = i + 45
+ elseif cmd == 26 and i == 2 and height % 4 == 1 then -- vvcurveto
+ add(cmd, table.unpack(args, i, i + 44))
+ height = height - 45
+ i = i + 45
+ -- rcurveline/rlinecurve: At least 8 arguments must be preserved, all previous instances
+ -- need different commands
+ elseif cmd == 24 then -- rcurveline
+ height = height - 48
+ local count
+ if height >= 8 then
+ count = 48
+ else
+ count = 48 - 8 + height
+ height = 8
+ end
+ add(8, table.unpack(args, i, i + count - 1)) -- 8 = rrcurveto
+ i = i + count
+ elseif cmd == 25 then -- rlinecurve
+ height = height - 48
+ local count
+ if height >= 8 then
+ count = 48
+ else
+ count = 48 - 8 + height
+ height = 8
+ end
+ add(5, table.unpack(args, i, i + count - 1)) -- 5 = rlineto
+ i = i + count
+ else -- Some commands have an optional last argument which can appear after multiple of 48 arguments,
+ -- so it's safer to never leave a element alone in a line.
+ height = height - 48
+ local count
+ if height > 1 then
+ count = 48
+ else
+ -- assert(height == 1)
+ count = 24--48 - 25 + height
+ height = 25
+ end
+ add(cmd, table.unpack(args, i, i + count - 1))
+ i = i + count
+ end
+ end
+ add(cmd, table.unpack(args, i))
+ end
+ end
+ return table.concat(cs_parts)
+end
+
+return function(cs, upem)
+ return convert_cs(cs, upem or 1000)
+end