summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorElie Roux <elie.roux@telecom-bretagne.eu>2013-05-06 05:26:35 -0700
committerElie Roux <elie.roux@telecom-bretagne.eu>2013-05-06 05:26:35 -0700
commit6cb8c7ab0b577053c57872d476b8a5933369fbea (patch)
tree7edc5fc21fa26aaeb15de8c439ee518ec224bd16
parent778267979a304bd83228fd0077c453a953d35fd0 (diff)
parentdc3781fc328b18282f42b7813a7952d00f36ef8c (diff)
downloadluaotfload-6cb8c7ab0b577053c57872d476b8a5933369fbea.tar.gz
Merge pull request #15 from lualatex/master
Sync with lualatex repo
-rw-r--r--NEWS8
-rw-r--r--README73
-rw-r--r--filegraph.dot7
-rw-r--r--luaotfload-auxiliary.lua66
-rw-r--r--luaotfload-colors.lua348
-rw-r--r--luaotfload-database.lua65
-rw-r--r--luaotfload-features.lua287
-rw-r--r--luaotfload-loaders.lua8
-rw-r--r--luaotfload-override.lua14
-rwxr-xr-xluaotfload-tool.lua31
-rw-r--r--luaotfload.dtx107
-rwxr-xr-xmkglyphlist10
-rw-r--r--tests/systemfonts.tex2
13 files changed, 570 insertions, 456 deletions
diff --git a/NEWS b/NEWS
index 3858d8f..2cdf365 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,8 @@ Change History
--------------
2013/04/xx, luaotfload v2.2:
+ * There is now a central, non-personal dev repo on github:
+ https://github.com/lualatex/luaotfload
* Synchronisation with ConTeXt from TeXLive 2013, inducing
backward-incompatible changes in the font structure (fontspec and
unicode-math must be updated)
@@ -10,7 +12,7 @@ Change History
the LuaTeX-Plain format)
* Improved and extended documentation
* Font filenames are stored in the database (file: lookups more efficient)
- * Optional caching of name: lookups
+ * Optional caching of name: lookups (uses separate cache file)
* Increased fidelity of XeTeX emulation
* Renaming mkluatexfontdb into luaotfload-tool (the old behavior is kept if
the script is symlinked/ renamed mkluatexfontdb)
@@ -21,8 +23,8 @@ Change History
* The Adobe Glyph List (font-age.lua) is now built via script (mkglyphlist)
* Hans adapted the font loader to several of our requests (attribute
allocation, custom merged package name etc.)
- * There is now a central, non-personal dev repo on github:
- https://github.com/lualatex/luaotfload
+ * Auxiliary functions for package authors
+ * Fallbacks for older versions of dependent packages
2013/04/27, luaotfload v1.3:
* blacklisting lingoes.ttf (segfaults)
diff --git a/README b/README
index 8dc2003..4730e88 100644
--- a/README
+++ b/README
@@ -1,42 +1,46 @@
- The luaotfload package
-
-Luaotfload is an adaptation of the ConTeXt font loading system for Plain and
-LaTeX. It allows OpenType fonts to be loaded with OpenType features accessible
-through the XeTeX font syntax.
-
-It may be loaded in Plain LuaTeX with "\input luaotfload.sty" and in LuaLaTeX
-with "\usepackage{luaotfload}". LuaLaTeX users may be interested in the
-fontspec package which provides a high-level interface to the functionality
+*******************************************************************************
+ The Luaotfload Package
+*******************************************************************************
+
+Luaotfload is an adaptation of the ConTeXt font loading system for the Plain
+and LaTeX formats. It allows OpenType fonts to be loaded with font features
+accessible using an extended font request syntax while providing compatibility
+with XeTeX. By indexing metadata in a database it facilitates loading fonts by
+their proper names instead of file names.
+
+Luaotfload may be loaded in Plain LuaTeX with "\input luaotfload.sty" and in
+LuaLaTeX with "\usepackage{luaotfload}". LuaLaTeX users may be interested in
+the fontspec package which provides a high-level interface to the functionality
provided by this package.
Please see the documentation luaotfload.pdf for more information.
-This package is developed on <http://github.com/khaledhosny/luaotfload>.
-Please report bugs at the Github address above.
+This package is developed by the LuaLaTeX dev team on
+<http://github.com/lualatex/luaotfload>. Please report bugs to the issue
+tracker there.
-Discussion of development for LuaLaTeX is held in the lualatex-dev mailing
-list. See <http://www.tug.org/mailman/listinfo/lualatex-dev> to join or to
-view the archives.
+The development for LuaLaTeX is discussed on the lualatex-dev mailing list. See
+<http://www.tug.org/mailman/listinfo/lualatex-dev> for details.
Responsible Persons
--------------------
-
+-------------------------------------------------------------------------------
The following people have contributed to this package.
Khaled Hosny <khaledhosny@eglug.org>
Elie Roux <elie.roux@telecom-bretagne.eu>
Will Robertson <will.robertson@latex-project.org>
-
+Philipp Gesang <philipp.gesang@alumni.uni-heidelberg.de>
Installation
-------------
+-------------------------------------------------------------------------------
Here are the recommended installation methods (preferred first).
1. If you are using TeX Live 2008 or later, use 'tlmgr install luaotfload'.
-Alternatively, try your (TeX or Linux) distribution's package management system.
+ Alternatively, try your (TeX or Linux) distribution's package management
+ system.
2. a. Download luaotfload.tds.zip from CTAN.
b. Unzip it at the root of one or your TDS trees.
@@ -50,22 +54,27 @@ Alternatively, try your (TeX or Linux) distribution's package management system.
4. Try to figure it out by looking at the Makefile and comments in the sources.
License
--------
+-------------------------------------------------------------------------------
+
+The luaotfload bundle, as a derived work of ConTeXt, is distributed under the
+GNU GPLv2 license:
-The luaotfload bundle is distributed under the GNU GPLv2 license:
<http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
-This license requires the license itself to be distributed with the work.
-It may be located within the documentation luaotfload.pdf.
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
+This license requires the license itself to be distributed with the work. For
+its full text see the documentation in luaotfload.pdf.
+
+
+ DISCLAIMER
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; version 2.
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
-See headers of each source file for copyright details.
+ See headers of each source file for copyright details.
diff --git a/filegraph.dot b/filegraph.dot
index d69937b..36e5764 100644
--- a/filegraph.dot
+++ b/filegraph.dot
@@ -139,9 +139,10 @@ strict digraph luaotfload_files { //looks weird with circo ...
label = <
<table cellborder="0" bgcolor="#FFFFFFAA">
<th> <td colspan="2"> <font point-size="12" face="Iwona Italic">Luaotfload Libraries</font> </td> </th>
- <tr> <td>luaotfload-lib-dir.lua</td> <td>luaotfload-features.lua</td> </tr>
- <tr> <td>luaotfload-override.lua</td> <td>luaotfload-loaders.lua</td> </tr>
- <tr> <td>luaotfload-database.lua</td> <td>luaotfload-color.lua</td> </tr>
+ <tr> <td>luaotfload-lib-dir.lua</td> <td>luaotfload-features.lua</td> </tr>
+ <tr> <td>luaotfload-override.lua</td> <td>luaotfload-loaders.lua</td> </tr>
+ <tr> <td>luaotfload-database.lua</td> <td>luaotfload-color.lua</td> </tr>
+ <tr> <td>luaotfload-auxiliary.lua</td> </tr>
</table>
>,
]
diff --git a/luaotfload-auxiliary.lua b/luaotfload-auxiliary.lua
index 844c170..5de964d 100644
--- a/luaotfload-auxiliary.lua
+++ b/luaotfload-auxiliary.lua
@@ -4,7 +4,7 @@
-- DESCRIPTION: part of luaotfload
-- REQUIREMENTS: luaotfload 2.2
-- AUTHOR: Khaled Hosny, Élie Roux, Philipp Gesang
--- VERSION: 1.0
+-- VERSION: 2.2
-- CREATED: 2013-05-01 14:40:50+0200
-----------------------------------------------------------------------
--
@@ -36,6 +36,69 @@ local stringbyte = string.byte
-----------------------------------------------------------------------
--[[doc--
+
+The font object (tfmdata) structure has changed since version 1.x, so
+in case other packages haven’t been updated we put fallbacks in place
+where they’d expect them. Specifically we have in mind:
+
+ · fontspec
+ · unicode-math
+ · microtype (most likely fixed till TL2013)
+
+--doc]]--
+
+--- fontobj -> fontobj
+local add_fontdata_fallbacks = function (fontdata)
+ if type(fontdata) == "table" then
+ local fontparameters = fontdata.parameters
+ local metadata
+ if not fontdata.shared then --- that would be a tfm
+ --- we can’t really catch everything that
+ --- goes wrong; for some reason, fontspec.lua
+ --- just assumes it always gets an otf object,
+ --- so its capheight callback, which does not
+ --- bother to do any checks, will access
+ --- fontdata.shared no matter what ...
+ fontdata.units = fontdata.units_per_em
+ else --- otf
+ metadata = fontdata.shared.rawdata.metadata
+ fontdata.units = fontparameters.units
+ local resources = fontdata.resources
+ fontdata.size = fontparameters.size
+ --- for legacy fontspec.lua and unicode-math.lua
+ fontdata.shared.otfdata = metadata
+ fontdata.shared.otfdata.metadata = metadata --- brr, that’s meta indeed
+ --- for microtype.lua
+ fontdata.shared.otfdata.luatex = {
+ unicodes = resources.unicodes,
+ features = resources.features,
+ }
+ end
+ end
+ return fontdata
+end
+
+luatexbase.add_to_callback(
+ "luaotfload.patch_font",
+ add_fontdata_fallbacks,
+ "luaotfload.fontdata_fallbacks")
+
+--[[doc--
+
+Additionally, the font registry is expected at fonts.identifiers
+(fontspec) or fonts.ids (microtype), but in the meantime it has been
+migrated to fonts.hashes.identifiers. We’ll make luaotfload satisfy
+those assumptions. (Maybe it’d be more appropriate to use
+font.getfont() since Hans made it a harmless wrapper [1].)
+
+[1] http://www.ntg.nl/pipermail/ntg-context/2013/072166.html
+
+--doc]]--
+
+fonts.identifiers = fonts.hashes.identifiers
+fonts.ids = fonts.hashes.identifiers
+
+--[[doc--
This sets two dimensions apparently relied upon by the unicode-math
package.
--doc]]--
@@ -71,6 +134,7 @@ end
--[[doc--
This callback corrects some values of the Cambria font.
--doc]]--
+--- fontobj -> unit
local patch_cambria_domh = function (fontdata)
local mathconstants = fontdata.MathConstants
if mathconstants and fontdata.psname == "CambriaMath" then
diff --git a/luaotfload-colors.lua b/luaotfload-colors.lua
index 3d8bfab..ec076c2 100644
--- a/luaotfload-colors.lua
+++ b/luaotfload-colors.lua
@@ -1,44 +1,110 @@
if not modules then modules = { } end modules ['luaotfload-colors'] = {
- version = 1.001,
+ version = 2.200,
comment = "companion to luaotfload.lua (font color)",
- author = "Khaled Hosny and Elie Roux",
+ author = "Khaled Hosny, Elie Roux, Philipp Gesang",
copyright = "Luaotfload Development Team",
- license = "GPL"
+ license = "GNU GPL v2"
}
-local newnode = node.new
-local nodetype = node.id
-local traverse_nodes = node.traverse
-local insert_node_before = node.insert_before
-local insert_node_after = node.insert_after
+--[[doc--
+buggy coloring with the pre_output_filter when expansion is enabled
+ · tfmdata for different expansion values is split over different objects
+ · in ``initializeexpansion()``, chr.expansion_factor is set, and only
+ those characters that have it are affected
+ · in constructors.scale: chr.expansion_factor = ve*1000 if commented out
+ makes the bug vanish
+--doc]]--
-local stringformat = string.format
-local stringgsub = string.gsub
-local stringfind = string.find
-local otffeatures = fonts.constructors.newfeatures("otf")
-local ids = fonts.hashes.identifiers
-local registerotffeature = otffeatures.register
+local color_callback = config.luaotfload.color_callback
+if not color_callback then
+ --- maybe this would be better as a method: "early" | "late"
+ color_callback = "pre_linebreak_filter"
+-- color_callback = "pre_output_filter" --- old behavior, breaks expansion
+end
-local function setcolor(tfmdata,value)
- local sanitized
- local properties = tfmdata.properties
- if value then
- value = tostring(value)
- if #value == 6 or #value == 8 then
- sanitized = value
- elseif #value == 7 then
- _, _, sanitized = stringfind(value, "(......)")
- elseif #value > 8 then
- _, _, sanitized = stringfind(value, "(........)")
- else
- -- broken color code ignored, issue a warning?
- end
+local newnode = node.new
+local nodetype = node.id
+local traverse_nodes = node.traverse
+local insert_node_before = node.insert_before
+local insert_node_after = node.insert_after
+
+local stringformat = string.format
+local stringgsub = string.gsub
+local stringfind = string.find
+local stringsub = string.sub
+
+local otffeatures = fonts.constructors.newfeatures("otf")
+local identifiers = fonts.hashes.identifiers
+local registerotffeature = otffeatures.register
+
+local add_color_callback --[[ this used to be a global‽ ]]
+
+--[[doc--
+This converts a single octet into a decimal with three digits of
+precision. The optional second argument limits precision to a single
+digit.
+--doc]]--
+
+--- string -> bool? -> string
+local hex_to_dec = function (hex,one) --- one isn’t actually used anywhere ...
+ if one then
+ return stringformat("%.1g", tonumber(hex, 16)/255)
+ else
+ return stringformat("%.3g", tonumber(hex, 16)/255)
end
+end
+
+--[[doc--
+Color string validator / parser.
+--doc]]--
+
+local lpeg = require"lpeg"
+local lpegmatch = lpeg.match
+local C, Cg, Ct, P, R, S = lpeg.C, lpeg.Cg, lpeg.Ct, lpeg.P, lpeg.R, lpeg.S
+
+local digit16 = R("09", "af", "AF")
+local octet = C(digit16 * digit16)
+
+local p_rgb = octet * octet * octet
+local p_rgba = p_rgb * octet
+local valid_digits = C(p_rgba + p_rgb) -- matches eight or six hex digits
+
+local p_Crgb = Cg(octet/hex_to_dec, "red") --- for captures
+ * Cg(octet/hex_to_dec, "green")
+ * Cg(octet/hex_to_dec, "blue")
+local p_Crgba = p_Crgb * Cg(octet/hex_to_dec, "alpha")
+local extract_color = Ct(p_Crgba + p_Crgb)
+
+--- string -> (string | nil)
+local sanitize_color_expression = function (digits)
+ digits = tostring(digits)
+ local sanitized = lpegmatch(valid_digits, digits)
+ if not sanitized then
+ luaotfload.warning(
+ "“%s” is not a valid rgb[a] color expression", digits)
+ return nil
+ end
+ return sanitized
+end
+
+--[[doc--
+``setcolor`` modifies tfmdata.properties.color in place
+--doc]]--
+
+--- fontobj -> string -> unit
+---
+--- (where “string” is a rgb value as three octet
+--- hexadecimal, with an optional fourth transparency
+--- value)
+---
+local setcolor = function (tfmdata, value)
+ local sanitized = sanitize_color_expression(value)
+ local properties = tfmdata.properties
if sanitized then
- tfmdata.properties.color = sanitized
+ properties.color = sanitized
add_color_callback()
end
end
@@ -52,133 +118,187 @@ registerotffeature {
}
}
-local function hex2dec(hex,one)
- if one then
- return stringformat("%.1g", tonumber(hex, 16)/255)
- else
- return stringformat("%.3g", tonumber(hex, 16)/255)
- end
-end
-local res
+--- something is carried around in ``res``
+--- for later use by color_handler() --- but what?
+
+local res --- <- state of what?
-local function pageresources(a)
+--- float -> unit
+local function pageresources(alpha)
local res2
if not res then
res = "/TransGs1<</ca 1/CA 1>>"
end
- res2 = stringformat("/TransGs%s<</ca %s/CA %s>>", a, a, a)
- res = stringformat("%s%s", res, stringfind(res, res2) and "" or res2)
+ res2 = stringformat("/TransGs%s<</ca %s/CA %s>>",
+ alpha, alpha, alpha)
+ res = stringformat("%s%s",
+ res,
+ stringfind(res, res2) and "" or res2)
end
-local function hex_to_rgba(hex)
- local r, g, b, a, push, pop, res3
- if hex then
- if #hex == 6 then
- _, _, r, g, b = stringfind(hex, '(..)(..)(..)')
- elseif #hex == 8 then
- _, _, r, g, b, a = stringfind(hex, '(..)(..)(..)(..)')
- a = hex2dec(a,true)
- pageresources(a)
- end
- else
- return nil
+--- we store results of below color handler as tuples of
+--- push/pop strings
+local color_cache = { } --- (string, (string * string)) hash_t
+
+--- string -> (string * string)
+local hex_to_rgba = function (digits)
+ if not digits then
+ return
end
- r = hex2dec(r)
- g = hex2dec(g)
- b = hex2dec(b)
- if a then
- push = stringformat('/TransGs%g gs %s %s %s rg', a, r, g, b)
- pop = '0 g /TransGs1 gs'
- else
- push = stringformat('%s %s %s rg', r, g, b)
- pop = '0 g'
+
+ --- this is called like a thousand times, so some
+ --- memoizing is in order.
+ local cached = color_cache[digits]
+ if not cached then
+ local push, pop
+ local rgb = lpegmatch(extract_color, digits)
+ if rgb.alpha then
+ pageresources(rgb.alpha)
+ push = stringformat(
+ "/TransGs%g gs %s %s %s rg",
+ rgb.alpha,
+ rgb.red,
+ rgb.green,
+ rgb.blue)
+ pop = "0 g /TransGs1 gs"
+ else
+ push = stringformat(
+ "%s %s %s rg",
+ rgb.red,
+ rgb.green,
+ rgb.blue)
+ pop = "0 g"
+ end
+ color_cache[digits] = { push, pop }
+ return push, pop
end
- return push, pop
+
+ return cached[1], cached[2]
end
-local glyph = nodetype('glyph')
-local hlist = nodetype('hlist')
-local vlist = nodetype('vlist')
-local whatsit = nodetype('whatsit')
-local pgi = nodetype('page_insert')
-local sbox = nodetype('sub_box')
+--- Luatex internal types
+
+local glyph_t = nodetype("glyph")
+local hlist_t = nodetype("hlist")
+local vlist_t = nodetype("vlist")
+local whatsit_t = nodetype("whatsit")
+local page_insert_t = nodetype("page_insert")
+local sub_box_t = nodetype("sub_box")
-local function lookup_next_color(head)
+--- node -> nil | -1 | color‽
+local lookup_next_color
+lookup_next_color = function (head) --- paragraph material
for n in traverse_nodes(head) do
- if n.id == glyph then
- if ids[n.font] and ids[n.font].properties and ids[n.font].properties.color then
- return ids[n.font].properties.color
+ local n_id = n.id
+
+ if n_id == glyph_t then
+ local n_font
+ if identifiers[n_font]
+ and identifiers[n_font].properties
+ and identifiers[n_font].properties.color
+ then
+ return identifiers[n.font].properties.color
else
return -1
end
- elseif n.id == vlist or n.id == hlist or n.id == sbox then
+
+ elseif n_id == vlist_t or n_id == hlist_t or n_id == sub_box_t then
local r = lookup_next_color(n.list)
- if r == -1 then
- return -1
- elseif r then
+ if r then
return r
end
- elseif n.id == whatsit or n.id == pgi then
+
+ elseif n_id == whatsit_t or n_id == page_insert_t then
return -1
end
end
return nil
end
-local function node_colorize(head, current_color, next_color)
+--[[doc--
+While the second argument and second returned value are apparently
+always nil when the function is called, they temporarily take string
+values during the node list traversal.
+--doc]]--
+
+local cnt = 0
+--- node -> string -> int -> (node * string)
+local node_colorize
+node_colorize = function (head, current_color, next_color)
for n in traverse_nodes(head) do
- if n.id == hlist or n.id == vlist or n.id == sbox then
- local next_color_in = lookup_next_color(n.next) or next_color
+ local n_id = n.id
+ local nextnode = n.next
+
+ if n_id == hlist_t or n_id == vlist_t or n_id == sub_box_t then
+ local next_color_in = lookup_next_color(nextnode) or next_color
n.list, current_color = node_colorize(n.list, current_color, next_color_in)
- elseif n.id == glyph then
- local tfmdata = ids[n.font]
+
+ elseif n_id == glyph_t then
+ cnt = cnt + 1
+ local tfmdata = identifiers[n.font]
+
+ --- colorization is restricted to those fonts
+ --- that received the “color” property upon
+ --- loading (see ``setcolor()`` above)
if tfmdata and tfmdata.properties and tfmdata.properties.color then
- if tfmdata.properties.color ~= current_color then
- local pushcolor = hex_to_rgba(tfmdata.properties.color)
- local push = newnode(whatsit, 8)
- push.mode = 1
- push.data = pushcolor
- head = insert_node_before(head, n, push)
- current_color = tfmdata.properties.color
+ local font_color = tfmdata.properties.color
+-- luaotfload.info(
+-- "n: %d; %s; %d %s, %s",
+-- cnt, utf.char(n.char), n.font, "<TRUE>", font_color)
+ if font_color ~= current_color then
+ local pushcolor = hex_to_rgba(font_color)
+ local push = newnode(whatsit_t, 8)
+ push.mode = 1
+ push.data = pushcolor
+ head = insert_node_before(head, n, push)
+ current_color = font_color
end
- local next_color_in = lookup_next_color (n.next) or next_color
- if next_color_in ~= tfmdata.properties.color then
- local _, popcolor = hex_to_rgba(tfmdata.properties.color)
- local pop = newnode(whatsit, 8)
- pop.mode = 1
- pop.data = popcolor
- head = insert_node_after(head, n, pop)
- current_color = nil
+ local next_color_in = lookup_next_color (nextnode) or next_color
+ if next_color_in ~= font_color then
+ local _, popcolor = hex_to_rgba(font_color)
+ local pop = newnode(whatsit_t, 8)
+ pop.mode = 1
+ pop.data = popcolor
+ head = insert_node_after(head, n, pop)
+ current_color = nil
end
+
+-- else
+-- luaotfload.info(
+-- "n: %d; %s; %d %s",
+-- cnt, utf.char(n.char), n.font, "<FALSE>")
end
end
end
return head, current_color
end
-local function font_colorize(head)
- -- check if our page resources existed in the previous run
- -- and remove it to avoid duplicating it later
- if res then
- local r = "/ExtGState<<"..res..">>"
- tex.pdfpageresources = stringgsub(tex.pdfpageresources, r, "")
- end
- local h = node_colorize(head, nil, nil)
- -- now append our page resources
- if res and stringfind(res, "%S") then -- test for non-empty string
- local r = "/ExtGState<<"..res..">>"
- tex.pdfpageresources = tex.pdfpageresources..r
- end
- return h
+--- node -> node
+local color_handler = function (head)
+ -- check if our page resources existed in the previous run
+ -- and remove it to avoid duplicating it later
+ if res then
+ local r = "/ExtGState<<" .. res .. ">>"
+ tex.pdfpageresources = stringgsub(tex.pdfpageresources, r, "")
+ end
+ local new_head = node_colorize(head, nil, nil)
+ -- now append our page resources
+ if res and stringfind(res, "%S") then -- test for non-empty string
+ local r = "/ExtGState<<" .. res .. ">>"
+ tex.pdfpageresources = tex.pdfpageresources..r
+ end
+ return new_head
end
local color_callback_activated = 0
-function add_color_callback()
+--- unit -> unit
+add_color_callback = function ( )
if color_callback_activated == 0 then
- luatexbase.add_to_callback(
- "pre_output_filter", font_colorize, "luaotfload.colorize")
+ luatexbase.add_to_callback(color_callback,
+ color_handler,
+ "luaotfload.color_handler")
color_callback_activated = 1
end
end
diff --git a/luaotfload-database.lua b/luaotfload-database.lua
index aaba55a..576341f 100644
--- a/luaotfload-database.lua
+++ b/luaotfload-database.lua
@@ -1,7 +1,7 @@
if not modules then modules = { } end modules ['luaotfload-database'] = {
version = 2.2,
comment = "companion to luaotfload.lua",
- author = "Khaled Hosny and Elie Roux",
+ author = "Khaled Hosny, Elie Roux, Philipp Gesang",
copyright = "Luaotfload Development Team",
license = "GNU GPL v2"
}
@@ -98,7 +98,7 @@ local writable_path
if caches then
writable_path = caches.getwritablepath("names","")
if not writable_path then
- error("Impossible to find a suitable writeable cache...")
+ luaotfload.error("Impossible to find a suitable writeable cache...")
end
names.path.dir = writable_path
names.path.path = filejoin(writable_path, names.path.basename)
@@ -116,6 +116,7 @@ Auxiliary functions
local report = logs.names_report
+--- string -> string
local sanitize_string = function (str)
if str ~= nil then
return utf8gsub(utf8lower(str), "[^%a%d]", "")
@@ -133,11 +134,10 @@ This is a sketch of the luaotfload db:
// preliminary additions of v2.2:
basenames : (string, int) hash; // where int is the index in mappings
barenames : (string, int) hash; // where int is the index in mappings
- request_cache : lookup_cache; // see below
}
and fontentry = {
familyname : string;
- filename : (string * bool);
+ filename : (string * int); // int: subfont
fontname : string;
fullname : string;
names : {
@@ -188,21 +188,15 @@ mtx-fonts has in names.tma:
width : string;
}
-
--doc]]--
local fontnames_init = function (keep_cache) --- returns dbobj
return {
mappings = { },
status = { },
- --- adding filename mapping increases the
- --- size of the serialized db on my system
- --- (5840 font files) by a factor of 1.09
- --- if we store only the indices in the
- --- mappings table
barenames = { },
basenames = { },
--- fullnames = { },
+-- fullnames = { }, // -> status
version = names.version,
}
end
@@ -261,18 +255,21 @@ local update_names
local fonts_loaded = false
local fonts_reloaded = false
+--- limit output when approximate font matching (luaotfload-tool -F)
+local fuzzy_limit = 1 --- display closest only
+
--- unit -> dbobj
load_names = function ( )
local starttime = os.gettimeofday()
local foundname, data = load_lua_file(names.path.path)
if data then
- report("info", 1, "db",
+ report("both", 2, "db",
"Font names database loaded", "%s", foundname)
report("info", 3, "db", "Loading took %0.f ms",
1000*(os.gettimeofday()-starttime))
else
- report("info", 1, "db",
+ report("both", 0, "db",
[[Font names database not found, generating new one.
This can take several minutes; please be patient.]])
data = update_names(fontnames_init(false))
@@ -286,7 +283,7 @@ end
load_lookups = function ( )
local foundname, data = load_lua_file(names.path.lookup_path)
if data then
- report("both", 1, "cache",
+ report("both", 3, "cache",
"Lookup cache loaded (%s)", foundname)
else
report("both", 1, "cache",
@@ -296,8 +293,6 @@ load_lookups = function ( )
return data
end
-local fuzzy_limit = 1 --- display closest only
-
local style_synonyms = { set = { } }
do
style_synonyms.list = {
@@ -382,25 +377,20 @@ Even if we find a matching font eventually, the next time the
user compiles Eir document E will have to stand through the delay
again.
Thus, some caching of results -- even between runs -- is in order.
-We’ll just store successful lookups in the database in a record of
-the respective lookup type.
+We’ll just store successful name: lookups in a separate cache file.
type lookup_cache = (string, (string * num)) dict
-TODO:
+Complete, needs testing:
× 1) add cache to dbobj
× 2) wrap lookups in cached versions
× 3) make caching optional (via the config table) for debugging
× 4) make names_update() cache aware (nil if “force”)
× 5) add logging
× 6) add cache control to luaotfload-tool
- × 7) incr db version
- 8) wishlist: save cache only at the end of a run
- 9) ???
- n) PROFIT!!!
+ × 7) incr db version (now 2.203)
+ × 8) save cache only at the end of a run
-The name lookup requires both the “name” and some other
-keys, so we’ll concatenate them.
The spec is modified in place (ugh), so we’ll have to catalogue what
fields actually influence its behavior.
@@ -415,20 +405,11 @@ Idk what the “spec” resolver is for.
* name: contains both the name resolver from luatex-fonts and resolve()
below
-The following fields of a resolved spec need to be cached:
---doc]]--
-local cache_fields = {
- "forced", "hash", "lookup", "name", "resolved", "sub",
-}
-
---[[doc--
From my reading of font-def.lua, what a resolver does is
basically rewrite the “name” field of the specification record
with the resolution.
Also, the fields “resolved”, “sub”, “force” etc. influence the outcome.
-We’ll just cache a deep copy of the entire spec as it leaves the
-resolver, lest we want to worry if we caught all the details.
--doc]]--
--- 'a -> 'a -> table -> (string * int|boolean * boolean)
@@ -458,12 +439,8 @@ resolve_cached = function (_, _, specification)
names.lookups[request] = entry
--- obviously, the updated cache needs to be stored.
- --- for the moment, we write the entire db to disk
- --- whenever the cache is updated.
--- TODO this should trigger a save only once the
--- document is compiled (finish_pdffile callback?)
- --- TODO we should speed up writing by separating
- --- the cache from the db
report("both", 5, "cache", "saving updated cache")
save_lookups()
return filename, subfont, true
@@ -681,15 +658,12 @@ resolve = function (_,_,specification) -- the 1st two parameters are used by Con
if not fonts_reloaded then
--- last straw: try reloading the database
return reload_db(
- "unresolved font name: “" .. name .. "”",
+ "unresolved font name: ‘" .. name .. "’",
resolve, nil, nil, specification
)
end
--- else, fallback to requested name
- --- specification.name is empty with absolute paths, looks
- --- like a bug in the specification parser <TODO< is it still
- --- relevant? looks not...
return specification.name, false, false
end --- resolve()
@@ -1491,7 +1465,7 @@ save_lookups = function ( )
if lucname and type(caches.compile) == "function" then
os.remove(lucname)
caches.compile(lookups, luaname, lucname)
- report("info", 1, "cache", "Lookup cache saved")
+ report("both", 3, "cache", "Lookup cache saved")
return names.path.lookup_path
end
end
@@ -1518,7 +1492,7 @@ save_names = function (fontnames)
end
end
end
- report("info", 0, "db", "Failed to save names database")
+ report("both", 0, "db", "Failed to save names database")
return nil
end
@@ -1537,6 +1511,7 @@ end
--- export functionality to the namespace “fonts.names”
names.flush_cache = flush_cache
+names.save_lookups = save_lookups
names.load = load_names
names.save = save_names
names.scan = scan_external_dir
@@ -1546,7 +1521,7 @@ names.crude_file_lookup_verbose = crude_file_lookup_verbose
--- replace the resolver from luatex-fonts
if config.luaotfload.resolver == "cached" then
- report("info", 0, "cache", "caching of name: lookups active")
+ report("both", 2, "cache", "caching of name: lookups active")
names.resolve = resolve_cached
names.resolvespec = resolve_cached
else
diff --git a/luaotfload-features.lua b/luaotfload-features.lua
index 494d02d..f91aee7 100644
--- a/luaotfload-features.lua
+++ b/luaotfload-features.lua
@@ -1,26 +1,28 @@
if not modules then modules = { } end modules ["features"] = {
- version = 1.000,
+ version = 2.200,
comment = "companion to luaotfload.lua",
- author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ author = "Hans Hagen, Khaled Hosny, Elie Roux, Philipp Gesang",
copyright = "PRAGMA ADE / ConTeXt Development Team",
license = "see context related readme files"
}
-local format, insert = string.format, table.insert
-local type, next = type, next
-local lpegmatch = lpeg.match
+local format, insert = string.format, table.insert
+local type, next = type, next
+local lpegmatch = lpeg.match
---[[ begin included font-ltx.lua ]]
--- this appears to be based in part on luatex-fonts-def.lua
local fonts = fonts
--- A bit of tuning for definitions.
+--HH A bit of tuning for definitions.
fonts.constructors.namemode = "specification" -- somehow latex needs this (changed name!) => will change into an overload
--- tricky: we sort of bypass the parser and directly feed all into
--- the sub parser
+--[[HH--
+ tricky: we sort of bypass the parser and directly feed all into
+ the sub parser
+--HH]]--
function fonts.definers.getspecification(str)
return "", str, "", ":", str
@@ -31,53 +33,9 @@ local old_feature_list = { }
local report = logs.names_report
local stringlower = string.lower
-local stringsub = string.sub
local stringgsub = string.gsub
-local stringfind = string.find
-local stringexplode = string.explode
local stringis_empty = string.is_empty
---[[doc--
-Apparently, these “modifiers” are another measure of emulating \XETEX,
-cf. “About \XETEX”, by Jonathan Kew, 2005; and
- “The \XETEX Reference Guide”, by Will Robertson, 2011.
---doc]]--
-
-local supported = {
- b = "bold",
- i = "italic",
- bi = "bolditalic",
- aat = false,
- icu = false,
- gr = false,
-}
-
---- this parses the optional flags after the slash
---- the original behavior is that multiple slashes
---- are valid but they might cancel prior settings
---- example: {name:Antykwa Torunska/I/B} -> bold
-
-local isstyle = function (request)
- request = stringlower(request)
- request = stringexplode(request, "/")
-
- for _,v in next, request do
- local stylename = supported[v]
- if stylename then
- old_feature_list.style = stylename
- elseif stringfind(v, "^s=") then
- --- after all, we want everything after the second byte ...
- local val = stringsub(v, 3)
- old_feature_list.optsize = val
- elseif stylename == false then
- report("log", 0,
- "load", "unsupported font option: %s", v)
- elseif not stringis_empty(v) then
- old_feature_list.style = stringgsub(v, "[^%a%d]", "")
- end
- end
-end
-
--- TODO an option to dump the default features for a script would make
--- a nice addition to luaotfload-tool
@@ -135,13 +93,36 @@ defaults.tibt = defaults.khmr
defaults.lao = defaults.thai
--[[doc--
-Which features are active by default depends on the script requested.
+
+ As discussed, we will issue a warning because of incomplete support
+ when one of the scripts below is requested.
+
+ Reference: https://github.com/lualatex/luaotfload/issues/31
+
+--doc]]--
+
+local support_incomplete = table.tohash({
+ "deva", "beng", "guru", "gujr",
+ "orya", "taml", "telu", "knda",
+ "mlym", "sinh",
+}, true)
+
+--[[doc--
+
+ Which features are active by default depends on the script
+ requested.
+
--doc]]--
--- (string, string) dict -> (string, string) dict
local set_default_features = function (speclist)
speclist = speclist or { }
local script = speclist.script or "dflt"
+ if support_incomplete[script] then
+ report("log", 0, "load",
+ "support for the requested script: “%s” may be incomplete",
+ script)
+ end
report("log", 0, "load",
"auto-selecting default features for script: %s",
@@ -169,84 +150,6 @@ local set_default_features = function (speclist)
return speclist
end
--- --[==[obsolete--
-local function issome () old_feature_list.lookup = 'name' end
-local function isfile () old_feature_list.lookup = 'file' end
-local function isname () old_feature_list.lookup = 'name' end
-local function thename(s) old_feature_list.name = s end
-local function issub (v) old_feature_list.sub = v end
-local function istrue (s) old_feature_list[s] = true end
-local function isfalse(s) old_feature_list[s] = false end
-local function iskey (k,v) old_feature_list[k] = v end
-
-local P, S, R, C = lpeg.P, lpeg.S, lpeg.R, lpeg.C
-
-local spaces = P(" ")^0
---local namespec = (1-S("/:("))^0 -- was: (1-S("/: ("))^0
---[[phg-- this prevents matching of absolute paths as file names --]]--
-local namespec = (1-S("/:("))^1
-local filespec = (R("az", "AZ") * P(":"))^-1 * (1-S(":("))^1
-local stylespec = spaces * P("/") * (((1-P(":"))^0)/isstyle) * spaces
-local filename = (P("file:")/isfile * (filespec/thename))
- + (P("[") * P(true)/isname * (((1-P("]"))^0)/thename) * P("]"))
-local fontname = (P("name:")/isname * (namespec/thename)) + P(true)/issome * (namespec/thename)
-local sometext = (R("az","AZ","09") + S("+-.,"))^1
-local truevalue = P("+") * spaces * (sometext/istrue)
-local falsevalue = P("-") * spaces * (sometext/isfalse)
-local keyvalue = P("+") + (C(sometext) * spaces * P("=") * spaces * C(sometext))/iskey
-local somevalue = sometext/istrue
-local subvalue = P("(") * (C(P(1-S("()"))^1)/issub) * P(")") -- for Kim
-local option = spaces * (keyvalue + falsevalue + truevalue + somevalue) * spaces
-local options = P(":") * spaces * (P(";")^0 * option)^0
-local oldsyntax = (filename + fontname) * subvalue^0 * stylespec^0 * options^0
-
---- to be annihilated
-local function old_behavior (specification) -- xetex mode
- old_feature_list = { }
- lpeg.match(oldsyntax,specification.specification)
- old_feature_list = set_default_features(old_feature_list)
- if old_feature_list.style then
- specification.style = old_feature_list.style
- old_feature_list.style = nil
- end
- if old_feature_list.optsize then
- specification.optsize = old_feature_list.optsize
- old_feature_list.optsize = nil
- end
- if old_feature_list.name then
- if resolvers.findfile(old_feature_list.name, "tfm") then
- old_feature_list.lookup = "file"
- old_feature_list.name = file.addsuffix(old_feature_list.name, "tfm")
- elseif resolvers.findfile(old_feature_list.name, "ofm") then
- old_feature_list.lookup = "file"
- old_feature_list.name = file.addsuffix(old_feature_list.name, "ofm")
- end
-
- specification.name = old_feature_list.name
- old_feature_list.name = nil
- end
- --- this test overwrites valid file: requests for xetex bracket
- --- syntax
- if old_feature_list.lookup then
- specification.lookup = old_feature_list.lookup
- old_feature_list.lookup = nil
- end
- if old_feature_list.sub then
- specification.sub = old_feature_list.sub
- old_feature_list.sub = nil
- end
- if not old_feature_list.mode then
- -- if no mode is set, use our default
- old_feature_list.mode = fonts.mode
- end
- specification.features.normal = fonts.handlers.otf.features.normalize(old_feature_list)
- return specification
-end
-
---fonts.definers.registersplit(":",old_behavior,"cryptic")
---fonts.definers.registersplit("", old_behavior,"more cryptic") -- catches \font\text=[names]
---obsolete]==]--
-
-----------------------------------------------------------------------
--- request syntax parser 2.2
-----------------------------------------------------------------------
@@ -282,37 +185,28 @@ end
--- according to my reconstruction, the correct chaining
--- of the lookups for each category is as follows:
---
---- | File -> ( db/filename lookup;
---- db/basename lookup;
---- kpse.find_file() )
---- | Name -> ( names.resolve() )
---- | Path -> ( db/filename lookup;
---- db/basename lookup;
---- kpse.find_file();
---- fullpath lookup )
---- | Anon -> ( names.resolve(); (* most general *)
---- db/filename lookup;
---- db/basename lookup;
---- kpse.find_file();
---- fullpath lookup )
+--- | File -> ( db/filename lookup )
---
---- the database should be generated only if the chain has
---- been completed, and then only once.
+--- | Name -> ( db/name lookup,
+--- db/filename lookup )
---
---- caching of successful lookups is essential. we need
---- an additional subtable "cached" in the database. it
---- should be nil’able by issuing luaotfload-tool --flush or
---- something. if a cache miss is followed by a successful
---- lookup, then it will be counted as new addition to the
---- cache. we also need a config option to ignore caching.
+--- | Path -> ( db/filename lookup,
+--- fullpath lookup )
---
---- also everything has to be finished by tomorrow at noon.
+--- | Anon -> ( kpse.find_file(), // <- for tfm, ofm
+--- db/name lookup,
+--- db/filename lookup,
+--- fullpath lookup )
+---
+--- caching of successful lookups is essential. we now
+--- as of v2.2 have an experimental lookup cache that is
+--- stored in a separate file. it pertains only to name:
+--- lookups, and is described in more detail in
+--- luaotfload-database.lua.
---
-----------------------------------------------------------------------
-local stringlower = string.lower
-
local toboolean = function (s)
if s == "true" then return true end
if s == "false" then return false end
@@ -348,17 +242,19 @@ local decimal = digit^1 * (dot * digit^0)^-1
The slash notation: called “modifiers” (Kew) or “font options”
(Robertson, Goosens)
we only support the shorthands for italic / bold / bold italic
- shapes, the rest is ignored.
+ shapes, as well as setting optical size, the rest is ignored.
--doc]]--
local style_modifier = (P"BI" + P"IB" + P"bi" + P"ib" + S"biBI")
/ stringlower
-local other_modifier = P"S=" * decimal --- optical size; unsupported
- + P"AAT" + P"aat" --- apple stuff; unsupported
+local size_modifier = S"Ss" * P"=" --- optical size
+ * Cc"optsize" * C(decimal)
+local other_modifier = P"AAT" + P"aat" --- apple stuff; unsupported
+ P"ICU" + P"icu" --- not applicable
+ P"GR" + P"gr" --- sil stuff; unsupported
local garbage_modifier = ((1 - colon - slash)^0 * Cc(false))
local modifier = slash * (other_modifier --> ignore
+ Cs(style_modifier) --> collect
+ + Ct(size_modifier) --> collect
+ garbage_modifier) --> warn
local modifier_list = Cg(Ct(modifier^0), "modifiers")
@@ -409,15 +305,15 @@ local specification = (prefixed + unprefixed)
local font_request = Ct(path_lookup * (colon^-1 * features)^-1
+ specification * (colon * features)^-1)
--- lpeg.print(font_request)
---- new parser: 632 rules
+-- lpeg.print(font_request)
+--- new parser: 657 rules
--- old parser: 230 rules
local import_values = {
--- That’s what the 1.x parser did, not quite as graciously,
--- with an array of branch expressions.
-- "style", "optsize",--> from slashed notation; handled otherwise
- "lookup", "sub" --[[‽]], "mode",
+ "lookup", "sub", "mode",
}
local lookup_types = { "anon", "file", "name", "path" }
@@ -441,21 +337,21 @@ local supported = {
gr = false,
}
+--- (string | (string * string) | bool) list -> (string * number)
local handle_slashed = function (modifiers)
local style, optsize
for i=1, #modifiers do
local mod = modifiers[i]
- if supported[mod] then
- style = supported[mod]
- --elseif stringfind(v, "^s=") then
- elseif stringsub(v, 1, 2) == "s=" then
- local val = stringsub(v, 3)
- optsize = val
- elseif stylename == false then
+ if type(mod) == "table" and mod[1] == "optsize" then --> optical size
+ optsize = tonumber(mod[2])
+ elseif mod == false then
+ --- ignore
report("log", 0,
"load", "unsupported font option: %s", v)
- elseif not stringis_empty(v) then
- style = stringgsub(v, "[^%a%d]", "")
+ elseif supported[mod] then
+ style = supported[mod]
+ elseif not stringis_empty(mod) then
+ style = stringgsub(mod, "[^%a%d]", "")
end
end
return style, optsize
@@ -465,6 +361,18 @@ end
local handle_request = function (specification)
local request = lpegmatch(font_request,
specification.specification)
+ if not request then
+ --- happens when called with an absolute path
+ --- in an anonymous lookup;
+ --- we try to behave as friendly as possible
+ --- just go with it ...
+ report("log", 0, "load", "invalid request “%s” of type anon",
+ specification.specification)
+ report("log", 0, "load", "use square bracket syntax or consult the documentation.")
+ specification.name = specification.specification
+ specification.lookup = "file"
+ return specification
+ end
local lookup, name = select_lookup(request)
request.features = set_default_features(request.features)
@@ -501,15 +409,9 @@ local compare_requests = function (spec)
return new
end
---fonts.definers.registersplit(":", compare_requests, "cryptic")
---fonts.definers.registersplit("", compare_requests, "more cryptic") -- catches \font\text=[names]
-
fonts.definers.registersplit(":", handle_request, "cryptic")
fonts.definers.registersplit("", handle_request, "more cryptic") -- catches \font\text=[names]
---fonts.definers.registersplit(":",old_behavior,"cryptic")
---fonts.definers.registersplit("", old_behavior,"more cryptic") -- catches \font\text=[names]
-
---[[ end included font-ltx.lua ]]
--[[doc--
@@ -531,11 +433,15 @@ local otf = fonts.handlers.otf
local registerotffeature = otf.features.register
local setmetatableindex = table.setmetatableindex
--- In the userdata interface we can not longer tweak the loaded font as
--- conveniently as before. For instance, instead of pushing extra data in
--- in the table using the original structure, we now have to operate on
--- the mkiv representation. And as the fontloader interface is modelled
--- after fontforge we cannot change that one too much either.
+--[[HH--
+
+ In the userdata interface we can not longer tweak the loaded font as
+ conveniently as before. For instance, instead of pushing extra data in
+ in the table using the original structure, we now have to operate on
+ the mkiv representation. And as the fontloader interface is modelled
+ after fontforge we cannot change that one too much either.
+
+--HH]]--
local types = {
substitution = "gsub_single",
@@ -799,24 +705,7 @@ local anum_specification = {
--- below the specifications as given in the removed font-otc.lua
--- the rest was identical to what this file had from the beginning
--- both make the “anum.tex” test pass anyways
---
---local anum_specification = {
--- {
--- type = "substitution",
--- features = { arab = { urd = true, dflt = true } },
--- data = anum_arabic,
--- flags = noflags, -- { },
--- valid = valid,
--- },
--- {
--- type = "substitution",
--- features = { arab = { urd = true } },
--- data = anum_persian,
--- flags = noflags, -- { },
--- valid = valid,
--- },
---}
---
+
otf.addfeature("anum",anum_specification)
registerotffeature {
diff --git a/luaotfload-loaders.lua b/luaotfload-loaders.lua
index 8ab6b29..c9c30de 100644
--- a/luaotfload-loaders.lua
+++ b/luaotfload-loaders.lua
@@ -1,3 +1,11 @@
+if not modules then modules = { } end modules ["loaders"] = {
+ version = 2.200,
+ comment = "companion to luaotfload.lua",
+ author = "Hans Hagen, Khaled Hosny, Elie Roux, Philipp Gesang",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
local fonts = fonts
---
diff --git a/luaotfload-override.lua b/luaotfload-override.lua
index 2b9ef8b..863187f 100644
--- a/luaotfload-override.lua
+++ b/luaotfload-override.lua
@@ -1,12 +1,11 @@
if not modules then modules = { } end modules ['luat-ovr'] = {
- version = 1.001,
+ version = 2.2,
comment = "companion to luatex-*.tex",
- author = "Khaled Hosny and Elie Roux",
+ author = "Khaled Hosny, Elie Roux, Philipp Gesang",
copyright = "Luaotfload Development Team",
license = "GNU GPL v2"
}
-
local module_name = "luaotfload"
local texiowrite_nl = texio.write_nl
@@ -27,6 +26,7 @@ We recreate the verbosity levels previously implemented in font-nms:
==========================================================
--doc]]--
+
local loglevel = 1 --- default
local logout = "log"
@@ -81,12 +81,4 @@ logs.names_report = function (mode, lvl, ...)
end
end
-if containers then
- --- This will vanish as soon as Hans fixes it in data-con
- --- https://github.com/lualatex/luaotfload/issues/17
-
- containers.cleanname = function (name)
- return (string.gsub(string.lower(name),"[^%w%d\128\255]+","-"))
- end
-end
-- vim:tw=71:sw=4:ts=4:expandtab
diff --git a/luaotfload-tool.lua b/luaotfload-tool.lua
index bb935cf..0cd19b1 100755
--- a/luaotfload-tool.lua
+++ b/luaotfload-tool.lua
@@ -1,13 +1,28 @@
#!/usr/bin/env texlua
+-----------------------------------------------------------------------
+-- FILE: luaotfload-tool.lua
+-- DESCRIPTION: database functionality
+-- REQUIREMENTS: luaotfload 2.2
+-- AUTHOR: Khaled Hosny, Élie Roux, Philipp Gesang
+-- VERSION: 2.2
+-- LICENSE: GPL v2
+-- CREATED: 2013-05-06 13:37:12+0200
+-----------------------------------------------------------------------
--[[doc--
-This file was originally written by Elie Roux and Khaled Hosny and is under CC0
-license (see http://creativecommons.org/publicdomain/zero/1.0/legalcode).
+
+This file was originally written (as \fileent{mkluatexfontdb.lua}) by
+Elie Roux and Khaled Hosny and, as a derived work of ConTeXt, is
+provided under the terms of the GPL v2.0 license as printed in full
+text in the manual (luaotfload.pdf).
+
+ \url{http://www.gnu.org/licenses/old-licenses/gpl-2.0.html}.
This file is a wrapper for the luaotfload font names module
(luaotfload-database.lua). It is part of the luaotfload bundle, please
see the luaotfload documentation for more info. Report bugs to
-\url{https://github.com/lualatex/luaotfload/issues}.
+
+ \url{https://github.com/lualatex/luaotfload/issues}.
--doc]]--
@@ -15,7 +30,6 @@ kpse.set_program_name"luatex"
local stringformat = string.format
local texiowrite_nl = texio.write_nl
-local stringfind = string.find
local stringlower = string.lower
@@ -93,7 +107,7 @@ require"luaotfload-override.lua" --- this populates the logs.* namespace
require"luaotfload-database"
require"alt_getopt"
-local version = "2.2" -- same version number as luaotfload
+local version = "2.2" -- same version number as luaotfload
local names = fonts.names
local db_src_out = names.path.dir.."/"..names.path.basename
@@ -253,11 +267,10 @@ actions.generate = function (job)
end
actions.flush = function (job)
- local success, fontnames = names.flush_cache()
+ local success, lookups = names.flush_cache()
if success then
- local savedname = names.save(fontnames)
- logs.names_report("info", 2, "cache",
- "Cache emptied", #fontnames.mappings)
+ local savedname = names.save_lookups()
+ logs.names_report("info", 2, "cache", "Cache emptied")
if savedname then
return true, true
end
diff --git a/luaotfload.dtx b/luaotfload.dtx
index fd71485..ddd0116 100644
--- a/luaotfload.dtx
+++ b/luaotfload.dtx
@@ -1,10 +1,14 @@
% \iffalse meta-comment
%
-% Copyright (C) 2009-2013 by Elie Roux <elie.roux@telecom-bretagne.eu>
-% and Khaled Hosny <khaledhosny@eglug.org>
-% (Support: <lualatex-dev@tug.org>.)
+% Copyright (C) 2009-2013
+% by Elie Roux <elie.roux@telecom-bretagne.eu>
+% and Khaled Hosny <khaledhosny@eglug.org>
+% and Philipp Gesang <philipp.gesang@alumni.uni-heidelberg.de>
%
-% This work is under the CC0 license.
+% Home: https://github.com/lualatex/luaotfload
+% Support: <lualatex-dev@tug.org>.
+%
+% This work is under the GPL v2.0 license.
%
% This work consists of the main source file luaotfload.dtx
% and the derived files
@@ -47,11 +51,15 @@
\preamble
This is a generated file.
-Copyright (C) 2009-2013 by by Elie Roux <elie.roux@telecom-bretagne.eu>
- and Khaled Hosny <khaledhosny@eglug.org>
- (Support: <lualatex-dev@tug.org>.)
+Copyright (C) 2009-2013
+ by Elie Roux <elie.roux@telecom-bretagne.eu>
+ and Khaled Hosny <khaledhosny@eglug.org>
+ and Philipp Gesang <philipp.gesang@alumni.uni-heidelberg.de>
+
+ Home: https://github.com/lualatex/luaotfload
+ Support: <lualatex-dev@tug.org>.
-This work is under the CC0 license.
+This work is under the GPL v2.0 license.
This work consists of the main source file luaotfload.dtx
and the derived files
@@ -119,12 +127,18 @@ and the derived files
citecolor=\primarycolor,
pdftitle={The luaotfload package},
pdfsubject={OpenType layout system for Plain TeX and LaTeX},
- pdfauthor={Elie Roux & Khaled Hosny},
+ pdfauthor={Elie Roux & Khaled Hosny & Philipp Gesang},
pdfkeywords={luatex, lualatex, unicode, opentype}
]{hyperref}
\usepackage{fontspec}
-%usepackage{unicode-math}%% broken
-\setmainfont[Numbers=OldStyle,Ligatures=TeX]{Linux Libertine O}
+\usepackage{unicode-math}
+\setmainfont[
+ Numbers = OldStyle,
+ Ligatures = TeX,
+ BoldFont = {Linux Libertine Bold},
+ ItalicFont = {Linux Libertine Italic},
+ SlantedFont = {Linux Libertine Italic},
+]{Linux Libertine O}
\setmonofont[Ligatures=TeX,Scale=MatchLowercase]{Liberation Mono}
%setsansfont[Ligatures=TeX]{Linux Biolinum O}
\setsansfont[Ligatures=TeX,Scale=MatchLowercase]{Iwona Medium}
@@ -164,6 +178,27 @@ and the derived files
\usepackage{syntax}%% bnf for font request syntax
+\usepackage{titlesec}
+
+\def\movecountertomargin#1{\llap{\rmfamily\upshape#1\hskip2em}}
+\def\zeropoint{0pt}
+\titleformat \part
+ {\normalsize\rmfamily\bfseries}
+ {\movecountertomargin\thepart} \zeropoint {}
+\titleformat \section
+ {\normalsize\rmfamily\scshape}%% no \word; life is full of disappointments
+ {\movecountertomargin\thesection} \zeropoint {}
+\titleformat \subsection
+ {\small\rmfamily\itshape}
+ {\movecountertomargin\thesubsection} \zeropoint {}
+
+\usepackage{tocloft}
+\renewcommand \cftpartfont {\rmfamily\upshape}
+\renewcommand \cftsecfont {\rmfamily\upshape}
+\renewcommand \cftsubsecfont {\rmfamily\upshape}
+\setlength \cftbeforepartskip {1ex}
+\setlength \cftbeforesecskip {1ex}
+
\VerbatimFootnotes
\begin{document}
\DocInput{luaotfload.dtx}%
@@ -192,9 +227,10 @@ and the derived files
% \GetFileInfo{luaotfload.drv}
%
% \title{The \identifier{luaotfload} package}
-% \date{2013/04/16 v2.2}
-% \author{Elie Roux and Khaled Hosny\\
-% Support: \email{lualatex-dev@tug.org}}
+% \date{2013/05/05 v2.2}
+% \author{Elie Roux · Khaled Hosny · Philipp Gesang\\
+% Home: \url{https://github.com/lualatex/luaotfload}\\
+% Support: \email{lualatex-dev@tug.org}}
%
% \maketitle
%
@@ -296,7 +332,7 @@ and the derived files
%
% <path lookup> ::= \{ {\sc all_characters} - `]' \} ;
%
-% <modifier> ::= `/', (`I' | `B' | `BI' | `IB') ;
+% <modifier> ::= `/', (`I' | `B' | `BI' | `IB' | `S=', \{ {\sc digit} \} ) ;
%
% <subfont no> ::= `(', \{ {\sc digit} \}, `)' ;
%
@@ -1104,6 +1140,9 @@ and the derived files
% (\abbrev{pfa}, \abbrev{pfb}).
% \ouritem {luaotfload-database.lua} font names database.
% \ouritem {luaotfload-colors.lua} color handling.
+% \ouritem {luaotfload-auxiliary.lua} access to internal functionality
+% for package authors
+% (proposals for additions welcome).
% \end{itemize}
%
% \begin{figure}[b]
@@ -1178,10 +1217,13 @@ and the derived files
luaotfload = luaotfload or {}
local luaotfload = luaotfload
-config = config or { }
-config.luaotfload = config.luaotfload or { }
-config.luaotfload.resolver = config.luaotfload.resolver or "normal"
-config.luaotfload.definer = config.luaotfload.definer or "patch"
+config = config or { }
+config.luaotfload = config.luaotfload or { }
+------.luaotfload.resolver = config.luaotfload.resolver or "normal"
+config.luaotfload.resolver = config.luaotfload.resolver or "cached"
+config.luaotfload.definer = config.luaotfload.definer or "patch"
+config.luaotfload.loglevel = config.luaotfload.loglevel or 1
+config.luaotfload.color_callback = config.luaotfload.color_callback or "pre_linebreak_filter"
--luaotfload.prefer_merge = config.luaotfload.prefer_merge or true
luaotfload.module = {
@@ -1191,7 +1233,7 @@ luaotfload.module = {
description = "OpenType layout system.",
author = "Elie Roux & Hans Hagen",
copyright = "Elie Roux",
- license = "CC0"
+ license = "GPL v2.0"
}
local luatexbase = luatexbase
@@ -1378,7 +1420,7 @@ local pop_namespaces = function (normalglobal, isolate)
local _G = _G
local mode = "non-destructive"
if isolate then mode = "destructive" end
- log("pop namespace from font loader -- "..mode)
+ log("pop namespace from font loader -- " .. mode)
for k, v in next, _G do
if not normalglobal[k] then
context_environment[k] = v
@@ -1419,6 +1461,7 @@ tex.attribute[0] = 0
% \begin{macrocode}
loadmodule"merged.lua"
+---loadmodule"font-odv.lua" --- <= Devanagari support from Context
if fonts then
@@ -1518,20 +1561,9 @@ add_to_callback("find_vf_file",
loadmodule"lib-dir.lua" --- required by luaofload-database.lua
loadmodule"override.lua" --- “luat-ovr”
-logs.set_loglevel(config.luaotfload.loglevel or 2)
+logs.set_loglevel(config.luaotfload.loglevel)
% \end{macrocode}
-% \CONTEXT does not support ofm, these lines were added in order to make it
-% work. However they do not seem necessary so they are commented for now.
-%
-% \begin{macrocode}
--- if fonts and fonts.readers.tfm then
--- fonts.readers.ofm = fonts.readers.tfm
--- fonts.handlers.ofm = fonts.handlers.tfm --- empty anyways
--- fonts.formats.ofm = fonts.formats.tfm --- “type1”
--- --- fonts.readers.sequence[#fonts.readers.sequence+1] = "ofm"
---end
-% \end{macrocode}
% Now we load the modules written for \identifier{luaotfload}.
%
% \begin{macrocode}
@@ -1575,8 +1607,8 @@ formats.ofm = "type1"
%
% \begin{macrocode}
request_resolvers.file = function (specification)
- --local found = fonts.names.crude_file_lookup(specification.name)
- local found = fonts.names.crude_file_lookup_verbose(specification.name)
+ local found = fonts.names.crude_file_lookup(specification.name)
+ --local found = fonts.names.crude_file_lookup_verbose(specification.name)
specification.name = found[1]
--if format then specification.forced = format end
end
@@ -1658,7 +1690,10 @@ local read_font_file = fonts.definers.read
--- spec -> size -> id -> tmfdata
local patch_defined_font = function (specification, size, id)
local tfmdata = read_font_file(specification, size, id)
- if type(tfmdata) == "table" then
+ if type(tfmdata) == "table" and tfmdata.shared then
+ --- We need to test for the “shared” field here
+ --- or else the fontspec capheight callback will
+ --- operate on tfm fonts.
call_callback("luaotfload.patch_font", tfmdata)
end
return tfmdata
diff --git a/mkglyphlist b/mkglyphlist
index d73a608..281c736 100755
--- a/mkglyphlist
+++ b/mkglyphlist
@@ -27,9 +27,13 @@ require"lpeg"
require"socket"
kpse.set_program_name"luatex"
-dofile(kpse.find_file("lualibs-lua.lua", "lua"))
-dofile(kpse.find_file("lualibs-lpeg.lua", "lua"))
-dofile(kpse.find_file("lualibs-table.lua", "lua")) --- for serialization
+for _, lib in next, { "lualibs-lua.lua",
+ "lualibs-lpeg.lua",
+ "lualibs-table.lua", } do
+ local found = assert(kpse.find_file(lib, "lua"),
+ "Could not locate " .. lib)
+ require(found)
+end
local C, Cf, Cg, Ct, P, R =
lpeg.C, lpeg.Cf, lpeg.Cg, lpeg.Ct, lpeg.P, lpeg.R
diff --git a/tests/systemfonts.tex b/tests/systemfonts.tex
index 0e842db..af08509 100644
--- a/tests/systemfonts.tex
+++ b/tests/systemfonts.tex
@@ -21,6 +21,8 @@
\font\lmbi ={Latin Modern Roman/BI:+liga} at 10pt
\font\lms ={Latin Modern Roman Slanted:+liga} at 10pt
\font\lmltn ={Latin Modern Roman:script=latn} at 10pt
+%% get this font here:
+%% http://sourceforge.net/projects/arabeyes/files/kacst_fonts/kacst_one_5.0.tar.bz2/download
\font\arab ={KacstOne:mode=node;script=arab} at 10pt
\termesr fi fl ffi ffl ff\par