local function check(buf, i, afterI) local checksum = 0 while i < afterI do if i+60 < afterI then local num1, num2, num3, num4, num5, num6, num7, num8, num9, num10, num11, num12, num13, num14, num15, num16, newI = string.unpack(">I4I4I4I4I4I4I4I4I4I4I4I4I4I4I4I4", buf, i) i = newI checksum = checksum + num1 + num2 + num3 + num4 + num5 + num6 + num7 + num8 + num9 + num10 + num11 + num12 + num13 + num14 + num15 + num16 elseif i+28 < afterI then local num1, num2, num3, num4, num5, num6, num7, num8, newI = string.unpack(">I4I4I4I4I4I4I4I4", buf, i) i = newI checksum = checksum + num1 + num2 + num3 + num4 + num5 + num6 + num7 + num8 elseif i+12 < afterI then local num1, num2, num3, num4, newI = string.unpack(">I4I4I4I4", buf, i) i = newI checksum = checksum + num1 + num2 + num3 + num4 else local num num, i = string.unpack(">I4", buf, i) checksum = checksum + num end end return checksum & 0xFFFFFFFF end local function log2floor(i) local j = 0 if i>>8 ~= 0 then j = j + 8 end if i>>(j+4) ~= 0 then j = j + 4 end if i>>(j+2) ~= 0 then j = j + 2 end if i>>(j+1) ~= 0 then j = j + 1 end return j end return { write = function(magic, tables) local tabdata = {} for t, val in next, tables do tabdata[#tabdata+1] = {string.format("%-4s", t), val .. string.rep("\0", (#val+3&~3)-#val), #val} end table.sort(tabdata, function(a,b)return a[1]c4I2I2I2I2", magic, #tabdata, 1<c4I4I4I4", tab[1], thischeck, offset, tab[3]) checksum = checksum + check(tabs[i+1], 1, 17) + thischeck offset = offset + #data tabs[i+1+#tabdata] = data end if headindex then local data = tabs[headindex] data = data:sub(1,8) .. string.pack(">I4", 0xB1B0AFBA-checksum&0xFFFFFFFF) .. data:sub(13) -- Benchmarking suggests that this is faster than a LPEG version tabs[headindex] = data end return table.concat(tabs) end, parse = function(buf, off, fontid) off = off or 1 local headMagic, numTables headMagic, numTables, off = string.unpack(">c4I2", buf, off) if headMagic == "ttcf" then if numTables > 2 then -- numTables is actually the major version here, 1&2 are basically equal error[[Unsupported TTC header version]] end headMagic, numTables, off = string.unpack(">I2I4", buf, off) fontid = fontid or 1 if numTables < fontid then error[[There aren't that many fonts in this file]] end off = string.unpack(">I4", buf, off + (fontid-1)*4)+1 headMagic, numTables, off = string.unpack(">c4I2", buf, off) end off = off+6 local tables = {} for i=1,numTables do local tag, check, offset, len, newOff = string.unpack(">c4I4I4I4", buf, off) off = newOff tables[tag] = {offset+1, len} if offset+len > #buf then error[[Font file too small]] end end return headMagic, tables end, }