summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/context/base/mkiv/font-otr.lua
diff options
context:
space:
mode:
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.lua275
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