From b100f5ade2a457477428c7b29f2a3bec0e2eb022 Mon Sep 17 00:00:00 2001 From: Hans Hagen Date: Fri, 20 Dec 2013 23:45:00 +0100 Subject: beta 2013.12.20 23:45 --- tex/context/base/context-version.pdf | Bin 4109 -> 4110 bytes tex/context/base/font-con.lua | 39 +++++++++ tex/context/base/font-ctx.lua | 88 +++++++++++++++++++-- tex/context/base/font-mis.lua | 2 +- tex/context/base/font-otf.lua | 21 +++-- tex/context/base/lang-ini.lua | 1 - tex/context/base/status-files.pdf | Bin 24599 -> 24612 bytes tex/context/base/status-lua.pdf | Bin 228086 -> 228104 bytes tex/generic/context/luatex/luatex-fonts-merged.lua | 46 +++++++++-- 9 files changed, 171 insertions(+), 26 deletions(-) diff --git a/tex/context/base/context-version.pdf b/tex/context/base/context-version.pdf index 64ce0b25d..a690bcfec 100644 Binary files a/tex/context/base/context-version.pdf and b/tex/context/base/context-version.pdf differ diff --git a/tex/context/base/font-con.lua b/tex/context/base/font-con.lua index 24b03222c..09293895e 100644 --- a/tex/context/base/font-con.lua +++ b/tex/context/base/font-con.lua @@ -278,6 +278,42 @@ function constructors.aftercopyingcharacters(target,original) -- can be used for additional tweaking end +-- It's probably ok to hash just the indices because there is not that much +-- chance that one will shift slots and leave the others unset then. Anyway, +-- there is of course some overhead here, but it might as well get compensated +-- by less time spent on including the font resource twice. For the moment +-- we default to false, so a macro package has to enable it explicitly. In +-- LuaTeX the fullname is used to identify a font as being unique. + +constructors.sharefonts = false +constructors.nofsharedfonts = 0 +local sharednames = { } + +function constructors.trytosharefont(target,tfmdata) + if constructors.sharefonts then + local characters = target.characters + local n = 1 + local t = { target.psname } + local u = sortedkeys(characters) + for i=1,#u do + n = n + 1 ; t[n] = k + n = n + 1 ; t[n] = characters[u[i]].index or k + end + local h = md5.HEX(concat(t," ")) + local s = sharednames[h] + if s then + if trace_defining then + report_defining("font %a uses backend resources of font %a",target.fullname,s) + end + target.fullname = s + constructors.nofsharedfonts = constructors.nofsharedfonts + 1 + target.properties.sharedwith = s + else + sharednames[h] = target.fullname + end + end +end + function constructors.enhanceparameters(parameters) local xheight = parameters.x_height local quad = parameters.quad @@ -790,9 +826,12 @@ function constructors.scale(tfmdata,specification) end targetcharacters[unicode] = chr end + -- constructors.aftercopyingcharacters(target,tfmdata) -- + constructors.trytosharefont(target,tfmdata) + -- return target end diff --git a/tex/context/base/font-ctx.lua b/tex/context/base/font-ctx.lua index 6c3402683..b08a6aed2 100644 --- a/tex/context/base/font-ctx.lua +++ b/tex/context/base/font-ctx.lua @@ -134,6 +134,70 @@ utilities.strings.formatters.add(formatters,"font:features",[["'"..table.sequenc constructors.resolvevirtualtoo = true -- context specific (due to resolver) +constructors.sharefonts = true -- experimental +constructors.nofsharedhashes = 0 +constructors.nofsharedvectors = 0 +constructors.noffontsloaded = 0 + +local shares = { } +local hashes = { } + +function constructors.trytosharefont(target,tfmdata) + constructors.noffontsloaded = constructors.noffontsloaded + 1 + if constructors.sharefonts then + local properties = target.properties + local fullname = target.fullname + local fonthash = target.specification.hash + local sharedname = hashes[fonthash] + if sharedname then + -- this is ok for context as we know that only features can mess with font definitions + -- so a similar hash means that the fonts are similar too + if trace_defining then + report_defining("font %a uses backend resources of font %a (%s)",target.fullname,sharedname,"common hash") + end + target.fullname = sharedname + properties.sharedwith = sharedname + constructors.nofsharedfonts = constructors.nofsharedfonts + 1 + constructors.nofsharedhashes = constructors.nofsharedhashes + 1 + else + -- the one takes more time (in the worst case of many cjk fonts) but it also saves + -- embedding time + local characters = target.characters + local n = 1 + local t = { target.psname } + local u = sortedkeys(characters) + for i=1,#u do + n = n + 1 ; t[n] = k + n = n + 1 ; t[n] = characters[u[i]].index or k + end + local checksum = md5.HEX(concat(t," ")) + local sharedname = shares[checksum] + local fullname = target.fullname + if sharedname then + if trace_defining then + report_defining("font %a uses backend resources of font %a (%s)",fullname,sharedname,"common vector") + end + fullname = sharedname + properties.sharedwith= sharedname + constructors.nofsharedfonts = constructors.nofsharedfonts + 1 + constructors.nofsharedvectors = constructors.nofsharedvectors + 1 + else + shares[checksum] = fullname + end + target.fullname = fullname + hashes[fonthash] = fullname + end + end +end + + +directives.register("fonts.checksharing",function(v) + if not v then + report_defining("font sharing in backend is disabled") + end + constructors.sharefonts = v +end) + local limited = false directives.register("system.inputmode", function(v) @@ -1366,13 +1430,14 @@ function loggers.reportdefinedfonts() local parameters = data.parameters or { } tn = tn + 1 t[tn] = { - format("%03i",id or 0), - format("%09i",parameters.size or 0), - properties.type or "real", - properties.format or "unknown", - properties.name or "", - properties.psname or "", - properties.fullname or "", + format("%03i",id or 0), + format("%09i",parameters.size or 0), + properties.type or "real", + properties.format or "unknown", + properties.name or "", + properties.psname or "", + properties.fullname or "", + properties.sharedwith or "", } report_status("%s: % t",properties.name,sortedkeys(data)) end @@ -1413,7 +1478,14 @@ end luatex.registerstopactions(loggers.reportusedfeatures) statistics.register("fonts load time", function() - return statistics.elapsedseconds(fonts) + local elapsed = statistics.elapsedseconds(fonts) + local nofshared = constructors.nofsharedfonts or 0 + if nofshared > 0 then + return format("%sfor %s fonts, %s shared in backend, %s common vectors, %s common hashes", + elapsed,constructors.noffontsloaded,nofshared,constructors.nofsharedvectors,constructors.nofsharedhashes) + else + return elapsed + end end) -- experimental mechanism for Mojca: diff --git a/tex/context/base/font-mis.lua b/tex/context/base/font-mis.lua index 5ac9d671c..e1d1ebeb9 100644 --- a/tex/context/base/font-mis.lua +++ b/tex/context/base/font-mis.lua @@ -22,7 +22,7 @@ local handlers = fonts.handlers handlers.otf = handlers.otf or { } local otf = handlers.otf -otf.version = otf.version or 2.748 +otf.version = otf.version or 2.749 otf.cache = otf.cache or containers.define("fonts", "otf", otf.version, true) function otf.loadcached(filename,format,sub) diff --git a/tex/context/base/font-otf.lua b/tex/context/base/font-otf.lua index e52946059..51c2af00f 100644 --- a/tex/context/base/font-otf.lua +++ b/tex/context/base/font-otf.lua @@ -48,7 +48,7 @@ local otf = fonts.handlers.otf otf.glists = { "gsub", "gpos" } -otf.version = 2.748 -- beware: also sync font-mis.lua +otf.version = 2.749 -- beware: also sync font-mis.lua otf.cache = containers.define("fonts", "otf", otf.version, true) local fontdata = fonts.hashes.identifiers @@ -103,23 +103,28 @@ function otf.fileformat(filename) local leader = lower(io.loadchunk(filename,4)) local suffix = lower(file.suffix(filename)) if leader == "otto" then - return "opentype", "otf", suffix == "otf" + return formats.otf, suffix == "otf" elseif leader == "ttcf" then - return "truetype", "ttc", suffix == "ttc" + return formats.ttc, suffix == "ttc" elseif suffix == "ttc" then - return "truetype", "ttc", true + return formats.ttc, true + elseif suffix == "dfont" then + return formats.dfont, true else - return "truetype", "ttf", suffix == "ttf" + return formats.ttf, suffix == "ttf" end end +-- local function otf_format(filename) +-- -- return formats[lower(file.suffix(filename))] +-- end + local function otf_format(filename) - local format, suffix, okay = otf.fileformat(filename) + local format, okay = otf.fileformat(filename) if not okay then report_otf("font %a is actually an %a file",filename,format) end - -- return formats[lower(file.suffix(filename))] - return suffix + return format end local function load_featurefile(raw,featurefile) diff --git a/tex/context/base/lang-ini.lua b/tex/context/base/lang-ini.lua index 642213253..a9f428caa 100644 --- a/tex/context/base/lang-ini.lua +++ b/tex/context/base/lang-ini.lua @@ -20,7 +20,6 @@ local type, tonumber = type, tonumber local utfbyte = utf.byte local format, gsub = string.format, string.gsub local concat, sortedkeys, sortedpairs = table.concat, table.sortedkeys, table.sortedpairs -local lpegmatch = lpeg.match local settings_to_array = utilities.parsers.settings_to_array diff --git a/tex/context/base/status-files.pdf b/tex/context/base/status-files.pdf index b5cd4633c..cb9c68b5d 100644 Binary files a/tex/context/base/status-files.pdf and b/tex/context/base/status-files.pdf differ diff --git a/tex/context/base/status-lua.pdf b/tex/context/base/status-lua.pdf index b504da2ad..270d2ec65 100644 Binary files a/tex/context/base/status-lua.pdf and b/tex/context/base/status-lua.pdf differ diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua index 688cfecb5..228b9727c 100644 --- a/tex/generic/context/luatex/luatex-fonts-merged.lua +++ b/tex/generic/context/luatex/luatex-fonts-merged.lua @@ -1,6 +1,6 @@ -- merged file : luatex-fonts-merged.lua -- parent file : luatex-fonts.lua --- merge date : 12/20/13 00:55:14 +-- merge date : 12/20/13 23:45:10 do -- begin closure to overcome local limits and interference @@ -3762,6 +3762,33 @@ function constructors.beforecopyingcharacters(target,original) end function constructors.aftercopyingcharacters(target,original) end +constructors.sharefonts=false +constructors.nofsharedfonts=0 +local sharednames={} +function constructors.trytosharefont(target,tfmdata) + if constructors.sharefonts then + local characters=target.characters + local n=1 + local t={ target.psname } + local u=sortedkeys(characters) + for i=1,#u do + n=n+1;t[n]=k + n=n+1;t[n]=characters[u[i]].index or k + end + local h=md5.HEX(concat(t," ")) + local s=sharednames[h] + if s then + if trace_defining then + report_defining("font %a uses backend resources of font %a",target.fullname,s) + end + target.fullname=s + constructors.nofsharedfonts=constructors.nofsharedfonts+1 + target.properties.sharedwith=s + else + sharednames[h]=target.fullname + end + end +end function constructors.enhanceparameters(parameters) local xheight=parameters.x_height local quad=parameters.quad @@ -4194,6 +4221,7 @@ function constructors.scale(tfmdata,specification) targetcharacters[unicode]=chr end constructors.aftercopyingcharacters(target,tfmdata) + constructors.trytosharefont(target,tfmdata) return target end function constructors.finalize(tfmdata) @@ -6396,7 +6424,7 @@ local report_otf=logs.reporter("fonts","otf loading") local fonts=fonts local otf=fonts.handlers.otf otf.glists={ "gsub","gpos" } -otf.version=2.748 +otf.version=2.749 otf.cache=containers.define("fonts","otf",otf.version,true) local fontdata=fonts.hashes.identifiers local chardata=characters and characters.data @@ -6439,21 +6467,23 @@ function otf.fileformat(filename) local leader=lower(io.loadchunk(filename,4)) local suffix=lower(file.suffix(filename)) if leader=="otto" then - return "opentype","otf",suffix=="otf" + return formats.otf,suffix=="otf" elseif leader=="ttcf" then - return "truetype","ttc",suffix=="ttc" + return formats.ttc,suffix=="ttc" elseif suffix=="ttc" then - return "truetype","ttc",true + return formats.ttc,true + elseif suffix=="dfont" then + return formats.dfont,true else - return "truetype","ttf",suffix=="ttf" + return formats.ttf,suffix=="ttf" end end local function otf_format(filename) - local format,suffix,okay=otf.fileformat(filename) + local format,okay=otf.fileformat(filename) if not okay then report_otf("font %a is actually an %a file",filename,format) end - return suffix + return format end local function load_featurefile(raw,featurefile) if featurefile and featurefile~="" then -- cgit v1.2.3