diff options
Diffstat (limited to 'tex/context/base/font-otr.lua')
-rw-r--r-- | tex/context/base/font-otr.lua | 160 |
1 files changed, 85 insertions, 75 deletions
diff --git a/tex/context/base/font-otr.lua b/tex/context/base/font-otr.lua index 1b53601a9..ddbe6d271 100644 --- a/tex/context/base/font-otr.lua +++ b/tex/context/base/font-otr.lua @@ -32,10 +32,6 @@ if not modules then modules = { } end modules ['font-otr'] = { -- Optimizing the widths wil be done anyway as it save quite some on a cjk font -- and the existing (old) code if okay. --- todo: duplicates --- todo: markclasses : checking needed (see font-otf) --- --- todo: check all unsigned / signed (will be done last) -- todo: more messages (only if really needed) -- -- todo (in old loader and new one) math: @@ -47,19 +43,36 @@ if not modules then modules = { } end modules ['font-otr'] = { -- vert_variants -> vvariants -> next in tex, so better 'sizes' -- horiz_variants -> hvariants -> next in tex, so better 'sizes' -- +-- considered, in math: +-- -- start -> first (so we can skip the first same-size one) -- end -> last -- --- We can optimize kern pairs (i.e. simple h only positioning) later if we want --- which is easier as then we know if we have clashes between features. We can have --- kerns as well as moves (smaller files) --- -- Widths and weights are kind of messy: for instance lmmonolt has a pfmweight of -- 400 while it should be 300. So, for now we mostly stick to the old compromis. -- We don't really need all those language tables so they might be dropped some -- day. +-- The new reader is faster on some aspects and slower on other. The memory footprint +-- is lower. The string reader is a bit faster than the file reader. The new reader +-- gives more efficient tables and has bit more analysis. In practice these times are +-- not that relevant because we cache. The otf files take a it more time because we +-- need to calculate the boundingboxes. In theory the processing of text should be +-- somewhat faster especially for complex fonts with many lookups. +-- +-- old new str reader +-- lmroman12-regular.otf 0.103 0.203 0.195 +-- latinmodern-math.otf 0.454 0.768 0.712 +-- husayni.ttf 1.142 1.526 1.259 +-- +-- If there is demand I will consider making a ff compatible table dumper but it's +-- probably more fun to provide a way to show features applied. + +-- I experimented a bit with f:readbyte(n) and f:readshort() and so and it is indeed +-- faster but it might not be the real bottleneck as we still need to juggle data. It +-- is probably more memory efficient as no intermediate strings are involved. + if not characters then require("char-def") require("char-ini") @@ -90,7 +103,7 @@ handlers.otf = otf local readers = otf.readers or { } otf.readers = readers --- local streamreader = utilities.streams -- faster on big files +----- streamreader = utilities.streams -- faster on big files local streamreader = utilities.files -- faster on identify readers.streamreader = streamreader @@ -130,6 +143,8 @@ end local tableversion = 0.001 local privateoffset = fonts.constructors and fonts.constructors.privateoffset or 0xF0000 -- 0x10FFFF +readers.tableversion = tableversion + local reportedskipped = { } local function reportskippedtable(tag) @@ -585,7 +600,7 @@ local languages = { }, } -local standardromanencoding = { [0] = -- hijacked from wikipedia +local standardromanencoding = { [0] = -- taken from wikipedia "notdef", ".null", "nonmarkingreturn", "space", "exclam", "quotedbl", "numbersign", "dollar", "percent", "ampersand", "quotesingle", "parenleft", "parenright", "asterisk", "plus", "comma", "hyphen", "period", "slash", @@ -898,11 +913,10 @@ readers.head = function(f,fontdata) glyphformat = readshort(f), } fontdata.fontheader = fontheader - fontdata.nofglyphs = 0 else fontdata.fontheader = { } - fontdata.nofglyphs = 0 end + fontdata.nofglyphs = 0 end -- This table is a rather simple one. No treatment of values is needed here. Most @@ -940,9 +954,8 @@ readers.hhea = function(f,fontdata,specification) end end --- We probably never need all these variables, but we do need the nofglyphs --- when loading other tables. Again we use the microsoft names but see no reason --- to have "max" in each name. +-- We probably never need all these variables, but we do need the nofglyphs when loading other +-- tables. Again we use the microsoft names but see no reason to have "max" in each name. -- fontdata.maximumprofile can be bad @@ -988,8 +1001,8 @@ readers.maxp = function(f,fontdata,specification) end end --- Here we filter the (advance) widths (that can be different from the boundingbox --- width of course). +-- Here we filter the (advance) widths (that can be different from the boundingbox width of +-- course). readers.hmtx = function(f,fontdata,specification) if specification.glyphs then @@ -1028,10 +1041,9 @@ readers.hmtx = function(f,fontdata,specification) end end --- The post table relates to postscript (printing) but has some relevant --- properties for other usage as well. We just use the names from the microsoft --- specification. The version 2.0 description is somewhat fuzzy but it is a --- hybrid with overloads. +-- The post table relates to postscript (printing) but has some relevant properties for other +-- usage as well. We just use the names from the microsoft specification. The version 2.0 +-- description is somewhat fuzzy but it is a hybrid with overloads. readers.post = function(f,fontdata,specification) local datatable = fontdata.tables.post @@ -1103,9 +1115,10 @@ readers.cff = function(f,fontdata,specification) end end --- Not all cmaps make sense .. e.g. dfont is obsolete and probably more are not --- relevant. Let's see what we run into. There is some weird calculation going --- on here because we offset in a table being a blob of memory or file. +-- Not all cmaps make sense .. e.g. dfont is obsolete and probably more are not relevant. Let's see +-- what we run into. There is some weird calculation going on here because we offset in a table +-- being a blob of memory or file. Anyway, I can't stand lunatic formats like this esp when there +-- is no real gain. local formatreaders = { } @@ -1129,7 +1142,7 @@ formatreaders[4] = function(f,fontdata,offset) for i=1,nofsegments do endchars[i] = readushort(f) end - local reserved = readushort(f) + local reserved = readushort(f) -- 0 for i=1,nofsegments do startchars[i] = readushort(f) end @@ -1153,31 +1166,34 @@ formatreaders[4] = function(f,fontdata,offset) if startchar == 0xFFFF and endchar == 0xFFFF then break elseif offset == 0 then - for char=startchar,endchar do - local unicode = char - local index = mod(char + delta,65536) + for unicode=startchar,endchar do + index = mod(unicode + delta,65536) if index and index > 0 then local glyph = glyphs[index] - if not glyph.unicode then - glyph.unicode = unicode + if glyph then + if not glyph.unicode then + glyph.unicode = unicode + end + mapping[index] = unicode + -- report("case 1: %C %04i %s",unicode,index,glyphs[index].name) end - mapping[index] = unicode - -- report("%C %04i %05i %s",unicode,index,glyphs[index].name) end end else local shift = (segment-nofsegments+offset/2) - startchar - for char=startchar,endchar do - local unicode = mod(char + delta,65536) - local slot = shift + char - local index = indices[slot] + for unicode=startchar,endchar do + local slot = shift + unicode + local index = indices[slot] if index and index > 0 then + index = mod(index + delta,65536) local glyph = glyphs[index] - if not glyph.unicode then - glyph.unicode = unicode + if glyph then + if not glyph.unicode then + glyph.unicode = unicode + end + mapping[index] = unicode + -- report("case 2: %C %04i %s",unicode,index,glyphs[index].name) end - mapping[index] = unicode - -- report("%C %04i %05i %s",unicode,index,glyphs[index].name) end end end @@ -1349,10 +1365,10 @@ function readers.cmap(f,fontdata,specification) -- checkcmap(f,fontdata,records,0, 3, 4) -- checkcmap(f,fontdata,records,1, 0, 6) checkcmap(f,fontdata,records,0, 5,14) --- variantcid = records[0] and records[0][5] --- if variantcid then --- formatreaders[14](f,fontdata,offset,variantcid[14]) --- end + -- variantcid = records[0] and records[0][5] + -- if variantcid then + -- formatreaders[14](f,fontdata,offset,variantcid[14]) + -- end -- fontdata.cidmaps = { version = version, @@ -1365,11 +1381,9 @@ function readers.cmap(f,fontdata,specification) end end --- The glyf table depends on the loca table. We have one entry to much --- in the locations table (the last one is a dummy) because we need to --- calculate the size of a glyph blob from the delta, although we not --- need it in our usage (yet). We can remove the locations table when --- we're done (todo: cleanup finalizer). +-- The glyf table depends on the loca table. We have one entry to much in the locations table (the +-- last one is a dummy) because we need to calculate the size of a glyph blob from the delta, +-- although we not need it in our usage (yet). We can remove the locations table when we're done. function readers.loca(f,fontdata,specification) if specification.glyphs then @@ -1383,9 +1397,8 @@ function readers.glyf(f,fontdata,specification) -- part goes to cff module end end --- Here we have a table that we really need for later processing although a more --- advanced gpos table can also be available. Todo: we need a 'fake' lookup for --- this (analogue to ff). +-- Here we have a table that we really need for later processing although a more advanced gpos table +-- can also be available. Todo: we need a 'fake' lookup for this (analogue to ff). function readers.kern(f,fontdata,specification) if specification.kerns then @@ -1514,7 +1527,7 @@ local function packoutlines(data,makesequence) for i=1,#segments do local segment = segments[i] local h = concat(segment," ") - if hash[h] > 1 then + if hash[h] > 1 then -- minimal one shared in order to hash local idx = reverse[h] if not idx then last = last + 1 @@ -1866,39 +1879,32 @@ function readers.loadfont(filename,n) -- return { tableversion = tableversion, - -- cache_uuid = false, -- only when cached - -- cache_version = false, -- only when cached + creator = "context mkiv", size = fontdata.filesize, time = fontdata.filetime, - -- warnings = { }, glyphs = fontdata.glyphs, descriptions = fontdata.descriptions, format = fontdata.format, goodies = { }, - -- lookups = { }, metadata = getinfo(fontdata,n), properties = { hasitalics = fontdata.hasitalics or false, }, resources = { - -- anchor_to_lookup = fontdata.anchor_to_lookup or { }, - creator = "context mkiv", - duplicates = { }, -- todo - features = fontdata.features, - filename = fontdata.filename, - -- lookup_to_anchor = fontdata.lookup_to_anchor or { }, - sublookups = fontdata.sublookups, - subtables = fontdata.subtables, - -- lookuptags = { }, -- will be metatable using offsets: gsub-1, gpos-1 etc - lookuptypes = fontdata.lookuptypes or { }, - marks = fontdata.marks or { }, - markclasses = fontdata.markclasses or { }, - marksets = fontdata.marksets or { }, - private = privateoffset, - sequences = fontdata.sequences, - variants = fontdata.variants, -- variant -> unicode -> glyph - version = getname(fontdata,"version"), - cidinfo = fontdata.cidinfo, + duplicates = { }, -- todo + features = fontdata.features, + filename = fontdata.filename, + sublookups = fontdata.sublookups, + subtables = fontdata.subtables, + marks = fontdata.marks or { }, + markclasses = fontdata.markclasses or { }, + marksets = fontdata.marksets or { }, + private = privateoffset, + sequences = fontdata.sequences, + variants = fontdata.variants, -- variant -> unicode -> glyph + version = getname(fontdata,"version"), + cidinfo = fontdata.cidinfo, + mathconstants = fontdata.mathconstants, }, } end @@ -1955,6 +1961,10 @@ function readers.expand(fontdata) report("the %a helper is not yet implemented","unpack") end +function readers.compact(fontdata) + report("the %a helper is not yet implemented","compact") +end + -- if fonts.hashes then |