summaryrefslogtreecommitdiff
path: root/macros/luatex/generic
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2022-06-17 03:01:24 +0000
committerNorbert Preining <norbert@preining.info>2022-06-17 03:01:24 +0000
commitf9418ac1e9385653cfa09da311bb2d405a936334 (patch)
tree764fc072c0bea51901ba3ef3a6dd915400df47c5 /macros/luatex/generic
parentb83d15e1ff2e551eb7391d45becd87dce59d39b8 (diff)
CTAN sync 202206170301
Diffstat (limited to 'macros/luatex/generic')
-rw-r--r--macros/luatex/generic/luaotfload/NEWS8
-rw-r--r--macros/luatex/generic/luaotfload/README.md4
-rw-r--r--macros/luatex/generic/luaotfload/filegraph.pdfbin40007 -> 40019 bytes
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-2022-06-15.lua (renamed from macros/luatex/generic/luaotfload/fontloader-2022-02-24.lua)583
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-dsp.lua5
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-imp-ligatures.lua4
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-map.lua6
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-osd.lua59
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-otc.lua57
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-otl.lua2
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-otr.lua6
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-oup.lua210
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-ttf.lua235
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-reference.lua419
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-auxiliary.lua4
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-bcp47.lua85
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-case.lua312
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-colors.lua115
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-conf.pdfbin77694 -> 77540 bytes
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-configuration.lua4
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-database.lua13
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-diagnostics.lua4
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-dvi.lua4
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-embolden.lua4
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-fallback.lua4
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-features.lua128
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-filelist.lua4
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-glyphlist.lua4
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-harf-define.lua6
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-harf-plug.lua24
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-harf-var-cff2.lua6
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-harf-var-t2-writer.lua4
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-harf-var-ttf.lua18
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-hashing.lua2
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-init.lua4
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-latex.pdfbin494195 -> 495247 bytes
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-latex.tex29
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-letterspace.lua4
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-loaders.lua84
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-log.lua4
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-main.tex391
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-multiscript.lua4
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-notdef.lua4
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-parsers.lua45
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-resolvers.lua12
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-scripts.lua4
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-status.lua84
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-suppress.lua4
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-szss.lua4
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-t3.lua142
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-tool.144
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-tool.lua18
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-tool.pdfbin76968 -> 76805 bytes
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-tool.rst4
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-tounicode.lua4
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-unicode.lua96
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload.conf.528
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload.conf.rst4
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload.lua4
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload.sty2
-rw-r--r--macros/luatex/generic/luaotfload/scripts-demo.pdfbin21673 -> 19082 bytes
-rw-r--r--macros/luatex/generic/luaotfload/shaper-demo-graphite.pdfbin8548 -> 8560 bytes
-rw-r--r--macros/luatex/generic/luaotfload/shaper-demo.pdfbin8469 -> 8481 bytes
63 files changed, 2285 insertions, 1081 deletions
diff --git a/macros/luatex/generic/luaotfload/NEWS b/macros/luatex/generic/luaotfload/NEWS
index 7c6c57eefb..289861f917 100644
--- a/macros/luatex/generic/luaotfload/NEWS
+++ b/macros/luatex/generic/luaotfload/NEWS
@@ -1,5 +1,13 @@
Change History
--------------
+2022-06-15 luaotfload v3.22
+
+ * Tailored case mappings
+ * Avoid database rebuilds when switching Lua versions
+ * Improved attribute settings of ActualText nodes in harf mode
+ * Callback-based customization for color parameter
+ * Various bug fixes
+
2022-03-18 luaotfload v3.21
* Fix performance regression introduced in version 3.19.
diff --git a/macros/luatex/generic/luaotfload/README.md b/macros/luatex/generic/luaotfload/README.md
index 57be111ba2..4a1fa3a3b0 100644
--- a/macros/luatex/generic/luaotfload/README.md
+++ b/macros/luatex/generic/luaotfload/README.md
@@ -1,8 +1,8 @@
# The Luaotfload Package
-VERSION: 3.21
+VERSION: 3.22
-DATE: 2022-03-18
+DATE: 2022-06-15
## Description
diff --git a/macros/luatex/generic/luaotfload/filegraph.pdf b/macros/luatex/generic/luaotfload/filegraph.pdf
index fd38f172d8..07ccf2b986 100644
--- a/macros/luatex/generic/luaotfload/filegraph.pdf
+++ b/macros/luatex/generic/luaotfload/filegraph.pdf
Binary files differ
diff --git a/macros/luatex/generic/luaotfload/fontloader-2022-02-24.lua b/macros/luatex/generic/luaotfload/fontloader-2022-06-15.lua
index aee123be03..5e0af8e484 100644
--- a/macros/luatex/generic/luaotfload/fontloader-2022-02-24.lua
+++ b/macros/luatex/generic/luaotfload/fontloader-2022-06-15.lua
@@ -1,6 +1,6 @@
--[[info-----------------------------------------------------------------------
Luaotfload fontloader package
- build 2022-02-24 08:04:22
+ build 2022-06-15 18:33:10
-------------------------------------------------------------------------------
© 2022 PRAGMA ADE / ConTeXt Development Team
@@ -63,7 +63,7 @@
--info]]-----------------------------------------------------------------------
-do --- [luaotfload, fontloader-2022-02-24.lua scope for “data-con” 23a0f5386d46a1c157ae82a373e35fa0] ---
+do --- [luaotfload, fontloader-2022-06-15.lua scope for “data-con” 23a0f5386d46a1c157ae82a373e35fa0] ---
if not modules then modules={} end modules ['data-con']={
version=1.100,
@@ -184,10 +184,10 @@ function containers.cleanname(name)
return (gsub(lower(name),"[^%w\128-\255]+","-"))
end
-end --- [luaotfload, fontloader-2022-02-24.lua scope for “data-con”] ---
+end --- [luaotfload, fontloader-2022-06-15.lua scope for “data-con”] ---
-do --- [luaotfload, fontloader-2022-02-24.lua scope for “basics-nod” 1750af43148def9e7a75c6900a96f9dc] ---
+do --- [luaotfload, fontloader-2022-06-15.lua scope for “basics-nod” 1750af43148def9e7a75c6900a96f9dc] ---
if not modules then modules={} end modules ['luatex-fonts-nod']={
version=1.001,
@@ -454,10 +454,10 @@ do
end
end
-end --- [luaotfload, fontloader-2022-02-24.lua scope for “basics-nod”] ---
+end --- [luaotfload, fontloader-2022-06-15.lua scope for “basics-nod”] ---
-do --- [luaotfload, fontloader-2022-02-24.lua scope for “basics-chr” 1bb1ea05b5ca1bb5a9848b9eb66322bf] ---
+do --- [luaotfload, fontloader-2022-06-15.lua scope for “basics-chr” ce4afac7ba19471f3c8f90800839f315] ---
characters=characters or {}
@@ -4291,10 +4291,10 @@ characters.indicgroups={
},
}
-end --- [luaotfload, fontloader-2022-02-24.lua scope for “basics-chr”] ---
+end --- [luaotfload, fontloader-2022-06-15.lua scope for “basics-chr”] ---
-do --- [luaotfload, fontloader-2022-02-24.lua scope for “font-ini” 5343de60613adb24cdd7a8d2ee1d153c] ---
+do --- [luaotfload, fontloader-2022-06-15.lua scope for “font-ini” 5343de60613adb24cdd7a8d2ee1d153c] ---
if not modules then modules={} end modules ['font-ini']={
version=1.001,
@@ -4335,10 +4335,10 @@ if node and not tex.getfontoffamily then
tex.getfontoffamily=node.family_font
end
-end --- [luaotfload, fontloader-2022-02-24.lua scope for “font-ini”] ---
+end --- [luaotfload, fontloader-2022-06-15.lua scope for “font-ini”] ---
-do --- [luaotfload, fontloader-2022-02-24.lua scope for “fonts-mis” 17e967c9ec4d001deefd43ddf25e98f7] ---
+do --- [luaotfload, fontloader-2022-06-15.lua scope for “fonts-mis” 17e967c9ec4d001deefd43ddf25e98f7] ---
if not modules then modules={} end modules ['luatex-font-mis']={
version=1.001,
@@ -4370,10 +4370,10 @@ function font.each()
return table.sortedhash(fonts.hashes.identifiers)
end
-end --- [luaotfload, fontloader-2022-02-24.lua scope for “fonts-mis”] ---
+end --- [luaotfload, fontloader-2022-06-15.lua scope for “fonts-mis”] ---
-do --- [luaotfload, fontloader-2022-02-24.lua scope for “font-con” 724e5dd14aec2d4d189f8619898004cf] ---
+do --- [luaotfload, fontloader-2022-06-15.lua scope for “font-con” 724e5dd14aec2d4d189f8619898004cf] ---
if not modules then modules={} end modules ['font-con']={
version=1.001,
@@ -5741,10 +5741,10 @@ function constructors.addcoreunicodes(unicodes)
return unicodes
end
-end --- [luaotfload, fontloader-2022-02-24.lua scope for “font-con”] ---
+end --- [luaotfload, fontloader-2022-06-15.lua scope for “font-con”] ---
-do --- [luaotfload, fontloader-2022-02-24.lua scope for “fonts-enc” c24fd6b4f34f87b9c4ff5e6193ce2656] ---
+do --- [luaotfload, fontloader-2022-06-15.lua scope for “fonts-enc” c24fd6b4f34f87b9c4ff5e6193ce2656] ---
if not modules then modules={} end modules ['luatex-font-enc']={
version=1.001,
@@ -5819,10 +5819,10 @@ function encodings.load(filename)
return containers.write(encodings.cache,name,data)
end
-end --- [luaotfload, fontloader-2022-02-24.lua scope for “fonts-enc”] ---
+end --- [luaotfload, fontloader-2022-06-15.lua scope for “fonts-enc”] ---
-do --- [luaotfload, fontloader-2022-02-24.lua scope for “font-cid” 22b0367742fb253deef84ef7ccf5e8de] ---
+do --- [luaotfload, fontloader-2022-06-15.lua scope for “font-cid” 22b0367742fb253deef84ef7ccf5e8de] ---
if not modules then modules={} end modules ['font-cid']={
version=1.001,
@@ -5973,10 +5973,10 @@ function cid.getmap(specification)
return found
end
-end --- [luaotfload, fontloader-2022-02-24.lua scope for “font-cid”] ---
+end --- [luaotfload, fontloader-2022-06-15.lua scope for “font-cid”] ---
-do --- [luaotfload, fontloader-2022-02-24.lua scope for “font-map” c4a39db5ad822b348aa61bca5f4a599a] ---
+do --- [luaotfload, fontloader-2022-06-15.lua scope for “font-map” 27ee748150e56f5f0e5f0fefc864f35e] ---
if not modules then modules={} end modules ['font-map']={
version=1.001,
@@ -6164,9 +6164,9 @@ function mappings.addtounicode(data,filename,checklookups,forceligatures)
local usedmap=cidinfo and fonts.cid.getmap(cidinfo)
local uparser=makenameparser()
if usedmap then
- oparser=usedmap and makenameparser(cidinfo.ordering)
- cidnames=usedmap.names
- cidcodes=usedmap.unicodes
+ oparser=usedmap and makenameparser(cidinfo.ordering)
+ cidnames=usedmap.names
+ cidcodes=usedmap.unicodes
end
local ns=0
local nl=0
@@ -6384,10 +6384,10 @@ function mappings.addtounicode(data,filename,checklookups,forceligatures)
end
end
-end --- [luaotfload, fontloader-2022-02-24.lua scope for “font-map”] ---
+end --- [luaotfload, fontloader-2022-06-15.lua scope for “font-map”] ---
-do --- [luaotfload, fontloader-2022-02-24.lua scope for “font-vfc” a81c29eda98cd62cbebdb6c93544b50d] ---
+do --- [luaotfload, fontloader-2022-06-15.lua scope for “font-vfc” a81c29eda98cd62cbebdb6c93544b50d] ---
if not modules then modules={} end modules ['font-vfc']={
version=1.001,
@@ -6484,10 +6484,10 @@ helpers.commands=utilities.storage.allocate {
dummy=dummy,
}
-end --- [luaotfload, fontloader-2022-02-24.lua scope for “font-vfc”] ---
+end --- [luaotfload, fontloader-2022-06-15.lua scope for “font-vfc”] ---
-do --- [luaotfload, fontloader-2022-02-24.lua scope for “font-otr” 91f70c1216e60227e1437b6c8dcd8647] ---
+do --- [luaotfload, fontloader-2022-06-15.lua scope for “font-otr” 1896ac990a961f6d6fec551ca9b52a83] ---
if not modules then modules={} end modules ['font-otr']={
version=1.001,
@@ -8295,13 +8295,13 @@ function readers.getinfo(filename,specification)
}
end
end
-function readers.rehash(fontdata,hashmethod)
+function readers.rehash()
report("the %a helper is not yet implemented","rehash")
end
-function readers.checkhash(fontdata)
+function readers.checkhash()
report("the %a helper is not yet implemented","checkhash")
end
-function readers.pack(fontdata,hashmethod)
+function readers.pack()
report("the %a helper is not yet implemented","pack")
end
function readers.unpack(fontdata)
@@ -8331,10 +8331,10 @@ function readers.extend(fontdata)
end
end
-end --- [luaotfload, fontloader-2022-02-24.lua scope for “font-otr”] ---
+end --- [luaotfload, fontloader-2022-06-15.lua scope for “font-otr”] ---
-do --- [luaotfload, fontloader-2022-02-24.lua scope for “font-oti” 309a75f9c14b77d87e94eba827dc4e71] ---
+do --- [luaotfload, fontloader-2022-06-15.lua scope for “font-oti” 309a75f9c14b77d87e94eba827dc4e71] ---
if not modules then modules={} end modules ['font-oti']={
version=1.001,
@@ -8477,10 +8477,10 @@ function otffeatures.checkeddefaultlanguage(featuretype,autolanguage,languages)
end
end
-end --- [luaotfload, fontloader-2022-02-24.lua scope for “font-oti”] ---
+end --- [luaotfload, fontloader-2022-06-15.lua scope for “font-oti”] ---
-do --- [luaotfload, fontloader-2022-02-24.lua scope for “font-ott” 3f67b1b1d40bbc222681d8db4aff0f42] ---
+do --- [luaotfload, fontloader-2022-06-15.lua scope for “font-ott” 3f67b1b1d40bbc222681d8db4aff0f42] ---
if not modules then modules={} end modules ["font-ott"]={
version=1.001,
@@ -9596,10 +9596,10 @@ function otffeatures.normalize(features,wrap)
end
end
-end --- [luaotfload, fontloader-2022-02-24.lua scope for “font-ott”] ---
+end --- [luaotfload, fontloader-2022-06-15.lua scope for “font-ott”] ---
-do --- [luaotfload, fontloader-2022-02-24.lua scope for “font-cff” e38c1a40e1d1d577cdf7920fa50d0654] ---
+do --- [luaotfload, fontloader-2022-06-15.lua scope for “font-cff” e38c1a40e1d1d577cdf7920fa50d0654] ---
if not modules then modules={} end modules ['font-cff']={
version=1.001,
@@ -11828,10 +11828,10 @@ function readers.cffcheck(filename)
end
end
-end --- [luaotfload, fontloader-2022-02-24.lua scope for “font-cff”] ---
+end --- [luaotfload, fontloader-2022-06-15.lua scope for “font-cff”] ---
-do --- [luaotfload, fontloader-2022-02-24.lua scope for “font-ttf” feba1fdc80160343b24f89ef978e53cb] ---
+do --- [luaotfload, fontloader-2022-06-15.lua scope for “font-ttf” a3ff07150b3535fd32f68748d53fcd36] ---
if not modules then modules={} end modules ['font-ttf']={
version=1.001,
@@ -12011,95 +12011,123 @@ local function applyaxis(glyph,shape,deltas,dowidth)
end
end
elseif cnt>0 then
- local function find(i)
- local prv=cnt
- for j=1,cnt do
- local nxt=dpoints[j]
- if nxt==i then
- return false,j,false
- elseif nxt>i then
- return prv,false,j
- end
- prv=j
- end
- return prv,false,1
- end
- for i=1,nofpoints do
- local d1,d2,d3=find(i)
- local p2=points[i]
- if d2 then
- xv[i]=xvalues[d2]
- yv[i]=yvalues[d2]
- else
- local n1=dpoints[d1]
- local n3=dpoints[d3]
- if n1>nofpoints then
- n1=nofpoints
- end
- if n3>nofpoints then
- n3=nofpoints
- end
- local p1=points[n1]
- local p3=points[n3]
- local p1x=p1[1]
- local p2x=p2[1]
- local p3x=p3[1]
- local p1y=p1[2]
- local p2y=p2[2]
- local p3y=p3[2]
- local x1=xvalues[d1]
- local y1=yvalues[d1]
- local x3=xvalues[d3]
- local y3=yvalues[d3]
- local fx
- local fy
- if p1x==p3x then
- if x1==x3 then
- fx=x1
- else
- fx=0
- end
- elseif p2x<=min(p1x,p3x) then
- if p1x<p3x then
- fx=x1
- else
- fx=x3
- end
- elseif p2x>=max(p1x,p3x) then
- if p1x>p3x then
- fx=x1
- else
- fx=x3
+ local contours=shape.contours
+ local nofcontours=#contours
+ local first=1
+ local firstindex=1
+ for contour=1,nofcontours do
+ local last=contours[contour]
+ if last>=first then
+ local lastindex=cnt
+ if firstindex<cnt then
+ for currentindex=firstindex,cnt do
+ local found=dpoints[currentindex]
+ if found<=first then
+ firstindex=currentindex
+ end
+ if found==last then
+ lastindex=currentindex
+ break;
+ elseif found>last then
+ break
+ end
end
- else
- fx=(p2x-p1x)/(p3x-p1x)
- fx=(1-fx)*x1+fx*x3
end
- if p1y==p3y then
- if y1==y3 then
- fy=y1
- else
- fy=0
- end
- elseif p2y<=min(p1y,p3y) then
- if p1y<p3y then
- fy=y1
- else
- fy=y3
+ local function find(i)
+ local prv=lastindex
+ for j=firstindex,lastindex do
+ local nxt=dpoints[j]
+ if nxt==i then
+ return false,j,false
+ elseif nxt>i then
+ return prv,false,j
+ end
+ prv=j
end
- elseif p2y>=max(p1y,p3y) then
- if p1y>p3y then
- fy=y1
+ return prv,false,firstindex
+ end
+ for point=first,last do
+ local d1,d2,d3=find(point)
+ local p2=points[point]
+ if d2 then
+ xv[point]=xvalues[d2]
+ yv[point]=yvalues[d2]
else
- fy=y3
+ local n1=dpoints[d1]
+ local n3=dpoints[d3]
+ if n1>nofpoints then
+ n1=nofpoints
+ end
+ if n3>nofpoints then
+ n3=nofpoints
+ end
+ local p1=points[n1]
+ local p3=points[n3]
+ local p1x=p1[1]
+ local p2x=p2[1]
+ local p3x=p3[1]
+ local p1y=p1[2]
+ local p2y=p2[2]
+ local p3y=p3[2]
+ local x1=xvalues[d1]
+ local y1=yvalues[d1]
+ local x3=xvalues[d3]
+ local y3=yvalues[d3]
+ local fx
+ local fy
+ if p1x==p3x then
+ if x1==x3 then
+ fx=x1
+ else
+ fx=0
+ end
+ elseif p2x<=min(p1x,p3x) then
+ if p1x<p3x then
+ fx=x1
+ else
+ fx=x3
+ end
+ elseif p2x>=max(p1x,p3x) then
+ if p1x>p3x then
+ fx=x1
+ else
+ fx=x3
+ end
+ else
+ fx=(p2x-p1x)/(p3x-p1x)
+ fx=(1-fx)*x1+fx*x3
+ end
+ if p1y==p3y then
+ if y1==y3 then
+ fy=y1
+ else
+ fy=0
+ end
+ elseif p2y<=min(p1y,p3y) then
+ if p1y<p3y then
+ fy=y1
+ else
+ fy=y3
+ end
+ elseif p2y>=max(p1y,p3y) then
+ if p1y>p3y then
+ fy=y1
+ else
+ fy=y3
+ end
+ else
+ fy=(p2y-p1y)/(p3y-p1y)
+ fy=(1-fy)*y1+fy*y3
+ end
+ xv[point]=fx
+ yv[point]=fy
end
- else
- fy=(p2y-p1y)/(p3y-p1y)
- fy=(1-fy)*y1+fy*y3
end
- xv[i]=fx
- yv[i]=fy
+ if lastindex<cnt then
+ firstindex=lastindex+1
+ end
end
+ first=last+1
end
for i=1,nofpoints do
local pi=points[i]
@@ -13063,10 +13091,10 @@ function readers.gvar(f,fontdata,specification,glyphdata,shapedata)
end
end
-end --- [luaotfload, fontloader-2022-02-24.lua scope for “font-ttf”] ---
+end --- [luaotfload, fontloader-2022-06-15.lua scope for “font-ttf”] ---
-do --- [luaotfload, fontloader-2022-02-24.lua scope for “font-dsp” 7616dae672693fd8ec0f1892358019a2] ---
+do --- [luaotfload, fontloader-2022-06-15.lua scope for “font-dsp” 4935e6605ffd7bf57e66f0b6c132f883] ---
if not modules then modules={} end modules ['font-dsp']={
version=1.001,
@@ -15112,7 +15140,7 @@ do
local scriptoffset=tableoffset+readushort(f)
local featureoffset=tableoffset+readushort(f)
local lookupoffset=tableoffset+readushort(f)
- local variationsoffset=version>0x00010000 and (tableoffset+readulong(f)) or 0
+ local variationsoffset=version>0x00010000 and readulong(f) or 0
if not scriptoffset then
return
end
@@ -15132,7 +15160,7 @@ do
resolvelookups(f,lookupoffset,fontdata,lookups,lookuptypes,lookuphandlers,what,tableoffset)
end
if variationsoffset>0 then
- loadvariations(f,fontdata,variationsoffset,lookuptypes,featurehash,featureorder)
+ loadvariations(f,fontdata,tableoffset+variationsoffset,lookuptypes,featurehash,featureorder)
end
end
end
@@ -16247,6 +16275,7 @@ function readers.hvar(f,fontdata,specification)
local variations={}
local innerindex={}
local outerindex={}
+ local deltas={}
if variationoffset>0 then
regions,deltas=readvariationdata(f,variationoffset,factors)
end
@@ -16343,10 +16372,10 @@ function readers.mvar(f,fontdata,specification)
end
end
-end --- [luaotfload, fontloader-2022-02-24.lua scope for “font-dsp”] ---
+end --- [luaotfload, fontloader-2022-06-15.lua scope for “font-dsp”] ---
-do --- [luaotfload, fontloader-2022-02-24.lua scope for “font-oup” e6e2cc0a202aec2c787d5524e64d340a] ---
+do --- [luaotfload, fontloader-2022-06-15.lua scope for “font-oup” 76dc3379061e5650f772909966b5759e] ---
if not modules then modules={} end modules ['font-oup']={
version=1.001,
@@ -16359,6 +16388,7 @@ local next,type=next,type
local P,R,S=lpeg.P,lpeg.R,lpeg.S
local lpegmatch=lpeg.match
local insert,remove,copy,unpack=table.insert,table.remove,table.copy,table.unpack
+local find=string.find
local formatters=string.formatters
local sortedkeys=table.sortedkeys
local sortedhash=table.sortedhash
@@ -17217,61 +17247,137 @@ local function unifyglyphs(fontdata,usenames)
fontdata.nofglyphs=nofglyphs
return indices,names
end
-local p_crappyname do
+local stripredundant do
local p_hex=R("af","AF","09")
local p_digit=R("09")
local p_done=S("._-")^0+P(-1)
+ local p_style=P(".")
local p_alpha=R("az","AZ")
local p_ALPHA=R("AZ")
- p_crappyname=(
+ local p_crappyname=(
lpeg.utfchartabletopattern({ "uni","u" },true)*S("Xx_")^0*p_hex^1
+lpeg.utfchartabletopattern({ "identity","glyph","jamo" },true)*p_hex^1
+lpeg.utfchartabletopattern({ "index","afii" },true)*p_digit^1
+p_digit*p_hex^3+p_alpha*p_digit^1
+P("aj")*p_digit^1+P("eh_")*(p_digit^1+p_ALPHA*p_digit^1)+(1-P("_"))^1*P("_uni")*p_hex^1+P("_")*P(1)^1
)*p_done
-end
-local forcekeep=false
-directives.register("otf.keepnames",function(v)
- report_cleanup("keeping weird glyph names, expect larger files and more memory usage")
- forcekeep=v
-end)
-local function stripredundant(fontdata)
- local descriptions=fontdata.descriptions
- if descriptions then
- local n=0
- local c=0
- if (not context and fonts.privateoffsets.keepnames) or forcekeep then
- for unicode,d in next,descriptions do
- if d.class=="base" then
- d.class=nil
- c=c+1
+ if context then
+ local forcekeep=false
+ directives.register("otf.keepnames",function(v)
+ report_cleanup("keeping weird glyph names, expect larger files and more memory usage")
+ forcekeep=v
+ end)
+ local function stripvariants(descriptions,list)
+ local n=list and #list or 0
+ if n>0 then
+ for i=1,n do
+ local g=list[i]
+ if g then
+ local d=descriptions[g]
+ if d and d.name then
+ d.name=nil
+ n=n+1
+ end
+ end
end
end
- else
- for unicode,d in next,descriptions do
- local name=d.name
- if name and lpegmatch(p_crappyname,name) then
- d.name=nil
- n=n+1
- end
- if d.class=="base" then
- d.class=nil
- c=c+1
+ return n
+ end
+ local function stripparts(descriptions,list)
+ local n=list and #list or 0
+ if n>0 then
+ for i=1,n do
+ local g=list[i].glyph
+ if g then
+ local d=descriptions[g]
+ if d and d.name then
+ d.name=nil
+ n=n+1
+ end
+ end
end
end
+ return n
end
- if trace_cleanup then
- if n>0 then
- report_cleanup("%s bogus names removed (verbose unicode)",n)
+ local function collectsimple(fontdata)
+ return nil
+ end
+ stripredundant=function(fontdata)
+ local descriptions=fontdata.descriptions
+ if descriptions then
+ local n=0
+ local c=0
+ for unicode,d in next,descriptions do
+ local m=d.math
+ if m then
+ n=n+stripvariants(descriptions,m.vvariants)
+ n=n+stripvariants(descriptions,m.hvariants)
+ n=n+stripparts (descriptions,m.vparts)
+ n=n+stripparts (descriptions,m.hparts)
+ end
+ end
+ if forcekeep then
+ for unicode,d in next,descriptions do
+ if d.class=="base" then
+ d.class=nil
+ c=c+1
+ end
+ end
+ else
+ local keeplist=collectsimple(fontdata)
+ for unicode,d in next,descriptions do
+ local name=d.name
+ if name then
+ if keeplist and keeplist[name] then
+ elseif lpegmatch(p_crappyname,name) then
+ d.name=nil
+ n=n+1
+ end
+ end
+ if d.class=="base" then
+ d.class=nil
+ c=c+1
+ end
+ end
+ end
+ if trace_cleanup then
+ if n>0 then
+ report_cleanup("%s bogus names removed (verbose unicode)",n)
+ end
+ if c>0 then
+ report_cleanup("%s base class tags removed (default is base)",c)
+ end
+ end
end
- if c>0 then
- report_cleanup("%s base class tags removed (default is base)",c)
+ end
+ else
+ stripredundant=function(fontdata)
+ local descriptions=fontdata.descriptions
+ if descriptions then
+ if fonts.privateoffsets.keepnames then
+ for unicode,d in next,descriptions do
+ if d.class=="base" then
+ d.class=nil
+ end
+ end
+ else
+ for unicode,d in next,descriptions do
+ local name=d.name
+ if name then
+ if lpegmatch(p_crappyname,name) then
+ d.name=nil
+ end
+ end
+ if d.class=="base" then
+ d.class=nil
+ end
+ end
+ end
end
end
end
+ readers.stripredundant=stripredundant
end
-readers.stripredundant=stripredundant
function readers.getcomponents(fontdata)
local resources=fontdata.resources
if resources then
@@ -17355,8 +17461,7 @@ readers.unifymissing=unifymissing
function readers.rehash(fontdata,hashmethod)
if not (fontdata and fontdata.glyphs) then
return
- end
- if hashmethod=="indices" then
+ elseif hashmethod=="indices" then
fontdata.hashmethod="indices"
elseif hashmethod=="names" then
fontdata.hashmethod="names"
@@ -19108,10 +19213,10 @@ end
expandlookups(sublookups,sequences)
end
-end --- [luaotfload, fontloader-2022-02-24.lua scope for “font-oup”] ---
+end --- [luaotfload, fontloader-2022-06-15.lua scope for “font-oup”] ---
-do --- [luaotfload, fontloader-2022-02-24.lua scope for “font-otl” 67078f58bc1a612e4646523538a4e3eb] ---
+do --- [luaotfload, fontloader-2022-06-15.lua scope for “font-otl” 308b1aab04bc131da7eb8e8c3b0471d4] ---
if not modules then modules={} end modules ['font-otl']={
version=1.001,
@@ -19139,7 +19244,7 @@ local trace_defining=false registertracker("fonts.defining",function(v) trace_d
local report_otf=logs.reporter("fonts","otf loading")
local fonts=fonts
local otf=fonts.handlers.otf
-otf.version=3.119
+otf.version=3.120
otf.cache=containers.define("fonts","otl",otf.version,true)
otf.svgcache=containers.define("fonts","svg",otf.version,true)
otf.pngcache=containers.define("fonts","png",otf.version,true)
@@ -19839,10 +19944,10 @@ otf.coverup={
end
}
-end --- [luaotfload, fontloader-2022-02-24.lua scope for “font-otl”] ---
+end --- [luaotfload, fontloader-2022-06-15.lua scope for “font-otl”] ---
-do --- [luaotfload, fontloader-2022-02-24.lua scope for “font-oto” 9febc4d75d17a543cd73fb17918f7307] ---
+do --- [luaotfload, fontloader-2022-06-15.lua scope for “font-oto” 9febc4d75d17a543cd73fb17918f7307] ---
if not modules then modules={} end modules ['font-oto']={
version=1.001,
@@ -20311,10 +20416,10 @@ registerotffeature {
}
otf.basemodeinitializer=featuresinitializer
-end --- [luaotfload, fontloader-2022-02-24.lua scope for “font-oto”] ---
+end --- [luaotfload, fontloader-2022-06-15.lua scope for “font-oto”] ---
-do --- [luaotfload, fontloader-2022-02-24.lua scope for “font-otj” b2c165bd6771a57633f992d07384b739] ---
+do --- [luaotfload, fontloader-2022-06-15.lua scope for “font-otj” b2c165bd6771a57633f992d07384b739] ---
if not modules then modules={} end modules ['font-otj']={
version=1.001,
@@ -21807,10 +21912,10 @@ function injections.handler(head,where)
end
end
-end --- [luaotfload, fontloader-2022-02-24.lua scope for “font-otj”] ---
+end --- [luaotfload, fontloader-2022-06-15.lua scope for “font-otj”] ---
-do --- [luaotfload, fontloader-2022-02-24.lua scope for “font-ota” 2bb12d708e35bc05443eba791e2554e7] ---
+do --- [luaotfload, fontloader-2022-06-15.lua scope for “font-ota” 2bb12d708e35bc05443eba791e2554e7] ---
if not modules then modules={} end modules ['font-ota']={
version=1.001,
@@ -22304,10 +22409,10 @@ directives.register("otf.analyze.useunicodemarks",function(v)
analyzers.useunicodemarks=v
end)
-end --- [luaotfload, fontloader-2022-02-24.lua scope for “font-ota”] ---
+end --- [luaotfload, fontloader-2022-06-15.lua scope for “font-ota”] ---
-do --- [luaotfload, fontloader-2022-02-24.lua scope for “font-ots” 55316a605d11a1d07d38795224c90a63] ---
+do --- [luaotfload, fontloader-2022-06-15.lua scope for “font-ots” 55316a605d11a1d07d38795224c90a63] ---
if not modules then modules={} end modules ['font-ots']={
version=1.001,
@@ -25967,10 +26072,10 @@ registerotffeature {
},
}
-end --- [luaotfload, fontloader-2022-02-24.lua scope for “font-ots”] ---
+end --- [luaotfload, fontloader-2022-06-15.lua scope for “font-ots”] ---
-do --- [luaotfload, fontloader-2022-02-24.lua scope for “font-osd” a67b6fb465e7a8b9ecf7c6bbf8dfda03] ---
+do --- [luaotfload, fontloader-2022-06-15.lua scope for “font-osd” 9b5337b0051b8e42b6c8329127c59794] ---
if not modules then modules={} end modules ['font-osd']={
version=1.001,
@@ -25979,6 +26084,14 @@ if not modules then modules={} end modules ['font-osd']={
copyright="TAT Zetwerk / PRAGMA ADE / ConTeXt Development Team",
license="see context related readme files"
}
+local experiment1=false
+local experiment2=false
+local experiment2b1=false
+local experiment2b2=false
+experiments.register("fonts.indic.experiment1",function(v) experiment1=v end)
+experiments.register("fonts.indic.experiment2",function(v) experiment2=v end)
+experiments.register("fonts.indic.experiment2b1",function(v) experiment2b1=v end)
+experiments.register("fonts.indic.experiment2b2",function(v) experiment2b2=v end)
local insert,remove,imerge,copy,tohash=table.insert,table.remove,table.imerge,table.copy,table.tohash
local next,type,rawget=next,type,rawget
local formatters=string.formatters
@@ -27508,7 +27621,7 @@ local function reorder_two(head,start,stop,font,attr,nbspaces)
local subpos=nil
local postpos=nil
reorderreph.coverage={}
- rephbase[font]={}
+ rephbase[font]={}
for i=1,#seqsubset do
local subset=seqsubset[i]
local kind=subset[1]
@@ -27685,7 +27798,7 @@ local function reorder_two(head,start,stop,font,attr,nbspaces)
logprocess("reorder two, handle nbsp")
end
end
- else
+ else
local last=getnext(stop)
while current~=last do
local next=getnext(current)
@@ -27748,7 +27861,7 @@ local function reorder_two(head,start,stop,font,attr,nbspaces)
logprocess("reorder two, handle matra")
end
end
- if not moved[current] and dependent_vowel[char] then
+ if dependent_vowel[char] then
if pre_mark[char] then
moved[current]=true
local prev,next=getboth(current)
@@ -27927,8 +28040,8 @@ local function analyze_next_chars_one(c,font,variant)
if not n then
return c
end
+ local v=ischar(n,font)
if variant==1 then
- local v=ischar(n,font)
if v and nukta[v] then
n=getnext(n)
if n then
@@ -27961,7 +28074,6 @@ local function analyze_next_chars_one(c,font,variant)
end
end
elseif variant==2 then
- local v=ischar(n,font)
if v and nukta[v] then
c=n
end
@@ -27985,11 +28097,11 @@ local function analyze_next_chars_one(c,font,variant)
end
end
end
- local n=getnext(c)
+ n=getnext(c)
if not n then
return c
end
- local v=ischar(n,font)
+ v=ischar(n,font)
if not v then
return c
end
@@ -28094,12 +28206,11 @@ local function analyze_next_chars_one(c,font,variant)
end
end
local function analyze_next_chars_two(c,font)
- local n,v
- n=getnext(c)
+ local n=getnext(c)
if not n then
return c
end
- v=ischar(n,font)
+ local v=ischar(n,font)
if v and nukta[v] then
c=n
end
@@ -28605,10 +28716,10 @@ for i=1,nofscripts do
methods[scripts_two[i]]=method_two
end
-end --- [luaotfload, fontloader-2022-02-24.lua scope for “font-osd”] ---
+end --- [luaotfload, fontloader-2022-06-15.lua scope for “font-osd”] ---
-do --- [luaotfload, fontloader-2022-02-24.lua scope for “font-ocl” 2a377351ae23c339764ec8ce2e8e9164] ---
+do --- [luaotfload, fontloader-2022-06-15.lua scope for “font-ocl” 2a377351ae23c339764ec8ce2e8e9164] ---
if not modules then modules={} end modules ['font-ocl']={
version=1.001,
@@ -29156,10 +29267,10 @@ if context then
}
end
-end --- [luaotfload, fontloader-2022-02-24.lua scope for “font-ocl”] ---
+end --- [luaotfload, fontloader-2022-06-15.lua scope for “font-ocl”] ---
-do --- [luaotfload, fontloader-2022-02-24.lua scope for “font-otc” 582295d3d1e44cd4a31e8bbc1156f7c1] ---
+do --- [luaotfload, fontloader-2022-06-15.lua scope for “font-otc” 57f5270b894e40efa93149c7d3fb0209] ---
if not modules then modules={} end modules ['font-otc']={
version=1.001,
@@ -29276,7 +29387,7 @@ local function validspecification(specification,name)
return specification,name
end
end
-local function addfeature(data,feature,specifications)
+local function addfeature(data,feature,specifications,prepareonly)
if not specifications then
report_otf("missing specification")
return
@@ -29575,8 +29686,6 @@ local function addfeature(data,feature,specifications)
local rules=list.rules
local coverage={}
if rules then
- local rulehash={}
- local rulesize=0
local lookuptype=types[featuretype]
for nofrules=1,#rules do
local rule=rules[nofrules]
@@ -29607,6 +29716,14 @@ local function addfeature(data,feature,specifications)
local lookups=rule.lookups or false
local subtype=nil
if lookups and sublookups then
+ if #lookups>0 then
+ local ns=stop-start+1
+ for i=1,ns do
+ if lookups[i]==nil then
+ lookups[i]=0
+ end
+ end
+ end
local l={}
for k,v in sortedhash(lookups) do
local t=type(v)
@@ -29654,8 +29771,7 @@ local function addfeature(data,feature,specifications)
hashed[i]=t
end
sequence=hashed
- rulesize=rulesize+1
- rulehash[rulesize]={
+ local ruleset={
nofrules,
lookuptype,
sequence,
@@ -29667,8 +29783,15 @@ local function addfeature(data,feature,specifications)
}
for unic in sortedhash(sequence[start]) do
local cu=coverage[unic]
- if not cu then
- coverage[unic]=rulehash
+ if cu then
+ local n=cu.n+1
+ cu[n]=ruleset
+ cu.n=n
+ else
+ coverage[unic]={
+ ruleset,
+ n=1,
+ }
end
end
sequence.n=nofsequences
@@ -29676,7 +29799,6 @@ local function addfeature(data,feature,specifications)
end
end
end
- rulehash.n=rulesize
end
return coverage
end
@@ -29897,8 +30019,11 @@ local function addfeature(data,feature,specifications)
order=featureorder,
[stepkey]=steps,
nofsteps=nofsteps,
- type=types[featuretype],
+ type=specification.handler or types[featuretype],
}
+ if prepareonly then
+ return sequence
+ end
end
end
if sequence then
@@ -29969,10 +30094,10 @@ end
otf.enhancers.enhance=enhance
otf.enhancers.register("check extra features",enhance)
-end --- [luaotfload, fontloader-2022-02-24.lua scope for “font-otc”] ---
+end --- [luaotfload, fontloader-2022-06-15.lua scope for “font-otc”] ---
-do --- [luaotfload, fontloader-2022-02-24.lua scope for “font-onr” 6d161533f3437435e12a0ad64866df44] ---
+do --- [luaotfload, fontloader-2022-06-15.lua scope for “font-onr” 6d161533f3437435e12a0ad64866df44] ---
if not modules then modules={} end modules ['font-onr']={
version=1.001,
@@ -30345,10 +30470,10 @@ function readers.getinfo(filename)
end
end
-end --- [luaotfload, fontloader-2022-02-24.lua scope for “font-onr”] ---
+end --- [luaotfload, fontloader-2022-06-15.lua scope for “font-onr”] ---
-do --- [luaotfload, fontloader-2022-02-24.lua scope for “font-one” bd39d42055a44ca2002f8ddbbbbf27c3] ---
+do --- [luaotfload, fontloader-2022-06-15.lua scope for “font-one” bd39d42055a44ca2002f8ddbbbbf27c3] ---
if not modules then modules={} end modules ['font-one']={
version=1.001,
@@ -31063,10 +31188,10 @@ registerafmenhancer("normalize features",enhance_normalize_features)
registerafmenhancer("check extra features",otfenhancers.enhance)
registerafmenhancer("fix names",enhance_fix_names)
-end --- [luaotfload, fontloader-2022-02-24.lua scope for “font-one”] ---
+end --- [luaotfload, fontloader-2022-06-15.lua scope for “font-one”] ---
-do --- [luaotfload, fontloader-2022-02-24.lua scope for “font-afk” 9da14e0fb22129c053acc599d1312544] ---
+do --- [luaotfload, fontloader-2022-06-15.lua scope for “font-afk” 9da14e0fb22129c053acc599d1312544] ---
if not modules then modules={} end modules ['font-afk']={
version=1.001,
@@ -31233,10 +31358,10 @@ fonts.handlers.afm.helpdata={
}
}
-end --- [luaotfload, fontloader-2022-02-24.lua scope for “font-afk”] ---
+end --- [luaotfload, fontloader-2022-06-15.lua scope for “font-afk”] ---
-do --- [luaotfload, fontloader-2022-02-24.lua scope for “fonts-tfm” f0eb5e2a8068b17ad401bb7efdba1630] ---
+do --- [luaotfload, fontloader-2022-06-15.lua scope for “fonts-tfm” f0eb5e2a8068b17ad401bb7efdba1630] ---
if not modules then modules={} end modules ['luatex-fonts-tfm']={
version=1.001,
@@ -31751,10 +31876,10 @@ registertfmfeature {
}
}
-end --- [luaotfload, fontloader-2022-02-24.lua scope for “fonts-tfm”] ---
+end --- [luaotfload, fontloader-2022-06-15.lua scope for “fonts-tfm”] ---
-do --- [luaotfload, fontloader-2022-02-24.lua scope for “font-lua” 1fbfdf7b689b2bdfd0e3bb9bf74ce136] ---
+do --- [luaotfload, fontloader-2022-06-15.lua scope for “font-lua” 1fbfdf7b689b2bdfd0e3bb9bf74ce136] ---
if not modules then modules={} end modules ['font-lua']={
version=1.001,
@@ -31794,10 +31919,10 @@ function readers.lua(specification)
return check_lua(specification,fullname)
end
-end --- [luaotfload, fontloader-2022-02-24.lua scope for “font-lua”] ---
+end --- [luaotfload, fontloader-2022-06-15.lua scope for “font-lua”] ---
-do --- [luaotfload, fontloader-2022-02-24.lua scope for “font-def” b9d908c2338b7dc443ce9d1e9fcb7139] ---
+do --- [luaotfload, fontloader-2022-06-15.lua scope for “font-def” b9d908c2338b7dc443ce9d1e9fcb7139] ---
if not modules then modules={} end modules ['font-def']={
version=1.001,
@@ -32197,10 +32322,10 @@ if not context then
callbacks.register('define_font',definers.read,"definition of fonts (tfmdata preparation)")
end
-end --- [luaotfload, fontloader-2022-02-24.lua scope for “font-def”] ---
+end --- [luaotfload, fontloader-2022-06-15.lua scope for “font-def”] ---
-do --- [luaotfload, fontloader-2022-02-24.lua scope for “font-shp” a40862fe382d26c1f3753431254bcfdd] ---
+do --- [luaotfload, fontloader-2022-06-15.lua scope for “font-shp” a40862fe382d26c1f3753431254bcfdd] ---
if not modules then modules={} end modules ['font-shp']={
version=1.001,
@@ -32565,10 +32690,10 @@ callback.register("glyph_stream_provider",function(id,index,mode)
return ""
end)
-end --- [luaotfload, fontloader-2022-02-24.lua scope for “font-shp”] ---
+end --- [luaotfload, fontloader-2022-06-15.lua scope for “font-shp”] ---
-do --- [luaotfload, fontloader-2022-02-24.lua scope for “fonts-def” f435e0875f203f343157baeff876ec9c] ---
+do --- [luaotfload, fontloader-2022-06-15.lua scope for “fonts-def” f435e0875f203f343157baeff876ec9c] ---
if not modules then modules={} end modules ['luatex-fonts-def']={
version=1.001,
@@ -32649,10 +32774,10 @@ function fonts.definers.applypostprocessors(tfmdata)
return tfmdata
end
-end --- [luaotfload, fontloader-2022-02-24.lua scope for “fonts-def”] ---
+end --- [luaotfload, fontloader-2022-06-15.lua scope for “fonts-def”] ---
-do --- [luaotfload, fontloader-2022-02-24.lua scope for “fonts-ext” 32013cbc5d5d336be8b1d1e5879d86c4] ---
+do --- [luaotfload, fontloader-2022-06-15.lua scope for “fonts-ext” 32013cbc5d5d336be8b1d1e5879d86c4] ---
if not modules then modules={} end modules ['luatex-fonts-ext']={
version=1.001,
@@ -32838,10 +32963,10 @@ registerotffeature {
}
}
-end --- [luaotfload, fontloader-2022-02-24.lua scope for “fonts-ext”] ---
+end --- [luaotfload, fontloader-2022-06-15.lua scope for “fonts-ext”] ---
-do --- [luaotfload, fontloader-2022-02-24.lua scope for “font-imp-tex” ceb087ef6fa2f89aed7179f60ddf8f35] ---
+do --- [luaotfload, fontloader-2022-06-15.lua scope for “font-imp-tex” ceb087ef6fa2f89aed7179f60ddf8f35] ---
if not modules then modules={} end modules ['font-imp-tex']={
version=1.001,
@@ -32940,10 +33065,10 @@ registerotffeature {
description="arabic digits",
}
-end --- [luaotfload, fontloader-2022-02-24.lua scope for “font-imp-tex”] ---
+end --- [luaotfload, fontloader-2022-06-15.lua scope for “font-imp-tex”] ---
-do --- [luaotfload, fontloader-2022-02-24.lua scope for “font-imp-ligatures” 26ffcf089391445f7af59536c8814364] ---
+do --- [luaotfload, fontloader-2022-06-15.lua scope for “font-imp-ligatures” 250f6f4488ee770c23177afb2ff75676] ---
if not modules then modules={} end modules ['font-imp-ligatures']={
version=1.001,
@@ -33038,12 +33163,12 @@ local function blockligatures(str)
before=before,
current={ one,two },
after=after,
- lookups={ 1 },
+ lookups={ 1,false },
}
revert[new]={
current={ one,zwj },
after={ two },
- lookups={ 1 },
+ lookups={ 1,false },
}
end
end
@@ -33057,10 +33182,10 @@ if context then
}
end
-end --- [luaotfload, fontloader-2022-02-24.lua scope for “font-imp-ligatures”] ---
+end --- [luaotfload, fontloader-2022-06-15.lua scope for “font-imp-ligatures”] ---
-do --- [luaotfload, fontloader-2022-02-24.lua scope for “font-imp-italics” defcb415bc1e0a0999b27773902adc18] ---
+do --- [luaotfload, fontloader-2022-06-15.lua scope for “font-imp-italics” defcb415bc1e0a0999b27773902adc18] ---
if not modules then modules={} end modules ['font-imp-italics']={
version=1.001,
@@ -33164,10 +33289,10 @@ if context then
registerafmfeature(dimensions_specification)
end
-end --- [luaotfload, fontloader-2022-02-24.lua scope for “font-imp-italics”] ---
+end --- [luaotfload, fontloader-2022-06-15.lua scope for “font-imp-italics”] ---
-do --- [luaotfload, fontloader-2022-02-24.lua scope for “font-imp-effects” d05997c1826355548ec9aec1346f9f23] ---
+do --- [luaotfload, fontloader-2022-06-15.lua scope for “font-imp-effects” d05997c1826355548ec9aec1346f9f23] ---
if not modules then modules={} end modules ['font-imp-effects']={
version=1.001,
@@ -33524,10 +33649,10 @@ local specification={
registerotffeature(specification)
registerafmfeature(specification)
-end --- [luaotfload, fontloader-2022-02-24.lua scope for “font-imp-effects”] ---
+end --- [luaotfload, fontloader-2022-06-15.lua scope for “font-imp-effects”] ---
-do --- [luaotfload, fontloader-2022-02-24.lua scope for “fonts-lig” fbd251eea3810a43a8d5542319361d68] ---
+do --- [luaotfload, fontloader-2022-06-15.lua scope for “fonts-lig” fbd251eea3810a43a8d5542319361d68] ---
fonts.handlers.otf.addfeature {
@@ -35596,10 +35721,10 @@ fonts.handlers.otf.addfeature {
["type"]="ligature",
}
-end --- [luaotfload, fontloader-2022-02-24.lua scope for “fonts-lig”] ---
+end --- [luaotfload, fontloader-2022-06-15.lua scope for “fonts-lig”] ---
-do --- [luaotfload, fontloader-2022-02-24.lua scope for “fonts-gbn” 34e4543a02f6fbc8c2ade896cb6dc7df] ---
+do --- [luaotfload, fontloader-2022-06-15.lua scope for “fonts-gbn” 34e4543a02f6fbc8c2ade896cb6dc7df] ---
if not modules then modules={} end modules ['luatex-fonts-gbn']={
version=1.001,
@@ -35864,7 +35989,7 @@ function nodes.simple_font_handler(head,groupcode,size,packtype,direction)
return head
end
-end --- [luaotfload, fontloader-2022-02-24.lua scope for “fonts-gbn”] ---
+end --- [luaotfload, fontloader-2022-06-15.lua scope for “fonts-gbn”] ---
--- vim:ft=lua:sw=2:ts=8:et:tw=79
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-dsp.lua b/macros/luatex/generic/luaotfload/fontloader-font-dsp.lua
index 7028f7c087..d036783284 100644
--- a/macros/luatex/generic/luaotfload/fontloader-font-dsp.lua
+++ b/macros/luatex/generic/luaotfload/fontloader-font-dsp.lua
@@ -2515,7 +2515,7 @@ do
local scriptoffset = tableoffset + readushort(f)
local featureoffset = tableoffset + readushort(f)
local lookupoffset = tableoffset + readushort(f)
- local variationsoffset = version > 0x00010000 and (tableoffset + readulong(f)) or 0
+ local variationsoffset = version > 0x00010000 and readulong(f) or 0
if not scriptoffset then
return
end
@@ -2541,7 +2541,7 @@ do
end
--
if variationsoffset > 0 then
- loadvariations(f,fontdata,variationsoffset,lookuptypes,featurehash,featureorder)
+ loadvariations(f,fontdata,tableoffset + variationsoffset,lookuptypes,featurehash,featureorder)
end
end
end
@@ -3820,6 +3820,7 @@ function readers.hvar(f,fontdata,specification)
local variations = { }
local innerindex = { } -- size is mapcount
local outerindex = { } -- size is mapcount
+ local deltas = { }
if variationoffset > 0 then
regions, deltas = readvariationdata(f,variationoffset,factors)
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-imp-ligatures.lua b/macros/luatex/generic/luaotfload/fontloader-font-imp-ligatures.lua
index 091eb5d4b4..02833707ba 100644
--- a/macros/luatex/generic/luaotfload/fontloader-font-imp-ligatures.lua
+++ b/macros/luatex/generic/luaotfload/fontloader-font-imp-ligatures.lua
@@ -104,14 +104,14 @@ local function blockligatures(str)
before = before,
current = { one, two },
after = after,
- lookups = { 1 }, -- not shared !
+ lookups = { 1, false }, -- not shared !
}
revert[new] = {
-- before = before,
current = { one, zwj },
-- after = { two, unpack(after) },
after = { two },
- lookups = { 1 }, -- not shared !
+ lookups = { 1, false }, -- not shared !
}
end
end
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-map.lua b/macros/luatex/generic/luaotfload/fontloader-font-map.lua
index c983ea9634..4aa937ed16 100644
--- a/macros/luatex/generic/luaotfload/fontloader-font-map.lua
+++ b/macros/luatex/generic/luaotfload/fontloader-font-map.lua
@@ -253,9 +253,9 @@ function mappings.addtounicode(data,filename,checklookups,forceligatures)
local usedmap = cidinfo and fonts.cid.getmap(cidinfo)
local uparser = makenameparser() -- hm, every time?
if usedmap then
- oparser = usedmap and makenameparser(cidinfo.ordering)
- cidnames = usedmap.names
- cidcodes = usedmap.unicodes
+ oparser = usedmap and makenameparser(cidinfo.ordering)
+ cidnames = usedmap.names
+ cidcodes = usedmap.unicodes
end
local ns = 0
local nl = 0
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-osd.lua b/macros/luatex/generic/luaotfload/fontloader-font-osd.lua
index 34c0472903..d169faf64d 100644
--- a/macros/luatex/generic/luaotfload/fontloader-font-osd.lua
+++ b/macros/luatex/generic/luaotfload/fontloader-font-osd.lua
@@ -6,6 +6,16 @@ if not modules then modules = { } end modules ['font-osd'] = { -- script devanag
license = "see context related readme files"
}
+local experiment1 = false
+local experiment2 = false
+local experiment2b1 = false
+local experiment2b2 = false
+
+experiments.register("fonts.indic.experiment1", function(v) experiment1 = v end)
+experiments.register("fonts.indic.experiment2", function(v) experiment2 = v end)
+experiments.register("fonts.indic.experiment2b1", function(v) experiment2b1 = v end)
+experiments.register("fonts.indic.experiment2b2", function(v) experiment2b2 = v end)
+
-- we need to check nbsphash (context only)
-- A few remarks:
@@ -1382,13 +1392,16 @@ local function reorder_one(head,start,stop,font,attr,nbspaces)
end
if reph or vattu then
+-- print(">>> has reph or vattu")
local current = start
local cns = nil
local done = false
while current ~= stop do
+-- print("\t>>> current ~= stop yet")
local c = current
local n = getnext(current)
if ra[getchar(current)] and halant[getchar(n)] then
+-- print("\t\t>>> current ra; next halant")
c = n
n = getnext(n)
local b, bn = base, base
@@ -1402,6 +1415,7 @@ local function reorder_one(head,start,stop,font,attr,nbspaces)
if getstate(current,s_rphf) then
-- position Reph (Ra + H) after post-base 'matra' (if any) since these
-- become marks on the 'matra', not on the base glyph
+-- print("\t\t\t>>> ra + halant form → reph")
if b ~= current then
if current == start then
if head == start then
@@ -1421,6 +1435,7 @@ local function reorder_one(head,start,stop,font,attr,nbspaces)
end
elseif cns and getnext(cns) ~= current then -- todo: optimize next
-- position below-base Ra (vattu) following the consonants on which it is placed (either the base consonant or one of the pre-base consonants)
+-- print("\t\t\t>>> ra below base (vattu) → rkrf")
local cp = getprev(current)
local cnsn = getnext(cns)
setlink(cp,n)
@@ -1434,14 +1449,17 @@ local function reorder_one(head,start,stop,font,attr,nbspaces)
current = getprev(n)
end
else
+-- print("\t\t>>> NOT! current ra; next halant")
local char = getchar(current)
if consonant[char] then
+-- print("\t\t\t>>> is consonant")
cns = current
local next = getnext(cns)
if halant[getchar(next)] then
cns = next
end
if not vatucache[char] then
+-- print("\t\t\t\t>>> is in vatucache")
next = getnext(cns)
while dependent_vowel[getchar(next)] do
cns = next
@@ -1449,6 +1467,7 @@ local function reorder_one(head,start,stop,font,attr,nbspaces)
end
end
elseif char == c_nbsp then
+-- print("\t\t\t>>> is nbsp")
nbspaces = nbspaces + 1
cns = current
local next = getnext(cns)
@@ -1917,6 +1936,8 @@ local function reorder_two(head,start,stop,font,attr,nbspaces) -- maybe do a pas
reorderreph.coverage = { } -- use local
rephbase[font] = { } -- use local
+-- print("!!!!!! reorder two ")
+
for i=1,#seqsubset do
-- this can be done more efficient, the last test and less getnext
@@ -2104,6 +2125,7 @@ local function reorder_two(head,start,stop,font,attr,nbspaces) -- maybe do a pas
end
end
else -- not Stand Alone cluster
+-- print("!!!! not standalone cluster")
local last = getnext(stop)
while current ~= last do -- find base consonant
local next = getnext(current)
@@ -2173,7 +2195,10 @@ local function reorder_two(head,start,stop,font,attr,nbspaces) -- maybe do a pas
end
end
--
- if not moved[current] and dependent_vowel[char] then
+-- print("char: " .. char)
+-- if not moved[current] and dependent_vowel[char] then
+ if dependent_vowel[char] then
+-- print(">>!! dependent vowel")
if pre_mark[char] then -- or: if before_main or before_half
moved[current] = true
-- can be helper to remove one node
@@ -2384,8 +2409,8 @@ local function analyze_next_chars_one(c,font,variant) -- skip one dependent vowe
if not n then
return c
end
+ local v = ischar(n,font)
if variant == 1 then
- local v = ischar(n,font)
if v and nukta[v] then
n = getnext(n)
if n then
@@ -2418,7 +2443,6 @@ local function analyze_next_chars_one(c,font,variant) -- skip one dependent vowe
end
end
elseif variant == 2 then
- local v = ischar(n,font)
if v and nukta[v] then
c = n
end
@@ -2443,11 +2467,11 @@ local function analyze_next_chars_one(c,font,variant) -- skip one dependent vowe
end
end
-- c = ms_matra(c)
- local n = getnext(c)
+ n = getnext(c)
if not n then
return c
end
- local v = ischar(n,font)
+ v = ischar(n,font)
if not v then
return c
end
@@ -2555,13 +2579,22 @@ local function analyze_next_chars_one(c,font,variant) -- skip one dependent vowe
end
end
+-- Consonant syllable:
+--
+-- { C + [ N ] + < H + [ < ZWNJ | ZWJ > ] | < ZWNJ | ZWJ > + H > }
+-- + C
+-- + [ N ]
+-- + [ A ]
+-- + [ < H + [ < ZWNJ|ZWJ > ] | { M } + [ N ] + [ H ] > ]
+-- + [ SM ]
+-- + [ ( VD ) ]
+
local function analyze_next_chars_two(c,font)
- local n, v
- n = getnext(c)
+ local n = getnext(c)
if not n then
return c
end
- v = ischar(n,font)
+ local v = ischar(n,font)
if v and nukta[v] then
c = n
end
@@ -2677,6 +2710,10 @@ local function analyze_next_chars_two(c,font)
for k=1,#vowels do
local v = vowels[k]
if pre_mark[v] and not already_pre_mark then
+-- print(">>> pre_mark")
+-- if dependent_vowel[v] then
+-- print(">>>> dependent vowel")
+-- end
already_pre_mark = true
elseif above_mark[v] and not already_above_mark then
already_above_mark = true
@@ -3031,12 +3068,15 @@ local function method_two(head,font,attr)
end
end
if independent_vowel[char] then
+-- print("!!>>> independent_vowel")
-- vowel-based syllable: [Ra+H]+V+[N]+[<[<ZWJ|ZWNJ>]+H+C|ZWJ+C>]+[{M}+[N]+[H]]+[SM]+[(VD)]
current = analyze_next_chars_one(c,font,1)
syllableend = current
else
+-- print("!!>>> dependent vowel")
local standalone = char == c_nbsp
if standalone then
+-- print("!!>>> standalone")
nbspaces = nbspaces + 1
local p = getprev(current)
if not p then
@@ -3050,10 +3090,12 @@ local function method_two(head,font,attr)
end
end
if standalone then
+-- print("!!>>>>>>> next standalone")
-- Stand Alone cluster (at the start of the word only): #[Ra+H]+NBSP+[N]+[<[<ZWJ|ZWNJ>]+H+C>]+[{M}+[N]+[H]]+[SM]+[(VD)]
current = analyze_next_chars_one(c,font,2)
syllableend = current
elseif consonant[getchar(current)] then
+-- print("!!>>>>>>> a consonant")
-- WHY current INSTEAD OF c ?
-- Consonant syllable: {C+[N]+<H+[<ZWNJ|ZWJ>]|<ZWNJ|ZWJ>+H>} + C+[N]+[A] + [< H+[<ZWNJ|ZWJ>] | {M}+[N]+[H]>]+[SM]+[(VD)]
current = analyze_next_chars_two(current,font) -- not c !
@@ -3062,6 +3104,7 @@ local function method_two(head,font,attr)
end
end
if syllableend then
+-- print("!!!>>> syllable end")
syllabe = syllabe + 1
local c = syllablestart
local n = getnext(syllableend)
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-otc.lua b/macros/luatex/generic/luaotfload/fontloader-font-otc.lua
index 2c955dbce9..67b77b1113 100644
--- a/macros/luatex/generic/luaotfload/fontloader-font-otc.lua
+++ b/macros/luatex/generic/luaotfload/fontloader-font-otc.lua
@@ -130,7 +130,7 @@ local function validspecification(specification,name)
end
end
-local function addfeature(data,feature,specifications)
+local function addfeature(data,feature,specifications,prepareonly)
-- todo: add some validator / check code so that we're more tolerant to
-- user errors
@@ -226,6 +226,9 @@ local function addfeature(data,feature,specifications)
local stepkey = coverup.stepkey
local register = coverup.register
+ -- todo: directly pass a coverage i.e. for privates that later will be
+ -- set
+
local function prepare_substitution(list,featuretype,nocheck)
local coverage = { }
local cover = coveractions[featuretype]
@@ -461,13 +464,13 @@ local function addfeature(data,feature,specifications)
return false
end
+ -- 0 == remove, false = ignore (remove is default)
+
local function prepare_chain(list,featuretype,sublookups,nocheck)
-- todo: coveractions
local rules = list.rules
local coverage = { }
if rules then
- local rulehash = { }
- local rulesize = 0
local lookuptype = types[featuretype]
for nofrules=1,#rules do
local rule = rules[nofrules]
@@ -498,6 +501,15 @@ local function addfeature(data,feature,specifications)
local lookups = rule.lookups or false
local subtype = nil
if lookups and sublookups then
+ -- inspect(lookups)
+ if #lookups > 0 then
+ local ns = stop - start + 1
+ for i=1,ns do
+ if lookups[i] == nil then
+ lookups[i] = 0
+ end
+ end
+ end
local l = { }
for k, v in sortedhash(lookups) do
local t = type(v)
@@ -535,6 +547,7 @@ local function addfeature(data,feature,specifications)
if nofsequences > 0 then -- we merge coverage into one
-- we copy as we can have different fonts
if hassteps(lookups) then
+ -- sequence is the before|current|after match list
local hashed = { }
for i=1,nofsequences do
local t = { }
@@ -547,9 +560,9 @@ local function addfeature(data,feature,specifications)
end
hashed[i] = t
end
+ -- hashed is the before|current|after match hash
sequence = hashed
- rulesize = rulesize + 1
- rulehash[rulesize] = {
+ local ruleset = {
nofrules, -- 1
lookuptype, -- 2
sequence, -- 3
@@ -561,8 +574,15 @@ local function addfeature(data,feature,specifications)
}
for unic in sortedhash(sequence[start]) do
local cu = coverage[unic]
- if not cu then
- coverage[unic] = rulehash -- can now be done cleaner i think
+ if cu then
+ local n = cu.n + 1
+ cu[n] = ruleset
+ cu.n = n
+ else
+ coverage[unic] = {
+ ruleset,
+ n = 1,
+ }
end
end
sequence.n = nofsequences
@@ -571,7 +591,6 @@ local function addfeature(data,feature,specifications)
end
end
end
- rulehash.n = rulesize
end
return coverage
end
@@ -811,8 +830,11 @@ local function addfeature(data,feature,specifications)
order = featureorder,
[stepkey] = steps,
nofsteps = nofsteps,
- type = types[featuretype],
+ type = specification.handler or types[featuretype],
}
+ if prepareonly then
+ return sequence
+ end
end
end
@@ -900,6 +922,23 @@ local function enhance(data,filename,raw)
end
end
+-- local function enhance(data,filename,raw)
+-- local first = 1
+-- local last = #extrafeatures
+-- while true do
+-- for slot=first,last do
+-- local specification = extrafeatures[slot]
+-- addfeature(data,specification.name,specification)
+-- end
+-- if #extrafeatures > last then
+-- first = last + 1
+-- last = #extrafeatures
+-- else
+-- break
+-- end
+-- end
+-- end
+
otf.enhancers.enhance = enhance
otf.enhancers.register("check extra features",enhance)
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-otl.lua b/macros/luatex/generic/luaotfload/fontloader-font-otl.lua
index ae2dda4f39..f36e533ca0 100644
--- a/macros/luatex/generic/luaotfload/fontloader-font-otl.lua
+++ b/macros/luatex/generic/luaotfload/fontloader-font-otl.lua
@@ -52,7 +52,7 @@ local report_otf = logs.reporter("fonts","otf loading")
local fonts = fonts
local otf = fonts.handlers.otf
-otf.version = 3.119 -- beware: also sync font-mis.lua and in mtx-fonts
+otf.version = 3.120 -- beware: also sync font-mis.lua and in mtx-fonts
otf.cache = containers.define("fonts", "otl", otf.version, true)
otf.svgcache = containers.define("fonts", "svg", otf.version, true)
otf.pngcache = containers.define("fonts", "png", otf.version, true)
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-otr.lua b/macros/luatex/generic/luaotfload/fontloader-font-otr.lua
index 286367ed9e..339de109f8 100644
--- a/macros/luatex/generic/luaotfload/fontloader-font-otr.lua
+++ b/macros/luatex/generic/luaotfload/fontloader-font-otr.lua
@@ -2499,15 +2499,15 @@ function readers.getinfo(filename,specification) -- string, nil|number|table
end
end
-function readers.rehash(fontdata,hashmethod)
+function readers.rehash() -- fontdata,hashmethod
report("the %a helper is not yet implemented","rehash")
end
-function readers.checkhash(fontdata)
+function readers.checkhash() --fontdata
report("the %a helper is not yet implemented","checkhash")
end
-function readers.pack(fontdata,hashmethod)
+function readers.pack() -- fontdata,hashmethod
report("the %a helper is not yet implemented","pack")
end
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-oup.lua b/macros/luatex/generic/luaotfload/fontloader-font-oup.lua
index 3bd2fe4828..248aad04d2 100644
--- a/macros/luatex/generic/luaotfload/fontloader-font-oup.lua
+++ b/macros/luatex/generic/luaotfload/fontloader-font-oup.lua
@@ -10,6 +10,7 @@ local next, type = next, type
local P, R, S = lpeg.P, lpeg.R, lpeg.S
local lpegmatch = lpeg.match
local insert, remove, copy, unpack = table.insert, table.remove, table.copy, table.unpack
+local find = string.find
local formatters = string.formatters
local sortedkeys = table.sortedkeys
@@ -944,15 +945,18 @@ local function unifyglyphs(fontdata,usenames)
return indices, names
end
-local p_crappyname do
+local stripredundant do
+
local p_hex = R("af","AF","09")
local p_digit = R("09")
local p_done = S("._-")^0 + P(-1)
+ -- local p_style = P(".ss") * p_digit * p_digit * P(-1)
+ local p_style = P(".")
local p_alpha = R("az","AZ")
local p_ALPHA = R("AZ")
- p_crappyname = (
+ local p_crappyname = (
-- (P("uni") + P("UNI") + P("Uni") + P("U") + P("u"))
lpeg.utfchartabletopattern({ "uni", "u" },true)
* S("Xx_")^0
@@ -980,56 +984,182 @@ local p_crappyname do
* P(1)^1
) * p_done
-end
+ -- In context we only keep glyph names because of tracing and access by name
+ -- so weird names make no sense.
--- In context we only keep glyph names because of tracing and access by name
--- so weird names make no sense.
+ if context then
-local forcekeep = false -- only for testing something
+ local forcekeep = false -- only for testing something
+-- local forcekeep = true
-directives.register("otf.keepnames",function(v)
- report_cleanup("keeping weird glyph names, expect larger files and more memory usage")
- forcekeep = v
-end)
+ directives.register("otf.keepnames",function(v)
+ report_cleanup("keeping weird glyph names, expect larger files and more memory usage")
+ forcekeep = v
+ end)
-local function stripredundant(fontdata)
- local descriptions = fontdata.descriptions
- if descriptions then
- local n = 0
- local c = 0
- -- in context we always strip
- if (not context and fonts.privateoffsets.keepnames) or forcekeep then
- for unicode, d in next, descriptions do
- if d.class == "base" then
- d.class = nil
- c = c + 1
+ -- local p_lesscrappyname =
+ -- lpeg.utfchartabletopattern({ "uni", "u" },true)
+ -- * S("Xx")^0
+ -- * p_hex^1
+ -- * p_style
+
+ local function stripvariants(descriptions,list)
+ local n = list and #list or 0
+ if n > 0 then
+ for i=1,n do
+ local g = list[i]
+ if g then
+ local d = descriptions[g]
+ if d and d.name then
+ d.name = nil
+ n = n + 1
+ end
+ end
end
end
- else
- for unicode, d in next, descriptions do
- local name = d.name
- if name and lpegmatch(p_crappyname,name) then
- d.name = nil
- n = n + 1
+ return n
+ end
+
+ local function stripparts(descriptions,list)
+ local n = list and #list or 0
+ if n > 0 then
+ for i=1,n do
+ local g = list[i].glyph
+ if g then
+ local d = descriptions[g]
+ if d and d.name then
+ d.name = nil
+ n = n + 1
+ end
+ end
end
- if d.class == "base" then
- d.class = nil
- c = c + 1
+ end
+ return n
+ end
+
+ -- local function collectsimple(fontdata)
+ -- local resources = fontdata.resources
+ -- local sequences = resources and resources.sequences
+ -- if sequences then
+ -- local keeplist = { }
+ -- for i=1,#sequences do
+ -- local s = sequences[i]
+ -- if s.type == "gsub_single" then
+ -- -- only simple ones
+ -- local features = s.features
+ -- local steps = s.steps
+ -- if features and steps then
+ -- local okay = false
+ -- for k, v in next, features do
+ -- if find(k,"^ss%d%d") then
+ -- okay = true
+ -- break
+ -- end
+ -- end
+ -- if okay then
+ -- for i=1,#steps do
+ -- local coverage = steps[i].coverage
+ -- if coverage then
+ -- for k, v in next, coverage do
+ -- keeplist[k] = v
+ -- end
+ -- end
+ -- end
+ -- end
+ -- end
+ -- end
+ -- end
+ -- return next(keeplist) and keeplist or nil
+ -- end
+ -- end
+
+ local function collectsimple(fontdata)
+ return nil
+ end
+
+ stripredundant = function(fontdata)
+ local descriptions = fontdata.descriptions
+ if descriptions then
+ local n = 0
+ local c = 0
+ for unicode, d in next, descriptions do
+ local m = d.math
+ if m then
+ n = n + stripvariants(descriptions,m.vvariants)
+ n = n + stripvariants(descriptions,m.hvariants)
+ n = n + stripparts (descriptions,m.vparts)
+ n = n + stripparts (descriptions,m.hparts)
+ end
+ end
+ if forcekeep then
+ for unicode, d in next, descriptions do
+ if d.class == "base" then
+ d.class = nil
+ c = c + 1
+ end
+ end
+ else
+ local keeplist = collectsimple(fontdata)
+ for unicode, d in next, descriptions do
+ local name = d.name
+ if name then
+ -- if lpegmatch(p_lesscrappyname,name) then
+ if keeplist and keeplist[name] then
+ -- keep name
+ elseif lpegmatch(p_crappyname,name) then
+ d.name = nil
+ n = n + 1
+ end
+ end
+ if d.class == "base" then
+ d.class = nil
+ c = c + 1
+ end
+ end
+ end
+ if trace_cleanup then
+ if n > 0 then
+ report_cleanup("%s bogus names removed (verbose unicode)",n)
+ end
+ if c > 0 then
+ report_cleanup("%s base class tags removed (default is base)",c)
+ end
end
end
end
- if trace_cleanup then
- if n > 0 then
- report_cleanup("%s bogus names removed (verbose unicode)",n)
- end
- if c > 0 then
- report_cleanup("%s base class tags removed (default is base)",c)
+
+ else
+
+ stripredundant = function(fontdata)
+ local descriptions = fontdata.descriptions
+ if descriptions then
+ if fonts.privateoffsets.keepnames then
+ for unicode, d in next, descriptions do
+ if d.class == "base" then
+ d.class = nil
+ end
+ end
+ else
+ for unicode, d in next, descriptions do
+ local name = d.name
+ if name then
+ if lpegmatch(p_crappyname,name) then
+ d.name = nil
+ end
+ end
+ if d.class == "base" then
+ d.class = nil
+ end
+ end
+ end
end
end
+
end
-end
-readers.stripredundant = stripredundant
+ readers.stripredundant = stripredundant
+
+end
function readers.getcomponents(fontdata) -- handy for resolving ligatures when names are missing
local resources = fontdata.resources
@@ -1128,8 +1258,7 @@ readers.unifymissing = unifymissing
function readers.rehash(fontdata,hashmethod) -- TODO: combine loops in one
if not (fontdata and fontdata.glyphs) then
return
- end
- if hashmethod == "indices" then
+ elseif hashmethod == "indices" then
fontdata.hashmethod = "indices"
elseif hashmethod == "names" then
fontdata.hashmethod = "names"
@@ -1137,7 +1266,6 @@ function readers.rehash(fontdata,hashmethod) -- TODO: combine loops in one
unifyresources(fontdata,indices)
copyduplicates(fontdata)
unifymissing(fontdata)
- -- stripredundant(fontdata)
else
fontdata.hashmethod = "unicodes"
local indices = unifyglyphs(fontdata)
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-ttf.lua b/macros/luatex/generic/luaotfload/fontloader-font-ttf.lua
index a2658d595a..d1a3972b2c 100644
--- a/macros/luatex/generic/luaotfload/fontloader-font-ttf.lua
+++ b/macros/luatex/generic/luaotfload/fontloader-font-ttf.lua
@@ -247,115 +247,148 @@ local function applyaxis(glyph,shape,deltas,dowidth)
-- Not the most efficient solution but we seldom do this. We
-- actually need to avoid the extra points here but I'll deal
-- with that when needed.
- local function find(i)
- local prv = cnt
- for j=1,cnt do
- local nxt = dpoints[j]
- if nxt == i then
- return false, j, false
- elseif nxt > i then
- return prv, false, j
- end
- prv = j
- end
- return prv, false, 1
- end
- -- We need the first and last points untouched so we first
- -- collect data.
- for i=1,nofpoints do
- local d1, d2, d3 = find(i)
- local p2 = points[i]
- if d2 then
- xv[i] = xvalues[d2]
- yv[i] = yvalues[d2]
- else
- local n1 = dpoints[d1]
- local n3 = dpoints[d3]
- -- Some day I need to figure out these extra points but
- -- I'll wait till the standard is more clear and fonts
- -- become better (ntg-context: fraunces.ttf > abcdef).
- if n1 > nofpoints then
- n1 = nofpoints
- end
- if n3 > nofpoints then
- n3 = nofpoints
- end
- --
- local p1 = points[n1]
- local p3 = points[n3]
- local p1x = p1[1]
- local p2x = p2[1]
- local p3x = p3[1]
- local p1y = p1[2]
- local p2y = p2[2]
- local p3y = p3[2]
- local x1 = xvalues[d1]
- local y1 = yvalues[d1]
- local x3 = xvalues[d3]
- local y3 = yvalues[d3]
- --
- local fx
- local fy
- --
- if p1x == p3x then
- if x1 == x3 then
- fx = x1
- else
- fx = 0
- end
- elseif p2x <= min(p1x,p3x) then
- if p1x < p3x then
- fx = x1
- else
- fx = x3
- end
- elseif p2x >= max(p1x,p3x) then
- if p1x > p3x then
- fx = x1
- else
- fx = x3
+ local contours = shape.contours
+ local nofcontours = #contours
+ local first = 1
+ local firstindex = 1
+ for contour=1,nofcontours do
+ local last = contours[contour]
+ if last >= first then
+ local lastindex = cnt
+ if firstindex < cnt then
+ for currentindex=firstindex,cnt do
+ local found = dpoints[currentindex]
+ if found <= first then
+ firstindex = currentindex
+ end
+ if found == last then
+ lastindex = currentindex
+ break;
+ elseif found > last then
+ break
+ end
end
- else
- fx = (p2x - p1x)/(p3x - p1x)
- fx = (1 - fx) * x1 + fx * x3
end
- --
- if p1y == p3y then
- if y1 == y3 then
- fy = y1
- else
- fy = 0
- end
- elseif p2y <= min(p1y,p3y) then
- if p1y < p3y then
- fy = y1
- else
- fy = y3
+ -- print("unicode: ",glyph.unicode or "?")
+ -- print("contour: ",first,contour,last)
+ -- print("index : ",firstindex,lastindex,cnt)
+ -- print("points : ",dpoints[firstindex],dpoints[lastindex])
+ local function find(i)
+ local prv = lastindex
+ for j=firstindex,lastindex do
+ local nxt = dpoints[j]
+ if nxt == i then
+ return false, j, false
+ elseif nxt > i then
+ return prv, false, j
+ end
+ prv = j
end
- elseif p2y >= max(p1y,p3y) then
- if p1y > p3y then
- fy = y1
+ return prv, false, firstindex
+ end
+ -- We need the first and last points untouched so we first
+ -- collect data.
+ for point=first,last do
+ local d1, d2, d3 = find(point)
+ local p2 = points[point]
+ if d2 then
+ xv[point] = xvalues[d2]
+ yv[point] = yvalues[d2]
else
- fy = y3
+ local n1 = dpoints[d1]
+ local n3 = dpoints[d3]
+ -- Some day I need to figure out these extra points but
+ -- I'll wait till the standard is more clear and fonts
+ -- become better (ntg-context: fraunces.ttf > abcdef).
+ if n1 > nofpoints then
+ n1 = nofpoints
+ end
+ if n3 > nofpoints then
+ n3 = nofpoints
+ end
+ --
+ local p1 = points[n1]
+ local p3 = points[n3]
+ local p1x = p1[1]
+ local p2x = p2[1]
+ local p3x = p3[1]
+ local p1y = p1[2]
+ local p2y = p2[2]
+ local p3y = p3[2]
+ local x1 = xvalues[d1]
+ local y1 = yvalues[d1]
+ local x3 = xvalues[d3]
+ local y3 = yvalues[d3]
+ --
+ local fx
+ local fy
+ --
+ if p1x == p3x then
+ if x1 == x3 then
+ fx = x1
+ else
+ fx = 0
+ end
+ elseif p2x <= min(p1x,p3x) then
+ if p1x < p3x then
+ fx = x1
+ else
+ fx = x3
+ end
+ elseif p2x >= max(p1x,p3x) then
+ if p1x > p3x then
+ fx = x1
+ else
+ fx = x3
+ end
+ else
+ fx = (p2x - p1x)/(p3x - p1x)
+ fx = (1 - fx) * x1 + fx * x3
+ end
+ --
+ if p1y == p3y then
+ if y1 == y3 then
+ fy = y1
+ else
+ fy = 0
+ end
+ elseif p2y <= min(p1y,p3y) then
+ if p1y < p3y then
+ fy = y1
+ else
+ fy = y3
+ end
+ elseif p2y >= max(p1y,p3y) then
+ if p1y > p3y then
+ fy = y1
+ else
+ fy = y3
+ end
+ else
+ fy = (p2y - p1y)/(p3y - p1y)
+ fy = (1 - fy) * y1 + fy * y3
+ end
+ -- -- maybe:
+ -- if p1y ~= p3y then
+ -- fy = (p2y - p1y)/(p3y - p1y)
+ -- fy = (1 - fy) * y1 + fy * y3
+ -- elseif abs(p1y-p2y) < abs(p3y-p2y) then
+ -- fy = y1
+ -- else
+ -- fy = y3
+ -- end
+ --
+ xv[point] = fx
+ yv[point] = fy
end
- else
- fy = (p2y - p1y)/(p3y - p1y)
- fy = (1 - fy) * y1 + fy * y3
end
- -- -- maybe:
- -- if p1y ~= p3y then
- -- fy = (p2y - p1y)/(p3y - p1y)
- -- fy = (1 - fy) * y1 + fy * y3
- -- elseif abs(p1y-p2y) < abs(p3y-p2y) then
- -- fy = y1
- -- else
- -- fy = y3
- -- end
- --
- xv[i] = fx
- yv[i] = fy
+ if lastindex < cnt then
+ firstindex = lastindex + 1
+ end
end
+ first = last + 1
end
+
for i=1,nofpoints do
local pi = points[i]
local fx = xv[i]
diff --git a/macros/luatex/generic/luaotfload/fontloader-reference.lua b/macros/luatex/generic/luaotfload/fontloader-reference.lua
index 736856d2be..13389b292a 100644
--- a/macros/luatex/generic/luaotfload/fontloader-reference.lua
+++ b/macros/luatex/generic/luaotfload/fontloader-reference.lua
@@ -1,6 +1,6 @@
-- merged file : c:/data/develop/context/sources/luatex-fonts-merged.lua
-- parent file : c:/data/develop/context/sources/luatex-fonts.lua
--- merge date : 2022-01-21 20:10
+-- merge date : 2022-05-11 11:34
do -- begin closure to overcome local limits and interference
@@ -10902,9 +10902,9 @@ function mappings.addtounicode(data,filename,checklookups,forceligatures)
local usedmap=cidinfo and fonts.cid.getmap(cidinfo)
local uparser=makenameparser()
if usedmap then
- oparser=usedmap and makenameparser(cidinfo.ordering)
- cidnames=usedmap.names
- cidcodes=usedmap.unicodes
+ oparser=usedmap and makenameparser(cidinfo.ordering)
+ cidnames=usedmap.names
+ cidcodes=usedmap.unicodes
end
local ns=0
local nl=0
@@ -13108,13 +13108,13 @@ function readers.getinfo(filename,specification)
}
end
end
-function readers.rehash(fontdata,hashmethod)
+function readers.rehash()
report("the %a helper is not yet implemented","rehash")
end
-function readers.checkhash(fontdata)
+function readers.checkhash()
report("the %a helper is not yet implemented","checkhash")
end
-function readers.pack(fontdata,hashmethod)
+function readers.pack()
report("the %a helper is not yet implemented","pack")
end
function readers.unpack(fontdata)
@@ -15557,95 +15557,123 @@ local function applyaxis(glyph,shape,deltas,dowidth)
end
end
elseif cnt>0 then
- local function find(i)
- local prv=cnt
- for j=1,cnt do
- local nxt=dpoints[j]
- if nxt==i then
- return false,j,false
- elseif nxt>i then
- return prv,false,j
- end
- prv=j
- end
- return prv,false,1
- end
- for i=1,nofpoints do
- local d1,d2,d3=find(i)
- local p2=points[i]
- if d2 then
- xv[i]=xvalues[d2]
- yv[i]=yvalues[d2]
- else
- local n1=dpoints[d1]
- local n3=dpoints[d3]
- if n1>nofpoints then
- n1=nofpoints
- end
- if n3>nofpoints then
- n3=nofpoints
- end
- local p1=points[n1]
- local p3=points[n3]
- local p1x=p1[1]
- local p2x=p2[1]
- local p3x=p3[1]
- local p1y=p1[2]
- local p2y=p2[2]
- local p3y=p3[2]
- local x1=xvalues[d1]
- local y1=yvalues[d1]
- local x3=xvalues[d3]
- local y3=yvalues[d3]
- local fx
- local fy
- if p1x==p3x then
- if x1==x3 then
- fx=x1
- else
- fx=0
- end
- elseif p2x<=min(p1x,p3x) then
- if p1x<p3x then
- fx=x1
- else
- fx=x3
- end
- elseif p2x>=max(p1x,p3x) then
- if p1x>p3x then
- fx=x1
- else
- fx=x3
+ local contours=shape.contours
+ local nofcontours=#contours
+ local first=1
+ local firstindex=1
+ for contour=1,nofcontours do
+ local last=contours[contour]
+ if last>=first then
+ local lastindex=cnt
+ if firstindex<cnt then
+ for currentindex=firstindex,cnt do
+ local found=dpoints[currentindex]
+ if found<=first then
+ firstindex=currentindex
+ end
+ if found==last then
+ lastindex=currentindex
+ break;
+ elseif found>last then
+ break
+ end
end
- else
- fx=(p2x-p1x)/(p3x-p1x)
- fx=(1-fx)*x1+fx*x3
end
- if p1y==p3y then
- if y1==y3 then
- fy=y1
- else
- fy=0
- end
- elseif p2y<=min(p1y,p3y) then
- if p1y<p3y then
- fy=y1
- else
- fy=y3
+ local function find(i)
+ local prv=lastindex
+ for j=firstindex,lastindex do
+ local nxt=dpoints[j]
+ if nxt==i then
+ return false,j,false
+ elseif nxt>i then
+ return prv,false,j
+ end
+ prv=j
end
- elseif p2y>=max(p1y,p3y) then
- if p1y>p3y then
- fy=y1
+ return prv,false,firstindex
+ end
+ for point=first,last do
+ local d1,d2,d3=find(point)
+ local p2=points[point]
+ if d2 then
+ xv[point]=xvalues[d2]
+ yv[point]=yvalues[d2]
else
- fy=y3
+ local n1=dpoints[d1]
+ local n3=dpoints[d3]
+ if n1>nofpoints then
+ n1=nofpoints
+ end
+ if n3>nofpoints then
+ n3=nofpoints
+ end
+ local p1=points[n1]
+ local p3=points[n3]
+ local p1x=p1[1]
+ local p2x=p2[1]
+ local p3x=p3[1]
+ local p1y=p1[2]
+ local p2y=p2[2]
+ local p3y=p3[2]
+ local x1=xvalues[d1]
+ local y1=yvalues[d1]
+ local x3=xvalues[d3]
+ local y3=yvalues[d3]
+ local fx
+ local fy
+ if p1x==p3x then
+ if x1==x3 then
+ fx=x1
+ else
+ fx=0
+ end
+ elseif p2x<=min(p1x,p3x) then
+ if p1x<p3x then
+ fx=x1
+ else
+ fx=x3
+ end
+ elseif p2x>=max(p1x,p3x) then
+ if p1x>p3x then
+ fx=x1
+ else
+ fx=x3
+ end
+ else
+ fx=(p2x-p1x)/(p3x-p1x)
+ fx=(1-fx)*x1+fx*x3
+ end
+ if p1y==p3y then
+ if y1==y3 then
+ fy=y1
+ else
+ fy=0
+ end
+ elseif p2y<=min(p1y,p3y) then
+ if p1y<p3y then
+ fy=y1
+ else
+ fy=y3
+ end
+ elseif p2y>=max(p1y,p3y) then
+ if p1y>p3y then
+ fy=y1
+ else
+ fy=y3
+ end
+ else
+ fy=(p2y-p1y)/(p3y-p1y)
+ fy=(1-fy)*y1+fy*y3
+ end
+ xv[point]=fx
+ yv[point]=fy
end
- else
- fy=(p2y-p1y)/(p3y-p1y)
- fy=(1-fy)*y1+fy*y3
end
- xv[i]=fx
- yv[i]=fy
+ if lastindex<cnt then
+ firstindex=lastindex+1
+ end
end
+ first=last+1
end
for i=1,nofpoints do
local pi=points[i]
@@ -19792,6 +19820,7 @@ function readers.hvar(f,fontdata,specification)
local variations={}
local innerindex={}
local outerindex={}
+ local deltas={}
if variationoffset>0 then
regions,deltas=readvariationdata(f,variationoffset,factors)
end
@@ -21181,7 +21210,7 @@ local trace_defining=false registertracker("fonts.defining",function(v) trace_d
local report_otf=logs.reporter("fonts","otf loading")
local fonts=fonts
local otf=fonts.handlers.otf
-otf.version=3.119
+otf.version=3.120
otf.cache=containers.define("fonts","otl",otf.version,true)
otf.svgcache=containers.define("fonts","svg",otf.version,true)
otf.pngcache=containers.define("fonts","png",otf.version,true)
@@ -23855,6 +23884,7 @@ local next,type=next,type
local P,R,S=lpeg.P,lpeg.R,lpeg.S
local lpegmatch=lpeg.match
local insert,remove,copy,unpack=table.insert,table.remove,table.copy,table.unpack
+local find=string.find
local formatters=string.formatters
local sortedkeys=table.sortedkeys
local sortedhash=table.sortedhash
@@ -24713,61 +24743,137 @@ local function unifyglyphs(fontdata,usenames)
fontdata.nofglyphs=nofglyphs
return indices,names
end
-local p_crappyname do
+local stripredundant do
local p_hex=R("af","AF","09")
local p_digit=R("09")
local p_done=S("._-")^0+P(-1)
+ local p_style=P(".")
local p_alpha=R("az","AZ")
local p_ALPHA=R("AZ")
- p_crappyname=(
+ local p_crappyname=(
lpeg.utfchartabletopattern({ "uni","u" },true)*S("Xx_")^0*p_hex^1
+lpeg.utfchartabletopattern({ "identity","glyph","jamo" },true)*p_hex^1
+lpeg.utfchartabletopattern({ "index","afii" },true)*p_digit^1
+p_digit*p_hex^3+p_alpha*p_digit^1
+P("aj")*p_digit^1+P("eh_")*(p_digit^1+p_ALPHA*p_digit^1)+(1-P("_"))^1*P("_uni")*p_hex^1+P("_")*P(1)^1
)*p_done
-end
-local forcekeep=false
-directives.register("otf.keepnames",function(v)
- report_cleanup("keeping weird glyph names, expect larger files and more memory usage")
- forcekeep=v
-end)
-local function stripredundant(fontdata)
- local descriptions=fontdata.descriptions
- if descriptions then
- local n=0
- local c=0
- if (not context and fonts.privateoffsets.keepnames) or forcekeep then
- for unicode,d in next,descriptions do
- if d.class=="base" then
- d.class=nil
- c=c+1
+ if context then
+ local forcekeep=false
+ directives.register("otf.keepnames",function(v)
+ report_cleanup("keeping weird glyph names, expect larger files and more memory usage")
+ forcekeep=v
+ end)
+ local function stripvariants(descriptions,list)
+ local n=list and #list or 0
+ if n>0 then
+ for i=1,n do
+ local g=list[i]
+ if g then
+ local d=descriptions[g]
+ if d and d.name then
+ d.name=nil
+ n=n+1
+ end
+ end
end
end
- else
- for unicode,d in next,descriptions do
- local name=d.name
- if name and lpegmatch(p_crappyname,name) then
- d.name=nil
- n=n+1
- end
- if d.class=="base" then
- d.class=nil
- c=c+1
+ return n
+ end
+ local function stripparts(descriptions,list)
+ local n=list and #list or 0
+ if n>0 then
+ for i=1,n do
+ local g=list[i].glyph
+ if g then
+ local d=descriptions[g]
+ if d and d.name then
+ d.name=nil
+ n=n+1
+ end
+ end
end
end
+ return n
end
- if trace_cleanup then
- if n>0 then
- report_cleanup("%s bogus names removed (verbose unicode)",n)
+ local function collectsimple(fontdata)
+ return nil
+ end
+ stripredundant=function(fontdata)
+ local descriptions=fontdata.descriptions
+ if descriptions then
+ local n=0
+ local c=0
+ for unicode,d in next,descriptions do
+ local m=d.math
+ if m then
+ n=n+stripvariants(descriptions,m.vvariants)
+ n=n+stripvariants(descriptions,m.hvariants)
+ n=n+stripparts (descriptions,m.vparts)
+ n=n+stripparts (descriptions,m.hparts)
+ end
+ end
+ if forcekeep then
+ for unicode,d in next,descriptions do
+ if d.class=="base" then
+ d.class=nil
+ c=c+1
+ end
+ end
+ else
+ local keeplist=collectsimple(fontdata)
+ for unicode,d in next,descriptions do
+ local name=d.name
+ if name then
+ if keeplist and keeplist[name] then
+ elseif lpegmatch(p_crappyname,name) then
+ d.name=nil
+ n=n+1
+ end
+ end
+ if d.class=="base" then
+ d.class=nil
+ c=c+1
+ end
+ end
+ end
+ if trace_cleanup then
+ if n>0 then
+ report_cleanup("%s bogus names removed (verbose unicode)",n)
+ end
+ if c>0 then
+ report_cleanup("%s base class tags removed (default is base)",c)
+ end
+ end
end
- if c>0 then
- report_cleanup("%s base class tags removed (default is base)",c)
+ end
+ else
+ stripredundant=function(fontdata)
+ local descriptions=fontdata.descriptions
+ if descriptions then
+ if fonts.privateoffsets.keepnames then
+ for unicode,d in next,descriptions do
+ if d.class=="base" then
+ d.class=nil
+ end
+ end
+ else
+ for unicode,d in next,descriptions do
+ local name=d.name
+ if name then
+ if lpegmatch(p_crappyname,name) then
+ d.name=nil
+ end
+ end
+ if d.class=="base" then
+ d.class=nil
+ end
+ end
+ end
end
end
end
+ readers.stripredundant=stripredundant
end
-readers.stripredundant=stripredundant
function readers.getcomponents(fontdata)
local resources=fontdata.resources
if resources then
@@ -24851,8 +24957,7 @@ readers.unifymissing=unifymissing
function readers.rehash(fontdata,hashmethod)
if not (fontdata and fontdata.glyphs) then
return
- end
- if hashmethod=="indices" then
+ elseif hashmethod=="indices" then
fontdata.hashmethod="indices"
elseif hashmethod=="names" then
fontdata.hashmethod="names"
@@ -30883,7 +30988,7 @@ local function validspecification(specification,name)
return specification,name
end
end
-local function addfeature(data,feature,specifications)
+local function addfeature(data,feature,specifications,prepareonly)
if not specifications then
report_otf("missing specification")
return
@@ -31182,8 +31287,6 @@ local function addfeature(data,feature,specifications)
local rules=list.rules
local coverage={}
if rules then
- local rulehash={}
- local rulesize=0
local lookuptype=types[featuretype]
for nofrules=1,#rules do
local rule=rules[nofrules]
@@ -31214,6 +31317,14 @@ local function addfeature(data,feature,specifications)
local lookups=rule.lookups or false
local subtype=nil
if lookups and sublookups then
+ if #lookups>0 then
+ local ns=stop-start+1
+ for i=1,ns do
+ if lookups[i]==nil then
+ lookups[i]=0
+ end
+ end
+ end
local l={}
for k,v in sortedhash(lookups) do
local t=type(v)
@@ -31261,8 +31372,7 @@ local function addfeature(data,feature,specifications)
hashed[i]=t
end
sequence=hashed
- rulesize=rulesize+1
- rulehash[rulesize]={
+ local ruleset={
nofrules,
lookuptype,
sequence,
@@ -31274,8 +31384,15 @@ local function addfeature(data,feature,specifications)
}
for unic in sortedhash(sequence[start]) do
local cu=coverage[unic]
- if not cu then
- coverage[unic]=rulehash
+ if cu then
+ local n=cu.n+1
+ cu[n]=ruleset
+ cu.n=n
+ else
+ coverage[unic]={
+ ruleset,
+ n=1,
+ }
end
end
sequence.n=nofsequences
@@ -31283,7 +31400,6 @@ local function addfeature(data,feature,specifications)
end
end
end
- rulehash.n=rulesize
end
return coverage
end
@@ -31504,8 +31620,11 @@ local function addfeature(data,feature,specifications)
order=featureorder,
[stepkey]=steps,
nofsteps=nofsteps,
- type=types[featuretype],
+ type=specification.handler or types[featuretype],
}
+ if prepareonly then
+ return sequence
+ end
end
end
if sequence then
@@ -31587,6 +31706,14 @@ if not modules then modules={} end modules ['font-osd']={
copyright="TAT Zetwerk / PRAGMA ADE / ConTeXt Development Team",
license="see context related readme files"
}
+local experiment1=false
+local experiment2=false
+local experiment2b1=false
+local experiment2b2=false
+experiments.register("fonts.indic.experiment1",function(v) experiment1=v end)
+experiments.register("fonts.indic.experiment2",function(v) experiment2=v end)
+experiments.register("fonts.indic.experiment2b1",function(v) experiment2b1=v end)
+experiments.register("fonts.indic.experiment2b2",function(v) experiment2b2=v end)
local insert,remove,imerge,copy,tohash=table.insert,table.remove,table.imerge,table.copy,table.tohash
local next,type,rawget=next,type,rawget
local formatters=string.formatters
@@ -33099,7 +33226,7 @@ local function reorder_two(head,start,stop,font,attr,nbspaces)
local subpos=nil
local postpos=nil
reorderreph.coverage={}
- rephbase[font]={}
+ rephbase[font]={}
for i=1,#seqsubset do
local subset=seqsubset[i]
local kind=subset[1]
@@ -33276,7 +33403,7 @@ local function reorder_two(head,start,stop,font,attr,nbspaces)
logprocess("reorder two, handle nbsp")
end
end
- else
+ else
local last=getnext(stop)
while current~=last do
local next=getnext(current)
@@ -33339,7 +33466,7 @@ local function reorder_two(head,start,stop,font,attr,nbspaces)
logprocess("reorder two, handle matra")
end
end
- if not moved[current] and dependent_vowel[char] then
+ if dependent_vowel[char] then
if pre_mark[char] then
moved[current]=true
local prev,next=getboth(current)
@@ -33518,8 +33645,8 @@ local function analyze_next_chars_one(c,font,variant)
if not n then
return c
end
+ local v=ischar(n,font)
if variant==1 then
- local v=ischar(n,font)
if v and nukta[v] then
n=getnext(n)
if n then
@@ -33552,7 +33679,6 @@ local function analyze_next_chars_one(c,font,variant)
end
end
elseif variant==2 then
- local v=ischar(n,font)
if v and nukta[v] then
c=n
end
@@ -33576,11 +33702,11 @@ local function analyze_next_chars_one(c,font,variant)
end
end
end
- local n=getnext(c)
+ n=getnext(c)
if not n then
return c
end
- local v=ischar(n,font)
+ v=ischar(n,font)
if not v then
return c
end
@@ -33685,12 +33811,11 @@ local function analyze_next_chars_one(c,font,variant)
end
end
local function analyze_next_chars_two(c,font)
- local n,v
- n=getnext(c)
+ local n=getnext(c)
if not n then
return c
end
- v=ischar(n,font)
+ local v=ischar(n,font)
if v and nukta[v] then
c=n
end
@@ -37702,12 +37827,12 @@ local function blockligatures(str)
before=before,
current={ one,two },
after=after,
- lookups={ 1 },
+ lookups={ 1,false },
}
revert[new]={
current={ one,zwj },
after={ two },
- lookups={ 1 },
+ lookups={ 1,false },
}
end
end
diff --git a/macros/luatex/generic/luaotfload/luaotfload-auxiliary.lua b/macros/luatex/generic/luaotfload/luaotfload-auxiliary.lua
index b34c56508e..eb21180902 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-auxiliary.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-auxiliary.lua
@@ -6,8 +6,8 @@
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-auxiliary",
- version = "3.21", --TAGVERSION
- date = "2022-03-18", --TAGDATE
+ version = "3.22", --TAGVERSION
+ date = "2022-06-15", --TAGDATE
description = "luaotfload submodule / auxiliary functions",
license = "GPL v2.0"
}
diff --git a/macros/luatex/generic/luaotfload/luaotfload-bcp47.lua b/macros/luatex/generic/luaotfload/luaotfload-bcp47.lua
new file mode 100644
index 0000000000..03dc65e5bc
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/luaotfload-bcp47.lua
@@ -0,0 +1,85 @@
+-- Suport for parsing BCP47 based language tags into components
+local normalize_case, language_tag do
+ local l = lpeg or require'lpeg'
+ local function rep(base, num, max)
+ max = max or num
+ if num == 1 then
+ if max == 1 then
+ return base
+ else
+ return base * base^-(max-1)
+ end
+ end
+ return base * rep(base, num - 1, max - 1)
+ end
+ local eor = #(l.P'-' + -1) -- End of record
+ local alpha = l.R('az', 'AZ')
+ local alphanum = l.R('az', 'AZ', '09')
+ local digit = l.R'09'
+ normalize_case = l.Cs(
+ (alphanum^2/string.lower)
+ * (
+ ('-' * (alphanum/string.upper) * (rep(alphanum, 3)/string.lower))
+ + ('-' * alphanum^3/string.lower)
+ + ('-' * rep(alphanum, 2)/string.upper)
+ )^0
+ * ('-' * alphanum * '-' * l.P(1)^1 / string.lower)^-1
+ + alphanum * '-' * l.P(1)^1 / string.lower
+ ) * -1
+ local extlang = l.Cg(rep(alpha, 3), 'extlang')
+ local language = l.Cg(rep(alpha, 2, 3), 'language') * ('-' * extlang * eor)^-1
+ local script = l.Cg(rep(alpha, 4), 'script')
+ local region = l.Cg(rep(alpha, 2) + rep(digit, 3), 'region')
+ local variant = l.Cg(rep(alphanum, 5, 8) + digit * rep(alphanum, 3), 'variant')
+ local singleton = l.R('09', 'aw', 'yz')
+ local extension = l.Cg(l.C(singleton) * l.Ct(('-' * l.C(rep(alphanum, 2, 8)))^1))
+ local privateuse = l.P'x' * l.Cg(l.Ct(('-' * l.C(rep(alphanum, 2, 8)))^1), 'private')
+ local irregular =
+ l.P'en-GB-oed' * l.Cc{language = 'en', region = 'GB', variant = 'oxendict'}
+ + l.P'i-ami' * l.Cc{language = 'ami'}
+ + l.P'i-bnn' * l.Cc{language = 'bnn'}
+ + l.P'i-default' * l.Cc{language = 'i-default'} -- Not deprecated
+ + l.P'i-enochian' * l.Cc{language = 'i-enochian'} -- The non-existance of a non deprecated language code for enochian
+ -- demonstrates a shocking for the language of my ancestors
+ + l.P'i-hak' * l.Cc{language = 'hak'}
+ + l.P'i-klingon' * l.Cc{language = 'tlh'}
+ + l.P'i-lux' * l.Cc{language = 'lb'}
+ + l.P'i-mingo' * l.Cc{language = 'i-mingo'} -- Not deprecated
+ + l.P'i-navajo' * l.Cc{language = 'nv'}
+ + l.P'i-pwn' * l.Cc{language = 'pwn'}
+ + l.P'i-tao' * l.Cc{language = 'tao'}
+ + l.P'i-tay' * l.Cc{language = 'tay'}
+ + l.P'i-tsu' * l.Cc{language = 'tsu'}
+ + l.P'sgn-BE-FR' * l.Cc{language = 'sfb'}
+ + l.P'sgn-BE-NL' * l.Cc{language = 'vgt'}
+ + l.P'sgn-CH-DE' * l.Cc{language = 'sgg'}
+ local regular =
+ l.P'art-lojban' * l.Cc{language = 'jbo'}
+ + l.P'cel-gaulish' * l.Cc{language = '...'}
+ + l.P'no-bok' * l.Cc{language = 'nb'}
+ + l.P'no-nyn' * l.Cc{language = 'nn'}
+ + l.P'zh-guoyu' * l.Cc{language = 'cmn'}
+ + l.P'zh-hakka' * l.Cc{language = 'hak'}
+ + l.P'zh-min' * l.Cc{language = '...'}
+ + l.P'zh-min-nan' * l.Cc{language = 'nan'}
+ + l.P'zh-xiang' * l.Cc{language = 'hsn'}
+ local grandfathered = irregular + regular
+ local langtag = language * ('-' * script * eor)^-1
+ * ('-' * region * eor)^-1
+ * ('-' * variant)^0
+ * (#('-' * singleton * '-') * l.Cg(l.Cf(l.Ct'' * ('-' * extension)^0, rawset), 'extension'))^-1
+ * ('-' * privateuse)^-1
+ language_tag = (grandfathered + l.Ct(langtag + privateuse)) * l.Cp()--* -1
+end
+local function parse(tag)
+ tag = normalize_case:match(tag)
+ if not tag then return end
+ local parsed, pos = language_tag:match(tag)
+ print(require'inspect'{parsed, pos})
+ -- if not parsed then return parsed end
+ return tag, parsed
+end
+for l in io.lines() do
+ print(parse(l))
+ -- io.stdout:write(parse(l), '\n')
+end
diff --git a/macros/luatex/generic/luaotfload/luaotfload-case.lua b/macros/luatex/generic/luaotfload/luaotfload-case.lua
index 33bb1bc924..f5a147334d 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-case.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-case.lua
@@ -21,6 +21,7 @@ local setdisc = direct.setdisc
local getdisc = direct.getdisc
local getfield = direct.getfield
local remove = direct.remove
+local free = direct.free
local copy = direct.copy
local insert_after = direct.insert_after
local traverse = direct.traverse
@@ -34,41 +35,133 @@ local disc = node.id'disc'
-- * Final_Sigma is never language dependent
-- * Other contexts are always language dependent
-- * The only languages with special mappings are Lithuanian (lt/"LTH "/lit), Turkish (tr/"TRK "/tur), and Azeri/Azerbaijani (az/"AZE "/aze)
+-- (Additionally we add special mappings for de-x-eszett, el, el-x-iota, hy-x-yiwn which are not present in SpecialCasing.txt)
]]
-local font_lang = setmetatable({}, {__index = function(t, fid)
- local f = font.getfont(fid)
- local lang = f.specification.features.normal.language
- lang = lang == 'lth' and 'lt' or lang == 'trk' and 'tr' or lang == 'aze' and 'az' or false
- t[fid] = lang
- return lang
-end})
+local UPPER_MASK = 0x3FF
+local HAS_VOWEL = 0x200000
+local HAS_YPOGEGRAMMENI = 0x400000
+local HAS_ACCENT = 0x800000
+local HAS_DIALYTIKA = 0x1000000
+local HAS_OTHER_GREEK_DIACRITIC = 0x2000000
-local function is_Final_Sigma(font, mapping, n, after)
- mapping = mapping.Final_Sigma
- if not mapping then return false end
- mapping = mapping._
- if not mapping then return false end
+local greek_data
+local greek_diacritic = {
+ [0x0300] = HAS_ACCENT,
+ [0x0301] = HAS_ACCENT,
+ [0x0342] = HAS_ACCENT,
+ [0x0302] = HAS_ACCENT,
+ [0x0303] = HAS_ACCENT,
+ [0x0311] = HAS_ACCENT,
+ [0x0308] = HAS_DIALYTIKA,
+ [0x0344] = HAS_DIALYTIKA | HAS_ACCENT,
+ [0x0345] = HAS_YPOGEGRAMMENI,
+ [0x0304] = HAS_OTHER_GREEK_DIACRITIC,
+ [0x0306] = HAS_OTHER_GREEK_DIACRITIC,
+ [0x0313] = HAS_OTHER_GREEK_DIACRITIC,
+ [0x0314] = HAS_OTHER_GREEK_DIACRITIC,
+ [0x0343] = HAS_OTHER_GREEK_DIACRITIC,
+}
+
+local greek_precombined_iota = {
+ [0x0391] = 0x1FBC,
+ [0x0397] = 0x1FCC,
+ [0x03A9] = 0x1FFC,
+}
+
+-- Greek handling based on https://icu.unicode.org/design/case/greek-upper
+-- with smaller variations since we ant to preserve nodes whenever possible.
+local function init_greek_data()
+ local NFD = require'lua-uni-normalize'.NFD
+ local data = {}
+ greek_data = data
+
+ local vowels = {
+ [utf8.codepoint'Α'] = true, [utf8.codepoint'Ε'] = true,
+ [utf8.codepoint'Η'] = true, [utf8.codepoint'Ι'] = true,
+ [utf8.codepoint'Ο'] = true, [utf8.codepoint'Ω'] = true,
+ [utf8.codepoint'Υ'] = true,
+ }
+ local function handle_char(c)
+ local decomp = NFD(utf8.char(c))
+ local first = utf8.codepoint(decomp)
+ local upper = uppercase[first]
+ if upper then
+ if not tonumber(upper) then
+ upper = upper._
+ assert(#upper == 1)
+ upper = upper[1]
+ end
+ else
+ upper = first
+ end
+ if upper > UPPER_MASK then return end -- Only happens for unassigned codepoints
+ local datum = upper
+ if vowels[upper] then
+ datum = datum | HAS_VOWEL
+ end
+ if utf8.len(decomp) > 1 then
+ for _, c in utf8.codes(decomp) do
+ local dia = greek_diacritic[c]
+ if dia and dia ~= HAS_OTHER_GREEK_DIACRITIC then datum = datum | dia end
+ end
+ end
+ data[c] = datum
+ end
+ for c = 0x0370, 0x03ff do handle_char(c) end
+ for c = 0x1f00, 0x1fff do handle_char(c) end
+ for c = 0x2126, 0x2126 do handle_char(c) end
+end
+
+local function font_lang(feature)
+ return setmetatable({}, {__index = function(t, fid)
+ local f = font.getfont(fid)
+ local features = f.specification.features.normal
+ local lang = features[feature]
+ if type(lang) ~= 'string' or lang == 'auto' then
+ lang = features.language
+ lang = lang == 'lth' and 'lt'
+ or lang == 'trk' and 'tr'
+ or lang == 'aze' and 'az'
+ or lang == 'hye' and 'hy'
+ or (lang == 'ell' or lang == 'pgr') and 'el'
+ or false
+ end
+ t[fid] = lang
+ return lang
+ end})
+end
+
+local function is_followed_by_cased(font, n, after)
n = getnext(n)
repeat
while n do
local char, id = is_char(n, font)
- if id == disc then
+ if not char and id == disc then
after = getnext(n)
n = getfield(n, 'replace')
char, id = is_char(n, font)
- elseif char then
+ end
+ if char then
if not case_ignorable[char] then
- return not cased[char] and mapping
+ return cased[char]
end
n = getnext(n)
else
- return mapping
+ return false
end
end
n, after = after
until not n
- return mapping
+ return false
+end
+
+local function is_Final_Sigma(font, mapping, n, after)
+ mapping = mapping.Final_Sigma
+ if not mapping then return false end
+ mapping = mapping._
+ if not mapping then return false end
+ return not is_followed_by_cased(font, n, after) and mapping
end
local function is_More_Above(font, mapping, n, after)
@@ -150,56 +243,181 @@ local function is_Language_Mapping(font, mapping, n, after, seen_soft_dotted, se
return is_More_Above(font, mapping, n, after) or is_Not_Before_Dot(font, mapping, n, after) or mapping._ -- Might be nil
end
-local function process(table)
- local function processor(head, font, after, seen_cased, seen_soft_dotted, seen_I)
+local function process(table, feature)
+ local font_lang = font_lang(feature)
+ -- The other seen_... are booleans, while seen_greek has more states:
+ -- - nil: Not greek
+ -- - true: Greek. Last was not a vowel with accent and without dialytika
+ -- - node: Greek. Last vowel with accent and without dialytika
+ local function processor(head, font, after, seen_cased, seen_soft_dotted, seen_I, seen_greek)
local lang = font_lang[font]
+ local greek, greek_iota
+ if lang == 'el' or lang == 'el-x-iota' then
+ if table == uppercase then
+ if not greek_data then
+ init_greek_data()
+ end
+ greek, greek_iota = greek_data, lang == 'el-x-iota'
+ end
+ lang = false
+ end
local n = head
while n do
do
local new = has_glyph(n)
if n ~= new then
- seen_cased, seen_soft_dotted, seen_I = nil
+ seen_cased, seen_soft_dotted, seen_I, seen_greek = nil
end
n = new
end
if not n then break end
local char, id = is_char(n, font)
if char then
- local mapping = table[char]
- if mapping then
- if tonumber(mapping) then
- setchar(n, mapping)
+ if greek and (char >= 0x0370 and char <= 0x03ff or char >= 0x1f00 and char <= 0x1fff or char == 0x2126) then
+ -- In the greek uppercase situation we want to remove diacritics except under some exceptions.
+ local first_datum = greek[char] or 0
+ local datum = first_datum
+ local upper = datum & UPPER_MASK
+ -- When a vowel ges an accent removed and does not have a dialytika and is followed by a Ι or Υ,
+ -- then this iota or ypsilon gets a dialytika.
+ if datum & HAS_VOWEL ~= 0 and seen_greek and seen_greek ~= true and (upper == 0x0399 or upper == 0x03a5) then
+ datum = datum | HAS_DIALYTIKA;
+ end
+ local has_ypogegrammeni = datum & HAS_YPOGEGRAMMENI ~= 0
+ local add_ypogegrammeni = has_ypogegrammeni
+ local post = getnext(n)
+ local last
+ local saved_tonos, saved_dialytika
+ while post do
+ local char = is_char(post, font)
+ if not char then break end
+ local diacritic_data = greek_diacritic[char]
+ if not diacritic_data then break end
+ -- Preserve flags to be aware if a dialytika has to be reinserted
+ -- TODO: Keep dialytika node around
+ datum = datum | diacritic_data
+ -- Preserve ypogegrammeni (iota subscript) but convert them into capital iotas.
+ -- If el-x-iota is active keep the combining character instead.
+ if diacritic_data & HAS_YPOGEGRAMMENI ~= 0 then
+ has_ypogegrammeni = true
+ if not greek_iota then
+ setchar(post, 0x0399)
+ end
+ last = post
+ post = getnext(post)
+ else
+ -- Otherwise they get removed
+ local old = post
+ head, post = remove(head, post)
+ if char == 0x0301 and not saved_tonos then
+ -- But if we have a tonos we might want to reinsert it later
+ saved_tonos = old
+ elseif diacritic_data & HAS_DIALYTIKA ~= 0 and not saved_dialytika then
+ -- Similar for dilytika
+ saved_dialytika = old
+ else
+ free(old)
+ end
+ end
+ end
+ -- Special case: An isolated Ή preserves the tonos.
+ if upper == 0x0397
+ and not has_ypogegrammeni
+ and not seen_cased
+ and not is_followed_by_cased(font, n, after)
+ then
+ if first_datum & HAS_ACCENT ~= 0 then
+ upper = 0x0389
+ -- If it's precomposed we don't have to keep any combining accents
+ if saved_tonos then
+ free(saved_tonos)
+ saved_tonos = nil
+ end
+ end
else
- mapping = seen_cased and is_Final_Sigma(font, mapping, n, after)
- or lang and is_Language_Mapping(font, mapping[lang], n, after, seen_soft_dotted, seen_I)
- or mapping._
- if #mapping == 0 then
- head, n = remove(head, n)
- goto continue
+ -- Not the special case so we don't have to keep the tonos node
+ if saved_tonos then
+ free(saved_tonos)
+ saved_tonos = nil
+ end
+ -- Handle precomposed dialytika. If both a combining ans a precomposed
+ -- dialyika are present (typically because the precomposed one is
+ -- automatically added at the beginning) prefer the combining one to
+ -- preserve attributes.
+ if datum & HAS_DIALYTIKA ~= 0 and not saved_dialytika then
+ if upper == 0x0399 then -- upper == 'Ι'
+ upper = 0x03AA
+ elseif upper == 0x03A5 then -- upper == 'Υ'
+ upper = 0x03AB
+ else
+ assert(false) -- Should not be possible
+ end
+ end
+ end
+ if greek_iota and add_ypogegrammeni then
+ local mapped = greek_precombined_iota[upper]
+ if mapped then -- AFAICT always true
+ upper = mapped
+ add_ypogegrammeni = false
+ end
+ end
+ setchar(n, upper)
+ -- Potentially reinsert accents
+ if saved_dialytika then
+ head, n = insert_after(head, n, saved_dialytika)
+ setchar(n, 0x0308) -- Needed since we might have a U+0344 (COMBINING GREEK DIALYTIKA TONOS)
+ end
+ if saved_tonos then
+ head, n = insert_after(head, n, saved_tonos)
+ end
+ if add_ypogegrammeni then
+ head, n = insert_after(head, n, copy(n))
+ setchar(n, 0x0399)
+ end
+ -- If we preserved any combining ypogegrammeni nodes, skip them now
+ n = last or n
+ seen_greek = datum & (HAS_VOWEL | HAS_ACCENT | HAS_DIALYTIKA) == HAS_VOWEL | HAS_ACCENT and n or true
+ seen_I, seen_soft_dotted = nil
+ else
+ local mapping = table[char]
+ if mapping then
+ if tonumber(mapping) then
+ setchar(n, mapping)
else
- setchar(n, mapping[1])
- for i=2, #mapping do
- head, n = insert_after(head, n, copy(n))
- setchar(n, mapping[i])
+ mapping = seen_cased and is_Final_Sigma(font, mapping, n, after)
+ or lang and is_Language_Mapping(font, mapping[lang], n, after, seen_soft_dotted, seen_I)
+ or mapping._
+ if #mapping == 0 then
+ local old = n
+ head, n = remove(head, n)
+ free(old)
+ goto continue
+ else
+ setchar(n, mapping[1])
+ for i=2, #mapping do
+ head, n = insert_after(head, n, copy(n))
+ setchar(n, mapping[i])
+ end
end
end
end
+ local char_ccc = ccc[char]
+ if not char_ccc or char_ccc == 230 then
+ seen_I = char == 0x49 or nil
+ seen_soft_dotted = soft_dotted[char]
+ end
+ seen_greek = nil
end
if not case_ignorable[char] then
seen_cased = cased[char] or nil
end
- local char_ccc = ccc[char]
- if not char_ccc or char_ccc == 230 then
- seen_I = char == 0x49 or nil
- seen_soft_dotted = soft_dotted[char]
- end
elseif id == disc and uses_font(n, font) then
local pre, post, rep = getdisc(n)
local after = getnext(n)
- pre, post, rep, seen_cased, seen_soft_dotted, seen_I =
- processor(pre, font, nil, seen_cased, seen_soft_dotted, seen_I),
- processor(post, font, after),
- processor(rep, font, after, seen_cased, seen_soft_dotted, seen_I)
+ pre, post, rep, seen_cased, seen_soft_dotted, seen_I, seen_greek =
+ processor(pre, font, nil, seen_cased, seen_soft_dotted, seen_I, seen_greek),
+ processor(post, font, after, seen_greek),
+ processor(rep, font, after, seen_cased, seen_soft_dotted, seen_I, seen_greek)
setdisc(n, pre, post, rep)
else
seen_cased, seen_soft_dotted, seen_I = nil
@@ -207,12 +425,12 @@ local function process(table)
n = getnext(n)
::continue::
end
- return head, seen_cased, seen_soft_dotted, seen_I
+ return head, seen_cased, seen_soft_dotted, seen_I, seen_greek
end
- return function(head, font) return (processor(head, font)) end
+ return function(head, font, ...) return (processor(head, font)) end
end
-local upper_process = process(uppercase)
+local upper_process = process(uppercase, 'upper')
otfregister {
name = 'upper',
description = 'Map to uppercase',
@@ -225,7 +443,7 @@ otfregister {
},
}
-local lower_process = process(lowercase)
+local lower_process = process(lowercase, 'lower')
otfregister {
name = 'lower',
description = 'Map to lowercase',
diff --git a/macros/luatex/generic/luaotfload/luaotfload-colors.lua b/macros/luatex/generic/luaotfload/luaotfload-colors.lua
index 05248b2a82..075b5210f5 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-colors.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-colors.lua
@@ -5,8 +5,8 @@
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-colors",
- version = "3.21", --TAGVERSION
- date = "2022-03-18", --TAGDATE
+ version = "3.22", --TAGVERSION
+ date = "2022-06-15", --TAGDATE
description = "luaotfload submodule / color",
license = "GPL v2.0",
author = "Khaled Hosny, Elie Roux, Philipp Gesang, Dohyun Kim, David Carlisle",
@@ -48,18 +48,22 @@ local nodetail = nodedirect.tail
local getattribute = nodedirect.has_attribute
local setattribute = nodedirect.set_attribute
+local call_callback = luatexbase.call_callback
+
local stringformat = string.format
local identifiers = fonts.hashes.identifiers
local add_color_callback --[[ this used to be a global‽ ]]
+local custom_setcolor, custom_settransparent
+
--[[doc--
Color string 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 C, Cc, P, R, S = lpeg.C, lpeg.Cc, lpeg.P, lpeg.R, lpeg.S
local spaces = S"\t "^0
local digit16 = R("09", "af", "AF")
@@ -68,12 +72,43 @@ local octet = digit16 * digit16 / function(s)
return tonumber(s, 16) / 255
end
-local extract_color = spaces * octet * octet * octet / function(r,g,b)
+local function lpeg_repeat(patt, count)
+ patt = P(patt)
+ local result = patt
+ for i = 2, count do
+ result = result * patt
+ end
+ return result
+end
+
+local split_color = spaces * C(lpeg_repeat(digit16, 6)) * (opaque + C(lpeg_repeat(digit16, 2)))^-1 * spaces * -1
+ + spaces * (C((spaces * (1 - S', ')^1)^1) + Cc(nil)) * spaces * (',' * spaces * C((spaces * (1 - S' ,')^1)^1)^-1 * spaces)^-1 * -1
+
+luatexbase.create_callback('luaotfload.split_color', 'exclusive', function(value)
+ local rgb, a = lpegmatch(split_color, value)
+ if not rgb and not a then
+ logreport("both", 0, "color",
+ "%q is not a valid rgb[a] color expression",
+ digits)
+ end
+ return rgb, a
+end)
+
+local extract_color = octet * octet * octet / function(r,g,b)
return stringformat("%.3g %.3g %.3g rg", r, g, b)
- end * (opaque + octet)^-1 * spaces * -1
+ end * -1
+luatexbase.create_callback('luaotfload.parse_color', 'exclusive', function(value)
+ local rgb = lpegmatch(extract_color, value)
+ if not rgb then
+ logreport("both", 0, "color",
+ "Invalid color part in color expression %q",
+ value)
+ end
+ return rgb
+end)
---- something is carried around in ``res``
---- for later use by color_handler() --- but what?
+-- Keep the currently collected page resources needed for the current
+-- colors in `res`.
local res = nil
@@ -86,17 +121,37 @@ local function pageresources(alpha)
return f
end
+local extract_transparent = octet * -1
+luatexbase.create_callback('luaotfload.parse_transparent', 'exclusive', function(value)
+ local a
+ if type(value) == 'string' then
+ a = lpegmatch(extract_transparent, value)
+ if not a then
+ logreport("both", 0, "color",
+ "Invalid transparency part in color expression %q",
+ value)
+ end
+ else
+ a = value
+ end
+ if a then
+ a = pageresources(a)
+ end
+ return a
+end)
+
+
--- string -> (string | nil)
local function sanitize_color_expression (digits)
digits = tostring(digits)
- local rgb, a = lpegmatch(extract_color, digits)
- if not rgb then
- logreport("both", 0, "color",
- "%q is not a valid rgb[a] color expression",
- digits)
- return
+ local rgb, a = call_callback('luaotfload.split_color', digits)
+ if rgb then
+ rgb = call_callback('luaotfload.parse_color', rgb)
end
- return rgb, (a and pageresources(a))
+ if a then
+ a = call_callback('luaotfload.parse_transparent', a)
+ end
+ return rgb, a
end
local color_stack = 0
@@ -125,8 +180,6 @@ local colorstack_t = node.subtype("pdf_colorstack")
local color_callback
local color_attr = luatexbase.new_attribute("luaotfload_color_attribute")
-local custom_setcolor
-
-- Pass nil for new_color or old_color to indicate no color
-- If color is nil, pass tail to decide where to add whatsit
local function color_whatsit (head, curr, stack, old_color, new_color, tail)
@@ -391,8 +444,38 @@ end
function luaotfload.set_colorhandler(cb)
custom_setcolor = cb
end
+function luaotfload.set_transparenthandler(cb)
+ custom_settransparent = cb
+end
+function luaotfload.set_transparent_colorstack(stack)
+ if type(transparent_stack) == 'number' then
+ tex.error"luaotfload's transparency stack can't be changed after it has been used"
+ else
+ local t = type(stack)
+ if t == 'function' or t == 'number' then
+ function transparent_stack()
+ if t == 'function' then
+ transparent_stack = stack()
+ else
+ transparent_stack = stack
+ end
+ return transparent_stack
+ end
+ else
+ tex.error("Invalid argument in luaotfload.set_transparent_colorstack")
+ end
+ end
+end
+
+setmetatable(fonts.handlers.otf.statistics.usedfeatures.color, {
+ __index = function(t, k)
+ t[k] = k
+ return k
+ end,
+})
return function ()
+ assert(logreport == luaotfload.log.report)
logreport = luaotfload.log.report
if not fonts then
logreport ("log", 0, "color",
diff --git a/macros/luatex/generic/luaotfload/luaotfload-conf.pdf b/macros/luatex/generic/luaotfload/luaotfload-conf.pdf
index 187f6d6542..ba983ed74c 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-conf.pdf
+++ b/macros/luatex/generic/luaotfload/luaotfload-conf.pdf
Binary files differ
diff --git a/macros/luatex/generic/luaotfload/luaotfload-configuration.lua b/macros/luatex/generic/luaotfload/luaotfload-configuration.lua
index 5a7205ba69..8368425334 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-configuration.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-configuration.lua
@@ -7,8 +7,8 @@
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-configuration",
- version = "3.21", --TAGVERSION
- date = "2022-03-18", --TAGDATE
+ version = "3.22", --TAGVERSION
+ date = "2022-06-15", --TAGDATE
description = "luaotfload submodule / config file reader",
license = "GPL v2.0"
}
diff --git a/macros/luatex/generic/luaotfload/luaotfload-database.lua b/macros/luatex/generic/luaotfload/luaotfload-database.lua
index ff43b97505..63f799ca41 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-database.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-database.lua
@@ -5,8 +5,8 @@
do -- block to avoid to many local variables error
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-database",
- version = "3.21", --TAGVERSION
- date = "2022-03-18", --TAGDATE
+ version = "3.22", --TAGVERSION
+ date = "2022-06-15", --TAGDATE
description = "luaotfload submodule / database",
license = "GPL v2.0",
author = "Khaled Hosny, Elie Roux, Philipp Gesang, Marcel Krüger",
@@ -201,7 +201,7 @@ local resolversfindfile = context_environment.resolvers.findfile
--- some of our own
local unicode = require'luaotfload-unicode'
-local casefold = unicode.casefold
+local casefold = require'lua-uni-case'.casefold
local alphnum_only = unicode.alphnum_only
local name_index = nil --> upvalue for names.data
@@ -516,8 +516,11 @@ end
local function load_lua_file (path_lua, path_luc)
local foundname, chunk = load_maybe_gzip (path_luc, true)
if foundname then
- chunk = assert (load (chunk, 'b'))
+ chunk = load (chunk, 'b')
else
+ chunk = nil
+ end
+ if not chunk then
foundname, chunk = load_maybe_gzip (path_lua, false)
if foundname then
chunk = assert (load (chunk, 't'))
@@ -2435,7 +2438,7 @@ local function count_removed (files)
local f = old[i]
if not kpsereadable_file (f) then
logreport ("log", 2, "db",
- "File %q does not exist in file system.")
+ "File %q does not exist in file system.", f)
nrem = nrem + 1
end
end
diff --git a/macros/luatex/generic/luaotfload/luaotfload-diagnostics.lua b/macros/luatex/generic/luaotfload/luaotfload-diagnostics.lua
index e0403d932c..25f79419a6 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-diagnostics.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-diagnostics.lua
@@ -7,8 +7,8 @@
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-diagnostics",
- version = "3.21", --TAGVERSION
- date = "2022-03-18", --TAGDATE
+ version = "3.22", --TAGVERSION
+ date = "2022-06-15", --TAGDATE
description = "luaotfload-tool submodule / diagnostics",
license = "GPL v2.0"
}
diff --git a/macros/luatex/generic/luaotfload/luaotfload-dvi.lua b/macros/luatex/generic/luaotfload/luaotfload-dvi.lua
index 3991eb110d..da045d1d34 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-dvi.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-dvi.lua
@@ -6,8 +6,8 @@
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-dvi",
- version = "3.21", --TAGVERSION
- date = "2022-03-18", --TAGDATE
+ version = "3.22", --TAGVERSION
+ date = "2022-06-15", --TAGDATE
description = "luaotfload submodule / DVI",
license = "GPL v2.0",
author = "Marcel Krüger",
diff --git a/macros/luatex/generic/luaotfload/luaotfload-embolden.lua b/macros/luatex/generic/luaotfload/luaotfload-embolden.lua
index 5699611da3..7bc4da5a76 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-embolden.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-embolden.lua
@@ -5,8 +5,8 @@
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-embolden",
- version = "3.21", --TAGVERSION
- date = "2022-03-18", --TAGDATE
+ version = "3.22", --TAGVERSION
+ date = "2022-06-15", --TAGDATE
description = "luaotfload submodule / embolden",
license = "GPL v2.0",
author = "Marcel Krüger"
diff --git a/macros/luatex/generic/luaotfload/luaotfload-fallback.lua b/macros/luatex/generic/luaotfload/luaotfload-fallback.lua
index d9a85b7578..253d16051c 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-fallback.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-fallback.lua
@@ -5,8 +5,8 @@
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-fallback",
- version = "3.21", --TAGVERSION
- date = "2022-03-18", --TAGDATE
+ version = "3.22", --TAGVERSION
+ date = "2022-06-15", --TAGDATE
description = "luaotfload submodule / fallback",
license = "GPL v2.0",
author = "Marcel Krüger"
diff --git a/macros/luatex/generic/luaotfload/luaotfload-features.lua b/macros/luatex/generic/luaotfload/luaotfload-features.lua
index 01c04becb1..6e64020570 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-features.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-features.lua
@@ -5,8 +5,8 @@
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-features",
- version = "3.21", --TAGVERSION
- date = "2022-03-18", --TAGDATE
+ version = "3.22", --TAGVERSION
+ date = "2022-06-15", --TAGDATE
description = "luaotfload submodule / features",
license = "GPL v2.0",
author = "Hans Hagen, Khaled Hosny, Elie Roux, Philipp Gesang, Marcel Krüger",
@@ -30,8 +30,6 @@ local table = table
local tabletohash = table.tohash
local tablesort = table.sort
-local stringunpack = string.unpack
-
--- this appears to be based in part on luatex-fonts-def.lua
local fonts = fonts
@@ -56,15 +54,6 @@ else
normalize = otf.features.normalize
end
---[[HH (font-xtx) --
- tricky: we sort of bypass the parser and directly feed all into
- the sub parser
---HH]]--
-
-function definers.getspecification(str)
- return "", str, "", ":", str
-end
-
local log = luaotfload.log
local report = log.report
@@ -76,7 +65,7 @@ local function cmp_by_idx (a, b) return a.idx < b.idx end
local defined_combos = 0
-local function handle_combination (combo, spec)
+local function handle_combination (combo, spec, size)
defined_combos = defined_combos + 1
if not combo [1] then
report ("both", 0, "features",
@@ -143,7 +132,7 @@ local function handle_combination (combo, spec)
local basechar = basefnt.characters
local baseprop = basefnt.properties
- baseprop.name = spec.name
+ baseprop.name = spec
baseprop.virtualized = true
basefnt.fonts = fontids
@@ -194,13 +183,16 @@ local function handle_combination (combo, spec)
" *> font %d / %d: imported %d glyphs into combo.",
i, nc, cnt)
end
- spec.lookup = "combo"
- spec.file = basefnt.filename
- spec.name = stringformat ("luaotfload<%d>", defined_combos)
- spec.features = { normal = { spec.specification } }
- spec.forced = "evl"
- spec.eval = function () return basefnt end
- return spec
+ return {
+ lookup = "combo",
+ file = basefnt.filename,
+ name = stringformat ("luaotfload<%d>", defined_combos),
+ specification = spec,
+ features = { normal = { } },
+ forced = "evl",
+ eval = function () return basefnt end,
+ size = size,
+ }
end
---[[ begin excerpt from font-ott.lua ]]
@@ -359,10 +351,9 @@ do
extract_subfont = full_path * sub_expr
end
---- spec -> spec
-local function handle_request (specification)
+local function analyze(spec_string, size)
local request = lpegmatch(luaotfload.parsers.font_request,
- specification.specification)
+ spec_string)
----inspect(request)
if not request then
--- happens when called with an absolute path
@@ -370,7 +361,7 @@ local function handle_request (specification)
--- we try to behave as friendly as possible
--- just go with it ...
report("log", 1, "features", "invalid request %q of type anon",
- specification.specification)
+ spec_string)
report("log", 1, "features",
"use square bracket syntax or consult the documentation.")
--- The result of \fontname must be re-feedable into \font
@@ -382,36 +373,62 @@ local function handle_request (specification)
--- parentheses).
--- https://github.com/lualatex/luaotfload/issues/57
local fullpath, sub = lpegmatch(extract_subfont,
- specification.specification)
+ spec_string)
if fullpath and sub then
- specification.sub = tonumber(sub) or sub
- specification.name = fullpath
+ return {
+ lookup = 'path',
+ sub = tonumber(sub) or sub,
+ name = fullpath,
+ size = size,
+ }
else
- specification.name = specification.specification
+ return {
+ lookup = 'path',
+ name = spec_string,
+ size = size,
+ }
end
- specification.lookup = "path"
- return specification
end
local lookup, name = request.lookup, request.name
if lookup == "combo" then
- return handle_combination (name, specification)
+ return handle_combination (name, spec_string, size)
end
- local features = specification.features
- if not features then
- features = { }
- specification.features = features
- end
+ local features = {
+ raw = request.features or {}
+ }
- features.raw = request.features or {}
- request.features = apply_default_features(features.raw)
+ local specification = {
+ specification = spec_string,
+ size = size,
+ lookup = lookup,
+ name = name,
+ sub = request.sub or false,
+ features = features,
+ }
- if name then
- specification.name = name
- specification.lookup = lookup or specification.lookup
+ if lookup == 'id' then
+ local original_font = fontidentifiers [request.id]
+ if not original_font then return end
+ local original_spec = original_font.specification
+ if not original_spec then return end
+ if size < 0 then
+ specification.size = original_spec.size * size // -1000
+ end
+ specification.lookup = original_spec.lookup
+ specification.name = original_spec.name
+ specification.sub = specification.sub or original_spec.sub
+ specification.style = original_spec.style
+ specification.optsize = original_spec.optsize
+ specification.forced = original_spec.forced
+ if original_spec.features then
+ features.raw = table.merged(original_spec.features.raw, features.raw)
+ end
end
+ local processed_features = apply_default_features(features.raw)
+
if request.modifiers then
local style, optsize = handle_slashed(request.modifiers)
specification.style, specification.optsize = style, optsize
@@ -420,11 +437,11 @@ local function handle_request (specification)
for n=1, #import_values do
local feat = import_values[n][1]
local keep = import_values[n][2]
- local newvalue = request.features[feat]
+ local newvalue = processed_features[feat]
if newvalue then
- specification[feat] = request.features[feat]
+ specification[feat] = newvalue
if not keep then
- request.features[feat] = nil
+ processed_features[feat] = nil
end
end
end
@@ -432,7 +449,7 @@ local function handle_request (specification)
--- The next line sets the “rand” feature to “random”; I haven’t
--- investigated it any further (luatex-fonts-ext), so it will
--- just stay here.
- features.normal = normalize (request.features)
+ features.normal = normalize (processed_features)
if features.normal.instance then
if features.normal.axis then
report("term and log", 0, "features", "instance and axis provided, instance will be ignored")
@@ -440,7 +457,6 @@ local function handle_request (specification)
specification.instance = features.normal.instance
end
end
- specification.sub = request.sub or specification.sub or false
local forced_mode = request.features and request.features.mode
if forced_mode then
@@ -453,8 +469,7 @@ local function handle_request (specification)
return specification
end
-fonts.names.handle_request = handle_request
-
+fonts.definers.analyze = analyze
if as_script == true then --- skip the remainder of the file
report ("log", 5, "features",
@@ -463,7 +478,7 @@ if as_script == true then --- skip the remainder of the file
end
do
- local helpers = fonts.handlers.otf.readers.helpers
+ local helpers = otf.readers.helpers
local axistofactors = helpers.axistofactors
local cleanname = helpers.cleanname
local getaxisscale = helpers.getaxisscale
@@ -479,7 +494,7 @@ do
function helpers.getfactors(tfmdata, instance) -- `instance` might refer to an `axis` value here
assert(instance == true or type(instance) == "string", "Fontloader changed interface of helpers.getfactors. This is a bug, please notify the luaotfload maintainers.")
local variabledata = tfmdata.variabledata
- if not variabledata or instance == "" then return end
+ if not variabledata then return end
local instances = variabledata.instances
local axis = variabledata.axis
local designaxis = variabledata.designaxis
@@ -525,15 +540,6 @@ do
end
end
--- MK: Added
-function fonts.definers.analyze (spec_string, size)
- return handle_request {
- size = size,
- specification = spec_string,
- }
-end
--- /MK
-
-- We assume that the other otf stuff is loaded already; though there’s
-- another check below during the initialization phase.
diff --git a/macros/luatex/generic/luaotfload/luaotfload-filelist.lua b/macros/luatex/generic/luaotfload/luaotfload-filelist.lua
index 191e6fd81b..a5dac9e640 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-filelist.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-filelist.lua
@@ -6,8 +6,8 @@
if luaotfload_module then luaotfload_module {
name = "luaotfload-filelist",
- version = "3.21", --TAGVERSION
- date = "2022-03-18", --TAGDATE
+ version = "3.22", --TAGVERSION
+ date = "2022-06-15", --TAGDATE
description = "luaotfload submodule / filelist",
license = "GPL v2.0"
} end
diff --git a/macros/luatex/generic/luaotfload/luaotfload-glyphlist.lua b/macros/luatex/generic/luaotfload/luaotfload-glyphlist.lua
index b13d9db86f..f585e298b8 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-glyphlist.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-glyphlist.lua
@@ -1,8 +1,8 @@
if luaotfload_module then
luaotfload_module {
name = "luaotfload-glyphlist",
- version = "3.21", --TAGVERSION
- date = "2022-03-18", --TAGDATE
+ version = "3.22", --TAGVERSION
+ date = "2022-06-15", --TAGDATE
description = "luaotfload submodule / autogenerated glyphlist",
copyright = "derived from https://raw.githubusercontent.com/adobe-type-tools/agl-aglfn/master/glyphlist.txt",
original = "Adobe Glyph List, version 2.0, September 20, 2002",
diff --git a/macros/luatex/generic/luaotfload/luaotfload-harf-define.lua b/macros/luatex/generic/luaotfload/luaotfload-harf-define.lua
index d311020cd4..c3b0a8509e 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-harf-define.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-harf-define.lua
@@ -5,8 +5,8 @@
do -- block to avoid to many local variables error
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-harf-define",
- version = "3.21", --TAGVERSION
- date = "2022-03-18", --TAGDATE
+ version = "3.22", --TAGVERSION
+ date = "2022-06-15", --TAGDATE
description = "luaotfload submodule / HarfBuzz font loading",
license = "GPL v2.0",
author = "Khaled Hosny, Marcel Krüger",
@@ -87,7 +87,7 @@ local variable_pattern do
local number = l.C(l.S'+-'^-1 * (l.R'09'^1 * ('.' * l.R'09'^0)^-1 + '.' * l.R'09'^1))
local name_or_tag = l.C(l.R('AZ', 'az')^1)
local pair = l.Ct(name_or_tag * white * '=' * white * (number + l.Cc(nil) * 'auto'))
- variable_pattern = l.Ct(pair * (white * ',' * white * pair)^0)
+ variable_pattern = l.Ct(pair * (white * ',' * white * pair)^0) * -1
end
local function loadfont(spec)
diff --git a/macros/luatex/generic/luaotfload/luaotfload-harf-plug.lua b/macros/luatex/generic/luaotfload/luaotfload-harf-plug.lua
index be05980a49..df0d0cf136 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-harf-plug.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-harf-plug.lua
@@ -4,8 +4,8 @@
-----------------------------------------------------------------------
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-harf-plug",
- version = "3.21", --TAGVERSION
- date = "2022-03-18", --TAGDATE
+ version = "3.22", --TAGVERSION
+ date = "2022-06-15", --TAGDATE
description = "luaotfload submodule / HarfBuzz shaping",
license = "GPL v2.0",
author = "Khaled Hosny, Marcel Krüger",
@@ -136,8 +136,8 @@ local function setprop(n, prop, value)
props[prop] = value
end
-local function inherit(t, base, properties)
- local n = newnode(t)
+local function inherit(t, sub, base, properties)
+ local n = newnode(t, sub)
setattrs(n, getattrs(base))
if properties then
setproperty(n, setmetatable({}, {__index = properties}))
@@ -146,7 +146,7 @@ local function inherit(t, base, properties)
end
-- New kern node of amount `v`, inheriting the properties/attributes of `n`.
local function newkern(v, n)
- local kern = inherit(kern_t, n, getproperty(n))
+ local kern = inherit(kern_t, 0, n, getproperty(n))
setkern(kern, v)
return kern
end
@@ -293,7 +293,7 @@ end
local function unsafetobreak(glyph)
return glyph
and glyph.flags
- and glyph.flags & fl_unsafe
+ and glyph.flags & fl_unsafe ~= 0
end
local shape
@@ -782,11 +782,11 @@ local function tonodes(head, node, run, glyphs)
elseif nextcluster + 1 == nodeindex then -- Oops, we went too far
nodeindex = nodeindex - 1
if node then
- local new = inherit(glyph_t, getprev(node), lastprops)
+ local new = inherit(glyph_t, 0, getprev(node), lastprops)
head, node = insertbefore(head, node, new)
else
node = tail(head)
- local new = inherit(glyph_t, node, lastprops)
+ local new = inherit(glyph_t, 0, node, lastprops)
head, node = insertafter(head, node, new)
end
setfont(node, fontid)
@@ -1050,8 +1050,8 @@ function process(head, font, _attr, direction)
return newhead or head
end
-local function pageliteral(data)
- local n = newnode(whatsit_t, pdfliteral_t)
+local function pageliteral(data, base)
+ local n = inherit(whatsit_t, pdfliteral_t, base, getproperty(base))
setwhatsitfield(n, "mode", 1) -- page
setwhatsitfield(n, "data", data) -- page
return n
@@ -1069,12 +1069,12 @@ local function post_process(head)
if startactual then
local actualtext = "/Span<</ActualText<FEFF"..startactual..">>>BDC"
- head = insertbefore(head, n, pageliteral(actualtext))
+ head = insertbefore(head, n, pageliteral(actualtext, n))
props[startactual_p] = nil
end
if endactual then
- head = insertafter(head, n, pageliteral("EMC"))
+ head = insertafter(head, n, pageliteral("EMC", n))
props[endactual_p] = nil
end
diff --git a/macros/luatex/generic/luaotfload/luaotfload-harf-var-cff2.lua b/macros/luatex/generic/luaotfload/luaotfload-harf-var-cff2.lua
index e9cff0c1ad..2ca928d32a 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-harf-var-cff2.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-harf-var-cff2.lua
@@ -5,8 +5,8 @@
do
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-harf-var-cff2",
- version = "3.21", --TAGVERSION
- date = "2022-03-18", --TAGDATE
+ version = "3.22", --TAGVERSION
+ date = "2022-06-15", --TAGDATE
description = "luaotfload submodule / CFF2 table processing",
license = "GPL v2.0",
author = "Marcel Krüger",
@@ -371,7 +371,7 @@ local function parse_vstore(buf, offset, variation)
return variation_data
end
-function parse_cff2(buf, i0, coords)
+local function parse_cff2(buf, i0, coords)
local fontid = 1
local major, minor, hdrSize, topSize = string.unpack(">BBBH", buf, i0)
if major ~= 2 then error[[Unsupported CFF version]] end
diff --git a/macros/luatex/generic/luaotfload/luaotfload-harf-var-t2-writer.lua b/macros/luatex/generic/luaotfload/luaotfload-harf-var-t2-writer.lua
index 7b44822e59..72239343d8 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-harf-var-t2-writer.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-harf-var-t2-writer.lua
@@ -5,8 +5,8 @@
do
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-harf-var-t2-writer",
- version = "3.21", --TAGVERSION
- date = "2022-03-18", --TAGDATE
+ version = "3.22", --TAGVERSION
+ date = "2022-06-15", --TAGDATE
description = "luaotfload submodule / Type 2 charstring writer",
license = "GPL v2.0",
author = "Marcel Krüger",
diff --git a/macros/luatex/generic/luaotfload/luaotfload-harf-var-ttf.lua b/macros/luatex/generic/luaotfload/luaotfload-harf-var-ttf.lua
index 7835466757..b39cd753ae 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-harf-var-ttf.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-harf-var-ttf.lua
@@ -5,8 +5,8 @@
do
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-harf-var-ttf",
- version = "3.21", --TAGVERSION
- date = "2022-03-18", --TAGDATE
+ version = "3.22", --TAGVERSION
+ date = "2022-06-15", --TAGDATE
description = "luaotfload submodule / gvar table processing",
license = "GPL v2.0",
author = "Marcel Krüger",
@@ -166,11 +166,12 @@ local function parse_glyf(loca, glyf, gid)
payload_length = payload_length + 8
end
if flags & 0x120 == 0x100 then -- Only applies to the last character
- payload_length = payload_length + 2 + sio.readcardinal2(offset + payload_length)
+ payload_length = payload_length + 2 + sio.readcardinal2(glyf, offset + payload_length)
end
component.flags = flags
component.payload = glyf:sub(offset, offset + payload_length - 1)
components[#components+1] = component
+ offset = offset + payload_length
until flags & 0x20 == 0
return components
else
@@ -328,6 +329,9 @@ local function serialize_glyf(points, map)
local x, y = component.x, component.y
x = x and math.floor(x + .5)
y = y and math.floor(y + .5)
+ if component.flags & 0x3 == 0x2 and (x >= 0x100 or x < -0x100 or y >= 0x100 or y < 0x100) then
+ component.flags = component.flags | 0x1
+ end
result = result
.. string.pack(component.flags & 0x2 == 0 and '>I2I2'
or component.flags & 0x1 == 0x1 and '>I2I2i2i2'
@@ -395,7 +399,13 @@ local function interpolate_glyf(loca, gvar_index, gvar, glyf, gid, coords, map)
if not var then
local start = loca[gid+1] + 1
local stop = loca[gid+2]
- return glyf:sub(start, stop)
+ -- If the glyph uses components then we can never just copy it but have to parse
+ -- it to rewrite the components if necessary.
+ if stop >= start + 2 and sio.readinteger2(glyf, start) < 0 then
+ return serialize_glyf(parse_glyf(loca, glyf, gid), map)
+ else
+ return glyf:sub(start, stop)
+ end
end
local points = parse_glyf(loca, glyf, gid)
if not points then return '' end
diff --git a/macros/luatex/generic/luaotfload/luaotfload-hashing.lua b/macros/luatex/generic/luaotfload/luaotfload-hashing.lua
new file mode 100644
index 0000000000..e88eab706c
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/luaotfload-hashing.lua
@@ -0,0 +1,2 @@
+local constructors = fonts.constructors
+local original_hashfeatures = constructors.hashfeatures
diff --git a/macros/luatex/generic/luaotfload/luaotfload-init.lua b/macros/luatex/generic/luaotfload/luaotfload-init.lua
index 8cb2b5ad3d..ff959e3502 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-init.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-init.lua
@@ -7,8 +7,8 @@
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-init",
- version = "3.21", --TAGVERSION
- date = "2022-03-18", --TAGDATE
+ version = "3.22", --TAGVERSION
+ date = "2022-06-15", --TAGDATE
description = "luaotfload submodule / initialization",
license = "GPL v2.0"
}
diff --git a/macros/luatex/generic/luaotfload/luaotfload-latex.pdf b/macros/luatex/generic/luaotfload/luaotfload-latex.pdf
index 966f94bea2..ef2cea7a10 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-latex.pdf
+++ b/macros/luatex/generic/luaotfload/luaotfload-latex.pdf
Binary files differ
diff --git a/macros/luatex/generic/luaotfload/luaotfload-latex.tex b/macros/luatex/generic/luaotfload/luaotfload-latex.tex
index 40b01af0de..b19fb2b665 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-latex.tex
+++ b/macros/luatex/generic/luaotfload/luaotfload-latex.tex
@@ -35,18 +35,18 @@
\makeatletter
-\usepackage {metalogo,multicol,fancyvrb,xspace}
+\usepackage {metalogo,multicol,fancyvrb}
\usepackage [x11names] {xcolor}
-\def \primarycolor {DodgerBlue4} %%-> rgb 16 78 139 | #104e8b
-\def \secondarycolor {Goldenrod4} %%-> rgb 139 105 200 | #8b6914
+\colorlet{primary}{DodgerBlue4}
+\colorlet{secondary}{Goldenrod4}
\usepackage[
bookmarks=true,
colorlinks=true,
- linkcolor=\primarycolor,
- urlcolor=\secondarycolor,
- citecolor=\primarycolor,
+ linkcolor=primary,
+ urlcolor=secondary,
+ citecolor=primary,
unicode,
pdftitle={The Luaotfload package},
pdfsubject={OpenType layout system for Plain TeX and LaTeX},
@@ -58,11 +58,8 @@
\usepackage {unicode-math}
\setmainfont[
-% Numbers = OldStyle, %% buggy with font cache
+ Numbers = OldStyle, %% buggy with font cache
Ligatures = TeX,
- BoldFont = {Linux Libertine O Bold},
- ItalicFont = {Linux Libertine O Italic},
- SlantedFont = {Linux Libertine O Italic},
]{Linux Libertine O}
\setmonofont[Ligatures=TeX,Scale=MatchLowercase]{InconsolataN-Regular.otf}
%setsansfont[Ligatures=TeX]{Linux Biolinum O}
@@ -71,15 +68,9 @@
\usepackage{hologo}
-\newcommand\TEX {\TeX\xspace}
-\newcommand\LUA {Lua\xspace}
-\newcommand\PDFTEX {pdf\TeX\xspace}
-\newcommand\LUATEX {Lua\TeX\xspace}
-\newcommand\XETEX {\XeTeX\xspace}
-\newcommand\LATEX {\LaTeX\xspace}
-\newcommand\LUALATEX {Lua\LaTeX\xspace}
-\newcommand\CONTEXT {Con\TeX t\xspace}
-\newcommand\OpenType {\identifier{Open\kern-.25ex Type}\xspace}
+\newcommand\Lua {Lua}
+\newcommand\ConTeXt {\hologo{ConTeXt}}
+\newcommand\OpenType {\identifier{Open\kern-.25ex Type}}
%% \groupedcommand, with some omissions taken from syst-aux.mkiv
\let \handlegroupnormalbefore \relax
diff --git a/macros/luatex/generic/luaotfload/luaotfload-letterspace.lua b/macros/luatex/generic/luaotfload/luaotfload-letterspace.lua
index 311279f09d..ef19afe384 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-letterspace.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-letterspace.lua
@@ -5,8 +5,8 @@
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-letterspace",
- version = "3.21", --TAGVERSION
- date = "2022-03-18", --TAGDATE
+ version = "3.22", --TAGVERSION
+ date = "2022-06-15", --TAGDATE
description = "luaotfload submodule / letterspacing",
license = "GPL v2.0",
copyright = "PRAGMA ADE / ConTeXt Development Team",
diff --git a/macros/luatex/generic/luaotfload/luaotfload-loaders.lua b/macros/luatex/generic/luaotfload/luaotfload-loaders.lua
index fcae6e6d9e..eb09443077 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-loaders.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-loaders.lua
@@ -8,8 +8,8 @@
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-loaders",
- version = "3.21", --TAGVERSION
- date = "2022-03-18", --TAGDATE
+ version = "3.22", --TAGVERSION
+ date = "2022-06-15", --TAGDATE
description = "luaotfload submodule / callback handling",
license = "GPL v2.0"
}
@@ -104,32 +104,80 @@ local function not_found_msg (specification, size, id)
logreport ("both", 0, "loaders",
"--------------------------------------------------------")
end
---[[doc--
- \subsection{\CONTEXT override}
- \label{define-font}
- We provide a simplified version of the original font definition
- callback.
+local definers --- (string, spec -> size -> id -> tmfdata) hash_t
+do
+ local hashed_cache = {}
+ local fontdata_cache = fonts.hashes.identifiers
+ local function register(fontdata, id)
+ if fontdata and id then
+ local hash = fontdata.properties.hash
+ if not hash then
+ logreport('both', 2, 'loaders', "Registering font %s with id %s with missing hash.", id, fontdata.properties.filename or "unknown")
+ elseif not hashed_cache[hash] then
+ hashed_cache[hash] = id
+ logreport('both', 4, 'loaders', "Registering font %s with id %s and hash %s.", id, fontdata.properties.filename or "unknown", hash)
+ end
+ fontdata_cache[id] = fontdata
+ end
+ end
+ function registered(hash)
+ local id = hashed_cache[hash]
+ return id, fontdata_cache[id]
+ end
+ fonts.definers.register = register
+ fonts.definers.registered = registered
---doc]]--
+ local extra_hash_funcs = {}
+ local function ltx_read(spec, size, id)
+ spec = type(spec) == 'string' and fonts.definers.analyze(spec, size) or spec
+ spec = fonts.definers.resolve(spec)
+
+ local hash = fonts.constructors.hashinstance(spec)
+
+ -- extra_hash_func allows the loader to determine additional hash parts
+ -- depending on the actual font. This is used e.g. for variable fonts which
+ -- should be hashed based on their designsize / modifiers too.
+ local extra_hash_func = extra_hash_funcs[hash]
+ if extra_hash_func then
+ hash = hash .. ' @ ' .. table.join(extra_hash_func(spec), ' @ ')
+ end
+
+ local cached = registered(hash)
+ if cached then return cached end -- already loaded
+
+ local fontdata = fonts.definers.loadfont(spec)
+ if not fontdata then
+ logreport('both', 2, 'loaders', 'Failed to load font ' .. spec.name)
+ return
+ end
+
+ -- If extra_hash_func was already set then the hash is already extended.
+ -- Otherwise we have to do it now if requested.
+ if not extra_hash_func then
+ extra_hash_func = fontdata.properties.extra_hash_func
+ if extra_hash_func then
+ hash = hash .. ' @ ' .. table.join(extra_hash_func(spec), ' @ ')
+ end
+ end
+ fontdata.properties.hash = hash
+ register(fontdata, id)
+ return fontdata
+ end
-local definers --- (string, spec -> size -> id -> tmfdata) hash_t
-do
- local ctx_read = fonts.definers.read
- local register = fonts.definers.register
local function read(specification, size, id)
- local tfmdata = ctx_read(specification, size, id)
- if not tfmdata or id or tonumber(tfmdata) then
- return tfmdata
+ local fontdata = ltx_read(specification, size, id)
+ if not fontdata or id or tonumber(fontdata) then
+ return fontdata
end
- id = font.define(tfmdata)
- register(tfmdata, id)
+ id = font.define(fontdata)
+ register(fontdata, id)
return id
end
local function patch (specification, size, id)
- local fontdata = ctx_read (specification, size, id)
+ local fontdata = ltx_read (specification, size, id)
----if not fontdata then not_found_msg (specification, size, id) end
if type (fontdata) == "table" and fontdata.encodingbytes == 2 then
--- We need to test for `encodingbytes` to avoid passing
diff --git a/macros/luatex/generic/luaotfload/luaotfload-log.lua b/macros/luatex/generic/luaotfload/luaotfload-log.lua
index 8622b465ef..74b364e874 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-log.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-log.lua
@@ -6,8 +6,8 @@
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-log",
- version = "3.21", --TAGVERSION
- date = "2022-03-18", --TAGDATE
+ version = "3.22", --TAGVERSION
+ date = "2022-06-15", --TAGDATE
description = "luaotfload submodule / logging",
license = "GPL v2.0",
author = "Khaled Hosny, Elie Roux, Philipp Gesang",
diff --git a/macros/luatex/generic/luaotfload/luaotfload-main.tex b/macros/luatex/generic/luaotfload/luaotfload-main.tex
index 9db7f4c75d..6d802cbbc2 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-main.tex
+++ b/macros/luatex/generic/luaotfload/luaotfload-main.tex
@@ -32,7 +32,7 @@
\beginfrontmatter
\setdocumenttitle {The \identifier{luaotfload} package}
- \setdocumentdate {2022-03-18 v3.21}
+ \setdocumentdate {2022-06-15 v3.22}
\setdocumentauthor {LaTeX3 Project\\
Elie Roux · Khaled Hosny · Philipp Gesang · Ulrike Fischer · Marcel Krüger\\
Home: \hyperlink {https://github.com/latex3/luaotfload}}
@@ -40,14 +40,14 @@
\typesetdocumenttitle
\beginabstractcontent
- This package is an adaptation of the \CONTEXT font loading system.
- It allows for loading \OpenType fonts with an extended syntax and adds
+ This package is an adaptation of the \ConTeXt\ font loading system.
+ It allows for loading \OpenType\ fonts with an extended syntax and adds
support for a variety of font features.
After discussion of the font loading API, this manual gives an
overview of the core components of \identifier{Luaotfload}: The
packaged font loader code, the names database, configuration, and
- helper functions on the \LUA\ end.
+ helper functions on the \Lua\ end.
\endabstractcontent
\endfrontmatter
@@ -62,6 +62,16 @@ Supported is the \identifier{luatex} versions of a current TeXLive 2019 (and a c
\endsection
\beginsection{Changes}
+\beginsubsection {New in version 3.22}
+\begin{itemize}
+ \item Tailored case mappings
+ \item Avoid database rebuilds when switching Lua versions
+ \item Improved attribute settings of ActualText nodes in harf mode
+ \item Callback-based customization for color parameter
+ \item Various bug fixes
+\end{itemize}
+\endsubsection
+
\beginsubsection {New in version 3.21 (by Ulrike Fischer/Marcel Krüger)}
\begin{itemize}
\item Fix performance regression introduced in version 3.19.
@@ -80,7 +90,7 @@ Supported is the \identifier{luatex} versions of a current TeXLive 2019 (and a c
\beginsubsection {New in version 3.19 (by Ulrike Fischer/Marcel Krüger)}
\begin{itemize}
- \item When used with Lua\TeX\ 1.15.0 or newer, variable fonts are supported
+ \item When used with \LuaTeX\ 1.15.0 or newer, variable fonts are supported
when using the \texttt{harf} shaper too.
\item A new algorithm for selecting fonts based on font family names allows
to more reliably load fonts based on their family name.
@@ -105,7 +115,7 @@ Supported is the \identifier{luatex} versions of a current TeXLive 2019 (and a c
\beginsubsection {New in version 3.17 (by Ulrike Fischer/Marcel Krüger)}
\begin{itemize}
- \item The experimental support for OpenType variable fonts has been extended
+ \item The experimental support for \OpenType\ variable fonts has been extended
to more reliably support modern fonts.
\item A number of small bugfixes.
\end{itemize}
@@ -123,7 +133,7 @@ Supported is the \identifier{luatex} versions of a current TeXLive 2019 (and a c
first/second discretionaries (the mechanism described in the LuaTeX manual,
section 5.6 for the of-f-ice example) to support a limited amount of
nesting.
- \item When the \texttt{node} shaper is used, experimental support for OpenType variable
+ \item When the \texttt{node} shaper is used, experimental support for \OpenType\ variable
fonts has been added. To use them, set the font feature \texttt{axis} to
a comma separated list of axis names and values. (E.g. \texttt{axis={weight=600}})
The supported axis names and value range depend on the font (see~page~\pageref{variablefonts}).
@@ -141,7 +151,7 @@ Supported is the \identifier{luatex} versions of a current TeXLive 2019 (and a c
\item In multiple error cases, error messages are shown instead of silently
generating bad output.
\item Write glyph ids instead of internal identifiers to DVI files. This
- allows using OpenType fonts when working with \identifier{dvilualatex}.
+ allows using \OpenType\ fonts when working with \identifier{dvilualatex}.
(This requires additional support from the DVI reader)
\item The\marginpar{\mbox{}\hfill \textbf{Change!}} set of font features which
are enabled by default has been changed to be more similar to HarfBuzz.
@@ -304,14 +314,14 @@ On the other side there is a lot new:
\begindescriptions
- \beginaltitem {Fontloader} The fontloader files imported from \CONTEXT\ have been updated to the current version.
- This was necessary to make \identifier{Luaotfload} compatible with the coming \LUATEX 1.08/1.09. Compared to the previous version from february 2017 quite a number of things have changed. Most importantly the handling of arabic fonts has greatly improved. But this also means that changes in the output are possible.
+ \beginaltitem {Fontloader} The fontloader files imported from \ConTeXt\ have been updated to the current version.
+ This was necessary to make \identifier{Luaotfload} compatible with the coming \LuaTeX\ 1.08/1.09. Compared to the previous version from february 2017 quite a number of things have changed. Most importantly the handling of arabic fonts has greatly improved. But this also means that changes in the output are possible.
\endaltitem
\beginaltitem {Lualibs} The update of the fontloader files also required an update of the \identifier{Lualibs} package. This \identifier{Luaotfload} version needs version 2.6 of \identifier{Lualibs}.
\endaltitem
- \beginaltitem {Maintenance} As the current maintainer wasn't available and it was urgent to get a \identifier{Luaotfload} compatible with \LUATEX 1.08/1.09 maintenance has been transfered to Ulrike Fischer and Marcel Krüger. The package was maintained and developed at \hyperlink{https://github.com/u-fischer/luaotfload}.
+ \beginaltitem {Maintenance} As the current maintainer wasn't available and it was urgent to get a \identifier{Luaotfload} compatible with \LuaTeX\ 1.08/1.09 maintenance has been transfered to Ulrike Fischer and Marcel Krüger. The package was maintained and developed at \hyperlink{https://github.com/u-fischer/luaotfload}.
\endaltitem
\beginaltitem {Documentation}
@@ -326,16 +336,16 @@ On the other side there is a lot new:
\beginsection {Introduction}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-Font management and installation has always been painful with \TEX. A
+Font management and installation has always been painful with \TeX. A
lot of files are needed for one font (\abbrev{tfm}, \abbrev{pfb},
\abbrev{map}, \abbrev{fd}, \abbrev{vf}), and due to the 8-Bit encoding
each font is limited to 256 characters.
-But the font world has evolved since the original \TEX, and new
+But the font world has evolved since the original \TeX, and new
typographic systems have appeared, most notably the so called
-\emphasis{smart font} technologies like \OpenType fonts (\abbrev{otf}).
+\emphasis{smart font} technologies like \OpenType\ fonts (\abbrev{otf}).
-These fonts can contain many more characters than \TEX fonts, as well
+These fonts can contain many more characters than \TeX\ fonts, as well
as additional functionality like ligatures, old-style numbers, small
capitals, etc., and support more complex writing systems like Arabic
and Indic\footnote{%
@@ -343,25 +353,25 @@ and Indic\footnote{%
scripts correctly. For these scripts it is recommended to use the harf mode along with the binary \identifier{luahbtex}.}
scripts.
-\OpenType fonts are widely deployed and available for all modern
+\OpenType\ fonts are widely deployed and available for all modern
operating systems.
As of 2013 they have become the de facto standard for advanced text
layout.
-However, until recently the only way to use them directly in the \TEX
-world was with the \XETEX engine.
+However, until recently the only way to use them directly in the \TeX\
+world was with the \XeTeX\ engine.
-Unlike \XETEX, \LUATEX has no built-in support for \OpenType or
-technologies other than the original \TEX fonts.
+Unlike \XeTeX, \LuaTeX\ has no built-in support for \OpenType\ or
+technologies other than the original \TeX\ fonts.
-Instead, it provides hooks for executing \LUA code during the \TEX run
+Instead, it provides hooks for executing \Lua\ code during the \TeX\ run
that allow implementing extensions for loading fonts and manipulating
how input text is processed without modifying the underlying engine.
This is where \identifier{luaotfload} comes into play:
-Based on code from \CONTEXT, it extends \LUATEX with functionality necessary
-for handling \OpenType fonts.
+Based on code from \ConTeXt, it extends \LuaTeX\ with functionality necessary
+for handling \OpenType\ fonts.
Additionally, it provides means for accessing fonts known to the operating
system conveniently by indexing the metadata.
@@ -372,9 +382,9 @@ system conveniently by indexing the metadata.
\beginsection {Thanks}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\identifier{Luaotfload} is part of \LUALATEX, the community-driven
-project to provide a foundation for using the \LATEX format with the
-full capabilites of the \LUATEX engine.
+\identifier{Luaotfload} is part of \hologo{LuaLaTeX}, the community-driven
+project to provide a foundation for using the \LaTeX\ format with the
+full capabilites of the \LuaTeX\ engine.
%
As such, the distinction between end users, contributors, and project
maintainers is intentionally kept less strict, lest we unduly
@@ -388,8 +398,8 @@ Their contributions -- be it patches, advice, or systematic
testing -- made the switch from version 1.x to 2.2 possible.
%
Also, Hans Hagen, the author of the font loader, made porting the
-code to \LATEX a breeze due to the extra effort he invested into
-isolating it from the rest of \CONTEXT, not to mention his assistance
+code to \LaTeX\ a breeze due to the extra effort he invested into
+isolating it from the rest of \ConTeXt, not to mention his assistance
in the task and willingness to respond to our suggestions.
\endsection
@@ -405,7 +415,7 @@ in the task and willingness to respond to our suggestions.
\meta{prefix}\nonproportional{:}%
\meta{font name}\nonproportional{:}%
\meta{font features}\nonproportional{\string}}%
- \meta{\TEX font features}
+ \meta{\TeX\ font features}
\endnarrower
\noindent
@@ -437,7 +447,7 @@ for a more formal description see figure \ref{font-syntax}.
\smallcaps {tfmname} is the name of a \abbrev{tfm} file.
\smallcaps {digit} again refers to bytes 48--57, and
\smallcaps {all\textunderscore characters} to all byte values.
- \smallcaps {csname} and \smallcaps {dimension} are the \TEX concepts.}
+ \smallcaps {csname} and \smallcaps {dimension} are the \TeX\ concepts.}
%
<definition> ::= `\\font', {\sc csname}, `=', <font request>, [ <size> ] ;
@@ -592,7 +602,7 @@ As is obvious from the last exception, the \inlinecode {file:} lookup will
not process paths to the font location -- only those
files found when generating the database are addressable this way.
%
-Continue below in the \XETEX section if you need to load your fonts
+Continue below in the \XeTeX\ section if you need to load your fonts
by path.
%
The file names corresponding to the example font names above are
@@ -620,7 +630,7 @@ Inside the square brackets, every character except for a closing bracket is
permitted, allowing for arbitrary paths to a font file -- including Windows
style paths with UNC or drive letter prepended -- to be specified.
%
-The \identifier{Luaotfload} syntax differs from \XETEX in that the subfont
+The \identifier{Luaotfload} syntax differs from \XeTeX\ in that the subfont
selector goes \emphasis{after} the closing bracket:
\beginnarrower
@@ -636,13 +646,13 @@ same way as an ordinary \inlinecode {file:} lookup.
\beginsubsection {Compatibility}
In addition to the regular prefixed requests, \identifier{luaotfload}
-accepts loading fonts the \XETEX way.
+accepts loading fonts the \XeTeX\ way.
%
There are again two modes: bracketed and unbracketed.
For the bracketed variety, see above, \ref{sec:bracket}.
Unbracketed (or, for lack of a better word: \emphasis{anonymous})
-font requests resemble the conventional \TEX syntax.
+font requests resemble the conventional \TeX\ syntax.
\beginnarrower
\nonproportional{\string\font\string\fontname\space= }%
@@ -653,7 +663,7 @@ font requests resemble the conventional \TEX syntax.
However, they have a broader spectrum of possible interpretations:
before anything else, \identifier{luaotfload} attempts to load a
-traditional \TEX Font Metric (\abbrev{tfm} or \abbrev{ofm}).
+traditional \TeX\ Font Metric (\abbrev{tfm} or \abbrev{ofm}).
%
If this fails, it performs a \inlinecode {path:} lookup, which itself will
fall back to a \inlinecode {file:} lookup.
@@ -665,7 +675,7 @@ The behavior of this “anonymous” lookup is configurable, see the configuatio
manpage for details.
Furthermore, \identifier{luaotfload} supports the slashed (shorthand)
-font style notation from \XETEX.
+font style notation from \XeTeX.
\beginnarrower
\nonproportional{\string\font\string\fontname\space= }%
@@ -681,8 +691,8 @@ Currently, four style modifiers are supported:
\inlinecode {B} for bold weight,
\inlinecode {BI} or \inlinecode {IB} for the combination of both.
%
-Other “slashed” modifiers are too specific to the \XETEX engine and
-have no meaning in \LUATEX.
+Other “slashed” modifiers are too specific to the \XeTeX\ engine and
+have no meaning in \LuaTeX.
\endsubsection
@@ -697,10 +707,10 @@ For example, conventional \TeX\ font can be loaded with a
\font \lmromanten = {file:ec-lmr10} at 10pt
\endlisting
-The \OpenType version of Janusz Nowacki’s font \emphasis{Antykwa
+The \OpenType\ version of Janusz Nowacki’s font \emphasis{Antykwa
Półtawskiego}\footnote{%
\hyperlink {http://jmn.pl/antykwa-poltawskiego/}, also available in
- in \TEX Live.
+ in \TeX\ Live.
}
in its condensed variant can be loaded as follows:
@@ -709,7 +719,7 @@ in its condensed variant can be loaded as follows:
\endlisting
The next example shows how to load the \emphasis{Porson} font digitized by
-the Greek Font Society using \XETEX-style syntax and an absolute path from a
+the Greek Font Society using \XeTeX-style syntax and an absolute path from a
non-standard directory:
\beginlisting
@@ -777,7 +787,7 @@ Which fits nicely with the whole set:
If the entire \emphasis{Iwona} family\footnote{%
\hyperlink {http://jmn.pl/kurier-i-iwona/},
- also in \TEX Live.
+ also in \TeX\ Live.
}
is installed in some location accessible by \identifier{luaotfload},
the regular shape can be loaded as follows:
@@ -823,12 +833,12 @@ general scheme for font requests:
\meta{font name}%
\nonproportional{:}%
\meta{font features}%
- \meta{\TEX font features}%
+ \meta{\TeX\ font features}%
\nonproportional{"}
\endnarrower
\noindent
-If style modifiers are present (\XETEX style), they must precede
+If style modifiers are present (\XeTeX\ style), they must precede
\meta{font features}.
The element \meta{font features} is a semicolon-separated list of feature
@@ -878,19 +888,19 @@ obviously, \inlinecode{random}.
\begindescriptions
\beginaltitem {mode}
- \identifier{luaotfload} had three \OpenType processing
+ \identifier{luaotfload} had three \OpenType\ processing
\emphasis{modes}:
\identifier{base}, \identifier{node} and \identifier{harf}.
- \identifier{base} mode works by mapping \OpenType
- features to traditional \TEX ligature and kerning mechanisms.
+ \identifier{base} mode works by mapping \OpenType\
+ features to traditional \TeX\ ligature and kerning mechanisms.
%
Supporting only non-contextual substitutions and kerning
pairs, it is the slightly faster, albeit somewhat limited, variant.
%
\identifier{node} mode works by processing \TeX’s internal
- node list directly at the \LUA end and supports
- a wider range of \OpenType features.
+ node list directly at the \Lua\ end and supports
+ a wider range of \OpenType\ features.
%
The downside is that the intricate operations required for
\identifier{node} mode may slow down typesetting especially
@@ -937,7 +947,7 @@ obviously, \inlinecode{random}.
\endaltitem
\beginaltitem {script} \phantomsection\label{script-tag}
- An \OpenType script tag;\footnote{%
+ An \OpenType\ script tag;\footnote{%
See \hyperlink {http://www.microsoft.com/typography/otspec/scripttags.htm}
for a list of valid values.
%
@@ -952,7 +962,7 @@ obviously, \inlinecode{random}.
\endaltitem
\beginaltitem {language}
- An \OpenType language system identifier,\footnote{%
+ An \OpenType\ language system identifier,\footnote{%
Cf. \hyperlink {http://www.microsoft.com/typography/otspec/languagetags.htm}.
}
defaulting to \inlinecode{dflt}.
@@ -1010,7 +1020,7 @@ obviously, \inlinecode{random}.
\beginaltitem {axis\&instance}
- Experimental!\marginpar{\mbox{}\hfill NEW in v3.15!} Support for OpenType variable fonts. \emph{Varible fonts are only
+ Experimental!\marginpar{\mbox{}\hfill NEW in v3.15!} Support for \OpenType\ variable fonts. \emph{Varible fonts are only
supported in \texttt{base} and \texttt{node} mode, not in \texttt{harf}
mode.}
@@ -1081,7 +1091,7 @@ obviously, \inlinecode{random}.
Context, see the file \fileent{typo-krn.lua} there.
%
The main difference is that \identifier{luaotfload} does not
- use \LUATEX attributes to assign letterspacing to regions,
+ use \LuaTeX\ attributes to assign letterspacing to regions,
but defines virtual letterspaced versions of a font.
The option \identifier{kernfactor} accepts a numeric value that
@@ -1093,7 +1103,8 @@ obviously, \inlinecode{random}.
pair of glyphs.
%
- Spaces\marginpar{\mbox{}\hfill NEW in v2.96!} between words are now stretched too. This is consistent with the \XETEX behaviour (and the amount of stretching should be similar). This
+ Spaces\marginpar{\mbox{}\hfill NEW in v2.96!} between words are now
+ stretched too. This is consistent with the \XeTeX\ behaviour (and the amount of stretching should be similar). This
naturally changes the output of a document. In case you want the old behaviour back use
\beginlisting
\directlua{luaotfload.letterspace.keepwordspacing = true}
@@ -1114,7 +1125,8 @@ obviously, \inlinecode{random}.
Ligatures\marginpar{\mbox{}\hfill NEW in v2.96!} are no longer split into their component glyphs.
- This change too make the \identifier{luaotfload} more compatible with \XETEX. It also makes it much easier to activate or deactivate ligature sets in letterspaced fonts.
+ This change too make the \identifier{luaotfload} more compatible with
+ \XeTeX. It also makes it much easier to activate or deactivate ligature sets in letterspaced fonts.
If you want to split ligatures, you should deactivate as you would do it with a not-letterspaced font, e.g. with the fontspec \identifier{Ligatures} option, or the low-level \identifier{-liga} and similar.
@@ -1128,7 +1140,7 @@ obviously, \inlinecode{random}.
\test No ligatures: fi -- ff \par
}
- For compatibility with \XETEX an alternative
+ For compatibility with \XeTeX\ an alternative
\identifier{letterspace} option is supplied that interprets the
supplied value as a \emphasis{percentage} of the font size but
is otherwise identical to \identifier{kernfactor}.
@@ -1145,7 +1157,7 @@ obviously, \inlinecode{random}.
Setting the ligatures with the font options is the recommended way, to activate or deactivate them. In case of special requirements
specific pairs of letters and ligatures may be exempt from
- letterspacing by defining the \LUA functions
+ letterspacing by defining the \Lua\ functions
\luaident{keeptogether} and \luaident{keepligature},
respectively, inside the namespace \inlinecode {luaotfload.letterspace}.
%
@@ -1162,7 +1174,7 @@ obviously, \inlinecode{random}.
analyzed into components.
%
(For details refer to the \emphasis{glyph nodes} section in the
- \LUATEX reference manual.)
+ \LuaTeX\ reference manual.)
%
The implementation of both functions is left entirely to the
user.
@@ -1180,7 +1192,7 @@ obviously, \inlinecode{random}.
namely \emphasis{character protrusion} and \emphasis{font
expansion}.
%
- Their arguments are names of \LUA tables that contain
+ Their arguments are names of \Lua\ tables that contain
values for the respective features.\footnote{%
For examples of the table layout please refer to the
section of the file \fileent{luaotfload-fonts-ext.lua} where the
@@ -1208,7 +1220,7 @@ obviously, \inlinecode{random}.
\inlinecode {pdfadjustspacing=2}
to activate protrusion and expansion, respectively.
See the
- \hyperlink [\PDFTEX manual]{http://mirrors.ctan.org/systems/pdftex/manual/pdftex-a.pdf}%
+ \hyperlink [\hologo{pdfTeX} manual]{http://mirrors.ctan.org/systems/pdftex/manual/pdftex-a.pdf}%
for details.
}:
@@ -1355,23 +1367,56 @@ obviously, \inlinecode{random}.
\beginaltitem {upper/lower}
The\phantomsection\label{upperlower}\marginpar{New in 3.16}
font features \texttt{upper} and \texttt{lower} can be used to map
- the text of a font to upper or lowercase before displaying it. Currently
- this implements the untailored Unicode case mapping algorithm, but it is
- planned to add tailoring later. For example
+ the text of a font to upper or lowercase before displaying it.
+
+ By default the casemapping is automatically tailored based on the active
+ \texttt{language} font feature. This automatic tailoring can be overwritten
+ by passing a two letter language tag to the \texttt{upper} or \texttt{lower}
+ feature. In addition to ordinary language tags, the tags \texttt{el-x-iota},
+ \texttt{hy-x-yiwn} and \texttt{de-x-eszett} can be used. \texttt{el-x-iota}
+ adapts the greek rules for uppercasing to keep iota subscripts as combining
+ characters which sufficiently well behaving fonts can render in appropriate
+ ways while the default for greek is to convert these into capital iotas.
+ \texttt{de-x-eszett} adapts uppercasing for german to use the capital eszett
+ instead of uppercasing the eszett to double capital s.
\beginlisting
- \font\test={name:LatinModernRoman:mode=node;+upper;}
+ \font\test={kpse:LinLibertine_R.otf:mode=node;+upper;}
+ \test Grüße
+ \font\test={kpse:LinLibertine_R.otf:mode=node;upper=de-x-eszett;}
\test Grüße
\endlisting
- {\Large\font\test={name:LatinModernRoman:mode=node;+upper;}\test Grüße}
+ {\Large
+ \font\test={kpse:LinLibertine\string_R.otf:mode=node;+upper;}\test Grüße
+ \font\test={kpse:LinLibertine\string_R.otf:mode=node;upper=de-x-eszett;}\test Grüße
+ }
+
+ \beginlisting
+ \font\test={kpse:LinLibertine_R.otf:mode=node;script=grek;+upper;}
+ No specified language: {\test εἰσενέγκῄς ἡμᾶς}\par
+ \font\test={kpse:LinLibertine_R.otf:mode=node;script=grek;language=ell;+upper;}
+ Greek uppercasing: {\test εἰσενέγκῄς ἡμᾶς}\par
+ \font\test={kpse:LinLibertine_R.otf:mode=node;script=grek;language=ell;+upper=el-x-iota;}
+ Greek variant: {\test εἰσενέγκῄς ἡμᾶς}\par
+ \endlisting
+
+ {%
+ \font\test={kpse:LinLibertine\string_R.otf:mode=node;script=grek;+upper;}
+ No specified language: {\test εἰσενέγκῄς ἡμᾶς}\par
+ \font\test={kpse:LinLibertine\string_R.otf:mode=node;script=grek;language=ell;+upper;}
+ Greek uppercasing: {\test εἰσενέγκῄς ἡμᾶς}\par
+ \font\test={kpse:LinLibertine\string_R.otf:mode=node;script=grek;language=ell;+upper=el-x-iota;}
+ Greek variant: {\test εἰσενέγκῄς ἡμᾶς}\par
+ }
+
\endaltitem
\beginaltitem {Variable fonts}
When\phantomsection\label{variablefonts}\marginpar{New in 3.16}
the \texttt{node} shaper is used,
- experimental support for OpenType variable
+ experimental support for \OpenType\ variable
fonts has been added. To use them, set the font feature \texttt{axis} to
a comma separated list of axis names and values. (E.g. \texttt{axis={weight=600}})
The supported axis names and value range depend on the font (see~page~\pageref{variablefonts}).
@@ -1419,8 +1464,8 @@ obviously, \inlinecode{random}.
\beginsubsection {Non-standard font features}
\identifier{luaotfload} adds a number of features that are not defined
-in the original \OpenType specification, most of them
-aiming at emulating the behavior familiar from other \TEX engines.
+in the original \OpenType\ specification, most of them
+aiming at emulating the behavior familiar from other \TeX\ engines.
%
Currently (2014) there are three of them:
@@ -1433,12 +1478,12 @@ Currently (2014) there are three of them:
\endaltitem
\beginaltitem {tlig}
- Applies legacy \TEX ligatures\footnote{%
+ Applies legacy \TeX\ ligatures\footnote{%
These contain the feature set \inlinecode {trep} of earlier
versions of \identifier{luaotfload}.
- Note to \XETEX users: this is the equivalent of the
- assignment \inlinecode {mapping=text-tex} using \XETEX's input
+ Note to \XeTeX\ users: this is the equivalent of the
+ assignment \inlinecode {mapping=text-tex} using \XeTeX's input
remapping feature.
}:
@@ -1572,13 +1617,13 @@ the respective font, if available.
\label{sec:fontdb}
As mentioned above, \identifier{luaotfload} keeps track of which
-fonts are available to \LUATEX by means of a \emphasis{database}.
+fonts are available to \LuaTeX\ by means of a \emphasis{database}.
%
This allows referring to fonts not only by explicit filenames but
also by the proper names contained in the metadata which is often
more accessible to humans.\footnote{%
The tool \hyperlink[\fileent{otfinfo}]{http://www.lcdf.org/type/}
- (comes with \TEX Live), when invoked on a font file with the
+ (comes with \TeX\ Live), when invoked on a font file with the
\inlinecode {-i} option, lists the variety of name fields defined for
it.
}
@@ -1614,12 +1659,12 @@ To this end, \identifier{luaotfload} comes with the utility
\fileent{luaotfload-tool} that offers an interface to the database
functionality.
%
-Being a \LUA script, there are two ways to run it:
+Being a \Lua\ script, there are two ways to run it:
either make it executable (\inlinecode {chmod +x} on unixoid systems) or
pass it as an argument to \fileent{texlua}.\footnote{%
Tests by the maintainer show only marginal performance gain by
running with Luigi Scarso’s
- \hyperlink [\identifier{Luajit\kern-.25ex\TEX}]{https://foundry.supelec.fr/projects/luajittex/},
+ \hyperlink [\identifier{Luajit\kern-.25ex\TeX}]{https://foundry.supelec.fr/projects/luajittex/},
which is probably due to the fact that most of the time is spent
on file system operations.
@@ -1749,8 +1794,8 @@ using the \inlinecode {-i} option (\inlinecode {--info}).
%
\noindent
The meaning of the printed values is described in section 4.4 of the
-\LUATEX reference manual.\footnote{%
- In \TEX Live: \fileent{texmf-dist/doc/luatex/base/luatexref-t.pdf}.
+\LuaTeX\ reference manual.\footnote{%
+ In \TeX\ Live: \fileent{texmf-dist/doc/luatex/base/luatexref-t.pdf}.
}
For a much more detailed report about a given font try the
@@ -1773,7 +1818,7 @@ capabilities refer to the manpage
\beginsubsection {Blacklisting Fonts}
\label{font-blacklist}
-Some fonts are problematic in general, or just in \LUATEX.
+Some fonts are problematic in general, or just in \LuaTeX.
%
If you find that compiling your document takes far too long or eats
away all your system’s memory, you can track down the culprit by
@@ -1795,7 +1840,7 @@ is ignored, so use this to add comments.
Place this file to some location where the \identifier{kpse}
library can find it, e.~g.
\fileent{texmf-local/tex/luatex/luaotfload} if you are running
-\identifier{\TEX Live},\footnote{%
+\identifier{\TeX\ Live},\footnote{%
You may have to run \inlinecode {mktexlsr} if you created a new file in
your \fileent{texmf} tree.
}
@@ -1829,19 +1874,19 @@ An example with explicit paths:
To a large extent, \identifier{luaotfload} relies on code originally
written by Hans Hagen for the
-\hyperlink[\identifier{\CONTEXT}]{http://wiki.contextgarden.net}
+\hyperlink[\identifier{\ConTeXt}]{http://wiki.contextgarden.net}
format.
%
-It integrates the font loader, written entirely in \LUA, as distributed
-in the \identifier{\LUATEX-Fonts} package.
+It integrates the font loader, written entirely in \Lua, as distributed
+in the \identifier{\LuaTeX-Fonts} package.
%
-The original \LUA source files have been combined using the \CONTEXT
+The original \Lua\ source files have been combined using the \ConTeXt\
packaging library into a single, self-contained blob. In
this form the font loader depends only on the \identifier{lualibs}
package and requires only minor adaptions to integrate into
\identifier{luaotfload}.
-The guiding principle is to let \CONTEXT/\LUATEX-Fonts take care of the
+The guiding principle is to let \ConTeXt/\LuaTeX-Fonts take care of the
implementation, and update the imported code as frequently as
necessary.
%
@@ -1850,8 +1895,8 @@ As maintainers, we aim at importing files from upstream essentially
clashes.
%
This job has been greatly alleviated since the advent of
-\LUATEX-Fonts, prior to which the individual dependencies had to be
-manually spotted and extracted from the \CONTEXT source code in a
+\LuaTeX-Fonts, prior to which the individual dependencies had to be
+manually spotted and extracted from the \ConTeXt\ source code in a
complicated and error-prone fashion.
\endsubsection
@@ -1865,16 +1910,16 @@ See see the figure on page \pageref{file-graph} for a
graphical representation of the dependencies.
%
\label{package}%
-Through the script \fileent{mkimport} a \CONTEXT library
+Through the script \fileent{mkimport} a \ConTeXt\ library
is invoked to create the \identifier{luaotfload} fontloader as a merged
(amalgamated) source file.\footnote{%
- In \CONTEXT, this facility can be accessed by means of a
+ In \ConTeXt, this facility can be accessed by means of a
\hyperlink[script]{https://bitbucket.org/phg/context-mirror/src/beta/scripts/context/lua/mtx-package.lua?at=beta}
which is integrated into \fileent{mtxrun} as a subcommand.
Run \inlinecode {mtxrun --script package --help} to display further
information.
For the actual merging code see the file
- \fileent{util-mrg.lua} that is part of \CONTEXT.
+ \fileent{util-mrg.lua} that is part of \ConTeXt.
}
%
This file constitutes the “default fontloader” and is part of the
@@ -1882,29 +1927,29 @@ This file constitutes the “default fontloader” and is part of the
where the uppercase letters are placeholders for the build date.
%
A companion to it, \fileent{luatex-basics-gen.lua} (renamed to \fileent{fontloader-basics-gen.lua} in \identifier{luaotfload})
-must be loaded beforehand to set up parts of the environment required by the \CONTEXT
-libraries.
+must be loaded beforehand to set up parts of the environment required
+by the \ConTeXt\ libraries.
%
-During a \TEX\ run, the fontloader initialization and injection happens
+During a \TeX\ run, the fontloader initialization and injection happens
in the module \fileent{luaotfload-init.lua}.
%
-Additionally, the “reference fontloader” as imported from \LUATEX-Fonts
+Additionally, the “reference fontloader” as imported from \LuaTeX-Fonts
is provided as the file \fileent{fontloader-reference.lua}.
%
-This file is self-contained in that it packages all the auxiliary \LUA
+This file is self-contained in that it packages all the auxiliary \Lua\
libraries too, as Luaotfload did up to the 2.5 series; since that job
has been offloaded to the \identifier{Lualibs} package, loading this
fontloader introduces a certain code duplication.
-A number of \emphasis{\LUA utility libraries} are not part of the
+A number of \emphasis{\Lua\ utility libraries} are not part of the
\identifier{luaotfload} fontloader, contrary to its equivalent in
-\LUATEX-Fonts. These are already provided by the \identifier{lualibs}
+\LuaTeX-Fonts. These are already provided by the \identifier{lualibs}
and have thus been omitted from the merge.\footnote{%
Faithful listeners will remember the pre-2.6 era when the fontloader
used to be integrated as-is which caused all kinds of code
duplication with the pervasive \identifier{lualibs} package.
This conceptual glitch has since been amended by tightening the
- coupling with the excellent \CONTEXT\ toolchain.
+ coupling with the excellent \ConTeXt\ toolchain.
}
\begindoublecolumns
@@ -1913,13 +1958,13 @@ and have thus been omitted from the merge.\footnote{%
\enddefinitions
\enddoublecolumns
-The reference fontloader is home to several \LUA files that can be
+The reference fontloader is home to several \Lua\ files that can be
grouped twofold as below:
\begindefinitions
\beginnormalitem
The \emphasis{font loader} itself.
- These files have been written for \LUATEX-Fonts and they are
+ These files have been written for \LuaTeX-Fonts and they are
distributed along with \identifier{luaotfload} so as to resemble
the state of the code when it was imported. Their purpose is either
to give a slightly aged version of a file if upstream considers
@@ -1936,7 +1981,7 @@ grouped twofold as below:
\beginnormalitem
Code related to \emphasis{font handling and node processing}, taken
- directly from \CONTEXT.
+ directly from \ConTeXt.
\begindoublecolumns
\begindefinitions
\directlua{printctxfontlist ()}
@@ -1946,15 +1991,15 @@ grouped twofold as below:
\enddefinitions
As an alternative to the merged file, \identifier {Luaotfload} may load
-individual unpackaged \LUA libraries that come with the source, or even
+individual unpackaged \Lua\ libraries that come with the source, or even
use the files from Context directly.
%
-Thus if you prefer running bleeding edge code from the \CONTEXT beta,
+Thus if you prefer running bleeding edge code from the \ConTeXt\ beta,
choose the \inlinecode {context} fontloader via the configuration file
(see sections \ref{sec:conf} and \ref{sec:pkg} below).
Also, the merged file at some point loads the Adobe Glyph List from a
-\LUA table that is contained in \fileent{luaotfload-glyphlist.lua},
+\Lua\ table that is contained in \fileent{luaotfload-glyphlist.lua},
which is automatically generated by the script
\fileent{mkglyphlist}.\footnote{%
See \fileent{luaotfload-font-enc.lua}.
@@ -1963,23 +2008,23 @@ which is automatically generated by the script
}
%
There is a make target \identifier{glyphs} that will create a fresh
-glyph list so we don’t need to import it from \CONTEXT any longer.
+glyph list so we don’t need to import it from \ConTeXt\ any longer.
In addition to these, \identifier{luaotfload} requires a number of
files not contained in the merge. Some of these have no equivalent in
-\LUATEX-Fonts or \CONTEXT, some were taken unmodified from the latter.
+\LuaTeX-Fonts or \ConTeXt, some were taken unmodified from the latter.
\beginfilelist
\beginaltitem {luaotfload-features.lua}
font feature handling; incorporates some of the code from
- \fileent{font-otc} from \CONTEXT;
+ \fileent{font-otc} from \ConTeXt;
\endaltitem
\beginaltitem {luaotfload-configuration.lua}
handling of \fileent{luaotfload.conf(5)}.
\endaltitem
\beginaltitem {luaotfload-log.lua}
- overrides the \CONTEXT logging functionality.
+ overrides the \ConTeXt\ logging functionality.
\endaltitem
\beginaltitem {luaotfload-loaders.lua}
registers readers in the fontloader for various kinds of
@@ -2028,13 +2073,13 @@ To specify the fontloader you wish to use, the configuration file
%
Its value can be one of the identifiers \inlinecode{default} or
\inlinecode{reference} (see above, section \ref{package}) or the name
-of a file somewhere in the search path of \LUATEX.
+of a file somewhere in the search path of \LuaTeX.
%
-This will make \identifier {Luaotfload} locate the \CONTEXT source by
+This will make \identifier {Luaotfload} locate the \ConTeXt\ source by
means of \identifier{kpathsea} lookups and use those instead of the
merged package.
%
-The parameter may be extended with a path to the \CONTEXT
+The parameter may be extended with a path to the \ConTeXt\
\fileent{texmf}, separated with a colon:
\beginlisting
@@ -2044,14 +2089,14 @@ The parameter may be extended with a path to the \CONTEXT
\noindent This setting allows accessing an installation -- e. g. the
standalone distribution or a source repository -- outside the current
-\TEX distribution.
+\TeX\ distribution.
Like the \identifier{Lualibs} package, the fontloader is deployed as a
-\emphasis{merged package} containing a series of \LUA files joined
+\emphasis{merged package} containing a series of \Lua\ files joined
together in their expected order and stripped of non-significant parts.
%
The \fileent{mkimport} utility assists in pulling the files from a
-\CONTEXT tree and packaging them for use with \identifier{Luaotfload}.%
+\ConTeXt\ tree and packaging them for use with \identifier{Luaotfload}.%
%
The state of the files currently in \identifier{Luaotfload}’s
repository can be queried:
@@ -2059,7 +2104,7 @@ repository can be queried:
./scripts/mkimport news
\endlisting
%
-The subcommand for importing takes the prefix of the desired \CONTEXT
+The subcommand for importing takes the prefix of the desired \ConTeXt\
\identifier{texmf} as an optional argument:
\beginlisting
./scripts/mkimport import ~/context/tex/texmf-context
@@ -2084,7 +2129,7 @@ Whether files have been updated in the upstream distribution can be
queried by \inlinecode{./scripts/mkimport news}.
%
This will compare the imported files with their counterparts in the
-\CONTEXT distribution and report changes.
+\ConTeXt\ distribution and report changes.
\endsubsection
@@ -2151,11 +2196,11 @@ as below:
This specifies that for the given project, \identifier{Luaotfload}
shall not attempt to automatically scan for fonts if it can’t resolve a
-request. The font-based colorization will happen during \LUATEX’s
+request. The font-based colorization will happen during \LuaTeX’s
pre-linebreak filter. The fontloader will output verbose information
about the fonts at definition time along with globally increased
verbosity. Lastly, the fontloader defaults to the less expensive
-\luaident{base} mode like it does in \CONTEXT.
+\luaident{base} mode like it does in \ConTeXt.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\beginsection {Auxiliary Functions}
@@ -2223,7 +2268,7 @@ writes an entire font object to the file \fileent{fontdump.lua}:
code, taking up 3~\abbrev{mb} of disk space.
%
By inspecting the output you can get a first impression of how a font
-is structured in \LUATEX’s memory, what elements it is composed of,
+is structured in \LuaTeX’s memory, what elements it is composed of,
and in what ways it can be rearranged.
\beginsubsubsection {Compatibility with Earlier Versions}
@@ -2247,16 +2292,16 @@ subtables in the meantime.
\beginsubsubsection{Patches}
-These are mostly concerned with establishing compatibility with \XETEX.
+These are mostly concerned with establishing compatibility with \XeTeX.
\beginfunctionlist
\beginaltitem {set_sscale_dimens}
- Calculate \texmacro{fontdimen}s 10 and 11 to emulate \XETEX.
+ Calculate \texmacro{fontdimen}s 10 and 11 to emulate \XeTeX.
\endaltitem
\beginaltitem {set_capheight}
- Calculates \texmacro{fontdimen} 8 like \XETEX.
+ Calculates \texmacro{fontdimen} 8 like \XeTeX.
\endaltitem
\beginaltitem {patch_cambria_domh}
@@ -2269,7 +2314,7 @@ These are mostly concerned with establishing compatibility with \XETEX.
\beginsubsection {Package Author’s Interface}
-As \LUATEX release 1.0 is nearing, the demand for a reliable interface
+As \LuaTeX\ release 1.0 is nearing, the demand for a reliable interface
for package authors increases.
\endsubsubsection
@@ -2334,7 +2379,7 @@ are defined for which scripts.
\beginaltitem {aux.sprint_math_dimension(id : int, dimension : string)}
Same as \luaident{get_math_dimension()}, but output the value
- in scaled points at the \TEX end.
+ in scaled points at the \TeX\ end.
\endaltitem
\endfunctionlist
@@ -2372,6 +2417,94 @@ are defined for which scripts.
\endsubsubsection
\endsubsection
+
+\beginsubsection {Format Author’s Interface}
+
+Additionally some functions are provided which should only be needed for
+format authors trying to integrate \identifier{luaotfload}'s color handling
+with the conventions of a specific format.
+
+End users should never have to work with these.
+
+\endsubsubsection
+
+\beginsubsubsection{Color setting}
+
+\identifier{luaotfload}'s \inlinecode{color} feature can apply color in two
+different ways: By default it inserts \inlinecode{pdf_colorstack} whatsits
+containing the PDF code to change the color.
+
+Alternatively a function can be provided which gets called on every glyph
+node to be colored. This function can then e.g. apply an attribute which gets
+interpreted later.
+
+This can be enabled separately for colors and transparency by passing such
+callback functions:
+
+\beginfunctionlist
+
+ \beginaltitem {luaotfload.set_colorhandler((head : node, n : node, color :
+ string) -> (head : node, n : node)}
+ Mark the node \luaident{n} in the list starting with \luaident{head}
+ to be colored with color \luaident{color}.
+
+ By default the color is represented by literal PDF code setting the
+ color.
+ \endaltitem
+
+ \beginaltitem {luaotfload.set_transparenthandler((head : node, n : node,
+ level : string) -> (head : node, n : node)}
+ Mark the node \luaident{n} in the list starting with \luaident{head}
+ to be set transparently with transparency level \luaident{level}.
+
+ By default the transparency level is represented by literal PDF code setting the
+ transparency.
+ \endaltitem
+
+\endfunctionlist
+
+When these functions aren't used, then the color is set based on colorstack 0.
+By default a new colorstack is allocated for transparency, but alternatively an
+existsing colorstack for this prpose can be set:
+
+\beginfunctionlist
+
+ \beginaltitem {luaotfload.set_transparent_colorstack(stack : int)}
+ Use colorstack \luaident{stack} for setting transparency.
+ \endaltitem
+
+\endfunctionlist
+
+\endsubsubsection
+
+\beginsubsubsection{Color selection}
+
+Additionally the translation of the argument to \inlinecode{color} to an
+actual PDF color can be customized though three \luaident{exclusive} callbacks:
+
+Since there is only a single \inlinecode{color} feature which sets both the
+color and the transparency, the first callback
+\luaident{luaotfload.split_color} gets called with a single string representing
+the feature value and is supposed to return two values representing the color
+and the transparency part.
+
+The default implementation splits the string the feature value at a comma and
+strips outer spaces for both result values, except the HTML style 8 hexdigit
+RGBA values get split into the first 6 and the last two digits.
+
+Afterwards the return values get passed to the
+\luaident{luaotfload.parse_color} respectively
+\luaident{luaotfload.parse_transparent} callbacks (except that \luaident{false}
+and \luaident{nil} skip the corresponding callback).
+
+These callbacks should translate these strings components into valid PDF
+commands applyind the described color or transparency.
+
+All error handling and reporting should be done in the callbacks.
+
+\endsubsubsection
+
+\endsubsection
\endsection
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -2425,7 +2558,7 @@ being (see above, page \pageref{font-blacklist}).
\beginsubsection {Font Features}
A common problem is the lack of features for some
-\OpenType fonts even when specified.
+\OpenType\ fonts even when specified.
%
This can be related to the fact that some fonts do not provide features
for the \inlinecode {dflt} script (see above on page \pageref{script-tag}),
@@ -2449,10 +2582,10 @@ languages by querying it in \fileent{luaotfload-tool}:
\endsubsection
-\beginsubsection {\LUATEX Programming}
+\beginsubsection {\LuaTeX\ Programming}
Another strategy that helps avoiding problems is to not access raw
-\LUATEX internals directly.
+\LuaTeX\ internals directly.
%
Some of them, even though they are dangerous to access, have not been
overridden or disabled.
@@ -2471,10 +2604,10 @@ Instead, the function \luaident{font.getfont()} should be used
because it has been replaced by a safe variant.
However, \luaident{font.getfont()} only covers fonts handled by the
-font loader, e.~g. \identifier{OpenType} and \identifier{TrueType}
+font loader, e.~g. \OpenType\ and \identifier{TrueType}
fonts, but not \abbrev{tfm} or \abbrev{ofm}.
%
-Should you absolutely require access to all fonts known to \LUATEX,
+Should you absolutely require access to all fonts known to \LuaTeX,
including the virtual and autogenerated ones, then you need to query
both \luaident{font.getfont()} and \luaident{font.fonts}.
%
@@ -2506,7 +2639,7 @@ recognizes only that exact version as its license.
The „any later version” clause of the original license text as
copyrighted by the \hyperlink [Free Software Foundation]{http://www.fsf.org/}
\emphasis {does not apply} to either \identifier {luaotfload} or the
-code imported from \CONTEXT.
+code imported from \ConTeXt.
The complete text of the license is given as a separate file \fileent
{COPYING} in the toplevel directory of the
diff --git a/macros/luatex/generic/luaotfload/luaotfload-multiscript.lua b/macros/luatex/generic/luaotfload/luaotfload-multiscript.lua
index c315698a56..bc3921e203 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-multiscript.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-multiscript.lua
@@ -5,8 +5,8 @@
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-multiscript",
- version = "3.21", --TAGVERSION
- date = "2022-03-18", --TAGDATE
+ version = "3.22", --TAGVERSION
+ date = "2022-06-15", --TAGDATE
description = "luaotfload submodule / multiscript",
license = "GPL v2.0",
author = "Marcel Krüger"
diff --git a/macros/luatex/generic/luaotfload/luaotfload-notdef.lua b/macros/luatex/generic/luaotfload/luaotfload-notdef.lua
index fb763390f1..418ea79d57 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-notdef.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-notdef.lua
@@ -5,8 +5,8 @@
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-notdef",
- version = "3.21", --TAGVERSION
- date = "2022-03-18", --TAGDATE
+ version = "3.22", --TAGVERSION
+ date = "2022-06-15", --TAGDATE
description = "luaotfload submodule / notdef",
license = "GPL v2.0",
author = "Marcel Krüger"
diff --git a/macros/luatex/generic/luaotfload/luaotfload-parsers.lua b/macros/luatex/generic/luaotfload/luaotfload-parsers.lua
index 6219525a7f..b2cc9c30ea 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-parsers.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-parsers.lua
@@ -7,8 +7,8 @@
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-parsers",
- version = "3.21", --TAGVERSION
- date = "2022-03-18", --TAGDATE
+ version = "3.22", --TAGVERSION
+ date = "2022-06-15", --TAGDATE
description = "luaotfload submodule / parsers",
license = "GPL v2.0"
}
@@ -498,27 +498,6 @@ local function handle_xetex_option (val)
return tostring(1 + tonumber(val))
end
---[[doc--
-
- Dirty test if a file: request is actually a path: lookup; don’t
- ask! Note this fails on Windows-style absolute paths. These will
- *really* have to use the correct request.
-
---doc]]--
-
-local function check_garbage (_,i, garbage)
- if stringfind(garbage, "/") then
- logreport("log", 0, "load", --- ffs use path!
- "warning: path in file: lookups is deprecated; ")
- logreport("log", 0, "load", "use bracket syntax instead!")
- logreport("log", 0, "load",
- "position: %d; full match: %q",
- i, garbage)
- return true
- end
- return false
-end
-
local featuresep = comma + semicolon
--- modifiers ---------------------------------------------------------
@@ -598,10 +577,12 @@ local combolist = Ct(combodef1 * (comborowsep * combodef)^1)
local subfont = P"(" * Cg(R'09'^1 / function (s)
return tonumber(s) + 1
end + (1 - S"()")^1, "sub") * P")"
+-- An optional subfont shouldn't use subfont^-1 to ensure that parens
+-- at the subfont location are never interpreted in different ways.
+local maybe_subfont = subfont + #(1 - P"(" + -1)
--- lookups -----------------------------------------------------------
local fontname = C((1-S":(/")^1) --- like luatex-fonts
-local unsupported = Cmt((1-S":(")^1, check_garbage)
local combo = Cg(P"combo", "lookup") * colon * ws
* Cg(combolist, "name")
--- initially we intended file: to emulate the behavior of
@@ -610,10 +591,10 @@ local combo = Cg(P"combo", "lookup") * colon * ws
--- turns out fontspec and other widely used packages rely on file:
--- with paths already, so we’ll add a less strict rule here. anyways,
--- we’ll emit a warning.
-local prefixed = P"file:" * ws * Cg(Cc"path", "lookup")
- * Cg(unsupported, "name")
- + Cg(P"name" + "file" + "kpse" + "my", "lookup")
+local prefixed = Cg(P"name" + "file" + "kpse" + "my", "lookup")
* colon * ws * Cg(fontname, "name")
+ + Cg(P"id", "lookup")
+ * colon * ws * Cg(R'09'^1 / tonumber, "id")
local unprefixed = Cg(Cc"anon", "lookup") * Cg(fontname, "name")
--- Bracketed “path” lookups: These may contain any character except
--- for unbalanced brackets. A backslash escapes any following
@@ -628,7 +609,6 @@ local path_balanced = { (path_content + V(2))^1
, lbrk * V(1)^-1 * rbrk }
local path_lookup = Cg(Cc"path", "lookup")
* lbrk * Cg(Cs(path_balanced), "name") * rbrk
- * subfont^-1
--- features ----------------------------------------------------------
local balanced_braces = P{((1 - S'{}') + '{' * V(1) * '}')^0}
@@ -655,12 +635,11 @@ local feature_list = Cf(Ct""
--- top-level rules ---------------------------------------------------
--- \font\foo=<specification>:<features>
local features = Cg(feature_list, "features")
-local specification = (prefixed + unprefixed)
- * subfont^-1
+local specification = (path_lookup + prefixed + unprefixed)
+ * maybe_subfont
* modifier_list
-local font_request = Ct(path_lookup * (colon^-1 * features)^-1
- + combo --> TODO: feature list needed?
- + specification * (colon * features)^-1)
+local font_request = Ct(specification * (colon^-1 * features)^-1
+ + combo) --> TODO: feature list needed?
-- lpeg.print(font_request)
--- v2.5 parser: 1065 rules
diff --git a/macros/luatex/generic/luaotfload/luaotfload-resolvers.lua b/macros/luatex/generic/luaotfload/luaotfload-resolvers.lua
index 0034010817..135a843cf3 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-resolvers.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-resolvers.lua
@@ -11,8 +11,8 @@
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-resolvers",
- version = "3.21", --TAGVERSION
- date = "2022-03-18", --TAGDATE
+ version = "3.22", --TAGVERSION
+ date = "2022-06-15", --TAGDATE
description = "luaotfload submodule / resolvers",
license = "GPL v2.0"
}
@@ -148,6 +148,10 @@ local function resolve_tex_format (specification)
local name = specification.name
for i=1, #tex_formats do
local format = tex_formats [i]
+ local name = name
+ if name:sub(-#format-1) ~= '.' .. format then -- Add an explicit extension to avoid finding local fonts in other formats
+ name = name .. '.' .. format
+ end
local resolved = resolvers_findfile(name, format)
if resolved then
return resolved, format
@@ -231,8 +235,8 @@ local function resolve_kpse (specification)
local resolved = resolvers_findfile(name, suffix)
if resolved then return resolved end
end
- for t, format in next, fonts.formats do --- brute force
- local resolved = kpsefind_file (name, format)
+ for _, t in ipairs{'otf', 'ttf', 'pfb', 'lua', 'afm'} do --- brute force
+ local resolved = resolvers_findfile (name, t)
if resolved then return resolved, t end
end
end
diff --git a/macros/luatex/generic/luaotfload/luaotfload-scripts.lua b/macros/luatex/generic/luaotfload/luaotfload-scripts.lua
index 60b6f603dc..8d98f7ce37 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-scripts.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-scripts.lua
@@ -5,8 +5,8 @@
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-script",
- version = "3.21", --TAGVERSION
- date = "2022-03-18", --TAGDATE
+ version = "3.22", --TAGVERSION
+ date = "2022-06-15", --TAGDATE
description = "luaotfload submodule / Script helpers",
license = "CC0 1.0 Universal",
author = "Marcel Krüger"
diff --git a/macros/luatex/generic/luaotfload/luaotfload-status.lua b/macros/luatex/generic/luaotfload/luaotfload-status.lua
index 5bd21db80c..7ec80b14fb 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-status.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-status.lua
@@ -1,6 +1,6 @@
return {
["hashes"]={
- { "fontloader-2022-02-24.lua", "4dc8ce07471f8af7aa98d835df654768" },
+ { "fontloader-2022-06-15.lua", "1d9c716b5c1d6ff84bee5e4ba3631eac" },
{ "fontloader-util-fil.lua", "d0accf4180201efd567816a25ad5e037" },
{ "fontloader-util-str.lua", "f4a9dd15c3e40cd3915749ac13837c95" },
{ "fontloader-l-unicode.lua", "f368874f11f3c525de5864fd413e4b24" },
@@ -24,7 +24,7 @@ return {
{ "fontloader-basics-nod.lua", "1750af43148def9e7a75c6900a96f9dc" },
{ "fontloader-font-imp-effects.lua", "d05997c1826355548ec9aec1346f9f23" },
{ "fontloader-font-imp-italics.lua", "defcb415bc1e0a0999b27773902adc18" },
- { "fontloader-font-imp-ligatures.lua", "26ffcf089391445f7af59536c8814364" },
+ { "fontloader-font-imp-ligatures.lua", "250f6f4488ee770c23177afb2ff75676" },
{ "fontloader-font-imp-tex.lua", "ceb087ef6fa2f89aed7179f60ddf8f35" },
{ "fontloader-font-shp.lua", "a40862fe382d26c1f3753431254bcfdd" },
{ "fontloader-font-def.lua", "b9d908c2338b7dc443ce9d1e9fcb7139" },
@@ -33,67 +33,67 @@ return {
{ "fontloader-font-one.lua", "bd39d42055a44ca2002f8ddbbbbf27c3" },
{ "fontloader-font-onr.lua", "6d161533f3437435e12a0ad64866df44" },
{ "fontloader-font-ocl.lua", "2a377351ae23c339764ec8ce2e8e9164" },
- { "fontloader-font-osd.lua", "a67b6fb465e7a8b9ecf7c6bbf8dfda03" },
- { "fontloader-font-otc.lua", "582295d3d1e44cd4a31e8bbc1156f7c1" },
+ { "fontloader-font-osd.lua", "9b5337b0051b8e42b6c8329127c59794" },
+ { "fontloader-font-otc.lua", "57f5270b894e40efa93149c7d3fb0209" },
{ "fontloader-font-ots.lua", "55316a605d11a1d07d38795224c90a63" },
{ "fontloader-font-ota.lua", "2bb12d708e35bc05443eba791e2554e7" },
- { "fontloader-font-oup.lua", "e6e2cc0a202aec2c787d5524e64d340a" },
+ { "fontloader-font-oup.lua", "76dc3379061e5650f772909966b5759e" },
{ "fontloader-font-otj.lua", "b2c165bd6771a57633f992d07384b739" },
{ "fontloader-font-oto.lua", "9febc4d75d17a543cd73fb17918f7307" },
- { "fontloader-font-otl.lua", "67078f58bc1a612e4646523538a4e3eb" },
+ { "fontloader-font-otl.lua", "308b1aab04bc131da7eb8e8c3b0471d4" },
{ "fontloader-font-ott.lua", "3f67b1b1d40bbc222681d8db4aff0f42" },
{ "fontloader-font-oti.lua", "309a75f9c14b77d87e94eba827dc4e71" },
- { "fontloader-font-dsp.lua", "7616dae672693fd8ec0f1892358019a2" },
- { "fontloader-font-ttf.lua", "feba1fdc80160343b24f89ef978e53cb" },
+ { "fontloader-font-dsp.lua", "4935e6605ffd7bf57e66f0b6c132f883" },
+ { "fontloader-font-ttf.lua", "a3ff07150b3535fd32f68748d53fcd36" },
{ "fontloader-font-cff.lua", "e38c1a40e1d1d577cdf7920fa50d0654" },
- { "fontloader-font-otr.lua", "91f70c1216e60227e1437b6c8dcd8647" },
+ { "fontloader-font-otr.lua", "1896ac990a961f6d6fec551ca9b52a83" },
{ "fontloader-font-vfc.lua", "a81c29eda98cd62cbebdb6c93544b50d" },
- { "fontloader-font-map.lua", "c4a39db5ad822b348aa61bca5f4a599a" },
+ { "fontloader-font-map.lua", "27ee748150e56f5f0e5f0fefc864f35e" },
{ "fontloader-font-cid.lua", "22b0367742fb253deef84ef7ccf5e8de" },
{ "fontloader-font-con.lua", "724e5dd14aec2d4d189f8619898004cf" },
{ "fontloader-font-ini.lua", "5343de60613adb24cdd7a8d2ee1d153c" },
{ "fontloader-data-con.lua", "23a0f5386d46a1c157ae82a373e35fa0" },
- { "fontloader-reference.lua", "066680a4fe38fad14eb27f56d4616104" },
+ { "fontloader-reference.lua", "c256fdcc4661bf9c868002fe0f996d73" },
{ "fontloader-basics-gen.lua", "4bc43036e9796fccb0b8869f4b05bf2e" },
{ "mktests", "918cb50be9ee8bd645ac1a27dc501e8c" },
- { "mkstatus", "1ad0366dc654e0d374b13acb88bdc195" },
+ { "mkstatus", "8bffa407d2323b24683f726fc6c1a634" },
{ "mkcharacters", "bfca0e96e1e351afe7077502f9595af9" },
{ "mkglyphlist", "7a8a8fdc0eac7fac2f13ec8f4e8e7aa9" },
{ "mkimport", "7d62f1042e548f8b9368f26b9ba4be5c" },
- { "luaotfload-glyphlist.lua", "990d281cc4c46f219d34f2104bf31409" },
+ { "luaotfload-glyphlist.lua", "a1eda1d4588777f77459f86bbe1f7500" },
{ "luaotfload-characters.lua", "76415ca3ede312cad6e09038323489ae" },
- { "luaotfload-dvi.lua", "8ddc7ee49050bcef1682c054f00d3bf5" },
- { "luaotfload-tounicode.lua", "fb7b0f47a74b414177bea5f982abf1de" },
- { "luaotfload-unicode.lua", "65c7651d19fe06ec17196c22c533f768" },
- { "luaotfload-resolvers.lua", "7fd3c8d3d5a76c89227110177e7979f3" },
- { "luaotfload-parsers.lua", "a7eb408eae165d6a61d11a705cab1b98" },
- { "luaotfload-fallback.lua", "e218dc2d291d024f2d1b45da766f6cfc" },
- { "luaotfload-szss.lua", "5d97cb13052848afe1aba7e7ebc1469c" },
- { "luaotfload-scripts.lua", "b987b6592183d5cc5ec858d5792cc381" },
- { "luaotfload-multiscript.lua", "3f88fec616eb7b3f56fc5932a0f1e4d8" },
- { "luaotfload-loaders.lua", "e9f98d4904d245facab3932c505ea0f8" },
- { "luaotfload-harf-plug.lua", "09076cf26ee8160a8eb667c6be500069" },
- { "luaotfload-harf-define.lua", "16079aa19c3862e2e8f6b8cb91cf037a" },
- { "luaotfload-notdef.lua", "c06af0d71ab75a68f3445ecc6fa4e7b3" },
- { "luaotfload-embolden.lua", "04466a99226e5724ef9287ec1a28263a" },
- { "luaotfload-letterspace.lua", "000b624f54d934aff044862b7a64d4e2" },
- { "luaotfload-features.lua", "26ff83b26be22a1962db807b51a362dc" },
- { "luaotfload-database.lua", "315be26e69005984329b81aa331e1365" },
- { "luaotfload-configuration.lua", "5b294133cd45a4a6f4b94388dbfc2964" },
- { "luaotfload-colors.lua", "5989cddee9b5371697c559ec201e27e7" },
- { "luaotfload-auxiliary.lua", "56ff5ca809e974b5630cdce6d287982d" },
- { "luaotfload-filelist.lua", "007dac159b4407ea6cb04dbfbc4d4c87" },
- { "luaotfload-tool.lua", "c3dcd23a9eb499b5878381b6ec01d8c9" },
- { "luaotfload-diagnostics.lua", "90d352ac043f299aa343830084deaa00" },
- { "luaotfload-log.lua", "22964216fb42c7b07623fc43da5149ac" },
- { "luaotfload-init.lua", "8acaf9e42a9c9fa1c398a0944d1a4d50" },
+ { "luaotfload-dvi.lua", "be1944354d7a1d6d4098966c9cc276b2" },
+ { "luaotfload-tounicode.lua", "20fa6d02bae4274d7fbe18ff8683ca76" },
+ { "luaotfload-unicode.lua", "69d17d1de56d8c0abdfb77ef7c11dfd6" },
+ { "luaotfload-resolvers.lua", "490ba5d0a7b5164f9908f690507e5569" },
+ { "luaotfload-parsers.lua", "daf4e973fb452f6a24d90c9a12508445" },
+ { "luaotfload-fallback.lua", "56b58f94896f842ef46f25cad0be39bb" },
+ { "luaotfload-szss.lua", "5512c588c3e53528f430d3dcd5342c61" },
+ { "luaotfload-scripts.lua", "85cd3d5a0df9a0faaf8888fca2352d91" },
+ { "luaotfload-multiscript.lua", "e84b33ced34f4ede4549e64831ba2e14" },
+ { "luaotfload-loaders.lua", "4b5f6a7ba70f6cbe4eb10c98cc54e39e" },
+ { "luaotfload-harf-plug.lua", "061fac6736fbe443c13fa66b1780366d" },
+ { "luaotfload-harf-define.lua", "ff5743a2e17370ec42e2715e7dcd3efa" },
+ { "luaotfload-notdef.lua", "a00724307cd32649101537414600da85" },
+ { "luaotfload-embolden.lua", "2050240a6c33c2cfbb4573f2c3f25507" },
+ { "luaotfload-letterspace.lua", "da30005de64912955267159c4310e215" },
+ { "luaotfload-features.lua", "cba1c85ff9f4bb3d1af3d3e40db30536" },
+ { "luaotfload-database.lua", "306e312f8d5cdebbfc8256bad91197ad" },
+ { "luaotfload-configuration.lua", "b9f0b1bebfc3cb0e79688c101b428ba5" },
+ { "luaotfload-colors.lua", "ceca08c762415386b78bbe6621ca2ba8" },
+ { "luaotfload-auxiliary.lua", "ef7e3f0b64c4dbfc1a498ce4078195aa" },
+ { "luaotfload-filelist.lua", "fb3ab92adb3e379822ed4568429b746c" },
+ { "luaotfload-tool.lua", "e2f826b49e3baff8d46f2454b985cf39" },
+ { "luaotfload-diagnostics.lua", "d7d7005692d1499e9685ab08f6152bf2" },
+ { "luaotfload-log.lua", "20d82599e760f75a4c080d2b08dfe084" },
+ { "luaotfload-init.lua", "0cf48cf4dbb22324a4b3e449830f21c5" },
{ "luaotfload-main.lua", "b19c9cc34cf1d676c39f872cfb41aef6" },
},
["notes"]={
["committer"]="Marcel Fabian Krüger <tex@2krueger.de>",
- ["description"]="v3.21/2022-03-18",
- ["loader"]="fontloader-2022-02-24.lua",
- ["revision"]="f3b4cee7b284e3e9d780315400166c53a4579f55",
- ["timestamp"]="2022-03-18 14:09:12 +0100",
+ ["description"]="v3.22/2022-06-15",
+ ["loader"]="fontloader-2022-06-15.lua",
+ ["revision"]="deb1cfef038a70ebd5a5762394adcbc0889c5cbf",
+ ["timestamp"]="2022-06-15 19:23:05 +0200",
},
} \ No newline at end of file
diff --git a/macros/luatex/generic/luaotfload/luaotfload-suppress.lua b/macros/luatex/generic/luaotfload/luaotfload-suppress.lua
index 71698946c3..6b105effbb 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-suppress.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-suppress.lua
@@ -5,8 +5,8 @@
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-suppress",
- version = "3.21", --TAGVERSION
- date = "2022-03-18", --TAGDATE
+ version = "3.22", --TAGVERSION
+ date = "2022-06-15", --TAGDATE
description = "luaotfload submodule / suppress",
license = "GPL v2.0",
author = "Marcel Krüger"
diff --git a/macros/luatex/generic/luaotfload/luaotfload-szss.lua b/macros/luatex/generic/luaotfload/luaotfload-szss.lua
index b1d77704cc..760e5c29b8 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-szss.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-szss.lua
@@ -5,8 +5,8 @@
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-szss",
- version = "3.21", --TAGVERSION
- date = "2022-03-18", --TAGDATE
+ version = "3.22", --TAGVERSION
+ date = "2022-06-15", --TAGDATE
description = "luaotfload submodule / Special feature handling",
license = "GPL v2.0",
author = "Marcel Krüger"
diff --git a/macros/luatex/generic/luaotfload/luaotfload-t3.lua b/macros/luatex/generic/luaotfload/luaotfload-t3.lua
new file mode 100644
index 0000000000..215ba4b918
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/luaotfload-t3.lua
@@ -0,0 +1,142 @@
+-----------------------------------------------------------------------
+-- FILE: luaotfload-t3.lua
+-- DESCRIPTION: part of luaotfload / Type 3
+-----------------------------------------------------------------------
+do -- block to avoid to many local variables error
+ assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
+ name = "luaotfload-t3",
+ version = "3.22", --TAGVERSION
+ date = "2022-06-15", --TAGDATE
+ description = "luaotfload submodule / Type 3 font handling",
+ license = "GPL v2.0",
+ author = "Marcel Krüger",
+ copyright = "Luaotfload Development Team",
+ }
+end
+
+--[[
+local function u8_to_utf16be(s)
+ local d = {}
+ local i = 0
+ for _, cp, cp2 in utf8.codes(s) do
+ i = i + 1
+ if cp > 0x10000 then
+ cp = cp - 0x10000
+ local high = (cp>>10) | 0xD800
+ local low = (cp&0x3FF) | 0xDC00
+ d[i] = string.format('%04X%04X', high, low)
+ else
+ d[i] = string.format('%04X', cp)
+ end
+ end
+ return table.concat(d, '', 1, i)
+end
+]]
+
+local function t3factory(basename, designsize, callback)
+ local count = 0
+ local gid_to_t3 = {}
+ local t3_to_gid = {}
+ return function(size)
+ local fids = {}
+ return function(gid, width, unicode)
+ local t3id = gid_to_t3[gid]
+ if not t3id then
+ t3id = count
+ count = count + 1
+ gid_to_t3[gid] = t3id
+ t3_to_gid[t3id] = gid
+ end
+ local t3fid, t3cid = t3id >> 8, ~(t3id & 0xFF)
+ local fid = fids[t3fid + 1]
+ local fontdir = fid and font.getfont(fid)
+ local characters = fontdir and fontdir.characters
+ if not (characters and characters[t3cid]) then
+ characters = characters or {}
+ -- First create the character
+ local char = {
+ width = width,
+ height = 0, -- We never look at these two anyway
+ depth = 0,
+ tounicode = unicode,
+ }
+ characters[t3cid] = char
+ if fid then -- Font already exists
+ font.addcharacters(fid, {
+ characters = {
+ [t3cid] = char,
+ },
+ })
+ else
+ fontdir = {
+ name = basename .. '_' .. basesize .. '_' .. t3fid,
+ format = 'type3',
+ psname = 'none',
+ filename = 'not_a_real_filename', -- Can't be null to ensure reuse
+ fullname = basename .. basesize .. '_' .. t3fid,
+ characters = characters,
+ designsize = basesize,
+ size = size,
+ cidinfo = {}, -- Can't be null to ensure reuse
+ attributes = '/FontDescriptor<<\z
+ /Type/FontDescriptor\z
+ /FontName/VirtualLuaFont\z
+ /Flags 4\z
+ /ItalicAngle 0\z
+ >>', -- TODO: Needs work
+ t3_handler = function(stage, _, cid)
+ cid = cid and assert(t3_to_gid[(t3fid << 8) | ~cid])
+ return callback(stage, cid)
+ end
+ }
+ fid = font.define(fontdir)
+ fids[t3fid + 1] = fid
+ end
+ end
+ vf.font(fid)
+ vf.char(t3cid)
+ end
+ end
+end
+
+luatexbase.add_to_callback('provide_charproc_data', function(stage, fid, ...)
+ local fontdir = font.getfont(fid)
+ if not fontdir then error'Unknown font' end
+ local handler = fontdir.t3_handler
+ if not handler then error'Missing t3handler in Type 3 font' end
+ return handler(stage, fid, ...)
+end, 'luaotfload.t3')
+
+return t3factory
+--[===[
+ function callback(stage, cid)
+ if stage == 1 then
+ local char = assert(characters[cid])
+ local head = assert(char.head)
+ local resource = tex.saveboxresource(head, nil--[[attributes]], nil--[[resources]], true--[[immediate]], 0--[[mode]], nil--[[margin]])
+ local name = string.format('/F%i', pdf.getxformname(resource))
+ local resources = characters.resources
+ if resources then
+ characters.resources = string.format('%s %s %i 0 R', resources, name, resource)
+ else
+ characters.resources = string.format('%s %i 0 R', name, resource)
+ end
+ char.resource = name
+ elseif stage == 2 then
+ local char = assert(characters[cid])
+ width = char.width/65781
+ return pdf.obj{
+ type = 'stream',
+ immediate = true,
+ -- objnum =
+ -- attr =
+ -- compresslevel =
+ string = string.format('%g 0 d0 %s Do', width, char.resource)
+ }, width
+ elseif stage == 3 then
+ return 65781/655360, string.format('/XObject<<%s>>', characters.resources)
+ end
+ print(stage, fid, cid)
+ end,
+ }
+]===]
diff --git a/macros/luatex/generic/luaotfload/luaotfload-tool.1 b/macros/luatex/generic/luaotfload/luaotfload-tool.1
index a450459d7a..8967467c46 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-tool.1
+++ b/macros/luatex/generic/luaotfload/luaotfload-tool.1
@@ -1,8 +1,5 @@
.\" Man page generated from reStructuredText.
.
-.TH LUAOTFLOAD-TOOL 1 "2022-03-18" "3.21" "text processing"
-.SH NAME
-luaotfload-tool \- generate and query the Luaotfload font names database
.
.nr rst2man-indent-level 0
.
@@ -30,6 +27,9 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
..
+.TH "LUAOTFLOAD-TOOL" 1 "2022-06-15" "3.22" "text processing"
+.SH NAME
+luaotfload-tool \- generate and query the Luaotfload font names database
.SH SYNOPSIS
.sp
\fBluaotfload\-tool\fP [ \-bcDfFiIlLnpqRSuvVhw ]
@@ -77,14 +77,14 @@ the \fILuaotfload\fP package. There are two general modes: \fBupdate\fP and
.SS update mode
.INDENT 0.0
.TP
-.B \-\-update\fP,\fB \-u
+.B \-\-update\fP,\fB \-u
Update the database; indexes new fonts.
.TP
-.B \-\-force\fP,\fB \-f
+.B \-\-force\fP,\fB \-f
Force rebuilding of the database; re\-indexes
all fonts.
.TP
-.B \-\-local\fP,\fB \-L
+.B \-\-local\fP,\fB \-L
Include font files in \fB$PWD\fP\&. This option
will cause large parts of the database to be
rebuilt. Thus it is quite inefficient.
@@ -93,16 +93,16 @@ the database is prevented from being saved
to disk, so the local fonts need to be parsed
with every invocation of \fBluaotfload\-tool\fP\&.
.TP
-.B \-\-no\-reload\fP,\fB \-n
+.B \-\-no\-reload\fP,\fB \-n
Suppress auto\-updates to the database (e.g.
when \fB\-\-find\fP is passed an unknown name).
.TP
-.B \-\-no\-compress\fP,\fB \-c
+.B \-\-no\-compress\fP,\fB \-c
Do not filter the plain text version of the
font index through gzip. Useful for debugging
if your editor is built without zlib.
.TP
-.B \-\-prefer\-texmf\fP,\fB \-p
+.B \-\-prefer\-texmf\fP,\fB \-p
Organize the file name database in a way so
that it prefer fonts in the \fITEXMF\fP tree over
system fonts if they are installed in both.
@@ -139,16 +139,16 @@ mapped to.
i.e. \fB\-\-find=file:foo.otf\fP checks whether
\fBfoo.otf\fP is indexed.
.TP
-.B \-\-fuzzy\fP,\fB \-F
+.B \-\-fuzzy\fP,\fB \-F
Show approximate matches to the file name if
the lookup was unsuccessful (requires
\fB\-\-find\fP).
.TP
-.B \-\-info\fP,\fB \-i
+.B \-\-info\fP,\fB \-i
Display basic information to a resolved font
file (requires \fB\-\-find\fP).
.TP
-.B \-\-inspect\fP,\fB \-I
+.B \-\-inspect\fP,\fB \-I
Display detailed information by loading the
font and analyzing the font table; very slow!
For the meaning of the returned fields see
@@ -189,7 +189,7 @@ format:
.sp
.nf
.ft C
-\&./luaotfload\-tool.lua \-\-list="format" \-\-fields="file\->base,version"
+\&./luaotfload\-tool.lua \-\-list=\(dqformat\(dq \-\-fields=\(dqfile\->base,version\(dq
.ft P
.fi
.UNINDENT
@@ -230,7 +230,7 @@ The default is plainname,version*.
.SS font and lookup caches
.INDENT 0.0
.TP
-.B \-\-flush\-lookups
+.B \-\-flush\-lookups
Clear font name lookup cache (experimental).
.TP
.BI \-\-cache\fB= DIRECTIVE
@@ -249,15 +249,15 @@ cache;
.SS debugging methods
.INDENT 0.0
.TP
-.B \-\-show\-blacklist\fP,\fB \-b
+.B \-\-show\-blacklist\fP,\fB \-b
Show blacklisted files (not directories).
.TP
-.B \-\-dry\-run\fP,\fB \-D
+.B \-\-dry\-run\fP,\fB \-D
Don’t load fonts when updating the database;
scan directories only.
(For debugging file system related issues.)
.TP
-.B \-\-no\-strip
+.B \-\-no\-strip
Do not strip redundant information after
building the database. Warning: this will
inflate the index to about two to three times
@@ -331,7 +331,7 @@ state.
Set verbosity level to \fIn\fP or the number of
repetitions of \fB\-v\fP\&.
.TP
-.B \-\-quiet
+.B \-\-quiet
No verbose output (log level set to zero).
.TP
.BI \-\-log\fB= CHANNEL
@@ -347,11 +347,11 @@ directory (the name will be chosen
automatically.
.UNINDENT
.TP
-.B \-\-version\fP,\fB \-V
+.B \-\-version\fP,\fB \-V
Show version numbers of components as well as
some basic information and exit.
.TP
-.B \-\-help\fP,\fB \-h
+.B \-\-help\fP,\fB \-h
Show help message and exit.
.TP
.BI \-\-diagnose\fB= CHECK
@@ -387,12 +387,12 @@ Read the configuration from \fIFILE\fP\&. See
\fBluaotfload.conf\fP(%) for documentation
concerning the format and available options.
.TP
-.B \-\-dumpconf
+.B \-\-dumpconf
Print the currently active configuration; the
output can be saved to a file and used for
bootstrapping a custom configuration files.
.TP
-.B \-\-aliases
+.B \-\-aliases
Dump the font name database as a kpathsea
aliases file. This option is experimental and
might go away.
diff --git a/macros/luatex/generic/luaotfload/luaotfload-tool.lua b/macros/luatex/generic/luaotfload/luaotfload-tool.lua
index c8125a8bef..56b433bf2b 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-tool.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-tool.lua
@@ -9,8 +9,8 @@
local ProvidesLuaModule = {
name = "luaotfload-tool",
- version = "3.21", --TAGVERSION
- date = "2022-03-18", --TAGDATE
+ version = "3.22", --TAGVERSION
+ date = "2022-06-15", --TAGDATE
description = "luaotfload-tool / database functionality",
license = "GPL v2.0"
}
@@ -1155,19 +1155,7 @@ function actions.query (job)
local query = job.query
- local tmpspec = {
- name = query,
- lookup = "name",
- specification = query,
- optsize = 0,
- features = { },
- }
-
- tmpspec = fonts.names.handle_request (tmpspec)
-
- if not tmpspec.size then
- tmpspec.size = 655360 --- assume 10pt
- end
+ local tmpspec = fonts.definers.analyze (query, 655360)
local foundname, subfont, success, needle
diff --git a/macros/luatex/generic/luaotfload/luaotfload-tool.pdf b/macros/luatex/generic/luaotfload/luaotfload-tool.pdf
index 931621cfc4..cb4c8141e0 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-tool.pdf
+++ b/macros/luatex/generic/luaotfload/luaotfload-tool.pdf
Binary files differ
diff --git a/macros/luatex/generic/luaotfload/luaotfload-tool.rst b/macros/luatex/generic/luaotfload/luaotfload-tool.rst
index b81c87731d..25d90cd33a 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-tool.rst
+++ b/macros/luatex/generic/luaotfload/luaotfload-tool.rst
@@ -6,9 +6,9 @@
generate and query the Luaotfload font names database
-----------------------------------------------------------------------
-:Date: 2022-03-18
+:Date: 2022-06-15
:Copyright: GPL v2.0
-:Version: 3.21
+:Version: 3.22
:Manual section: 1
:Manual group: text processing
diff --git a/macros/luatex/generic/luaotfload/luaotfload-tounicode.lua b/macros/luatex/generic/luaotfload/luaotfload-tounicode.lua
index 155ffb2d94..96ffd562b0 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-tounicode.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-tounicode.lua
@@ -5,8 +5,8 @@
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-tounicode",
- version = "3.21", --TAGVERSION
- date = "2022-03-18", --TAGDATE
+ version = "3.22", --TAGVERSION
+ date = "2022-06-15", --TAGDATE
description = "luaotfload submodule / tounicode",
license = "GPL v2.0",
author = "Hans Hagen, Khaled Hosny, Elie Roux, Philipp Gesang, Marcel Krüger",
diff --git a/macros/luatex/generic/luaotfload/luaotfload-unicode.lua b/macros/luatex/generic/luaotfload/luaotfload-unicode.lua
index c20c81ef8e..e504f892e2 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-unicode.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-unicode.lua
@@ -5,8 +5,8 @@
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-unicode",
- version = "3.21", --TAGVERSION
- date = "2022-03-18", --TAGDATE
+ version = "3.22", --TAGVERSION
+ date = "2022-06-15", --TAGDATE
description = "luaotfload submodule / Unicode helpers",
license = "CC0 1.0 Universal",
author = "Marcel Krüger"
@@ -23,46 +23,6 @@ local codepoint = lpeg.S'0123456789ABCDEF'^4/function(c)return tonumber(c, 16)en
local empty = {}
local result = {}
-local casefold do
- local nl = ('#' * (1-lpeg.P'\n')^0)^-1 * '\n'
- local entry = codepoint * "; " * lpeg.C(1) * ";" * lpeg.Ct((' ' * codepoint)^1) * "; " * nl
- local file = lpeg.Cf(
- lpeg.Ct(
- lpeg.Cg(lpeg.Ct"", "C")
- * lpeg.Cg(lpeg.Ct"", "F")
- * lpeg.Cg(lpeg.Ct"", "S")
- * lpeg.Cg(lpeg.Ct"", "T"))
- * nl^0 * lpeg.Cg(entry)^0 * nl^0 * -1
- , function(t, base, class, mapping)
- rawset(rawget(t, class), base, mapping)
- return t
- end)
-
- local f = io.open(kpse.find_file"CaseFolding.txt")
- local data = file:match(f:read'*a')
- f:close()
- function casefold(s, full, special)
- local first = special and data.T or empty
- local second = data.C
- local third = full and data.F or data.S
- local result = result
- for i = #result, 1, -1 do result[i] = nil end
- local i = 1
- for _, c in utf8codes(s) do
- local datum = first[c] or second[c] or third[c]
- if datum then
- local l = #datum
- move(datum, 1, l, i, result)
- i = i + l
- else
- result[i] = c
- i = i + 1
- end
- end
- return utf8char(unpack(result))
- end
-end
-
local alphnum_only do
local niceentry = lpeg.Cg(codepoint * ';' * (1-lpeg.P';')^0 * ';' * lpeg.S'LN' * lpeg.Cc(true))
local entry = niceentry^0 * (1-lpeg.P'\n')^0 * lpeg.P'\n'
@@ -232,8 +192,58 @@ do
f:close()
end
+do
+ local function eq(a, b)
+ if not a then return false end
+ if not b then return false end
+ if a == b then return true end
+ if #a ~= #b then return false end
+ for i=1,#a do if a[i] ~= b[i] then return false end end
+ return true
+ end
+ local function collapse(t, inherited)
+ inherited = t._ or inherited
+ local empty = true
+ for k,v in next, t do
+ if k ~= '_' then
+ if eq(inherited, collapse(v, inherited)) then
+ t[k] = nil
+ else
+ empty = false
+ end
+ end
+ end
+ return empty and inherited
+ end
+ local function cleanup(t)
+ for k,v in next, t do
+ if not tonumber(v) then
+ local collapsed = collapse(v)
+ if collapsed and #collapsed == 1 then
+ v = collapsed[1]
+ if k == v then
+ v = nil
+ end
+ t[k] = v
+ end
+ end
+ end
+ end
+ cleanup(uppercase)
+ cleanup(lowercase)
+end
+
+-- Here we manipulate the uppercase table a bit to add the `de-alt` language using capital eszett.
+uppercase[0x00DF]['de-x-eszett'] = { _ = { 0x1E9E } }
+uppercase[0x00DF]['de-alt'] = uppercase[0x00DF]['de-x-eszett']
+
+-- Special handling for Eastern Armenian based on Unicode document L2/20-143.
+uppercase[0x0587]['hy'] = { _ = { 0x0535, 0x054E } }
+-- Resore Unicode behavior. This entry is redundant, but we have to be aware of it
+-- if we later start to ignore unknown private use tags
+uppercase[0x0587]['hy-x-yiwn'] = { _ = uppercase[0x0587]._ }
+
return {
- casefold = casefold,
alphnum_only = alphnum_only,
casemapping = {
uppercase = uppercase,
diff --git a/macros/luatex/generic/luaotfload/luaotfload.conf.5 b/macros/luatex/generic/luaotfload/luaotfload.conf.5
index e8445359ca..dc5b1d3e50 100644
--- a/macros/luatex/generic/luaotfload/luaotfload.conf.5
+++ b/macros/luatex/generic/luaotfload/luaotfload.conf.5
@@ -1,8 +1,5 @@
.\" Man page generated from reStructuredText.
.
-.TH LUAOTFLOAD.CONF 5 "2022-03-18" "3.21" "text processing"
-.SH NAME
-luaotfload.conf \- Luaotfload configuration file
.
.nr rst2man-indent-level 0
.
@@ -30,6 +27,9 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
..
+.TH "LUAOTFLOAD.CONF" 5 "2022-06-15" "3.22" "text processing"
+.SH NAME
+luaotfload.conf \- Luaotfload configuration file
.SH SYNOPSIS
.INDENT 0.0
.IP \(bu 2
@@ -212,7 +212,7 @@ formats
T} T{
s
T} T{
-\fB"otf,ttf,ttc"\fP
+\fB\(dqotf,ttf,ttc\(dq\fP
T}
_
T{
@@ -285,7 +285,7 @@ containing one or more of these elements:
It corresponds loosely to the \fB\-\-formats\fP option to
\fBluaotfload\-tool\fP\&. Invalid or duplicate members are ignored; if the
list does not contain any useful identifiers, the default list
-\fB"otf,ttf,ttc"\fP will be used.
+\fB\(dqotf,ttf,ttc\(dq\fP will be used.
.sp
The variable \fBmax\-fonts\fP determines after processing how many font
files the font scanner will terminate the search. This is useful for
@@ -416,7 +416,7 @@ cache\-dir
T} T{
s
T} T{
-\fB"fonts"\fP
+\fB\(dqfonts\(dq\fP
T}
_
T{
@@ -424,7 +424,7 @@ names\-dir
T} T{
s
T} T{
-\fB"names"\fP
+\fB\(dqnames\(dq\fP
T}
_
T{
@@ -432,7 +432,7 @@ index\-file
T} T{
s
T} T{
-\fB"luaotfload\-names.lua"\fP
+\fB\(dqluaotfload\-names.lua\(dq\fP
T}
_
T{
@@ -440,7 +440,7 @@ lookups\-file
T} T{
s
T} T{
-\fB"luaotfload\-lookup\-cache.lua"\fP
+\fB\(dqluaotfload\-lookup\-cache.lua\(dq\fP
T}
_
.TE
@@ -472,7 +472,7 @@ anon\-sequence
T} T{
s
T} T{
-\fB"tex,path,name"\fP
+\fB\(dqtex,path,name\(dq\fP
T}
_
T{
@@ -480,7 +480,7 @@ color\-callback
T} T{
s
T} T{
-\fB"post_linebreak_filter"\fP
+\fB\(dqpost_linebreak_filter\(dq\fP
T}
_
T{
@@ -488,7 +488,7 @@ definer
T} T{
s
T} T{
-\fB"patch"\fP
+\fB\(dqpatch\(dq\fP
T}
_
T{
@@ -504,7 +504,7 @@ resolver
T} T{
s
T} T{
-\fB"cached"\fP
+\fB\(dqcached\(dq\fP
T}
_
T{
@@ -512,7 +512,7 @@ fontloader
T} T{
s
T} T{
-\fB"default"\fP
+\fB\(dqdefault\(dq\fP
T}
_
.TE
diff --git a/macros/luatex/generic/luaotfload/luaotfload.conf.rst b/macros/luatex/generic/luaotfload/luaotfload.conf.rst
index 3682a5789a..e7fa382899 100644
--- a/macros/luatex/generic/luaotfload/luaotfload.conf.rst
+++ b/macros/luatex/generic/luaotfload/luaotfload.conf.rst
@@ -6,9 +6,9 @@
Luaotfload configuration file
-----------------------------------------------------------------------
-:Date: 2022-03-18
+:Date: 2022-06-15
:Copyright: GPL v2.0
-:Version: 3.21
+:Version: 3.22
:Manual section: 5
:Manual group: text processing
diff --git a/macros/luatex/generic/luaotfload/luaotfload.lua b/macros/luatex/generic/luaotfload/luaotfload.lua
index 5b65b364d8..34181d0af7 100644
--- a/macros/luatex/generic/luaotfload/luaotfload.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload.lua
@@ -20,8 +20,8 @@ local authors = "\z
-- version number is used below!
local ProvidesLuaModule = {
name = "luaotfload",
- version = "3.21", --TAGVERSION
- date = "2022-03-18", --TAGDATE
+ version = "3.22", --TAGVERSION
+ date = "2022-06-15", --TAGDATE
description = "Lua based OpenType font support",
author = authors,
copyright = authors,
diff --git a/macros/luatex/generic/luaotfload/luaotfload.sty b/macros/luatex/generic/luaotfload/luaotfload.sty
index e5dba96300..6c9ceb1f43 100644
--- a/macros/luatex/generic/luaotfload/luaotfload.sty
+++ b/macros/luatex/generic/luaotfload/luaotfload.sty
@@ -39,7 +39,7 @@
\fi
\ifdefined\ProvidesPackage
\ProvidesPackage{luaotfload}%
- [2022/03/18 v3.21 OpenType layout system]
+ [2022/06/15 v3.22 OpenType layout system]
\fi
\directlua{
if xpcall(function ()%
diff --git a/macros/luatex/generic/luaotfload/scripts-demo.pdf b/macros/luatex/generic/luaotfload/scripts-demo.pdf
index b534b64a68..13825f2f01 100644
--- a/macros/luatex/generic/luaotfload/scripts-demo.pdf
+++ b/macros/luatex/generic/luaotfload/scripts-demo.pdf
Binary files differ
diff --git a/macros/luatex/generic/luaotfload/shaper-demo-graphite.pdf b/macros/luatex/generic/luaotfload/shaper-demo-graphite.pdf
index d78a09c63b..7bd624fc2e 100644
--- a/macros/luatex/generic/luaotfload/shaper-demo-graphite.pdf
+++ b/macros/luatex/generic/luaotfload/shaper-demo-graphite.pdf
Binary files differ
diff --git a/macros/luatex/generic/luaotfload/shaper-demo.pdf b/macros/luatex/generic/luaotfload/shaper-demo.pdf
index 78e4d82361..f9b07141b5 100644
--- a/macros/luatex/generic/luaotfload/shaper-demo.pdf
+++ b/macros/luatex/generic/luaotfload/shaper-demo.pdf
Binary files differ