diff options
Diffstat (limited to 'Master/texmf-dist/tex/context/base/mkiv/font-otr.lua')
-rw-r--r-- | Master/texmf-dist/tex/context/base/mkiv/font-otr.lua | 275 |
1 files changed, 105 insertions, 170 deletions
diff --git a/Master/texmf-dist/tex/context/base/mkiv/font-otr.lua b/Master/texmf-dist/tex/context/base/mkiv/font-otr.lua index c7ff6b72689..5bac75052ac 100644 --- a/Master/texmf-dist/tex/context/base/mkiv/font-otr.lua +++ b/Master/texmf-dist/tex/context/base/mkiv/font-otr.lua @@ -25,7 +25,7 @@ if not modules then modules = { } end modules ['font-otr'] = { -- are just a unicode string but it doesn't save that much. It will be an option -- some day. --- Optimizing the widths will be done anyway as it save quite some on a cjk font +-- Optimizing the widths wil be done anyway as it save quite some on a cjk font -- and the existing (old) code if okay. -- todo: more messages (only if really needed) @@ -67,7 +67,6 @@ if not modules then modules = { } end modules ['font-otr'] = { local next, type, tonumber = next, type, tonumber local byte, lower, char, gsub = string.byte, string.lower, string.char, string.gsub -local fullstrip = string.fullstrip local floor, round = math.floor, math.round local P, R, S, C, Cs, Cc, Ct, Carg, Cmt = lpeg.P, lpeg.R, lpeg.S, lpeg.C, lpeg.Cs, lpeg.Cc, lpeg.Ct, lpeg.Carg, lpeg.Cmt local lpegmatch = lpeg.match @@ -122,47 +121,11 @@ local read2dot14 = streamreader.read2dot14 -- 16-bit signed fixed num local readfword = readshort -- 16-bit signed integer that describes a quantity in FUnits local readufword = readushort -- 16-bit unsigned integer that describes a quantity in FUnits local readoffset = readushort -local readcardinaltable = streamreader.readcardinaltable -local readintegertable = streamreader.readintegertable function streamreader.readtag(f) return lower(stripstring(readstring(f,4))) end -local short = 2 -local ushort = 2 -local ulong = 4 - -directives.register("fonts.streamreader",function() - - streamreader = utilities.streams - - openfile = streamreader.open - closefile = streamreader.close - setposition = streamreader.setposition - skipshort = streamreader.skipshort - readbytes = streamreader.readbytes - readstring = streamreader.readstring - readbyte = streamreader.readcardinal1 - readushort = streamreader.readcardinal2 - readuint = streamreader.readcardinal3 - readulong = streamreader.readcardinal4 - readshort = streamreader.readinteger2 - readlong = streamreader.readinteger4 - readfixed = streamreader.readfixed4 - read2dot14 = streamreader.read2dot14 - readfword = readshort - readufword = readushort - readoffset = readushort - readcardinaltable = streamreader.readcardinaltable - readintegertable = streamreader.readintegertable - - function streamreader.readtag(f) - return lower(stripstring(readstring(f,4))) - end - -end) - -- date represented in number of seconds since 12:00 midnight, January 1, 1904. The value is represented as a -- signed 64-bit integer @@ -741,30 +704,20 @@ readers.helpers = helpers local function gotodatatable(f,fontdata,tag,criterium) if criterium and f then - local tables = fontdata.tables - if tables then - local datatable = tables[tag] - if datatable then - local tableoffset = datatable.offset - setposition(f,tableoffset) - return tableoffset - end - else - report("no tables") + local datatable = fontdata.tables[tag] + if datatable then + local tableoffset = datatable.offset + setposition(f,tableoffset) + return tableoffset end end end local function reportskippedtable(f,fontdata,tag,criterium) if criterium and f then - local tables = fontdata.tables - if tables then - local datatable = tables[tag] - if datatable then - report("loading of table %a skipped",tag) - end - else - report("no tables") + local datatable = fontdata.tables[tag] + if datatable then + report("loading of table %a skipped",tag) end end end @@ -796,16 +749,6 @@ local platformnames = { compatiblefullname = true, } -local platformextras = { - uniqueid = true, - version = true, - copyright = true, - license = true, - licenseurl = true, - manufacturer = true, - vendorurl = true, -} - function readers.name(f,fontdata,specification) local tableoffset = gotodatatable(f,fontdata,"name",true) if tableoffset then @@ -876,18 +819,6 @@ function readers.name(f,fontdata,specification) -- and extend when we run into it (todo: proper reverse hash) .. we're only -- interested in english anyway -- - local function decoded(platform,encoding,content) - local decoder = decoders[platform] - if decoder then - decoder = decoder[encoding] - end - if decoder then - return decoder(content) - else - return content - end - end - -- local function filter(platform,e,l) local namelist = namelists[platform] for i=1,#namelist do @@ -899,7 +830,14 @@ function readers.name(f,fontdata,specification) local language = name.language if (not e or encoding == e) and (not l or language == l) then setposition(f,name.offset) - local content = decoded(platform,encoding,readstring(f,name.length)) + local content = readstring(f,name.length) + local decoder = decoders[platform] + if decoder then + decoder = decoder[encoding] + end + if decoder then + content = decoder(content) + end if nametag then names[nametag] = { content = content, @@ -926,16 +864,23 @@ function readers.name(f,fontdata,specification) fontdata.extras = extras -- if specification.platformnames then - local collected = { } - local platformextras = specification.platformextras and platformextras + local collected = { } for platform, namelist in next, namelists do local filtered = false for i=1,#namelist do local entry = namelist[i] local name = entry.name - if platformnames[name] or (platformextras and platformextras[name]) then + if platformnames[name] then setposition(f,entry.offset) - local content = decoded(platform,entry.encoding,readstring(f,entry.length)) + local content = readstring(f,entry.length) + local encoding = entry.encoding + local decoder = decoders[platform] + if decoder then + decoder = decoder[encoding] + end + if decoder then + content = decoder(content) + end if filtered then filtered[name] = content else @@ -978,7 +923,7 @@ readers["os/2"] = function(f,fontdata) local version = readushort(f) local windowsmetrics = { version = version, - averagewidth = readshort(f), -- ushort? + averagewidth = readshort(f), weightclass = readushort(f), widthclass = readushort(f), fstype = readushort(f), @@ -1008,7 +953,7 @@ readers["os/2"] = function(f,fontdata) if version >= 1 then windowsmetrics.codepageranges = { readulong(f), readulong(f) } end - if version >= 2 then + if version >= 3 then windowsmetrics.xheight = readshort(f) windowsmetrics.capheight = readshort(f) windowsmetrics.defaultchar = readushort(f) @@ -1035,28 +980,24 @@ end readers.head = function(f,fontdata) local tableoffset = gotodatatable(f,fontdata,"head",true) if tableoffset then - local version = readulong(f) - local fontversion = readulong(f) local fontheader = { - version = version, - fontversion = number.to16dot16(fontversion), - fontversionnumber = fontversion, - -- checksum = readulong(f), - checksum = readushort(f) * 0x10000 + readushort(f), - magic = readulong(f), - flags = readushort(f), - units = readushort(f), - created = readlongdatetime(f), - modified = readlongdatetime(f), - xmin = readshort(f), - ymin = readshort(f), - xmax = readshort(f), - ymax = readshort(f), - macstyle = readushort(f), - smallpixels = readushort(f), - directionhint = readshort(f), - indextolocformat = readshort(f), - glyphformat = readshort(f), + version = readfixed(f), + revision = readfixed(f), + checksum = readulong(f), + magic = readulong(f), + flags = readushort(f), + units = readushort(f), + created = readlongdatetime(f), + modified = readlongdatetime(f), + xmin = readshort(f), + ymin = readshort(f), + xmax = readshort(f), + ymax = readshort(f), + macstyle = readushort(f), + smallpixels = readushort(f), + directionhint = readshort(f), + indextolocformat = readshort(f), + glyphformat = readshort(f), } fontdata.fontheader = fontheader else @@ -1072,7 +1013,7 @@ readers.hhea = function(f,fontdata,specification) local tableoffset = gotodatatable(f,fontdata,"hhea",specification.details) if tableoffset then fontdata.horizontalheader = { - version = readulong(f), + version = readfixed(f), -- two ushorts: major minor ascender = readfword(f), descender = readfword(f), linegap = readfword(f), @@ -1101,7 +1042,7 @@ readers.vhea = function(f,fontdata,specification) local tableoffset = gotodatatable(f,fontdata,"vhea",specification.details) if tableoffset then fontdata.verticalheader = { - version = readulong(f), + version = readfixed(f), ascender = readfword(f), descender = readfword(f), linegap = readfword(f), @@ -1134,15 +1075,15 @@ end readers.maxp = function(f,fontdata,specification) local tableoffset = gotodatatable(f,fontdata,"maxp",specification.details) if tableoffset then - local version = readulong(f) + local version = readfixed(f) local nofglyphs = readushort(f) fontdata.nofglyphs = nofglyphs - if version == 0x00005000 then + if version == 0.5 then fontdata.maximumprofile = { version = version, nofglyphs = nofglyphs, } - elseif version == 0x00010000 then + elseif version == 1.0 then fontdata.maximumprofile = { version = version, nofglyphs = nofglyphs, @@ -1183,14 +1124,15 @@ readers.hmtx = function(f,fontdata,specification) local leftsidebearing = 0 for i=0,nofmetrics-1 do local glyph = glyphs[i] - width = readshort(f) -- readushort + width = readshort(f) leftsidebearing = readshort(f) if width ~= 0 then glyph.width = width end - -- if leftsidebearing ~= 0 then - -- glyph.lsb = leftsidebearing - -- end +-- for now +-- if leftsidebearing ~= 0 then +-- glyph.lsb = leftsidebearing +-- end end -- The next can happen in for instance a monospace font or in a cjk font -- with fixed widths. @@ -1203,6 +1145,7 @@ readers.hmtx = function(f,fontdata,specification) -- glyph.lsb = leftsidebearing -- end end + -- hm, there can be a lsb here end end @@ -1252,7 +1195,7 @@ end readers.post = function(f,fontdata,specification) local tableoffset = gotodatatable(f,fontdata,"post",true) if tableoffset then - local version = readulong(f) + local version = readfixed(f) fontdata.postscript = { version = version, italicangle = round(1000*readfixed(f))/1000, @@ -1266,12 +1209,12 @@ readers.post = function(f,fontdata,specification) } if not specification.glyphs then -- enough done - elseif version == 0x00010000 then + elseif version == 1.0 then -- mac encoding (258 glyphs) for index=0,#standardromanencoding do glyphs[index].name = standardromanencoding[index] end - elseif version == 0x00020000 then + elseif version == 2.0 then local glyphs = fontdata.glyphs local nofglyphs = readushort(f) local indices = { } @@ -1302,6 +1245,10 @@ readers.post = function(f,fontdata,specification) end end end + elseif version == 2.5 then + -- depricated, will be done when needed + elseif version == 3.0 then + -- no ps name information end else fontdata.postscript = { } @@ -1374,18 +1321,34 @@ formatreaders[4] = function(f,fontdata,offset) -- skipshort(f,3) -- searchrange entryselector rangeshift -- + local endchars = { } + local startchars = { } + local deltas = { } + local offsets = { } + local indices = { } local mapping = fontdata.mapping local glyphs = fontdata.glyphs local duplicates = fontdata.duplicates local nofdone = 0 - local endchars = readcardinaltable(f,nofsegments,ushort) - local reserved = readushort(f) -- 0 - local startchars = readcardinaltable(f,nofsegments,ushort) - local deltas = readcardinaltable(f,nofsegments,ushort) - local offsets = readcardinaltable(f,nofsegments,ushort) + -- + for i=1,nofsegments do + endchars[i] = readushort(f) + end + local reserved = readushort(f) -- 0 + for i=1,nofsegments do + startchars[i] = readushort(f) + end + for i=1,nofsegments do + deltas[i] = readshort(f) + end + for i=1,nofsegments do + offsets[i] = readushort(f) + end -- format length language nofsegments searchrange entryselector rangeshift 4-tables - local size = (length - 2 * 2 - 5 * 2 - 4 * 2 * nofsegments) / 2 - local indices = readcardinaltable(f,size-1,ushort) + local size = (length - 2 * 2 - 5 * 2 - 4 * 2 * nofsegments) / 2 + for i=1,size-1 do + indices[i] = readushort(f) + end -- for segment=1,nofsegments do local startchar = startchars[segment] @@ -1964,16 +1927,14 @@ local function getinfo(maindata,sub,platformnames,rawfamilynames,metricstoo,inst designsize = fontdata.designsize, minsize = fontdata.minsize, maxsize = fontdata.maxsize, - boundingbox = fontheader and { fontheader.xmin or 0, fontheader.ymin or 0, fontheader.xmax or 0, fontheader.ymax or 0 } or nil, monospaced = (tonumber(postscript.monospaced or 0) > 0) or metrics.panosewidth == "monospaced", averagewidth = metrics.averagewidth, - xheight = metrics.xheight, -- can be missing - capheight = metrics.capheight or fontdata.maxy, -- can be missing + xheight = metrics.xheight, + capheight = metrics.capheight, -- not always present and probably crap ascender = metrics.typoascender, descender = metrics.typodescender, platformnames = platformnames or nil, instancenames = instancenames or nil, - tableoffsets = fontdata.tableoffsets, } if metricstoo then local keys = { @@ -2035,8 +1996,7 @@ local function loadtables(f,specification,offset) } for i=1,fontdata.noftables do local tag = lower(stripstring(readstring(f,4))) - -- local checksum = readulong(f) -- not used - local checksum = readushort(f) * 0x10000 + readushort(f) + local checksum = readulong(f) -- not used local offset = readulong(f) local length = readulong(f) if offset + length > filesize then @@ -2048,14 +2008,13 @@ local function loadtables(f,specification,offset) length = length, } end --- inspect(tables) fontdata.foundtables = sortedkeys(tables) if tables.cff or tables.cff2 then fontdata.format = "opentype" else fontdata.format = "truetype" end - return fontdata, tables + return fontdata end local function prepareglyps(fontdata) @@ -2084,7 +2043,7 @@ local variablefonts_supported = (context and true) or (logs and logs.application local function readdata(f,offset,specification) - local fontdata, tables = loadtables(f,specification,offset) + local fontdata = loadtables(f,specification,offset) if specification.glyphs then prepareglyps(fontdata) @@ -2223,20 +2182,10 @@ local function readdata(f,offset,specification) readtable("math",f,fontdata,specification) fontdata.locations = nil + fontdata.tables = nil fontdata.cidmaps = nil fontdata.dictionaries = nil -- fontdata.cff = nil - - if specification.tableoffsets then - fontdata.tableoffsets = tables - setmetatableindex(tables, { - version = fontdata.version, - noftables = fontdata.noftables, - searchrange = fontdata.searchrange, - entryselector = fontdata.entryselector, - rangeshift = fontdata.rangeshift, - }) - end return fontdata end @@ -2260,9 +2209,12 @@ local function loadfontdata(specification) fontdata = readdata(f,0,specification) elseif version == "ttcf" then local subfont = tonumber(specification.subfont) + local offsets = { } local ttcversion = readulong(f) local nofsubfonts = readulong(f) - local offsets = readcardinaltable(f,nofsubfonts,ulong) + for i=1,nofsubfonts do + offsets[i] = readulong(f) + end if subfont then -- a number of not if subfont >= 1 and subfont <= nofsubfonts then fontdata = readdata(f,offsets[subfont],specification) @@ -2344,13 +2296,12 @@ local function loadfont(specification,n,instance) specification.instance = specification.instance or instance end local function message(str) - report("fatal error in file %a: %s\n%s",specification.filename,str,debug and debug.traceback()) + report("fatal error in file %a: %s\n%s",specification.filename,str,debug.traceback()) end local ok, result = xpcall(loadfontdata,message,specification) if ok then return result end --- return loadfontdata(specification) end -- we need even less, but we can have a 'detail' variant @@ -2372,26 +2323,13 @@ function readers.loadshapes(filename,n,instance,streams) v.math = nil -- v.name = nil end - local names = fontdata.names - if names then - for k, v in next, names do - names[k] = fullstrip(v.content) - end - end end return fontdata and { - -- version = 0.123 -- todo - filename = filename, - format = fontdata.format, - glyphs = fontdata.glyphs, - units = fontdata.fontheader.units, - cffinfo = fontdata.cffinfo, - fontheader = fontdata.fontheader, - horizontalheader = fontdata.horizontalheader, - verticalheader = fontdata.verticalheader, - maximumprofile = fontdata.maximumprofile, - names = fontdata.names, - postscript = fontdata.postscript, + -- version = 0.123 -- todo + filename = filename, + format = fontdata.format, + glyphs = fontdata.glyphs, + units = fontdata.fontheader.units, } or { filename = filename, format = "unknown", @@ -2447,7 +2385,7 @@ function readers.loadfont(filename,n,instance) mathconstants = fontdata.mathconstants, colorpalettes = fontdata.colorpalettes, svgshapes = fontdata.svgshapes, - pngshapes = fontdata.pngshapes, + sbixshapes = fontdata.sbixshapes, variabledata = fontdata.variabledata, foundtables = fontdata.foundtables, }, @@ -2462,12 +2400,10 @@ function readers.getinfo(filename,specification) -- string, nil|number|table local platformnames = false local rawfamilynames = false local instancenames = true - local tableoffsets = false if type(specification) == "table" then subfont = tonumber(specification.subfont) platformnames = specification.platformnames rawfamilynames = specification.rawfamilynames - tableoffsets = specification.tableoffsets else subfont = tonumber(specification) end @@ -2476,7 +2412,6 @@ function readers.getinfo(filename,specification) -- string, nil|number|table details = true, platformnames = platformnames, instancenames = true, - tableoffsets = tableoffsets, -- rawfamilynames = rawfamilynames, } if fontdata then |