diff options
-rw-r--r-- | src/fontloader/misc/fontloader-font-con.lua | 8 | ||||
-rw-r--r-- | src/fontloader/misc/fontloader-font-otf.lua | 28 | ||||
-rw-r--r-- | src/fontloader/misc/fontloader-font-tfm.lua | 43 | ||||
-rw-r--r-- | src/fontloader/misc/fontloader-fonts-demo-vf-1.lua | 8 | ||||
-rw-r--r-- | src/fontloader/misc/fontloader-fonts-otn.lua | 76 | ||||
-rw-r--r-- | src/fontloader/misc/fontloader-plain.tex | 4 | ||||
-rw-r--r-- | src/fontloader/runtime/fontloader-reference.lua | 130 |
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 |