summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/fontloader/misc/fontloader-font-con.lua8
-rw-r--r--src/fontloader/misc/fontloader-font-otf.lua28
-rw-r--r--src/fontloader/misc/fontloader-font-tfm.lua43
-rw-r--r--src/fontloader/misc/fontloader-fonts-demo-vf-1.lua8
-rw-r--r--src/fontloader/misc/fontloader-fonts-otn.lua76
-rw-r--r--src/fontloader/misc/fontloader-plain.tex4
-rw-r--r--src/fontloader/runtime/fontloader-reference.lua130
7 files changed, 122 insertions, 175 deletions
diff --git a/src/fontloader/misc/fontloader-font-con.lua b/src/fontloader/misc/fontloader-font-con.lua
index 383a403..55d7793 100644
--- a/src/fontloader/misc/fontloader-font-con.lua
+++ b/src/fontloader/misc/fontloader-font-con.lua
@@ -170,8 +170,8 @@ constructors.setfactor()
function constructors.scaled(scaledpoints, designsize) -- handles designsize in sp as well
if scaledpoints < 0 then
+ local factor = constructors.factor
if designsize then
- local factor = constructors.factor
if designsize > factor then -- or just 1000 / when? mp?
return (- scaledpoints/1000) * designsize -- sp's
else
@@ -700,6 +700,7 @@ function constructors.scale(tfmdata,specification)
end
--
if hasmath then
+ --
-- todo, just operate on descriptions.math
local vn = character.next
if vn then
@@ -736,6 +737,11 @@ function constructors.scale(tfmdata,specification)
chr.horiz_variants = t
end
end
+ -- todo also check mathitalics (or that one can go away)
+ end
+ local vi = character.vert_italic
+ if vi and vi ~= 0 then
+ chr.vert_italic = vi*hdelta
end
local va = character.accent
if va then
diff --git a/src/fontloader/misc/fontloader-font-otf.lua b/src/fontloader/misc/fontloader-font-otf.lua
index 0ca1e98..f709e70 100644
--- a/src/fontloader/misc/fontloader-font-otf.lua
+++ b/src/fontloader/misc/fontloader-font-otf.lua
@@ -1999,9 +1999,10 @@ actions["merge kern classes"] = function(data,filename,raw)
local kernclass = subtable.kernclass -- name is inconsistent with anchor_classes
local lookup = subtable.lookup or subtable.name
if kernclass then -- the next one is quite slow
+ -- as fas as i can see the kernclass is a table with one entry and offsets
+ -- have no [1] so we could remov eon elevel (kernclass) and start offsets
+ -- at 1 but we're too far down the road now to fix that
if #kernclass > 0 then
- -- it's a table with one entry .. a future luatex can just
- -- omit that level
kernclass = kernclass[1]
lookup = type(kernclass.lookup) == "string" and kernclass.lookup or lookup
report_otf("fixing kernclass table of lookup %a",lookup)
@@ -2028,15 +2029,17 @@ actions["merge kern classes"] = function(data,filename,raw)
if splt then
local extrakerns = { }
local baseoffset = (fk-1) * maxseconds
- for sk=2,maxseconds do -- will become 1 based in future luatex
- local sv = seconds[sk]
-- for sk, sv in next, seconds do
- local splt = split[sv]
- if splt then -- redundant test
- local offset = offsets[baseoffset + sk]
- if offset then
- for i=1,#splt do
- extrakerns[splt[i]] = offset
+ for sk=2,maxseconds do
+ local sv = seconds[sk]
+ if sv then
+ local splt = split[sv]
+ if splt then -- redundant test
+ local offset = offsets[baseoffset + sk]
+ if offset then
+ for i=1,#splt do
+ extrakerns[splt[i]] = offset
+ end
end
end
end
@@ -2583,6 +2586,7 @@ local function copytotfm(data,cache_id)
-- watch out: luatex uses horiz_variants for the parts
--
local italic = m.italic
+ local vitalic = m.vitalic
--
local variants = m.hvariants
local parts = m.hparts
@@ -2623,12 +2627,14 @@ local function copytotfm(data,cache_id)
c.vert_variants = parts
elseif parts then
character.vert_variants = parts
- italic = m.vitalic
end
--
if italic and italic ~= 0 then
character.italic = italic -- overload
end
+ if vitalic and vitalic ~= 0 then
+ character.vert_italic = vitalic
+ end
--
local accent = m.accent
if accent then
diff --git a/src/fontloader/misc/fontloader-font-tfm.lua b/src/fontloader/misc/fontloader-font-tfm.lua
index 401dc83..2dd5768 100644
--- a/src/fontloader/misc/fontloader-font-tfm.lua
+++ b/src/fontloader/misc/fontloader-font-tfm.lua
@@ -25,6 +25,8 @@ local encodings = fonts.encodings
local tfm = constructors.newhandler("tfm")
tfm.version = 1.000
+tfm.maxnestingdepth = 5
+tfm.maxnestingsize = 65536*1024
local tfmfeatures = constructors.newfeatures("tfm")
local registertfmfeature = tfmfeatures.register
@@ -45,6 +47,18 @@ supplied by <l n='luatex'/>.</p>
-- ofm directive blocks local path search unless set; btw, in context we
-- don't support ofm files anyway as this format is obsolete
+-- we need to deal with nested virtual fonts, but because we load in the
+-- frontend we also need to make sure we don't nest too deep (esp when sizes
+-- get large)
+--
+-- (VTITLE Example of a recursion)
+-- (MAPFONT D 0 (FONTNAME recurse)(FONTAT D 2))
+-- (CHARACTER C A (CHARWD D 1)(CHARHT D 1)(MAP (SETRULE D 1 D 1)))
+-- (CHARACTER C B (CHARWD D 2)(CHARHT D 2)(MAP (SETCHAR C A)))
+-- (CHARACTER C C (CHARWD D 4)(CHARHT D 4)(MAP (SETCHAR C B)))
+--
+-- we added the same checks as below to the luatex engine
+
function tfm.setfeatures(tfmdata,features)
local okay = constructors.initializefeatures("tfm",tfmdata,features,trace_features,report_tfm)
if okay then
@@ -54,9 +68,12 @@ function tfm.setfeatures(tfmdata,features)
end
end
+local depth = { } -- table.setmetatableindex("number")
+
local function read_from_tfm(specification)
- local filename = specification.filename
- local size = specification.size
+ local filename = specification.filename
+ local size = specification.size
+ depth[filename] = (depth[filename] or 0) + 1
if trace_defining then
report_defining("loading tfm file %a at size %s",filename,size)
end
@@ -104,6 +121,25 @@ local function read_from_tfm(specification)
end
properties.virtualized = true
tfmdata.fonts = vfdata.fonts
+ tfmdata.type = "virtual" -- else nested calls with cummulative scaling
+ local fontlist = vfdata.fonts
+ local name = file.nameonly(filename)
+ for i=1,#fontlist do
+ local n = fontlist[i].name
+ local s = fontlist[i].size
+ local d = depth[filename]
+ s = constructors.scaled(s,vfdata.designsize)
+ if d > tfm.maxnestingdepth then
+ report_defining("too deeply nested virtual font %a with size %a, max nesting depth %s",n,s,tfm.maxnestingdepth)
+ fontlist[i] = { id = 0 }
+ elseif (d > 1) and (s > tfm.maxnestingsize) then
+ report_defining("virtual font %a exceeds size %s",n,s)
+ fontlist[i] = { id = 0 }
+ else
+ local t, id = fonts.constructors.readanddefine(n,s)
+ fontlist[i] = { id = id }
+ end
+ end
end
end
end
@@ -122,7 +158,10 @@ local function read_from_tfm(specification)
resources.unicodes = { }
resources.lookuptags = { }
--
+ depth[filename] = depth[filename] - 1
return tfmdata
+ else
+ depth[filename] = depth[filename] - 1
end
end
diff --git a/src/fontloader/misc/fontloader-fonts-demo-vf-1.lua b/src/fontloader/misc/fontloader-fonts-demo-vf-1.lua
index 3878ae6..13acd16 100644
--- a/src/fontloader/misc/fontloader-fonts-demo-vf-1.lua
+++ b/src/fontloader/misc/fontloader-fonts-demo-vf-1.lua
@@ -17,6 +17,7 @@ return function(specification)
{ "special", "pdf:1 0 0 rg" },
{ "special", "pdf:0 1 0 rg" },
{ "special", "pdf:0 0 1 rg" },
+ { "special", "pdf:0 0 1 rg" },
}
local chars = {
identifiers[id1].characters,
@@ -26,7 +27,12 @@ return function(specification)
for u, v in next, f1.characters do
local n = math.floor(math.random(1,3)+0.5)
local c = chars[n][u] or v
- v.commands = { color[n], { 'slot', n, u }, color[0] }
+ v.commands = {
+ color[n],
+ { 'slot', n, u },
+ color[0],
+ { 'nop' }
+ }
v.kerns = nil
v.width = c.width
v.height = c.height
diff --git a/src/fontloader/misc/fontloader-fonts-otn.lua b/src/fontloader/misc/fontloader-fonts-otn.lua
index 1b99c56..7fafadb 100644
--- a/src/fontloader/misc/fontloader-fonts-otn.lua
+++ b/src/fontloader/misc/fontloader-fonts-otn.lua
@@ -250,7 +250,6 @@ local disccodes = nodes.disccodes
local glyph_code = nodecodes.glyph
local glue_code = nodecodes.glue
local disc_code = nodecodes.disc
-local whatsit_code = nodecodes.whatsit
local math_code = nodecodes.math
local dir_code = whatcodes.dir
@@ -316,8 +315,6 @@ local notmatchpre = { }
local notmatchpost = { }
local notmatchreplace = { }
--- head is always a whatsit so we can safely assume that head is not changed
-
-- we use this for special testing and documentation
local checkstep = (nodes and nodes.tracers and nodes.tracers.steppers.check) or function() end
@@ -3320,43 +3317,6 @@ local function featuresprocessor(head,font,attr)
comprun(start,c_run)
start = getnext(start)
end
- elseif id == whatsit_code then -- will be function
- local subtype = getsubtype(start)
- if subtype == dir_code then
- local dir = getfield(start,"dir")
- if dir == "+TLT" then
- topstack = topstack + 1
- dirstack[topstack] = dir
- rlmode = 1
- elseif dir == "+TRT" then
- topstack = topstack + 1
- dirstack[topstack] = dir
- rlmode = -1
- elseif dir == "-TLT" or dir == "-TRT" then
- topstack = topstack - 1
- rlmode = dirstack[topstack] == "+TRT" and -1 or 1
- else
- rlmode = rlparmode
- end
- if trace_directions then
- report_process("directions after txtdir %a: parmode %a, txtmode %a, # stack %a, new dir %a",dir,rlparmode,rlmode,topstack,newdir)
- end
- elseif subtype == localpar_code then
- local dir = getfield(start,"dir")
- if dir == "TRT" then
- rlparmode = -1
- elseif dir == "TLT" then
- rlparmode = 1
- else
- rlparmode = 0
- end
- -- one might wonder if the par dir should be looked at, so we might as well drop the next line
- rlmode = rlparmode
- if trace_directions then
- report_process("directions after pardir %a: parmode %a, txtmode %a",dir,rlparmode,rlmode)
- end
- end
- start = getnext(start)
elseif id == math_code then
start = getnext(end_of_math(start))
else
@@ -3592,42 +3552,6 @@ local function featuresprocessor(head,font,attr)
comprun(start,c_run)
start = getnext(start)
end
- elseif id == whatsit_code then
- local subtype = getsubtype(start)
- if subtype == dir_code then
- local dir = getfield(start,"dir")
- if dir == "+TLT" then
- topstack = topstack + 1
- dirstack[topstack] = dir
- rlmode = 1
- elseif dir == "+TRT" then
- topstack = topstack + 1
- dirstack[topstack] = dir
- rlmode = -1
- elseif dir == "-TLT" or dir == "-TRT" then
- topstack = topstack - 1
- rlmode = dirstack[topstack] == "+TRT" and -1 or 1
- else
- rlmode = rlparmode
- end
- if trace_directions then
- report_process("directions after txtdir %a: parmode %a, txtmode %a, # stack %a, new dir %a",dir,rlparmode,rlmode,topstack,newdir)
- end
- elseif subtype == localpar_code then
- local dir = getfield(start,"dir")
- if dir == "TRT" then
- rlparmode = -1
- elseif dir == "TLT" then
- rlparmode = 1
- else
- rlparmode = 0
- end
- rlmode = rlparmode
- if trace_directions then
- report_process("directions after pardir %a: parmode %a, txtmode %a",dir,rlparmode,rlmode)
- end
- end
- start = getnext(start)
elseif id == math_code then
start = getnext(end_of_math(start))
else
diff --git a/src/fontloader/misc/fontloader-plain.tex b/src/fontloader/misc/fontloader-plain.tex
index 9902c49..99347ed 100644
--- a/src/fontloader/misc/fontloader-plain.tex
+++ b/src/fontloader/misc/fontloader-plain.tex
@@ -13,6 +13,10 @@
% We assume that pdf is used.
+\ifdefined\pdfextension
+ \input luatex-pdf \relax
+\fi
+
\pdfoutput 1
% We set the page dimensions because otherwise the backend does weird things
diff --git a/src/fontloader/runtime/fontloader-reference.lua b/src/fontloader/runtime/fontloader-reference.lua
index a2a598b..ae36617 100644
--- a/src/fontloader/runtime/fontloader-reference.lua
+++ b/src/fontloader/runtime/fontloader-reference.lua
@@ -1,6 +1,6 @@
-- merged file : luatex-fonts-merged.lua
-- parent file : luatex-fonts.lua
--- merge date : 10/09/15 21:28:28
+-- merge date : 11/19/15 19:13:15
do -- begin closure to overcome local limits and interference
@@ -4211,8 +4211,8 @@ end
constructors.setfactor()
function constructors.scaled(scaledpoints,designsize)
if scaledpoints<0 then
+ local factor=constructors.factor
if designsize then
- local factor=constructors.factor
if designsize>factor then
return (- scaledpoints/1000)*designsize
else
@@ -4650,6 +4650,10 @@ function constructors.scale(tfmdata,specification)
end
end
end
+ local vi=character.vert_italic
+ if vi and vi~=0 then
+ chr.vert_italic=vi*hdelta
+ end
local va=character.accent
if va then
chr.top_accent=vdelta*va
@@ -5833,6 +5837,8 @@ local constructors=fonts.constructors
local encodings=fonts.encodings
local tfm=constructors.newhandler("tfm")
tfm.version=1.000
+tfm.maxnestingdepth=5
+tfm.maxnestingsize=65536*1024
local tfmfeatures=constructors.newfeatures("tfm")
local registertfmfeature=tfmfeatures.register
constructors.resolvevirtualtoo=false
@@ -5845,9 +5851,11 @@ function tfm.setfeatures(tfmdata,features)
return {}
end
end
+local depth={}
local function read_from_tfm(specification)
local filename=specification.filename
local size=specification.size
+ depth[filename]=(depth[filename] or 0)+1
if trace_defining then
report_defining("loading tfm file %a at size %s",filename,size)
end
@@ -5891,6 +5899,25 @@ local function read_from_tfm(specification)
end
properties.virtualized=true
tfmdata.fonts=vfdata.fonts
+ tfmdata.type="virtual"
+ local fontlist=vfdata.fonts
+ local name=file.nameonly(filename)
+ for i=1,#fontlist do
+ local n=fontlist[i].name
+ local s=fontlist[i].size
+ local d=depth[filename]
+ s=constructors.scaled(s,vfdata.designsize)
+ if d>tfm.maxnestingdepth then
+ report_defining("too deeply nested virtual font %a with size %a, max nesting depth %s",n,s,tfm.maxnestingdepth)
+ fontlist[i]={ id=0 }
+ elseif (d>1) and (s>tfm.maxnestingsize) then
+ report_defining("virtual font %a exceeds size %s",n,s)
+ fontlist[i]={ id=0 }
+ else
+ local t,id=fonts.constructors.readanddefine(n,s)
+ fontlist[i]={ id=id }
+ end
+ end
end
end
end
@@ -5906,7 +5933,10 @@ local function read_from_tfm(specification)
properties.haslogatures=true
resources.unicodes={}
resources.lookuptags={}
+ depth[filename]=depth[filename]-1
return tfmdata
+ else
+ depth[filename]=depth[filename]-1
end
end
local function check_tfm(specification,fullname)
@@ -8652,7 +8682,7 @@ actions["merge kern classes"]=function(data,filename,raw)
local subtable=subtables[s]
local kernclass=subtable.kernclass
local lookup=subtable.lookup or subtable.name
- if kernclass then
+ if kernclass then
if #kernclass>0 then
kernclass=kernclass[1]
lookup=type(kernclass.lookup)=="string" and kernclass.lookup or lookup
@@ -8677,14 +8707,16 @@ actions["merge kern classes"]=function(data,filename,raw)
if splt then
local extrakerns={}
local baseoffset=(fk-1)*maxseconds
- for sk=2,maxseconds do
+ for sk=2,maxseconds do
local sv=seconds[sk]
- local splt=split[sv]
- if splt then
- local offset=offsets[baseoffset+sk]
- if offset then
- for i=1,#splt do
- extrakerns[splt[i]]=offset
+ if sv then
+ local splt=split[sv]
+ if splt then
+ local offset=offsets[baseoffset+sk]
+ if offset then
+ for i=1,#splt do
+ extrakerns[splt[i]]=offset
+ end
end
end
end
@@ -9145,6 +9177,7 @@ local function copytotfm(data,cache_id)
local m=d.math
if m then
local italic=m.italic
+ local vitalic=m.vitalic
local variants=m.hvariants
local parts=m.hparts
if variants then
@@ -9171,11 +9204,13 @@ local function copytotfm(data,cache_id)
c.vert_variants=parts
elseif parts then
character.vert_variants=parts
- italic=m.vitalic
end
if italic and italic~=0 then
character.italic=italic
end
+ if vitalic and vitalic~=0 then
+ character.vert_italic=vitalic
+ end
local accent=m.accent
if accent then
character.accent=accent
@@ -11610,7 +11645,6 @@ local disccodes=nodes.disccodes
local glyph_code=nodecodes.glyph
local glue_code=nodecodes.glue
local disc_code=nodecodes.disc
-local whatsit_code=nodecodes.whatsit
local math_code=nodecodes.math
local dir_code=whatcodes.dir
local localpar_code=whatcodes.localpar
@@ -14245,42 +14279,6 @@ local function featuresprocessor(head,font,attr)
comprun(start,c_run)
start=getnext(start)
end
- elseif id==whatsit_code then
- local subtype=getsubtype(start)
- if subtype==dir_code then
- local dir=getfield(start,"dir")
- if dir=="+TLT" then
- topstack=topstack+1
- dirstack[topstack]=dir
- rlmode=1
- elseif dir=="+TRT" then
- topstack=topstack+1
- dirstack[topstack]=dir
- rlmode=-1
- elseif dir=="-TLT" or dir=="-TRT" then
- topstack=topstack-1
- rlmode=dirstack[topstack]=="+TRT" and -1 or 1
- else
- rlmode=rlparmode
- end
- if trace_directions then
- report_process("directions after txtdir %a: parmode %a, txtmode %a, # stack %a, new dir %a",dir,rlparmode,rlmode,topstack,newdir)
- end
- elseif subtype==localpar_code then
- local dir=getfield(start,"dir")
- if dir=="TRT" then
- rlparmode=-1
- elseif dir=="TLT" then
- rlparmode=1
- else
- rlparmode=0
- end
- rlmode=rlparmode
- if trace_directions then
- report_process("directions after pardir %a: parmode %a, txtmode %a",dir,rlparmode,rlmode)
- end
- end
- start=getnext(start)
elseif id==math_code then
start=getnext(end_of_math(start))
else
@@ -14501,42 +14499,6 @@ local function featuresprocessor(head,font,attr)
comprun(start,c_run)
start=getnext(start)
end
- elseif id==whatsit_code then
- local subtype=getsubtype(start)
- if subtype==dir_code then
- local dir=getfield(start,"dir")
- if dir=="+TLT" then
- topstack=topstack+1
- dirstack[topstack]=dir
- rlmode=1
- elseif dir=="+TRT" then
- topstack=topstack+1
- dirstack[topstack]=dir
- rlmode=-1
- elseif dir=="-TLT" or dir=="-TRT" then
- topstack=topstack-1
- rlmode=dirstack[topstack]=="+TRT" and -1 or 1
- else
- rlmode=rlparmode
- end
- if trace_directions then
- report_process("directions after txtdir %a: parmode %a, txtmode %a, # stack %a, new dir %a",dir,rlparmode,rlmode,topstack,newdir)
- end
- elseif subtype==localpar_code then
- local dir=getfield(start,"dir")
- if dir=="TRT" then
- rlparmode=-1
- elseif dir=="TLT" then
- rlparmode=1
- else
- rlparmode=0
- end
- rlmode=rlparmode
- if trace_directions then
- report_process("directions after pardir %a: parmode %a, txtmode %a",dir,rlparmode,rlmode)
- end
- end
- start=getnext(start)
elseif id==math_code then
start=getnext(end_of_math(start))
else