summaryrefslogtreecommitdiff
path: root/tex/context/base/font-otf.lua
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/font-otf.lua')
-rw-r--r--tex/context/base/font-otf.lua194
1 files changed, 132 insertions, 62 deletions
diff --git a/tex/context/base/font-otf.lua b/tex/context/base/font-otf.lua
index 51c2af00f..ab32399a7 100644
--- a/tex/context/base/font-otf.lua
+++ b/tex/context/base/font-otf.lua
@@ -20,7 +20,7 @@ local type, next, tonumber, tostring = type, next, tonumber, tostring
local abs = math.abs
local insert = table.insert
local lpegmatch = lpeg.match
-local reversed, concat, remove = table.reversed, table.concat, table.remove
+local reversed, concat, remove, sortedkeys = table.reversed, table.concat, table.remove, table.sortedkeys
local ioflush = io.flush
local fastcopy, tohash, derivetable = table.fastcopy, table.tohash, table.derive
local formatters = string.formatters
@@ -768,7 +768,7 @@ actions["prepare glyphs"] = function(data,filename,raw)
}
local altuni = glyph.altuni
if altuni then
- local d
+ -- local d
for i=1,#altuni do
local a = altuni[i]
local u = a.unicode
@@ -783,15 +783,15 @@ actions["prepare glyphs"] = function(data,filename,raw)
vv = { [u] = unicode }
variants[v] = vv
end
- elseif d then
- d[#d+1] = u
- else
- d = { u }
+ -- elseif d then
+ -- d[#d+1] = u
+ -- else
+ -- d = { u }
end
end
- if d then
- duplicates[unicode] = d
- end
+ -- if d then
+ -- duplicates[unicode] = d -- is this needed ?
+ -- end
end
else
report_otf("potential problem: glyph %U is used but empty",index)
@@ -819,6 +819,7 @@ actions["check encoding"] = function(data,filename,raw)
local mapdata = raw.map or { }
local unicodetoindex = mapdata and mapdata.map or { }
+ local indextounicode = mapdata and mapdata.backmap or { }
-- local encname = lower(data.enc_name or raw.enc_name or mapdata.enc_name or "")
local encname = lower(data.enc_name or mapdata.enc_name or "")
local criterium = 0xFFFF -- for instance cambria has a lot of mess up there
@@ -829,42 +830,81 @@ actions["check encoding"] = function(data,filename,raw)
if trace_loading then
report_otf("checking embedded unicode map %a",encname)
end
- for unicode, index in next, unicodetoindex do -- altuni already covers this
- if unicode <= criterium and not descriptions[unicode] then
- local parent = indices[index] -- why nil?
- if not parent then
- report_otf("weird, unicode %U points to nowhere with index %H",unicode,index)
- else
- local parentdescription = descriptions[parent]
- if parentdescription then
- local altuni = parentdescription.altuni
- if not altuni then
- altuni = { { unicode = unicode } }
- parentdescription.altuni = altuni
- duplicates[parent] = { unicode }
- else
- local done = false
- for i=1,#altuni do
- if altuni[i].unicode == unicode then
- done = true
- break
- end
- end
- if not done then
- -- let's assume simple cjk reuse
- insert(altuni,{ unicode = unicode })
- insert(duplicates[parent],unicode)
+ -- if false then
+ -- for unicode, index in next, unicodetoindex do -- altuni already covers this
+ -- if unicode <= criterium and not descriptions[unicode] then
+ -- local parent = indices[index] -- why nil?
+ -- if not parent then
+ -- report_otf("weird, unicode %U points to nowhere with index %H",unicode,index)
+ -- else
+ -- local parentdescription = descriptions[parent]
+ -- if parentdescription then
+ -- local altuni = parentdescription.altuni
+ -- if not altuni then
+ -- altuni = { { unicode = unicode } }
+ -- parentdescription.altuni = altuni
+ -- duplicates[parent] = { unicode }
+ -- else
+ -- local done = false
+ -- for i=1,#altuni do
+ -- if altuni[i].unicode == unicode then
+ -- done = true
+ -- break
+ -- end
+ -- end
+ -- if not done then
+ -- -- let's assume simple cjk reuse
+ -- insert(altuni,{ unicode = unicode })
+ -- insert(duplicates[parent],unicode)
+ -- end
+ -- end
+ -- -- if trace_loading then
+ -- -- report_otf("weird, unicode %U points to nowhere with index %H",unicode,index)
+ -- -- end
+ -- else
+ -- report_otf("weird, unicode %U points to %U with index %H",unicode,index)
+ -- end
+ -- end
+ -- end
+ -- end
+ -- else
+ local hash = { }
+ for index, unicode in next, indices do -- indextounicode
+ hash[index] = descriptions[unicode]
+ end
+ local reported = { }
+ for unicode, index in next, unicodetoindex do
+ if not descriptions[unicode] then
+ local d = hash[index]
+ if d then
+ if d.unicode ~= unicode then
+ local c = d.copies
+ if c then
+ c[unicode] = true
+ else
+ d.copies = { [unicode] = true }
end
end
- if trace_loading then
- report_otf("weird, unicode %U points to nowhere with index %H",unicode,index)
- end
- else
- report_otf("weird, unicode %U points to %U with index %H",unicode,index)
+ elseif not reported[i] then
+ report_otf("missing index %i",index)
+ reported[i] = true
end
end
end
- end
+ for index, data in next, hash do -- indextounicode
+ data.copies = sortedkeys(data.copies)
+ end
+ for index, unicode in next, indices do -- indextounicode
+ local description = hash[index]
+ local copies = description.copies
+ if copies then
+ duplicates[unicode] = copies
+ description.copies = nil
+ else
+ report_otf("copies but no unicode parent %U",unicode)
+ end
+ end
+ -- end
elseif properties.cidinfo then
report_otf("warning: no unicode map, used cidmap %a",properties.cidinfo.usedname)
else
@@ -872,12 +912,15 @@ actions["check encoding"] = function(data,filename,raw)
end
if mapdata then
- mapdata.map = { } -- clear some memory
+ mapdata.map = { } -- clear some memory
+ mapdata.backmap = { } -- clear some memory
end
end
-- for the moment we assume that a font with lookups will not use
--- altuni so we stick to kerns only
+-- altuni so we stick to kerns only .. alternatively we can always
+-- do an indirect lookup uni_to_uni . but then we need that in
+-- all lookups
actions["add duplicates"] = function(data,filename,raw)
local descriptions = data.descriptions
@@ -888,29 +931,38 @@ actions["add duplicates"] = function(data,filename,raw)
local duplicates = resources.duplicates
for unicode, d in next, duplicates do
- for i=1,#d do
- local u = d[i]
- if not descriptions[u] then
- local description = descriptions[unicode]
- local duplicate = table.copy(description) -- else packing problem
- duplicate.comment = format("copy of U+%05X", unicode)
- descriptions[u] = duplicate
- local n = 0
- for _, description in next, descriptions do
- if kerns then
- local kerns = description.kerns
- for _, k in next, kerns do
- local ku = k[unicode]
- if ku then
- k[u] = ku
- n = n + 1
+ local nofduplicates = #d
+ if nofduplicates > 4 then
+ if trace_loading then
+ report_otf("ignoring excessive duplicates of %U (n=%s)",unicode,nofduplicates)
+ end
+ else
+ for i=1,nofduplicates do
+ local u = d[i]
+ if not descriptions[u] then
+ local description = descriptions[unicode]
+ local n = 0
+ for _, description in next, descriptions do
+ if kerns then
+ local kerns = description.kerns
+ for _, k in next, kerns do
+ local ku = k[unicode]
+ if ku then
+ k[u] = ku
+ n = n + 1
+ end
end
end
+ -- todo: lookups etc
+ end
+ if u > 0 then
+ local duplicate = table.copy(description) -- else packing problem
+ duplicate.comment = format("copy of U+%05X", unicode)
+ descriptions[u] = duplicate
+ if trace_loading then
+ report_otf("duplicating %U to %U with index %H (%s kerns)",unicode,u,description.index,n)
+ end
end
- -- todo: lookups etc
- end
- if trace_loading then
- report_otf("duplicating %U to %U with index %H (%s kerns)",unicode,u,description.index,n)
end
end
end
@@ -2084,6 +2136,24 @@ local function otftotfm(specification)
local features = specification.features.normal
local rawdata = otf.load(filename,sub,features and features.featurefile)
if rawdata and next(rawdata) then
+ local descriptions = rawdata.descriptions
+ local duplicates = rawdata.resources.duplicates
+ if duplicates then
+ local nofduplicates, nofduplicated = 0, 0
+ for parent, list in next, duplicates do
+ for i=1,#list do
+ local unicode = list[i]
+ if not descriptions[unicode] then
+ descriptions[unicode] = descriptions[parent] -- or copy
+ nofduplicated = nofduplicated + 1
+ end
+ end
+ nofduplicates = nofduplicates + #list
+ end
+ if trace_otf and nofduplicated ~= nofduplicates then
+ report_otf("%i extra duplicates copied out of %i",nofduplicated,nofduplicates)
+ end
+ end
rawdata.lookuphash = { }
tfmdata = copytotfm(rawdata,cache_id)
if tfmdata and next(tfmdata) then