Created
October 4, 2016 17:21
-
-
Save doraTeX/a802bfa15ae094f183ed1f3840a2c357 to your computer and use it in GitHub Desktop.
Show information of a TTC file (derived from zrdecompttc.lua https://gist.github.com/zr-tex8r/7058922 )
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- ttcinfo.lua | |
prog_name = "ttcinfo" | |
version = "0.1" | |
mod_date = "2016/10/05" | |
verbose = true | |
---------------------------------------- | |
ttc_file, ttf_base, ttf_ext, ttf_idb = nil | |
---------------------------------------- | |
do | |
local reader_meta = { | |
__tostring = function(self) | |
return "reader("..self.name..")" | |
end; | |
__index = { | |
cdata = function(self, ofs, len) | |
return make_cdata(self:read(ofs, len)) | |
end; | |
read = function(self, ofs, len) | |
self.file:seek("set", ofs) | |
local data = self.file:read(len) | |
sure(data:len() == len, 1) | |
return data | |
end; | |
close = function(self) | |
self.file:close() | |
end; | |
} | |
} | |
function make_reader(fname) | |
local file = io.open(fname, "rb") | |
sure(file, "cannot open for input", fname) | |
return setmetatable({ | |
name = fname, file = file | |
}, reader_meta) | |
end | |
end | |
---------------------------------------- | |
do | |
local cdata_meta = { | |
__tostring = function(self) | |
return "cdata(pos="..self._pos..")" | |
end; | |
__index = { | |
pos = function(self, p) | |
if not p then return self._pos end | |
self._pos = p | |
return self | |
end; | |
_unum = function(self, b) | |
local v, data = 0, self.data | |
sure(#data >= self._pos + b, 11) | |
for i = 1, b do | |
self._pos = self._pos + 1 | |
v = v * 256 + data:byte(self._pos) | |
end | |
return v | |
end; | |
_setunum = function(self, b, v) | |
local t, data = {}, self.data | |
t[1] = data:sub(1, self._pos) | |
self._pos = self._pos + b | |
sure(#data >= self._pos, 12) | |
t[b + 2] = data:sub(self._pos + 1) | |
for i = 1, b do | |
t[b + 2 - i] = string.char(v % 256) | |
v = math.floor(v / 256) | |
end | |
self.data = table.concat(t, "") | |
return self | |
end; | |
str = function(self, b) | |
local data = self.data | |
self._pos = self._pos + b | |
sure(#data >= self._pos, 13) | |
return data:sub(self._pos - b + 1, self._pos) | |
end; | |
setstr = function(self, s) | |
local t, data = {}, self.data | |
t[1], t[2] = data:sub(1, self._pos), s | |
self._pos = self._pos + #s | |
sure(#data >= self._pos, 14) | |
t[3] = data:sub(self._pos + 1) | |
self.data = table.concat(t, "") | |
return self | |
end; | |
ushort = function(self) | |
return self:_unum(2) | |
end; | |
ulong = function(self) | |
return self:_unum(4) | |
end; | |
setulong = function(self, v) | |
return self:_setunum(4, v) | |
end; | |
ulongs = function(self, num) | |
local t = {} | |
for i = 1, num do | |
t[i] = self:_unum(4) | |
end | |
return t | |
end; | |
} | |
} | |
function make_cdata(data) | |
return setmetatable({ | |
data = data, _pos = 0 | |
}, cdata_meta) | |
end | |
function empty_cdata(len) | |
return make_cdata(("\0"):rep(len)) | |
end | |
end | |
---------------------------------------- | |
do | |
local RDX = 0x10000 * 0x10000 | |
local MAGIC = 0x5F0F3CF5 | |
local SGOAL = 0xB1B0AFBA | |
function ttf_offset(reader) | |
local cd = reader:cdata(0, 12) | |
local tag = cd:str(4); info("tag", tag) | |
sure(tag == "ttcf", "TTC header missing") | |
local ver = cd:ulong(); info("version", ver) | |
local num = cd:ulong(); info("#fonts", num) | |
cd = reader:cdata(12, 4 * num) | |
local res = cd:ulongs(num); info("offset", stt(res)) | |
return res | |
end | |
local function check_sum(cd) | |
local sum, len = 0, #cd.data | |
sure(len % 4 == 0, 19) | |
cd:pos(0) | |
for i = 1, len / 4 do | |
sum = sum + cd:ulong() | |
if sum >= RDX then sum = sum - RDX end | |
end | |
return sum | |
end | |
local function madd(a, b) | |
local sum = a + b | |
if sum >= RDX then sum = sum - RDX end | |
return sum | |
end | |
local function msub(a, b) | |
local sum = a - b | |
if sum < 0 then sum = sum + RDX end | |
return sum | |
end | |
function ttf_flavor(reader, fofs) | |
local tag = reader:cdata(fofs, 4):str(4) | |
return (tag == "OTTO") and "otf" or "ttf" | |
end | |
end | |
---------------------------------------- | |
do | |
local stt_meta = { | |
__tostring = function(self) | |
return "{"..concat(self, ",").."}" | |
end | |
} | |
function stt(tbl) | |
return setmetatable(tbl, stt_meta) | |
end | |
function concat(tbl, ...) | |
local t = {} | |
for i = 1, #tbl do t[i] = tostring(tbl[i]) end | |
return table.concat(t, ...) | |
end | |
function info(...) | |
if not verbose then return end | |
local t = { prog_name, ... } | |
io.stderr:write(concat(t, ": ").."\n") | |
end | |
function abort(...) | |
verbose = true; info(...) | |
os.exit(-1) | |
end | |
function sure(val, a1, ...) | |
if val then return val end | |
if type(a1) == "number" then | |
a1 = "error("..a1..")" | |
end | |
abort(a1, ...) | |
end | |
end | |
---------------------------------------- | |
do | |
local suffix = "_1" | |
local function show_usage() | |
io.stdout:write(([[ | |
This is %s v%s <%s> by 'doraTeX' (derived from zrdecompttc.lua by 'ZR') | |
Usage: %s[.lua] <ttc_file> | |
]]):format(prog_name, version, mod_date, prog_name)) | |
os.exit(0) | |
end | |
local function out_name() | |
local base, t, ext = ttf_base | |
if base then | |
local _, _, b, e = base:find("^(.+)%.([a-zA-Z]+)$") | |
if b then base, ext = b, e end | |
t = not (base:find("%d")) | |
else | |
local ps = sure(ttc_file:find("[^/\\]+$"), 1) | |
base = ttc_file:sub(ps) | |
t = (base:sub(-4):lower() == ".ttc") and -5 or -1 | |
base, t = base:sub(1, t), true | |
end | |
if t then base = base..suffix end | |
local _, _, h, i, t = base:find("^(.-)(%d+)(%D*)$") | |
base = h:gsub("%%","%%%%").."%0"..(#i).."d".. | |
t:gsub("%%","%%%%")..".%s" | |
return base, i - 1, ext | |
end | |
function read_option() | |
if #arg == 0 then show_usage() end | |
local idx = 1 | |
while idx <= #arg do | |
local opt = arg[idx] | |
if opt:sub(1, 1) ~= "-" then break end | |
if opt == "-h" or opt == "--help" then | |
show_usage() | |
else abort("invalid option", opt) | |
end | |
idx = idx + 1 | |
end | |
sure(#arg == idx, "wrong number of arguments") | |
ttc_file = arg[idx] | |
ttf_base, ttf_idb, ttf_ext = out_name() | |
end | |
local function write_open(file) | |
local ofile = io.open(file, "wb") | |
sure(ofile, "cannot open for output", file) | |
return ofile | |
end | |
function main() | |
read_option() | |
local reader = make_reader(ttc_file) | |
local tofs = ttf_offset(reader) | |
for i = 1, #tofs do | |
local ext = ttf_ext or ttf_flavor(reader, tofs[i]) | |
local ttf_name = ttf_base:format(ttf_idb + i, ext) | |
info("Font #"..i, ttf_name) | |
end | |
reader:close() | |
end | |
end | |
---------------------------------------- | |
main() | |
-- EOF |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment