summaryrefslogtreecommitdiff
path: root/src/luaotfload-database.lua
diff options
context:
space:
mode:
authorPhilipp Gesang <phg@phi-gamma.net>2016-04-17 12:45:14 +0200
committerPhilipp Gesang <phg@phi-gamma.net>2016-04-17 12:45:14 +0200
commitc8734018b81eb2120372493a3767617eeaf0299c (patch)
tree987d7791ae6f39bcf371c72f87d6e8cf759f0c75 /src/luaotfload-database.lua
parentfc973a6dde1a78a59e50bc3850dfd0d06e7b2a03 (diff)
parent97ec9e582e5be33001c136a9c69b5eebee4fdb2a (diff)
downloadluaotfload-c8734018b81eb2120372493a3767617eeaf0299c.tar.gz
Merge pull request #330 from phi-gamma/master
fontloader update
Diffstat (limited to 'src/luaotfload-database.lua')
-rw-r--r--src/luaotfload-database.lua534
1 files changed, 304 insertions, 230 deletions
diff --git a/src/luaotfload-database.lua b/src/luaotfload-database.lua
index 1d5dfd8..fd806e0 100644
--- a/src/luaotfload-database.lua
+++ b/src/luaotfload-database.lua
@@ -1,5 +1,5 @@
if not modules then modules = { } end modules ['luaotfload-database'] = {
- version = "2.6",
+ version = "2.7",
comment = "companion to luaotfload-main.lua",
author = "Khaled Hosny, Elie Roux, Philipp Gesang",
copyright = "Luaotfload Development Team",
@@ -8,31 +8,105 @@ if not modules then modules = { } end modules ['luaotfload-database'] = {
--[[doc--
- Some statistics:
-
- a) TL 2012, mkluatexfontdb --force
- b) v2.4, luaotfload-tool --update --force
- c) v2.4, luaotfload-tool --update --force --formats=+afm,pfa,pfb
- d) Context, mtxrun --script fonts --reload --force
-
- (Keep in mind that Context does index fewer fonts since it
- considers only the contents of the minimals tree, not the
- tex live one!)
-
- time (m:s) peak VmSize (kB)
- a 1:19 386 018
- b 0:37 715 797
- c 2:27 1 017 674
- d 0:44 1 082 313
-
- Most of the increase in memory consumption from version 1.x to 2.2+
- can be attributed to the move from single-pass to a multi-pass
- approach to building the index: Information is first gathered from
- all reachable fonts and only afterwards processed, classified and
- discarded. Also, there is a good deal of additional stuff kept in
- the database now: two extra tables for file names and font families
- have been added, making font lookups more efficient while improving
- maintainability of the code.
+ With version 2.7 we killed of the Fontforge libraries in favor of
+ the Lua implementation of the OT format reader. There were many
+ reasons to do this on top of the fact that FF won’t be around at
+ version 1.0 anymore: In addition to maintainability, memory safety
+ and general code hygiene, the new reader shows an amazing
+ performance: Scanning of the 3200 font files on my system takes
+ around 23 s now, as opposed to 74 s with the Fontforge libs. Memory
+ usage has improved drastically as well, as illustrated by these
+ profiles:
+
+ GB
+ 1.324^ #
+ | #
+ | ::#
+ | : #::
+ | @: #:
+ | @: #:
+ | @@@: #:
+ | @@@ @: #:
+ | @@ @ @ @: #:
+ | @ @@:@ @ @: #: :
+ | @@ : @ :@ @ @: #: :
+ | @@: ::@@ :@@ ::@ :@ @ @: #: : :::
+ | @@ : :: @@ :@ : @ :@ @ @: #: : :: :
+ | @@ : ::: @@ :@ ::: @ :@ @ @: #: :: :: :
+ | @@@@ :: :::: @@ :@ : : @ :@ @ @: #: :: :::: ::
+ | :@ @@ :: :::: @@ :@ : :: : @ :@ @ @: #: :: :: :: ::
+ | @:@ @@ :: ::::: @@ :@ : :::: : @ :@ @ @: #: :::: :::: :: ::
+ | @@:@ @@ :: ::::::: @@ :@ : : :: : @ :@ @ @: #: ::: @: :: :: ::@
+ | @@@:@ @@ :: :: ::::: @@ :@ ::: :: : @ :@ @ @: #: ::: @: :: :: ::@
+ | @@@@@:@ @@ ::::::: ::::: @@ :@ ::: :: : @ :@ @ @: #: ::: ::@: :: :: ::@
+ 0 +----------------------------------------------------------------------->GB
+ 0 16.29
+
+ This is the memory usage during a complete database rebuild with
+ the Fontforge libraries. The same action using the new
+ ``getinfo()`` method gives a different picture:
+
+ MB
+ 43.37^ #
+ | @ @ @#
+ | @@ @ @ @# :
+ | @@@ : @: @ @ @# :
+ | @ @@@ : : @: @ @: :@# :
+ | @ @ @@@ : : @: @ @: :@# :
+ | @ : : :@ @@@:::: @::@ @: :@#:: :
+ | :: : @ : @ : :::@ @ :@@@:::::@::@ @:::@#::::
+ | : @ : :: : :@:: :@: :::::@ @ :@@@:::::@::@:@:::@#::::
+ | :: :@ : @ ::@:@:::@:: :@: :::::@: :@ :@@@:::::@::@:@:::@#::::
+ | :: :@::: :@ ::@:@: :@::::@::::::::@:::@::@@@:::::@::@:@:::@#::::
+ | :@::::@::: :@:::@:@: :@::::@::::::::@:::@::@@@:::::@::@:@:::@#::::
+ | :::::@::::@::: :@:::@:@: :@::::@::::::::@:::@::@@@:::::@::@:@:::@#::::
+ | ::: :@::::@::: :@:::@:@: :@::::@::::::::@:::@::@@@:::::@::@:@:::@#::::
+ | :::: :@::::@::: :@:::@:@: :@::::@::::::::@:::@::@@@:::::@::@:@:::@#::::
+ | :::: :@::::@::: :@:::@:@: :@::::@::::::::@:::@::@@@:::::@::@:@:::@#::::
+ | :::: :@::::@::: :@:::@:@: :@::::@::::::::@:::@::@@@:::::@::@:@:::@#::::
+ | :::: :@::::@::: :@:::@:@: :@::::@::::::::@:::@::@@@:::::@::@:@:::@#::::
+ | :::: :@::::@::: :@:::@:@: :@::::@::::::::@:::@::@@@:::::@::@:@:::@#::::
+ | :::: :@::::@::: :@:::@:@: :@::::@::::::::@:::@::@@@:::::@::@:@:::@#::::
+ 0 +----------------------------------------------------------------------->GB
+ 0 3.231
+
+ FF peaks at around 1.4 GB after 12.5 GB worth of allocations,
+ whereas the Lua implementation arrives at around 45 MB after 3.2 GB
+ total:
+
+ impl time(B) total(B) useful-heap(B) extra-heap(B)
+ fontforge 12,496,407,184 1,421,150,144 1,327,888,638 93,261,506
+ lua 3,263,698,960 45,478,640 37,231,892 8,246,748
+
+ Much of the inefficiency of Fontforge is a direct consequence of
+ having to parse the entire font to extract what essentially boils
+ down to a couple hundred bytes of metadata per font. Since some
+ information like design sizes (oh, Adobe!) is stuffed away in
+ Opentype tables, the vastly more efficient approach of
+ fontloader.info() proves insufficient for indexing. Thus, we ended
+ up using fontloader.open() which causes even the character tables
+ to be parsed, which incidentally are responsible for most of the
+ allocations during that peak of 1.4 GB measured above, along with
+ the encodings:
+
+ 20.67% (293,781,048B) 0x6A8F72: SplineCharCreate (splineutil.c:3878)
+ 09.82% (139,570,318B) 0x618ACD: _FontViewBaseCreate (fontviewbase.c:84)
+ 08.77% (124,634,384B) 0x6A8FB3: SplineCharCreate (splineutil.c:3885)
+ 04.53% (64,436,904B) in 80 places, all below massif's threshold (1.00%)
+ 02.68% (38,071,520B) 0x64E14E: addKernPair (parsettfatt.c:493)
+ 01.04% (14,735,320B) 0x64DE7D: addPairPos (parsettfatt.c:452)
+ 39.26% (557,942,484B) 0x64A4E0: PsuedoEncodeUnencoded (parsettf.c:5706)
+
+ What gives? For 2.7 we expect a rougher transition than a year back
+ due to the complete revamp of the OT loading code. Breakage of
+ fragile aspects like font and style names has been anticipated and
+ addressed prior to the 2016 pretest release. In contrast to the
+ earlier approach of letting FF do a complete dump and then harvest
+ identifiers from the output we now have to coordinate with upstream
+ as to which fields are actually needed in order to provide a
+ similarly acceptable name → file lookup. On the bright side, these
+ things are a lot simpler to fix than the rather tedious work of
+ having users update their Luatex binary =)
--doc]]--
@@ -53,11 +127,18 @@ local require = require
local tonumber = tonumber
local unpack = table.unpack
-local fontloaderinfo = fontloader.info
-local fontloaderclose = fontloader.close
-local fontloaderopen = fontloader.open
------ fontloaderto_table = fontloader.to_table
-local gzipopen = gzip.open
+local fonts = fonts or { }
+local fontshandlers = fonts.handlers or { }
+local otfhandler = fonts.handlers.otf or { }
+fonts.handlers = fontshandlers
+
+local read_font_file = otfhandler.readers.loadfont
+local read_font_info = read_font_file
+local close_font_file = function () end
+local get_english_names
+
+local gzipload = gzip.load
+local gzipsave = gzip.save
local iolines = io.lines
local ioopen = io.open
local iopopen = io.popen
@@ -291,8 +372,6 @@ This is a sketch of the luaotfload db:
prefmodifiers : string; // sanitized preferred subfamily (names table 14)
psname : string; // PostScript name
size : (false | float * float * float); // if available, size info from the size table converted from decipoints
- splainname : string; // sanitized version of the “plainname” field
- splitstyle : string; // style information obtained by splitting the full name at the last dash
subfamily : string; // sanitized subfamily (names table 2)
subfont : (int | bool); // integer if font is part of a TrueType collection ("ttc")
version : string; // font version string
@@ -361,44 +440,6 @@ local initialize_namedata = function (formats, created)
}
end
---[[doc--
-
- Since Luaotfload does not depend on the lualibs anymore we
- have to put our own small wrappers for the gzip library in
- place.
-
- load_gzipped -- Read and decompress and entire gzipped file.
- Returns the uncompressed content as a string.
-
---doc]]--
-
-local load_gzipped = function (filename)
- local gh = gzipopen (filename,"rb")
- if gh then
- local data = gh:read "*all"
- gh:close ()
- return data
- end
-end
-
---[[doc--
-
- save_gzipped -- Compress and write a string to file. The return
- value is the number of bytes written. Zlib parameters are: best
- compression and default strategy.
-
---doc]]--
-
-local save_gzipped = function (filename, data)
- local gh = gzipopen (filename, "wb9")
- if gh then
- gh:write (data)
- local bytes = gh:seek ()
- gh:close ()
- return bytes
- end
-end
-
--- When loading a lua file we try its binary complement first, which
--- is assumed to be located at an identical path, carrying the suffix
--- .luc.
@@ -427,7 +468,7 @@ local load_lua_file = function (path)
if not code then --- probe gzipped file
foundname = filereplacesuffix (path, "lua.gz")
- local chunk = load_gzipped (foundname)
+ local chunk = gzipload (foundname)
if chunk then
code = load (chunk, "t")
end
@@ -570,6 +611,12 @@ local italic_synonym = {
italic = true,
}
+local bold_synonym = {
+ bold = true,
+ black = true,
+ heavy = true,
+}
+
local style_category = {
regular = "r",
bold = "b",
@@ -975,7 +1022,6 @@ local lookup_fontname = function (specification, name, style)
local prefmodifiers = face.prefmodifiers
local subfamily = face.subfamily
if face.fontname == name
- or face.splainname == name
or face.fullname == name
or face.psname == name
then
@@ -1261,24 +1307,8 @@ find_closest = function (name, limit)
return false
end --- find_closest()
---[[doc--
-
- load_font_file -- Safely open a font file. See
- <http://www.ntg.nl/pipermail/ntg-context/2013/075885.html>
- regarding the omission of ``fontloader.close()``.
-
- TODO -- check if fontloader.info() is ready for prime in 0.78+
- -- fields /tables needed:
- -- names
- -- postscriptname
- -- validation_state
- -- ..
-
---doc]]--
-
local load_font_file = function (filename, subfont)
- local rawfont, _msg = fontloaderopen (filename, subfont)
- --local rawfont, _msg = fontloaderinfo (filename, subfont)
+ local rawfont, _msg = read_font_file (filename, subfont, true)
if not rawfont then
logreport ("log", 1, "db", "ERROR: failed to open %s.", filename)
return
@@ -1288,10 +1318,10 @@ end
--- rawdata -> (int * int * int | bool)
-local get_size_info = function (metadata)
- local design_size = metadata.design_size
- local design_range_top = metadata.design_range_top
- local design_range_bottom = metadata.design_range_bottom
+local get_size_info = function (rawinfo)
+ local design_size = rawinfo.design_size
+ local design_range_top = rawinfo.design_range_top
+ local design_range_bottom = rawinfo.design_range_bottom
local fallback_size = design_size ~= 0 and design_size
or design_range_bottom ~= 0 and design_range_bottom
@@ -1309,12 +1339,15 @@ local get_size_info = function (metadata)
return false
end
-local get_english_names = function (metadata)
- local names = metadata.names
- local english_names
+--[[doc--
+ get_english_names_from_ff -- For legacy Fontforge-style names
+ tables. Extracted from the actual names table, not the font item
+ itself.
+--doc]]--
+local get_english_names_from_ff = function (metadata)
+ local names = metadata.names
if names then
- --inspect(names)
for _, raw_namedata in next, names do
if raw_namedata.lang == "English (US)" then
return raw_namedata.names
@@ -1329,19 +1362,79 @@ local get_english_names = function (metadata)
fullname = metadata.fullname, }
end
+--[[doc--
+ map_enlish_names -- Names-table for Lua fontloader objects. This
+ may vanish eventually once we ditch Fontforge completely. Only
+ subset of entries of that table are actually relevant so we’ll
+ stick to that part.
+--doc]]--
+
+local names_items = {
+ compatfull = "compatiblefullname",
+ fullname = "fullname",
+ postscriptname = "postscriptname",
+ preffamily = "typographicfamily",
+ prefmodifiers = "typographicsubfamily",
+ family = "family",
+ subfamily = "subfamily",
+}
+
+local map_english_names = function (metadata)
+ local namesource
+ local platformnames = metadata.platformnames
+ --[[--
+ Hans added the “platformnames” option for us to access parts of
+ the original name table. The names are unreliable and
+ completely disorganized, sure, but the Windows variant of the
+ field often contains the superior information. Case in point:
+
+ ["platformnames"]={
+ ["macintosh"]={
+ ["compatiblefullname"]="Garamond Premr Pro Smbd It",
+ ["family"]="Garamond Premier Pro",
+ ["fullname"]="Garamond Premier Pro Semibold Italic",
+ ["postscriptname"]="GaramondPremrPro-SmbdIt",
+ ["subfamily"]="Semibold Italic",
+ },
+ ["windows"]={
+ ["family"]="Garamond Premr Pro Smbd",
+ ["fullname"]="GaramondPremrPro-SmbdIt",
+ ["postscriptname"]="GaramondPremrPro-SmbdIt",
+ ["subfamily"]="Italic",
+ ["typographicfamily"]="Garamond Premier Pro",
+ ["typographicsubfamily"]="Semibold Italic",
+ },
+ },
+
+ The essential bit is contained as “typographicfamily” (which we
+ call for historical reasons the “preferred family”) and the
+ “subfamily”. Only Why this is the case, only Adobe knows for
+ certain.
+ --]]--
+ if platformnames then
+ --inspect(metadata)
+ --namesource = platformnames.macintosh or platformnames.windows
+ namesource = platformnames.windows or platformnames.macintosh
+ end
+ namesource = namesource or metadata
+ local nameinfo = { }
+ for ours, theirs in next, names_items do
+ nameinfo [ours] = namesource [theirs]
+ end
+ return nameinfo
+end
+
+get_english_names = map_english_names
+
--[[--
- In case of broken PS names we set some dummies. However, we cannot
- directly modify the font data as returned by fontloader.open() because
- it is a userdata object.
+ In case of broken PS names we set some dummies.
For this reason we copy what is necessary whilst keeping the table
structure the same as in the tfmdata.
--]]--
local get_raw_info = function (metadata, basename)
- local fullname
local fontname = metadata.fontname
local fullname = metadata.fullname
- local psname
local validation_state = metadata.validation_state
if (validation_state and tablecontains (validation_state, "bad_ps_fontname"))
@@ -1364,32 +1457,31 @@ local get_raw_info = function (metadata, basename)
fullname = fullname,
italicangle = metadata.italicangle,
names = metadata.names,
- pfminfo = metadata.pfminfo,
units_per_em = metadata.units_per_em,
version = metadata.version,
- design_size = metadata.design_size,
- design_range_top = metadata.design_range_top,
- design_range_bottom = metadata.design_range_bottom,
+ design_size = metadata.design_size or metadata.designsize,
+ design_range_top = metadata.design_range_top or metadata.maxsize,
+ design_range_bottom = metadata.design_range_bottom or metadata.minsize,
}
end
local organize_namedata = function (rawinfo,
- english_names,
+ nametable,
basename,
info)
- local default_name = english_names.compatfull
- or english_names.fullname
- or english_names.postscriptname
+ local default_name = nametable.compatfull
+ or nametable.fullname
+ or nametable.postscriptname
or rawinfo.fullname
or rawinfo.fontname
or info.fullname
or info.fontname
- local default_family = english_names.preffamily
- or english_names.family
+ local default_family = nametable.preffamily
+ or nametable.family
or rawinfo.familyname
or info.familyname
--- local default_modifier = english_names.prefmodifiers
--- or english_names.subfamily
+-- local default_modifier = nametable.prefmodifiers
+-- or nametable.subfamily
local fontnames = {
--- see
--- https://developer.apple.com/fonts/TTRefMan/RM06/Chap6name.html
@@ -1404,19 +1496,19 @@ local organize_namedata = function (rawinfo,
--- non-abbreviated fashion, for most fonts at any rate.
--- However, in some fonts (e.g. CMU) all three fields are
--- identical.
- fullname = --[[ 18 ]] english_names.compatfull
- or --[[ 4 ]] english_names.fullname
+ fullname = --[[ 18 ]] nametable.compatfull
+ or --[[ 4 ]] nametable.fullname
or default_name,
--- we keep both the “preferred family” and the “family”
--- values around since both are valid but can turn out
--- quite differently, e.g. with Latin Modern:
--- preffamily: “Latin Modern Sans”,
--- family: “LM Sans 10”
- preffamily = --[[ 16 ]] english_names.preffamilyname,
- family = --[[ 1 ]] english_names.family or default_family,
- prefmodifiers = --[[ 17 ]] english_names.prefmodifiers,
- subfamily = --[[ 2 ]] english_names.subfamily,
- psname = --[[ 6 ]] english_names.postscriptname,
+ preffamily = --[[ 16 ]] nametable.preffamilyname,
+ family = --[[ 1 ]] nametable.family or default_family,
+ prefmodifiers = --[[ 17 ]] nametable.prefmodifiers,
+ subfamily = --[[ 2 ]] nametable.subfamily or rawinfo.subfamilyname,
+ psname = --[[ 6 ]] nametable.postscriptname,
},
metadata = {
@@ -1468,22 +1560,20 @@ local split_fontname = function (fontname)
end
end
-local organize_styledata = function (fontname,
- metadata,
- english_names,
- info)
- local pfminfo = metadata.pfminfo or { }
- local names = metadata.names
+local organize_styledata = function (metadata, rawinfo, info)
+ local pfminfo = metadata.pfminfo
+ local names = rawinfo.names
return {
--- see http://www.microsoft.com/typography/OTSPEC/features_pt.htm#size
- size = get_size_info (metadata),
- weight = pfminfo.weight or 400,
- split = split_fontname (fontname),
- width = pfminfo.width,
+ size = get_size_info (rawinfo),
+ pfmweight = pfminfo and pfminfo.weight or metadata.pfmweight or 400,
+ weight = rawinfo.weight or metadata.weight or "unspecified",
+ split = split_fontname (rawinfo.fontname),
+ width = pfminfo and pfminfo.width or metadata.pfmwidth,
italicangle = metadata.italicangle,
--- this is for querying, see www.ntg.nl/maps/40/07.pdf for details
- units_per_em = metadata.units_per_em,
+ units_per_em = metadata.units_per_em or metadata.units,
version = metadata.version,
}
end
@@ -1508,19 +1598,14 @@ ot_fullinfo = function (filename,
return nil
end
- local rawinfo = get_raw_info (metadata, basename)
- --- Closing the file manually is a tad faster and more memory
- --- efficient than having it closed by the gc
- fontloaderclose (metadata)
-
- local english_names = get_english_names (rawinfo)
+ local rawinfo = get_raw_info (metadata, basename)
+ local nametable = get_english_names (metadata)
local namedata = organize_namedata (rawinfo,
- english_names,
+ nametable,
basename,
info)
- local style = organize_styledata (namedata.fontname,
+ local style = organize_styledata (metadata,
rawinfo,
- english_names,
info)
local res = {
@@ -1533,6 +1618,7 @@ ot_fullinfo = function (filename,
style = style,
version = rawinfo.version,
}
+ close_font_file (metadata) --> FF only
return res
end
@@ -1555,15 +1641,13 @@ t1_fullinfo = function (filename, _subfont, location, basename, format)
local fullname = metadata.fullname
local familyname = metadata.familyname
local italicangle = metadata.italicangle
- local splitstyle = split_fontname (fontname)
local style = ""
local weight
sanitized = sanitize_fontnames ({
fontname = fontname,
psname = fullname,
- pfullname = fullname,
- metafamily = family,
+ metafamily = familyname,
familyname = familyname,
weight = metadata.weight, --- string identifier
prefmodifiers = style,
@@ -1589,13 +1673,11 @@ t1_fullinfo = function (filename, _subfont, location, basename, format)
fontname = sanitized.fontname,
familyname = sanitized.familyname,
plainname = fullname,
- splainname = sanitized.fullname,
psname = sanitized.fontname,
version = metadata.version,
size = false,
- splitstyle = splitstyle,
fontstyle_name = style ~= "" and style or weight,
- weight = metadata.pfminfo.weight or 400,
+ weight = metadata.pfminfo and pfminfo.weight or 400,
italicangle = italicangle,
}
end
@@ -1666,15 +1748,7 @@ local insert_fullinfo = function (fullname,
targetentrystatus,
info)
- local subfont
- if n_font ~= false then
- subfont = n_font - 1
- else
- subfont = false
- n_font = 1
- end
-
- local fullinfo = loader (fullname, subfont,
+ local fullinfo = loader (fullname, n_font,
location, basename,
format, info)
@@ -1759,7 +1833,7 @@ local read_font_names = function (fullname,
--- 4) get basic info, abort if fontloader can’t read it
- local info = fontloaderinfo (fullname)
+ local info = read_font_file (fullname)
if not info then
logreport ("log", 1, "db",
@@ -2518,23 +2592,27 @@ generate_filedata = function (mappings)
end
local pick_style
+local pick_fallback_style
local check_regular
do
- local splitfontname = lpeg.splitat "-"
-
local choose_exact = function (field)
--- only clean matches, without guessing
if italic_synonym [field] then
return "i"
end
- if field == "bold" then
+ if stringsub (field, 1, 10) == "bolditalic"
+ or stringsub (field, 1, 11) == "boldoblique" then
+ return "bi"
+ end
+
+ if stringsub (field, 1, 4) == "bold" then
return "b"
end
- if field == "bolditalic" or field == "boldoblique" then
- return "bi"
+ if stringsub (field, 1, 6) == "italic" then
+ return "i"
end
return false
@@ -2542,10 +2620,9 @@ do
pick_style = function (fontstyle_name,
prefmodifiers,
- subfamily,
- splitstyle)
+ subfamily)
local style
- if fontstyle_name then
+ if fontstyle_name --[[ff only]] then
style = choose_exact (fontstyle_name)
end
if not style then
@@ -2558,9 +2635,9 @@ do
return style
end
- pick_fallback_style = function (italicangle, weight)
+ pick_fallback_style = function (italicangle, weight, pfmweight)
--- more aggressive, but only to determine bold faces
- if weight > 500 then --- bold spectrum matches
+ if pfmweight > 500 or bold_synonym [weight] then --- bold spectrum matches
if italicangle == 0 then
return tostring (weight)
else
@@ -2576,23 +2653,29 @@ do
check_regular = function (fontstyle_name,
prefmodifiers,
subfamily,
- splitstyle,
italicangle,
- weight)
-
- if fontstyle_name then
- return regular_synonym [fontstyle_name]
- elseif prefmodifiers then
- return regular_synonym [prefmodifiers]
- elseif subfamily then
- return regular_synonym [subfamily]
- elseif splitstyle then
- return regular_synonym [splitstyle]
- elseif italicangle == 0 and weight == 400 then
- return true
+ weight,
+ pfmweight)
+ local plausible_weight
+ --[[--
+ This filters out undesirable candidates that specify their
+ prefmodifiers or subfamily as “regular” but are actually of
+ “semibold” or other weight—another drawback of the
+ oversimplifying classification into only three styles (r, i,
+ b, bi).
+ --]]--
+
+ if italicangle == 0 then
+ if pfmweight == 400 then plausible_weight = true
+ elseif weight and regular_synonym [weight] then plausible_weight = true end
+ end
+
+ if plausible_weight then
+ return fontstyle_name and regular_synonym [fontstyle_name]
+ or prefmodifiers and regular_synonym [prefmodifiers]
+ or subfamily and regular_synonym [subfamily]
end
-
- return nil
+ return false
end
end
@@ -2615,14 +2698,8 @@ local pull_values = function (entry)
entry.psname = english.psname
entry.fontname = info.fontname or metadata.fontname
entry.fullname = english.fullname or info.fullname
- entry.splainname = metadata.fullname
entry.prefmodifiers = english.prefmodifiers
- local metafamily = metadata.familyname
- local familyname = english.preffamily or english.family
- entry.familyname = familyname
- if familyname ~= metafamily then
- entry.metafamily = metadata.familyname
- end
+ entry.familyname = metadata.familyname or english.preffamily or english.family
entry.fontstyle_name = sanitized.fontstyle_name
entry.plainname = names.fullname
entry.subfamily = english.subfamily
@@ -2630,8 +2707,8 @@ local pull_values = function (entry)
--- pull style info ...
entry.italicangle = style.italicangle
entry.size = style.size
- entry.splitstyle = style.split
entry.weight = style.weight
+ entry.pfmweight = style.pfmweight
if config.luaotfload.db.strip == true then
entry.file = nil
@@ -2650,8 +2727,6 @@ local add_family = function (name, subtable, modifier, entry)
subtable [name] = familytable
end
- local size = entry.size
-
familytable [#familytable + 1] = {
index = entry.index,
modifier = modifier,
@@ -2690,56 +2765,39 @@ collect_families = function (mappings)
local subtable = get_subtable (families, entry)
local familyname = entry.familyname
- local metafamily = entry.metafamily
local fontstyle_name = entry.fontstyle_name
local prefmodifiers = entry.prefmodifiers
local subfamily = entry.subfamily
local weight = entry.weight
+ local pfmweight = entry.pfmweight
local italicangle = entry.italicangle
- local splitstyle = entry.splitstyle
local modifier = pick_style (fontstyle_name,
prefmodifiers,
- subfamily,
- splitstyle)
+ subfamily)
if not modifier then --- regular, exact only
modifier = check_regular (fontstyle_name,
prefmodifiers,
subfamily,
- splitstyle,
italicangle,
- weight)
- end
+ weight,
+ pfmweight)
+ end
+ --if familyname == "garamondpremierpro" then
+ --print(entry.fullname, "reg?",modifier, "->",fontstyle_name,
+ --prefmodifiers,
+ --subfamily,
+ --italicangle,
+ --pfmweight,
+ --weight)
+ --end
if modifier then
add_family (familyname, subtable, modifier, entry)
- --- registering the metafamilies is unreliable within the
- --- same table as identifiers might interfere with an
- --- unmarked style that lacks a metafamily, e.g.
- ---
- --- iwona condensed regular ->
- --- family: iwonacond
- --- metafamily: iwona
- --- iwona regular ->
- --- family: iwona
- --- metafamily: ø
- ---
- --- Both would be registered as under the same family,
- --- i.e. “iwona”, and depending on the loading order
- --- the query “name:iwona” can resolve to the condensed
- --- version instead of the actual unmarked one. The only
- --- way around this would be to introduce a separate
- --- table for metafamilies and do fallback queries on it.
- --- At the moment this is not pressing enough to justify
- --- further increasing the index size, maybe if need
- --- arises from the user side.
--- if metafamily and metafamily ~= familyname then
--- add_family (metafamily, subtable, modifier, entry)
--- end
- elseif weight > 500 then -- in bold spectrum
- modifier = pick_fallback_style (italicangle, weight)
+ elseif pfmweight > 500 then -- in bold spectrum
+ modifier = pick_fallback_style (italicangle, weight, pfmweight)
if modifier then
add_family (familyname, subtable, modifier, entry)
end
@@ -2815,7 +2873,7 @@ group_modifiers = function (mappings, families)
if modifier == info_modifier then
local index = info.index
local entry = mappings [index]
- local weight = entry.weight
+ local weight = entry.pfmweight
local diff = weight < 700 and 700 - weight or weight - 700
if diff < minimum then
minimum = diff
@@ -2834,7 +2892,7 @@ group_modifiers = function (mappings, families)
local index = info.index
local entry = mappings [index]
local size = entry.size
- if entry.weight == closest then
+ if entry.pfmweight == closest then
if size then
entries [#entries + 1] = {
size [1],
@@ -2897,7 +2955,7 @@ local collect_font_filenames = function ()
local bisect = config.luaotfload.misc.bisect
local max_fonts = config.luaotfload.db.max_fonts --- XXX revisit for lua 5.3 wrt integers
- tableappend (filenames, collect_font_filenames_texmf ())
+ --tableappend (filenames, collect_font_filenames_texmf ())
tableappend (filenames, collect_font_filenames_system ())
if config.luaotfload.db.scan_local == true then
tableappend (filenames, collect_font_filenames_local ())
@@ -3298,7 +3356,7 @@ save_names = function (currentnames)
local gzname = luaname .. ".gz"
if config.luaotfload.db.compress then
local serialized = tableserialize (currentnames, true)
- save_gzipped (gzname, serialized)
+ gzipsave (gzname, serialized)
caches.compile (currentnames, "", lucname)
else
tabletofile (luaname, currentnames, true)
@@ -3483,6 +3541,21 @@ local show_cache = function ( )
return true
end
+local use_fontforge = function (val)
+ if val == true then
+ local fontloader = fontloader
+ read_font_info = fontloader.info
+ read_font_file = fontloader.open
+ close_font_file = fontloader.close
+ get_english_names = get_english_names_from_ff
+ else
+ read_font_file = otfhandler.readers.getinfo
+ read_font_info = read_font_file
+ close_font_file = function () end
+ get_english_names = map_english_names
+ end
+end
+
-----------------------------------------------------------------------
--- export functionality to the namespace “fonts.names”
-----------------------------------------------------------------------
@@ -3513,7 +3586,8 @@ local export = {
erase_cache = erase_cache,
show_cache = show_cache,
find_closest = find_closest,
- -- for testing purpose
+ --- transitionary
+ use_fontforge = use_fontforge,
}
return {