summaryrefslogtreecommitdiff
path: root/tex/generic/context/luatex/luatex-fonts-merged.lua
diff options
context:
space:
mode:
Diffstat (limited to 'tex/generic/context/luatex/luatex-fonts-merged.lua')
-rw-r--r--tex/generic/context/luatex/luatex-fonts-merged.lua1164
1 files changed, 741 insertions, 423 deletions
diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua
index 0a14e6082..5499f8f18 100644
--- a/tex/generic/context/luatex/luatex-fonts-merged.lua
+++ b/tex/generic/context/luatex/luatex-fonts-merged.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 : 10/18/18 00:07:52
+-- merge date : 11/18/18 14:07:44
do -- begin closure to overcome local limits and interference
@@ -1107,7 +1107,6 @@ local table,string=table,string
local concat,sort,insert,remove=table.concat,table.sort,table.insert,table.remove
local format,lower,dump=string.format,string.lower,string.dump
local getmetatable,setmetatable=getmetatable,setmetatable
-local getinfo=debug.getinfo
local lpegmatch,patterns=lpeg.match,lpeg.patterns
local floor=math.floor
local stripper=patterns.stripper
@@ -1669,20 +1668,23 @@ local function do_serialize(root,name,depth,level,indexed)
end
elseif tv=="function" then
if functions then
- local f=getinfo(v).what=="C" and dump(dummy) or dump(v)
- if tk=="number" then
- if hexify then
- handle(format("%s [0x%X]=load(%q),",depth,k,f))
+ local getinfo=debug and debug.getinfo
+ if getinfo then
+ local f=getinfo(v).what=="C" and dump(dummy) or dump(v)
+ if tk=="number" then
+ if hexify then
+ handle(format("%s [0x%X]=load(%q),",depth,k,f))
+ else
+ handle(format("%s [%s]=load(%q),",depth,k,f))
+ end
+ elseif tk=="boolean" then
+ handle(format("%s [%s]=load(%q),",depth,k and "true" or "false",f))
+ elseif tk~="string" then
+ elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
+ handle(format("%s %s=load(%q),",depth,k,f))
else
- handle(format("%s [%s]=load(%q),",depth,k,f))
+ handle(format("%s [%q]=load(%q),",depth,k,f))
end
- elseif tk=="boolean" then
- handle(format("%s [%s]=load(%q),",depth,k and "true" or "false",f))
- elseif tk~="string" then
- elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
- handle(format("%s %s=load(%q),",depth,k,f))
- else
- handle(format("%s [%q]=load(%q),",depth,k,f))
end
end
else
@@ -4649,6 +4651,10 @@ function strings.newcollector()
end
end
end
+local f_16_16=formatters["%0.5N"]
+function number.to16dot16(n)
+ return f_16_16(n/65536.0)
+end
end -- closure
@@ -4661,6 +4667,7 @@ if not modules then modules={} end modules ['util-fil']={
copyright="PRAGMA ADE / ConTeXt Development Team",
license="see context related readme files"
}
+local tonumber=tonumber
local byte=string.byte
local char=string.char
utilities=utilities or {}
@@ -4819,17 +4826,17 @@ end
function files.readfixed2(f)
local a,b=byte(f:read(2),1,2)
if a>=0x80 then
- return (a-0x100)+b/0x100
+ tonumber((a-0x100).."."..b)
else
- return (a )+b/0x100
+ tonumber((a ).."."..b)
end
end
function files.readfixed4(f)
local a,b,c,d=byte(f:read(4),1,4)
if a>=0x80 then
- return (0x100*a+b-0x10000)+(0x100*c+d)/0x10000
+ tonumber((0x100*a+b-0x10000).."."..(0x100*c+d))
else
- return (0x100*a+b )+(0x100*c+d)/0x10000
+ tonumber((0x100*a+b ).."."..(0x100*c+d))
end
end
if bit32 then
@@ -4963,6 +4970,7 @@ local match,gmatch,gsub,lower=string.match,string.gmatch,string.gsub,string.lowe
local formatters,split,format,dump=string.formatters,string.split,string.format,string.dump
local loadfile,type=loadfile,type
local setmetatable,getmetatable,collectgarbage=setmetatable,getmetatable,collectgarbage
+local floor=math.floor
local dummyfunction=function()
end
local dummyreporter=function(c)
@@ -5273,6 +5281,11 @@ if arg then
end
end
end
+if not number.idiv then
+ function number.idiv(i,d)
+ return floor(i/d)
+ end
+end
end -- closure
@@ -9921,23 +9934,20 @@ function constructors.finalize(tfmdata)
if not properties.virtualized then
properties.virtualized=tfmdata.type=="virtual"
end
- if not tfmdata.properties then
- tfmdata.properties={
- fontname=tfmdata.fontname,
- filename=tfmdata.filename,
- fullname=tfmdata.fullname,
- name=tfmdata.name,
- psname=tfmdata.psname,
- encodingbytes=tfmdata.encodingbytes or 1,
- embedding=tfmdata.embedding or "subset",
- tounicode=tfmdata.tounicode or 1,
- cidinfo=tfmdata.cidinfo or nil,
- format=tfmdata.format or "type1",
- direction=tfmdata.direction or 0,
- writingmode=tfmdata.writingmode or "horizontal",
- identity=tfmdata.identity or "horizontal",
- }
- end
+ properties.fontname=tfmdata.fontname
+ properties.filename=tfmdata.filename
+ properties.fullname=tfmdata.fullname
+ properties.name=tfmdata.name
+ properties.psname=tfmdata.psname
+ properties.encodingbytes=tfmdata.encodingbytes or 1
+ properties.embedding=tfmdata.embedding or "subset"
+ properties.tounicode=tfmdata.tounicode or 1
+ properties.cidinfo=tfmdata.cidinfo or nil
+ properties.format=tfmdata.format or "type1"
+ properties.direction=tfmdata.direction or 0
+ properties.writingmode=tfmdata.writingmode or "horizontal"
+ properties.identity=tfmdata.identity or "horizontal"
+ properties.usedbitmap=tfmdata.usedbitmap
if not tfmdata.resources then
tfmdata.resources={}
end
@@ -11244,6 +11254,7 @@ if not modules then modules={} end modules ['font-otr']={
}
local next,type,tonumber=next,type,tonumber
local byte,lower,char,gsub=string.byte,string.lower,string.char,string.gsub
+local fullstrip=string.fullstrip
local floor,round=math.floor,math.round
local P,R,S,C,Cs,Cc,Ct,Carg,Cmt=lpeg.P,lpeg.R,lpeg.S,lpeg.C,lpeg.Cs,lpeg.Cc,lpeg.Ct,lpeg.Carg,lpeg.Cmt
local lpegmatch=lpeg.match
@@ -11520,19 +11531,29 @@ local helpers={}
readers.helpers=helpers
local function gotodatatable(f,fontdata,tag,criterium)
if criterium and f then
- local datatable=fontdata.tables[tag]
- if datatable then
- local tableoffset=datatable.offset
- setposition(f,tableoffset)
- return tableoffset
+ local tables=fontdata.tables
+ if tables then
+ local datatable=tables[tag]
+ if datatable then
+ local tableoffset=datatable.offset
+ setposition(f,tableoffset)
+ return tableoffset
+ end
+ else
+ report("no tables")
end
end
end
local function reportskippedtable(f,fontdata,tag,criterium)
if criterium and f then
- local datatable=fontdata.tables[tag]
- if datatable then
- report("loading of table %a skipped",tag)
+ local tables=fontdata.tables
+ if tables then
+ local datatable=tables[tag]
+ if datatable then
+ report("loading of table %a skipped",tag)
+ end
+ else
+ report("no tables")
end
end
end
@@ -11556,6 +11577,15 @@ local platformnames={
typographicsubfamily=true,
compatiblefullname=true,
}
+local platformextras={
+ uniqueid=true,
+ version=true,
+ copyright=true,
+ license=true,
+ licenseurl=true,
+ manufacturer=true,
+ vendorurl=true,
+}
function readers.name(f,fontdata,specification)
local tableoffset=gotodatatable(f,fontdata,"name",true)
if tableoffset then
@@ -11608,6 +11638,17 @@ function readers.name(f,fontdata,specification)
local names={}
local done={}
local extras={}
+ local function decoded(platform,encoding,content)
+ local decoder=decoders[platform]
+ if decoder then
+ decoder=decoder[encoding]
+ end
+ if decoder then
+ return decoder(content)
+ else
+ return content
+ end
+ end
local function filter(platform,e,l)
local namelist=namelists[platform]
for i=1,#namelist do
@@ -11619,14 +11660,7 @@ function readers.name(f,fontdata,specification)
local language=name.language
if (not e or encoding==e) and (not l or language==l) then
setposition(f,name.offset)
- local content=readstring(f,name.length)
- local decoder=decoders[platform]
- if decoder then
- decoder=decoder[encoding]
- end
- if decoder then
- content=decoder(content)
- end
+ local content=decoded(platform,encoding,readstring(f,name.length))
if nametag then
names[nametag]={
content=content,
@@ -11650,22 +11684,15 @@ function readers.name(f,fontdata,specification)
fontdata.extras=extras
if specification.platformnames then
local collected={}
+ local platformextras=specification.platformextras and platformextras
for platform,namelist in next,namelists do
local filtered=false
for i=1,#namelist do
local entry=namelist[i]
local name=entry.name
- if platformnames[name] then
+ if platformnames[name] or (platformextras and platformextras[name]) then
setposition(f,entry.offset)
- local content=readstring(f,entry.length)
- local encoding=entry.encoding
- local decoder=decoders[platform]
- if decoder then
- decoder=decoder[encoding]
- end
- if decoder then
- content=decoder(content)
- end
+ local content=decoded(platform,entry.encoding,readstring(f,entry.length))
if filtered then
filtered[name]=content
else
@@ -11748,10 +11775,13 @@ end
readers.head=function(f,fontdata)
local tableoffset=gotodatatable(f,fontdata,"head",true)
if tableoffset then
+ local version=readulong(f)
+ local fontversion=readulong(f)
local fontheader={
- version=readfixed(f),
- revision=readfixed(f),
- checksum=readulong(f),
+ version=version,
+ fontversion=number.to16dot16(fontversion),
+ fontversionnumber=fontversion,
+ checksum=readushort(f)*0x10000+readushort(f),
magic=readulong(f),
flags=readushort(f),
units=readushort(f),
@@ -11777,7 +11807,7 @@ readers.hhea=function(f,fontdata,specification)
local tableoffset=gotodatatable(f,fontdata,"hhea",specification.details)
if tableoffset then
fontdata.horizontalheader={
- version=readfixed(f),
+ version=readulong(f),
ascender=readfword(f),
descender=readfword(f),
linegap=readfword(f),
@@ -11805,7 +11835,7 @@ readers.vhea=function(f,fontdata,specification)
local tableoffset=gotodatatable(f,fontdata,"vhea",specification.details)
if tableoffset then
fontdata.verticalheader={
- version=readfixed(f),
+ version=readulong(f),
ascender=readfword(f),
descender=readfword(f),
linegap=readfword(f),
@@ -11832,15 +11862,15 @@ end
readers.maxp=function(f,fontdata,specification)
local tableoffset=gotodatatable(f,fontdata,"maxp",specification.details)
if tableoffset then
- local version=readfixed(f)
+ local version=readulong(f)
local nofglyphs=readushort(f)
fontdata.nofglyphs=nofglyphs
- if version==0.5 then
+ if version==0x00005000 then
fontdata.maximumprofile={
version=version,
nofglyphs=nofglyphs,
}
- elseif version==1.0 then
+ elseif version==0x00010000 then
fontdata.maximumprofile={
version=version,
nofglyphs=nofglyphs,
@@ -11877,7 +11907,7 @@ readers.hmtx=function(f,fontdata,specification)
local leftsidebearing=0
for i=0,nofmetrics-1 do
local glyph=glyphs[i]
- width=readshort(f)
+ width=readshort(f)
leftsidebearing=readshort(f)
if width~=0 then
glyph.width=width
@@ -11923,7 +11953,7 @@ end
readers.post=function(f,fontdata,specification)
local tableoffset=gotodatatable(f,fontdata,"post",true)
if tableoffset then
- local version=readfixed(f)
+ local version=readulong(f)
fontdata.postscript={
version=version,
italicangle=round(1000*readfixed(f))/1000,
@@ -11936,11 +11966,11 @@ readers.post=function(f,fontdata,specification)
maxmemtype1=readulong(f),
}
if not specification.glyphs then
- elseif version==1.0 then
+ elseif version==0x00010000 then
for index=0,#standardromanencoding do
glyphs[index].name=standardromanencoding[index]
end
- elseif version==2.0 then
+ elseif version==0x00020000 then
local glyphs=fontdata.glyphs
local nofglyphs=readushort(f)
local indices={}
@@ -11971,8 +12001,6 @@ readers.post=function(f,fontdata,specification)
end
end
end
- elseif version==2.5 then
- elseif version==3.0 then
end
else
fontdata.postscript={}
@@ -12529,14 +12557,16 @@ local function getinfo(maindata,sub,platformnames,rawfamilynames,metricstoo,inst
designsize=fontdata.designsize,
minsize=fontdata.minsize,
maxsize=fontdata.maxsize,
+ boundingbox=fontheader and { fontheader.xmin or 0,fontheader.ymin or 0,fontheader.xmax or 0,fontheader.ymax or 0 } or nil,
monospaced=(tonumber(postscript.monospaced or 0)>0) or metrics.panosewidth=="monospaced",
averagewidth=metrics.averagewidth,
xheight=metrics.xheight,
- capheight=metrics.capheight,
+ capheight=metrics.capheight or fontdata.maxy,
ascender=metrics.typoascender,
descender=metrics.typodescender,
platformnames=platformnames or nil,
instancenames=instancenames or nil,
+ tableoffsets=fontdata.tableoffsets,
}
if metricstoo then
local keys={
@@ -12594,7 +12624,7 @@ local function loadtables(f,specification,offset)
}
for i=1,fontdata.noftables do
local tag=lower(stripstring(readstring(f,4)))
- local checksum=readulong(f)
+ local checksum=readushort(f)*0x10000+readushort(f)
local offset=readulong(f)
local length=readulong(f)
if offset+length>filesize then
@@ -12612,7 +12642,7 @@ local function loadtables(f,specification,offset)
else
fontdata.format="truetype"
end
- return fontdata
+ return fontdata,tables
end
local function prepareglyps(fontdata)
local glyphs=setmetatableindex(function(t,k)
@@ -12633,7 +12663,7 @@ local function readtable(tag,f,fontdata,specification,...)
end
local variablefonts_supported=(context and true) or (logs and logs.application and true) or false
local function readdata(f,offset,specification)
- local fontdata=loadtables(f,specification,offset)
+ local fontdata,tables=loadtables(f,specification,offset)
if specification.glyphs then
prepareglyps(fontdata)
end
@@ -12743,9 +12773,18 @@ local function readdata(f,offset,specification)
readtable("gpos",f,fontdata,specification)
readtable("math",f,fontdata,specification)
fontdata.locations=nil
- fontdata.tables=nil
fontdata.cidmaps=nil
fontdata.dictionaries=nil
+ if specification.tableoffsets then
+ fontdata.tableoffsets=tables
+ setmetatableindex(tables,{
+ version=fontdata.version,
+ noftables=fontdata.noftables,
+ searchrange=fontdata.searchrange,
+ entryselector=fontdata.entryselector,
+ rangeshift=fontdata.rangeshift,
+ })
+ end
return fontdata
end
local function loadfontdata(specification)
@@ -12849,7 +12888,7 @@ local function loadfont(specification,n,instance)
specification.instance=specification.instance or instance
end
local function message(str)
- report("fatal error in file %a: %s\n%s",specification.filename,str,debug.traceback())
+ report("fatal error in file %a: %s\n%s",specification.filename,str,debug and debug.traceback())
end
local ok,result=xpcall(loadfontdata,message,specification)
if ok then
@@ -12871,12 +12910,25 @@ function readers.loadshapes(filename,n,instance,streams)
v.index=nil
v.math=nil
end
+ local names=fontdata.names
+ if names then
+ for k,v in next,names do
+ names[k]=fullstrip(v.content)
+ end
+ end
end
return fontdata and {
filename=filename,
format=fontdata.format,
glyphs=fontdata.glyphs,
units=fontdata.fontheader.units,
+ cffinfo=fontdata.cffinfo,
+ fontheader=fontdata.fontheader,
+ horizontalheader=fontdata.horizontalheader,
+ verticalheader=fontdata.verticalheader,
+ maximumprofile=fontdata.maximumprofile,
+ names=fontdata.names,
+ postscript=fontdata.postscript,
} or {
filename=filename,
format="unknown",
@@ -12940,10 +12992,12 @@ function readers.getinfo(filename,specification)
local platformnames=false
local rawfamilynames=false
local instancenames=true
+ local tableoffsets=false
if type(specification)=="table" then
subfont=tonumber(specification.subfont)
platformnames=specification.platformnames
rawfamilynames=specification.rawfamilynames
+ tableoffsets=specification.tableoffsets
else
subfont=tonumber(specification)
end
@@ -12952,6 +13006,7 @@ function readers.getinfo(filename,specification)
details=true,
platformnames=platformnames,
instancenames=true,
+ tableoffsets=tableoffsets,
}
if fontdata then
local subfonts=fontdata.subfonts
@@ -14219,7 +14274,7 @@ if not modules then modules={} end modules ['font-cff']={
copyright="PRAGMA ADE / ConTeXt Development Team",
license="see context related readme files"
}
-local next,type,tonumber=next,type,tonumber
+local next,type,tonumber,rawget=next,type,tonumber,rawget
local byte,char,gmatch=string.byte,string.char,string.gmatch
local concat,remove,unpack=table.concat,table.remove,table.unpack
local floor,abs,round,ceil,min,max=math.floor,math.abs,math.round,math.ceil,math.min,math.max
@@ -14227,6 +14282,8 @@ local P,C,R,S,C,Cs,Ct=lpeg.P,lpeg.C,lpeg.R,lpeg.S,lpeg.C,lpeg.Cs,lpeg.Ct
local lpegmatch=lpeg.match
local formatters=string.formatters
local bytetable=string.bytetable
+local idiv=number.idiv
+local rshift,band,extract=bit32.rshift,bit32.band,bit32.extract
local readers=fonts.handlers.otf.readers
local streamreader=readers.streamreader
local readstring=streamreader.readstring
@@ -14421,8 +14478,25 @@ do
end+P("\05")/function()
result.fontbbox={ unpack(stack,1,4) }
top=0
- end
-+P("\13")/function()
+ end+P("\06")/function()
+ result.bluevalues={ unpack(stack,1,top) }
+ top=0
+ end+P("\07")/function()
+ result.otherblues={ unpack(stack,1,top) }
+ top=0
+ end+P("\08")/function()
+ result.familyblues={ unpack(stack,1,top) }
+ top=0
+ end+P("\09")/function()
+ result.familyotherblues={ unpack(stack,1,top) }
+ top=0
+ end+P("\10")/function()
+ result.strhw=stack[top]
+ top=0
+ end+P("\11")/function()
+ result.strvw=stack[top]
+ top=0
+ end+P("\13")/function()
result.uniqueid=stack[top]
top=0
end+P("\14")/function()
@@ -14488,6 +14562,21 @@ do
end+P("\08")/function()
result.strokewidth=stack[top]
top=0
+ end+P("\09")/function()
+ result.bluescale=stack[top]
+ top=0
+ end+P("\10")/function()
+ result.bluesnap=stack[top]
+ top=0
+ end+P("\11")/function()
+ result.bluefuzz=stack[top]
+ top=0
+ end+P("\12")/function()
+ result.stemsnaph={ unpack(stack,1,top) }
+ top=0
+ end+P("\13")/function()
+ result.stemsnapv={ unpack(stack,1,top) }
+ top=0
end+P("\20")/function()
result.syntheticbase=stack[top]
top=0
@@ -14531,24 +14620,24 @@ do
top=0
end
)
- local p_last=P("\x0F")/"0"+P("\x1F")/"1"+P("\x2F")/"2"+P("\x3F")/"3"+P("\x4F")/"4"+P("\x5F")/"5"+P("\x6F")/"6"+P("\x7F")/"7"+P("\x8F")/"8"+P("\x9F")/"9"+P("\xAF")/""+P("\xBF")/""+P("\xCF")/""+P("\xDF")/""+P("\xEF")/""+R("\xF0\xFF")/""
local remap={
["\x00"]="00",["\x01"]="01",["\x02"]="02",["\x03"]="03",["\x04"]="04",["\x05"]="05",["\x06"]="06",["\x07"]="07",["\x08"]="08",["\x09"]="09",["\x0A"]="0.",["\x0B"]="0E",["\x0C"]="0E-",["\x0D"]="0",["\x0E"]="0-",["\x0F"]="0",
- ["\x10"]="10",["\x11"]="11",["\x12"]="12",["\x13"]="13",["\x14"]="14",["\x15"]="15",["\x16"]="16",["\x17"]="17",["\x18"]="18",["\x19"]="19",["\x1A"]="0.",["\x1B"]="0E",["\x1C"]="0E-",["\x1D"]="0",["\x1E"]="0-",["\x1F"]="0",
- ["\x20"]="20",["\x21"]="21",["\x22"]="22",["\x23"]="23",["\x24"]="24",["\x25"]="25",["\x26"]="26",["\x27"]="27",["\x28"]="28",["\x29"]="29",["\x2A"]="0.",["\x2B"]="0E",["\x2C"]="0E-",["\x2D"]="0",["\x2E"]="0-",["\x2F"]="0",
- ["\x30"]="30",["\x31"]="31",["\x32"]="32",["\x33"]="33",["\x34"]="34",["\x35"]="35",["\x36"]="36",["\x37"]="37",["\x38"]="38",["\x39"]="39",["\x3A"]="0.",["\x3B"]="0E",["\x3C"]="0E-",["\x3D"]="0",["\x3E"]="0-",["\x3F"]="0",
- ["\x40"]="40",["\x41"]="41",["\x42"]="42",["\x43"]="43",["\x44"]="44",["\x45"]="45",["\x46"]="46",["\x47"]="47",["\x48"]="48",["\x49"]="49",["\x4A"]="0.",["\x4B"]="0E",["\x4C"]="0E-",["\x4D"]="0",["\x4E"]="0-",["\x4F"]="0",
- ["\x50"]="50",["\x51"]="51",["\x52"]="52",["\x53"]="53",["\x54"]="54",["\x55"]="55",["\x56"]="56",["\x57"]="57",["\x58"]="58",["\x59"]="59",["\x5A"]="0.",["\x5B"]="0E",["\x5C"]="0E-",["\x5D"]="0",["\x5E"]="0-",["\x5F"]="0",
- ["\x60"]="60",["\x61"]="61",["\x62"]="62",["\x63"]="63",["\x64"]="64",["\x65"]="65",["\x66"]="66",["\x67"]="67",["\x68"]="68",["\x69"]="69",["\x6A"]="0.",["\x6B"]="0E",["\x6C"]="0E-",["\x6D"]="0",["\x6E"]="0-",["\x6F"]="0",
- ["\x70"]="70",["\x71"]="71",["\x72"]="72",["\x73"]="73",["\x74"]="74",["\x75"]="75",["\x76"]="76",["\x77"]="77",["\x78"]="78",["\x79"]="79",["\x7A"]="0.",["\x7B"]="0E",["\x7C"]="0E-",["\x7D"]="0",["\x7E"]="0-",["\x7F"]="0",
- ["\x80"]="80",["\x81"]="81",["\x82"]="82",["\x83"]="83",["\x84"]="84",["\x85"]="85",["\x86"]="86",["\x87"]="87",["\x88"]="88",["\x89"]="89",["\x8A"]="0.",["\x8B"]="0E",["\x8C"]="0E-",["\x8D"]="0",["\x8E"]="0-",["\x8F"]="0",
- ["\x90"]="90",["\x91"]="91",["\x92"]="92",["\x93"]="93",["\x94"]="94",["\x95"]="95",["\x96"]="96",["\x97"]="97",["\x98"]="98",["\x99"]="99",["\x9A"]="0.",["\x9B"]="0E",["\x9C"]="0E-",["\x9D"]="0",["\x9E"]="0-",["\x9F"]="0",
+ ["\x10"]="10",["\x11"]="11",["\x12"]="12",["\x13"]="13",["\x14"]="14",["\x15"]="15",["\x16"]="16",["\x17"]="17",["\x18"]="18",["\x19"]="19",["\x1A"]="1.",["\x1B"]="1E",["\x1C"]="1E-",["\x1D"]="1",["\x1E"]="1-",["\x1F"]="1",
+ ["\x20"]="20",["\x21"]="21",["\x22"]="22",["\x23"]="23",["\x24"]="24",["\x25"]="25",["\x26"]="26",["\x27"]="27",["\x28"]="28",["\x29"]="29",["\x2A"]="2.",["\x2B"]="2E",["\x2C"]="2E-",["\x2D"]="2",["\x2E"]="2-",["\x2F"]="2",
+ ["\x30"]="30",["\x31"]="31",["\x32"]="32",["\x33"]="33",["\x34"]="34",["\x35"]="35",["\x36"]="36",["\x37"]="37",["\x38"]="38",["\x39"]="39",["\x3A"]="3.",["\x3B"]="3E",["\x3C"]="3E-",["\x3D"]="3",["\x3E"]="3-",["\x3F"]="3",
+ ["\x40"]="40",["\x41"]="41",["\x42"]="42",["\x43"]="43",["\x44"]="44",["\x45"]="45",["\x46"]="46",["\x47"]="47",["\x48"]="48",["\x49"]="49",["\x4A"]="4.",["\x4B"]="4E",["\x4C"]="4E-",["\x4D"]="4",["\x4E"]="4-",["\x4F"]="4",
+ ["\x50"]="50",["\x51"]="51",["\x52"]="52",["\x53"]="53",["\x54"]="54",["\x55"]="55",["\x56"]="56",["\x57"]="57",["\x58"]="58",["\x59"]="59",["\x5A"]="5.",["\x5B"]="5E",["\x5C"]="5E-",["\x5D"]="5",["\x5E"]="5-",["\x5F"]="5",
+ ["\x60"]="60",["\x61"]="61",["\x62"]="62",["\x63"]="63",["\x64"]="64",["\x65"]="65",["\x66"]="66",["\x67"]="67",["\x68"]="68",["\x69"]="69",["\x6A"]="6.",["\x6B"]="6E",["\x6C"]="6E-",["\x6D"]="6",["\x6E"]="6-",["\x6F"]="6",
+ ["\x70"]="70",["\x71"]="71",["\x72"]="72",["\x73"]="73",["\x74"]="74",["\x75"]="75",["\x76"]="76",["\x77"]="77",["\x78"]="78",["\x79"]="79",["\x7A"]="7.",["\x7B"]="7E",["\x7C"]="7E-",["\x7D"]="7",["\x7E"]="7-",["\x7F"]="7",
+ ["\x80"]="80",["\x81"]="81",["\x82"]="82",["\x83"]="83",["\x84"]="84",["\x85"]="85",["\x86"]="86",["\x87"]="87",["\x88"]="88",["\x89"]="89",["\x8A"]="8.",["\x8B"]="8E",["\x8C"]="8E-",["\x8D"]="8",["\x8E"]="8-",["\x8F"]="8",
+ ["\x90"]="90",["\x91"]="91",["\x92"]="92",["\x93"]="93",["\x94"]="94",["\x95"]="95",["\x96"]="96",["\x97"]="97",["\x98"]="98",["\x99"]="99",["\x9A"]="9.",["\x9B"]="9E",["\x9C"]="9E-",["\x9D"]="9",["\x9E"]="9-",["\x9F"]="9",
["\xA0"]=".0",["\xA1"]=".1",["\xA2"]=".2",["\xA3"]=".3",["\xA4"]=".4",["\xA5"]=".5",["\xA6"]=".6",["\xA7"]=".7",["\xA8"]=".8",["\xA9"]=".9",["\xAA"]="..",["\xAB"]=".E",["\xAC"]=".E-",["\xAD"]=".",["\xAE"]=".-",["\xAF"]=".",
["\xB0"]="E0",["\xB1"]="E1",["\xB2"]="E2",["\xB3"]="E3",["\xB4"]="E4",["\xB5"]="E5",["\xB6"]="E6",["\xB7"]="E7",["\xB8"]="E8",["\xB9"]="E9",["\xBA"]="E.",["\xBB"]="EE",["\xBC"]="EE-",["\xBD"]="E",["\xBE"]="E-",["\xBF"]="E",
["\xC0"]="E-0",["\xC1"]="E-1",["\xC2"]="E-2",["\xC3"]="E-3",["\xC4"]="E-4",["\xC5"]="E-5",["\xC6"]="E-6",["\xC7"]="E-7",["\xC8"]="E-8",["\xC9"]="E-9",["\xCA"]="E-.",["\xCB"]="E-E",["\xCC"]="E-E-",["\xCD"]="E-",["\xCE"]="E--",["\xCF"]="E-",
["\xD0"]="-0",["\xD1"]="-1",["\xD2"]="-2",["\xD3"]="-3",["\xD4"]="-4",["\xD5"]="-5",["\xD6"]="-6",["\xD7"]="-7",["\xD8"]="-8",["\xD9"]="-9",["\xDA"]="-.",["\xDB"]="-E",["\xDC"]="-E-",["\xDD"]="-",["\xDE"]="--",["\xDF"]="-",
}
- local p_nibbles=P("\30")*Cs(((1-p_last)/remap)^0+p_last)/function(n)
+ local p_last=S("\x0F\x1F\x2F\x3F\x4F\x5F\x6F\x7F\x8F\x9F\xAF\xBF")+R("\xF0\xFF")
+ local p_nibbles=P("\30")*Cs(((1-p_last)/remap)^0*(P(1)/remap))/function(n)
top=top+1
stack[top]=tonumber(n) or 0
end
@@ -15169,7 +15258,7 @@ do
if trace_charstrings then
showstate("stem")
end
- stems=stems+top/2
+ stems=stems+idiv(top,2)
top=0
end
local function getmask()
@@ -15188,13 +15277,13 @@ do
if trace_charstrings then
showstate(operator==19 and "hintmark" or "cntrmask")
end
- stems=stems+top/2
+ stems=stems+idiv(top,2)
top=0
if stems==0 then
elseif stems<=8 then
return 1
else
- return floor((stems+7)/8)
+ return idiv(stems+7,8)
end
end
local function unsupported(t)
@@ -15233,7 +15322,7 @@ do
local function hsbw()
if version==1 then
if trace_charstrings then
- showstate("dotsection")
+ showstate("hsbw")
end
width=stack[top]
end
@@ -15419,76 +15508,98 @@ do
[036]=hflex1,
[037]=flex1,
}
- local c_endchar=char(14)
- local passon do
- local rshift=bit32.rshift
- local band=bit32.band
- local round=math.round
- local encode=table.setmetatableindex(function(t,i)
- for i=-2048,-1130 do
- t[i]=char(28,band(rshift(i,8),0xFF),band(i,0xFF))
- end
- for i=-1131,-108 do
- local v=0xFB00-i-108
- t[i]=char(band(rshift(v,8),0xFF),band(v,0xFF))
- end
- for i=-107,107 do
- t[i]=char(i+139)
- end
- for i=108,1131 do
- local v=0xF700+i-108
- t[i]=char(band(rshift(v,8),0xFF),band(v,0xFF))
- end
- for i=1132,2048 do
- t[i]=char(28,band(rshift(i,8),0xFF),band(i,0xFF))
- end
- return t[i]
- end)
- local function setvsindex()
- local vsindex=stack[top]
- updateregions(vsindex)
- top=top-1
+ local chars=setmetatableindex(function (t,k)
+ local v=char(k)
+ t[k]=v
+ return v
+ end)
+ local c_endchar=chars[14]
+ local encode={}
+ setmetatableindex(encode,function(t,i)
+ for i=-2048,-1130 do
+ t[i]=char(28,band(rshift(i,8),0xFF),band(i,0xFF))
end
- local function blend()
- local n=stack[top]
- top=top-1
- if not axis then
- elseif n==1 then
- top=top-nofregions
- local v=stack[top]
+ for i=-1131,-108 do
+ local v=0xFB00-i-108
+ t[i]=char(band(rshift(v,8),0xFF),band(v,0xFF))
+ end
+ for i=-107,107 do
+ t[i]=chars[i+139]
+ end
+ for i=108,1131 do
+ local v=0xF700+i-108
+ t[i]=char(extract(v,8,8),extract(v,0,8))
+ end
+ for i=1132,2048 do
+ t[i]=char(28,band(rshift(i,8),0xFF),band(i,0xFF))
+ end
+ setmetatableindex(encode,function(t,k)
+ local r=round(k)
+ local v=rawget(t,r)
+ if v then
+ return v
+ end
+ local v1=floor(k)
+ local v2=floor((k-v1)*0x10000)
+ return char(255,extract(v1,8,8),extract(v1,0,8),extract(v2,8,8),extract(v2,0,8))
+ end)
+ return t[i]
+ end)
+ readers.cffencoder=encode
+ local function p_setvsindex()
+ local vsindex=stack[top]
+ updateregions(vsindex)
+ top=top-1
+ end
+ local function p_blend()
+ local n=stack[top]
+ top=top-1
+ if not axis then
+ elseif n==1 then
+ top=top-nofregions
+ local v=stack[top]
+ for r=1,nofregions do
+ v=v+stack[top+r]*factors[r]
+ end
+ stack[top]=round(v)
+ else
+ top=top-nofregions*n
+ local d=top
+ local k=top-n
+ for i=1,n do
+ k=k+1
+ local v=stack[k]
for r=1,nofregions do
- v=v+stack[top+r]*factors[r]
- end
- stack[top]=round(v)
- else
- top=top-nofregions*n
- local d=top
- local k=top-n
- for i=1,n do
- k=k+1
- local v=stack[k]
- for r=1,nofregions do
- v=v+stack[d+r]*factors[r]
- end
- stack[k]=round(v)
- d=d+nofregions
+ v=v+stack[d+r]*factors[r]
end
+ stack[k]=round(v)
+ d=d+nofregions
end
end
- passon=function(operation)
- if operation==15 then
- setvsindex()
- elseif operation==16 then
- blend()
- else
- for i=1,top do
- r=r+1
- result[r]=encode[stack[i]]
- end
- r=r+1
- result[r]=char(operation)
- top=0
- end
+ end
+ local function p_getstem()
+ local n=0
+ if top%2~=0 then
+ n=1
+ end
+ if top>n then
+ stems=stems+idiv(top-n,2)
+ end
+ end
+ local function p_getmask()
+ local n=0
+ if top%2~=0 then
+ n=1
+ end
+ if top>n then
+ stems=stems+idiv(top-n,2)
+ end
+ if stems==0 then
+ return 0
+ elseif stems<=8 then
+ return 1
+ else
+ return idiv(stems+7,8)
end
end
local process
@@ -15576,19 +15687,90 @@ do
elseif t==12 then
i=i+1
local t=tab[i]
- local a=subactions[t]
- if a then
- a(t)
+ if justpass then
+ if t>=34 or t<=37 then
+ for i=1,top do
+ r=r+1;result[r]=encode[stack[i]]
+ end
+ r=r+1;result[r]=chars[12]
+ r=r+1;result[r]=chars[t]
+ top=0
+ else
+ local a=subactions[t]
+ if a then
+ a(t)
+ else
+ top=0
+ end
+ end
else
- if trace_charstrings then
- showvalue("<subaction>",t)
+ local a=subactions[t]
+ if a then
+ a(t)
+ else
+ if trace_charstrings then
+ showvalue("<subaction>",t)
+ end
+ top=0
end
- top=0
end
i=i+1
elseif justpass then
- passon(t)
- i=i+1
+ if t==15 then
+ p_setvsindex()
+ i=i+1
+ elseif t==16 then
+ local s=p_blend() or 0
+ i=i+s+1
+ elseif t==1 or t==3 or t==18 or operation==23 then
+ p_getstem()
+if true then
+ if top>0 then
+ for i=1,top do
+ r=r+1;result[r]=encode[stack[i]]
+ end
+ top=0
+ end
+ r=r+1;result[r]=chars[t]
+else
+ top=0
+end
+ i=i+1
+ elseif t==19 or t==20 then
+ local s=p_getmask() or 0
+if true then
+ if top>0 then
+ for i=1,top do
+ r=r+1;result[r]=encode[stack[i]]
+ end
+ top=0
+ end
+ r=r+1;result[r]=chars[t]
+ for j=1,s do
+ i=i+1
+ r=r+1;result[r]=chars[tab[i]]
+ end
+else
+ i=i+s
+ top=0
+end
+ i=i+1
+ elseif t==9 then
+ top=0
+ i=i+1
+ elseif t==13 then
+ local s=hsbw() or 0
+ i=i+s+1
+ else
+ if top>0 then
+ for i=1,top do
+ r=r+1;result[r]=encode[stack[i]]
+ end
+ top=0
+ end
+ r=r+1;result[r]=chars[t]
+ i=i+1
+ end
else
local a=actions[t]
if a then
@@ -15609,18 +15791,20 @@ do
end
end
local function setbias(globals,locals)
- if version==1 then
- return
- false,
- false
- else
local g,l=#globals,#locals
return
((g<1240 and 107) or (g<33900 and 1131) or 32768)+1,
((l<1240 and 107) or (l<33900 and 1131) or 32768)+1
- end
end
local function processshape(tab,index)
+ if not tab then
+ glyphs[index]={
+ boundingbox={ 0,0,0,0 },
+ width=0,
+ name=charset and charset[index] or nil,
+ }
+ return
+ end
tab=bytetable(tab)
x=0
y=0
@@ -15733,15 +15917,18 @@ do
glyphs=glphs or {}
globalbias,localbias=setbias(globals,locals)
nominalwidth,defaultwidth=setwidths(dictionary.private)
- startparsing(fontdata,data,streams)
- for index=1,#charstrings do
- processshape(charstrings[index],index-1)
- charstrings[index]=nil
+ if charstrings then
+ startparsing(fontdata,data,streams)
+ for index=1,#charstrings do
+ processshape(charstrings[index],index-1)
+ end
+ stopparsing(fontdata,data)
+ else
+ report("no charstrings")
end
- stopparsing(fontdata,data)
return glyphs
end
- parsecharstring=function(fontdata,data,dictionary,tab,glphs,index,doshapes,tversion)
+ parsecharstring=function(fontdata,data,dictionary,tab,glphs,index,doshapes,tversion,streams)
keepcurve=doshapes
version=tversion
strings=data.strings
@@ -15750,6 +15937,7 @@ do
charset=false
vsindex=dictionary.vsindex or 0
glyphs=glphs or {}
+ justpass=streams==true
globalbias,localbias=setbias(globals,locals)
nominalwidth,defaultwidth=setwidths(dictionary.private)
processshape(tab,index-1)
@@ -15903,7 +16091,7 @@ local function readfdselect(f,fontdata,data,glyphs,doshapes,version,streams)
local format=readbyte(f)
if format==1 then
for i=0,nofglyphs do
- local index=readbyte(i)
+ local index=readbyte(f)
fdindex[i]=index
if index>maxindex then
maxindex=index
@@ -15932,30 +16120,33 @@ local function readfdselect(f,fontdata,data,glyphs,doshapes,version,streams)
end
if maxindex>=0 then
local cidarray=cid.fdarray
- setposition(f,header.offset+cidarray)
- local dictionaries=readlengths(f)
- for i=1,#dictionaries do
- dictionaries[i]=readstring(f,dictionaries[i])
- end
- parsedictionaries(data,dictionaries)
- cid.dictionaries=dictionaries
- readcidprivates(f,data)
- for i=1,#dictionaries do
- readlocals(f,data,dictionaries[i])
- end
- startparsing(fontdata,data,streams)
- for i=1,#charstrings do
- parsecharstring(fontdata,data,dictionaries[fdindex[i]+1],charstrings[i],glyphs,i,doshapes,version)
- charstrings[i]=nil
+ if cidarray then
+ setposition(f,header.offset+cidarray)
+ local dictionaries=readlengths(f)
+ for i=1,#dictionaries do
+ dictionaries[i]=readstring(f,dictionaries[i])
+ end
+ parsedictionaries(data,dictionaries)
+ cid.dictionaries=dictionaries
+ readcidprivates(f,data)
+ for i=1,#dictionaries do
+ readlocals(f,data,dictionaries[i])
+ end
+ startparsing(fontdata,data,streams)
+ for i=1,#charstrings do
+ parsecharstring(fontdata,data,dictionaries[fdindex[i]+1],charstrings[i],glyphs,i,doshapes,version,streams)
+ end
+ stopparsing(fontdata,data)
+ else
+ report("no cid array")
end
- stopparsing(fontdata,data)
end
end
local gotodatatable=readers.helpers.gotodatatable
local function cleanup(data,dictionaries)
end
function readers.cff(f,fontdata,specification)
- local tableoffset=gotodatatable(f,fontdata,"cff",specification.details)
+ local tableoffset=gotodatatable(f,fontdata,"cff",specification.details or specification.glyphs)
if tableoffset then
local header=readheader(f)
if header.major~=1 then
@@ -15976,14 +16167,16 @@ function readers.cff(f,fontdata,specification)
parsedictionaries(data,dictionaries,"cff")
local dic=dictionaries[1]
local cid=dic.cid
- fontdata.cffinfo={
- familynamename=dic.familyname,
+ local cffinfo={
+ familyname=dic.familyname,
fullname=dic.fullname,
boundingbox=dic.boundingbox,
weight=dic.weight,
italicangle=dic.italicangle,
underlineposition=dic.underlineposition,
underlinethickness=dic.underlinethickness,
+ defaultwidth=dic.defaultwidthx,
+ nominalwidth=dic.nominalwidthx,
monospaced=dic.monospaced,
}
fontdata.cidinfo=cid and {
@@ -15991,12 +16184,30 @@ function readers.cff(f,fontdata,specification)
ordering=cid.ordering,
supplement=cid.supplement,
}
- if specification.glyphs then
- local all=specification.shapes or false
+ fontdata.cffinfo=cffinfo
+ local all=specification.shapes or specification.streams or false
+ if specification.glyphs or all then
if cid and cid.fdselect then
- readfdselect(f,fontdata,data,glyphs,all,"cff")
+ readfdselect(f,fontdata,data,glyphs,all,"cff",specification.streams)
else
- readnoselect(f,fontdata,data,glyphs,all,"cff")
+ readnoselect(f,fontdata,data,glyphs,all,"cff",specification.streams)
+ end
+ end
+ local private=dic.private
+ if private then
+ local data=private.data
+ if type(data)=="table" then
+ cffinfo.defaultwidth=data.defaultwidth or cffinfo.defaultwidth
+ cffinfo.nominalwidth=data.nominalwidth or cffinfo.nominalwidth
+ cffinfo.bluevalues=data.bluevalues
+ cffinfo.otherblues=data.otherblues
+ cffinfo.familyblues=data.familyblues
+ cffinfo.familyotherblues=data.familyotherblues
+ cffinfo.bluescale=data.bluescale
+ cffinfo.blueshift=data.blueshift
+ cffinfo.bluefuzz=data.bluefuzz
+ cffinfo.stdhw=data.stdhw
+ cffinfo.stdvw=data.stdvw
end
end
cleanup(data,dictionaries)
@@ -16030,7 +16241,7 @@ function readers.cff2(f,fontdata,specification)
end
data.factors=specification.factors
local cid=data.dictionaries[1].cid
- local all=specification.shapes or false
+ local all=specification.shapes or specification.streams or false
if cid and cid.fdselect then
readfdselect(f,fontdata,data,glyphs,all,"cff2",specification.streams)
else
@@ -16060,7 +16271,7 @@ function readers.cffcheck(filename)
dictionaries=dictionaries,
strings=strings,
glyphs=glyphs,
- nofglyphs=4,
+ nofglyphs=0,
}
parsedictionaries(data,dictionaries,"cff")
local cid=data.dictionaries[1].cid
@@ -16087,8 +16298,10 @@ if not modules then modules={} end modules ['font-ttf']={
local next,type,unpack=next,type,unpack
local band,rshift=bit32.band,bit32.rshift
local sqrt,round=math.sqrt,math.round
-local char=string.char
+local char,rep=string.char,string.rep
local concat=table.concat
+local idiv=number.idiv
+local setmetatableindex=table.setmetatableindex
local report=logs.reporter("otf reader","ttf")
local trace_deltas=false
local readers=fonts.handlers.otf.readers
@@ -16153,22 +16366,41 @@ local function mergecomposites(glyphs,shapes)
local yscale=matrix[4]
local xoffset=matrix[5]
local yoffset=matrix[6]
- for i=1,#subpoints do
- local p=subpoints[i]
- local x=p[1]
- local y=p[2]
- nofpoints=nofpoints+1
- points[nofpoints]={
- xscale*x+xrotate*y+xoffset,
- yscale*y+yrotate*x+yoffset,
- p[3]
- }
+ local count=#subpoints
+ if xscale==1 and yscale==1 and xrotate==0 and yrotate==0 then
+ for i=1,count do
+ local p=subpoints[i]
+ nofpoints=nofpoints+1
+ points[nofpoints]={
+ p[1]+xoffset,
+ p[2]+yoffset,
+ p[3]
+ }
+ end
+ else
+ for i=1,count do
+ local p=subpoints[i]
+ local x=p[1]
+ local y=p[2]
+ nofpoints=nofpoints+1
+ points[nofpoints]={
+ xscale*x+xrotate*y+xoffset,
+ yscale*y+yrotate*x+yoffset,
+ p[3]
+ }
+ end
end
- for i=1,#subcontours do
+ local subcount=#subcontours
+ if subcount==1 then
nofcontours=nofcontours+1
- contours[nofcontours]=offset+subcontours[i]
+ contours[nofcontours]=offset+subcontours[1]
+ else
+ for i=1,#subcontours do
+ nofcontours=nofcontours+1
+ contours[nofcontours]=offset+subcontours[i]
+ end
end
- offset=offset+#subpoints
+ offset=offset+count
else
report("missing contours composite %s, component %s of %s, glyph %s",index,i,#components,subindex)
end
@@ -16178,7 +16410,7 @@ local function mergecomposites(glyphs,shapes)
shape.components=nil
return contours,points
end
- for index=1,#glyphs do
+ for index=0,#glyphs-1 do
local shape=shapes[index]
if shape then
local components=shape.components
@@ -16188,7 +16420,7 @@ local function mergecomposites(glyphs,shapes)
end
end
end
-local function readnothing(f,nofcontours)
+local function readnothing(f)
return {
type="nothing",
}
@@ -16282,8 +16514,8 @@ local function applyaxis(glyph,shape,deltas,dowidth)
end
end
local quadratic=false
-local function contours2outlines_normal(glyphs,shapes)
- for index=1,#glyphs do
+local function contours2outlines_normal(glyphs,shapes)
+ for index=0,#glyphs-1 do
local shape=shapes[index]
if shape then
local glyph=glyphs[index]
@@ -16398,7 +16630,7 @@ local function contours2outlines_normal(glyphs,shapes)
end
end
local function contours2outlines_shaped(glyphs,shapes,keepcurve)
- for index=1,#glyphs do
+ for index=0,#glyphs-1 do
local shape=shapes[index]
if shape then
local glyph=glyphs[index]
@@ -16577,115 +16809,128 @@ local function toshort(n)
end
return char(band(rshift(n,8),0xFF),band(n,0xFF))
end
+local chars=setmetatableindex(function(t,k)
+ for i=0,255 do local v=char(i) t[i]=v end return t[k]
+end)
local function repackpoints(glyphs,shapes)
local noboundingbox={ 0,0,0,0 }
local result={}
- for index=1,#glyphs do
+ local xpoints={}
+ local ypoints={}
+ for index=0,#glyphs-1 do
local shape=shapes[index]
if shape then
local r=0
local glyph=glyphs[index]
- if false then
- else
- local contours=shape.contours
- local nofcontours=contours and #contours or 0
- local boundingbox=glyph.boundingbox or noboundingbox
- r=r+1 result[r]=toshort(nofcontours)
- r=r+1 result[r]=toshort(boundingbox[1])
- r=r+1 result[r]=toshort(boundingbox[2])
- r=r+1 result[r]=toshort(boundingbox[3])
- r=r+1 result[r]=toshort(boundingbox[4])
- if nofcontours>0 then
- for i=1,nofcontours do
- r=r+1 result[r]=toshort(contours[i]-1)
- end
- r=r+1 result[r]=s_zero
- local points=shape.points
- local currentx=0
- local currenty=0
- local xpoints={}
- local ypoints={}
- local x=0
- local y=0
- local lastflag=nil
- local nofflags=0
- for i=1,#points do
- local pt=points[i]
- local px=pt[1]
- local py=pt[2]
- local fl=pt[3] and 0x01 or 0x00
- if px==currentx then
- fl=fl+0x10
+ local contours=shape.contours
+ local nofcontours=contours and #contours or 0
+ local boundingbox=glyph.boundingbox or noboundingbox
+ r=r+1 result[r]=toshort(nofcontours)
+ r=r+1 result[r]=toshort(boundingbox[1])
+ r=r+1 result[r]=toshort(boundingbox[2])
+ r=r+1 result[r]=toshort(boundingbox[3])
+ r=r+1 result[r]=toshort(boundingbox[4])
+ if nofcontours>0 then
+ for i=1,nofcontours do
+ r=r+1 result[r]=toshort(contours[i]-1)
+ end
+ r=r+1 result[r]=s_zero
+ local points=shape.points
+ local currentx=0
+ local currenty=0
+ local x=0
+ local y=0
+ local lastflag=nil
+ local nofflags=0
+ for i=1,#points do
+ local pt=points[i]
+ local px=pt[1]
+ local py=pt[2]
+ local fl=pt[3] and 0x01 or 0x00
+ if px==currentx then
+ fl=fl+0x10
+ else
+ local dx=round(px-currentx)
+ x=x+1
+ if dx<-255 or dx>255 then
+ xpoints[x]=toshort(dx)
+ elseif dx<0 then
+ fl=fl+0x02
+ xpoints[x]=chars[-dx]
+ elseif dx>0 then
+ fl=fl+0x12
+ xpoints[x]=chars[dx]
else
- local dx=round(px-currentx)
- if dx<-255 or dx>255 then
- x=x+1 xpoints[x]=toshort(dx)
- elseif dx<0 then
- fl=fl+0x02
- x=x+1 xpoints[x]=char(-dx)
- elseif dx>0 then
- fl=fl+0x12
- x=x+1 xpoints[x]=char(dx)
- else
- fl=fl+0x02
- x=x+1 xpoints[x]=c_zero
- end
+ fl=fl+0x02
+ xpoints[x]=c_zero
end
- if py==currenty then
- fl=fl+0x20
+ end
+ if py==currenty then
+ fl=fl+0x20
+ else
+ local dy=round(py-currenty)
+ y=y+1
+ if dy<-255 or dy>255 then
+ ypoints[y]=toshort(dy)
+ elseif dy<0 then
+ fl=fl+0x04
+ ypoints[y]=chars[-dy]
+ elseif dy>0 then
+ fl=fl+0x24
+ ypoints[y]=chars[dy]
else
- local dy=round(py-currenty)
- if dy<-255 or dy>255 then
- y=y+1 ypoints[y]=toshort(dy)
- elseif dy<0 then
- fl=fl+0x04
- y=y+1 ypoints[y]=char(-dy)
- elseif dy>0 then
- fl=fl+0x24
- y=y+1 ypoints[y]=char(dy)
- else
- fl=fl+0x04
- y=y+1 ypoints[y]=c_zero
- end
- end
- currentx=px
- currenty=py
- if lastflag==fl then
- nofflags=nofflags+1
- else
- if nofflags==1 then
- r=r+1 result[r]=char(lastflag)
- elseif nofflags==2 then
- r=r+1 result[r]=char(lastflag,lastflag)
- elseif nofflags>2 then
- lastflag=lastflag+0x08
- r=r+1 result[r]=char(lastflag,nofflags-1)
- end
- nofflags=1
- lastflag=fl
+ fl=fl+0x04
+ ypoints[y]=c_zero
end
end
- if nofflags==1 then
- r=r+1 result[r]=char(lastflag)
- elseif nofflags==2 then
- r=r+1 result[r]=char(lastflag,lastflag)
- elseif nofflags>2 then
- lastflag=lastflag+0x08
- r=r+1 result[r]=char(lastflag,nofflags-1)
- end
- r=r+1 result[r]=concat(xpoints)
- r=r+1 result[r]=concat(ypoints)
+ currentx=px
+ currenty=py
+ if lastflag==fl then
+ nofflags=nofflags+1
+ else
+ if nofflags==1 then
+ r=r+1 result[r]=chars[lastflag]
+ elseif nofflags==2 then
+ r=r+1 result[r]=char(lastflag,lastflag)
+ elseif nofflags>2 then
+ lastflag=lastflag+0x08
+ r=r+1 result[r]=char(lastflag,nofflags-1)
+ end
+ nofflags=1
+ lastflag=fl
+ end
+ end
+ if nofflags==1 then
+ r=r+1 result[r]=chars[lastflag]
+ elseif nofflags==2 then
+ r=r+1 result[r]=char(lastflag,lastflag)
+ elseif nofflags>2 then
+ lastflag=lastflag+0x08
+ r=r+1 result[r]=char(lastflag,nofflags-1)
+ end
+ r=r+1 result[r]=concat(xpoints,"",1,x)
+ r=r+1 result[r]=concat(ypoints,"",1,y)
+ end
+ local stream=concat(result,"",1,r)
+ local length=#stream
+ local padding=idiv(length+3,4)*4-length
+ if padding>0 then
+ if padding==1 then
+ padding="\0"
+ elseif padding==2 then
+ padding="\0\0"
+ else
+ padding="\0\0\0"
end
+ padding=stream..padding
end
- glyph.stream=concat(result,"",1,r)
- else
+ glyph.stream=stream
end
end
end
+local flags={}
local function readglyph(f,nofcontours)
local points={}
- local instructions={}
- local flags={}
local contours={}
for i=1,nofcontours do
contours[i]=readshort(f)+1
@@ -16698,9 +16943,15 @@ local function readglyph(f,nofcontours)
local flag=readbyte(f)
flags[i]=flag
if band(flag,0x08)~=0 then
- for j=1,readbyte(f) do
+ local n=readbyte(f)
+ if n==1 then
i=i+1
flags[i]=flag
+ else
+ for j=1,n do
+ i=i+1
+ flags[i]=flag
+ end
end
end
i=i+1
@@ -16708,15 +16959,13 @@ local function readglyph(f,nofcontours)
local x=0
for i=1,nofpoints do
local flag=flags[i]
- local short=band(flag,0x02)~=0
- local same=band(flag,0x10)~=0
- if short then
- if same then
+ if band(flag,0x02)~=0 then
+ if band(flag,0x10)~=0 then
x=x+readbyte(f)
else
x=x-readbyte(f)
end
- elseif same then
+ elseif band(flag,0x10)~=0 then
else
x=x+readshort(f)
end
@@ -16725,15 +16974,13 @@ local function readglyph(f,nofcontours)
local y=0
for i=1,nofpoints do
local flag=flags[i]
- local short=band(flag,0x04)~=0
- local same=band(flag,0x20)~=0
- if short then
- if same then
+ if band(flag,0x04)~=0 then
+ if band(flag,0x20)~=0 then
y=y+readbyte(f)
else
y=y-readbyte(f)
end
- elseif same then
+ elseif band(flag,0x20)~=0 then
else
y=y+readshort(f)
end
@@ -16816,7 +17063,7 @@ local function readcomposite(f)
if band(flags,0x0100)~=0 then
instructions=true
end
- if not band(flags,0x0020)~=0 then
+ if band(flags,0x0020)==0 then
break
end
end
@@ -16831,21 +17078,27 @@ function readers.loca(f,fontdata,specification)
if datatable then
local offset=fontdata.tables.glyf.offset
local format=fontdata.fontheader.indextolocformat
+ local profile=fontdata.maximumprofile
+ local nofglyphs=profile and profile.nofglyphs
local locations={}
setposition(f,datatable.offset)
if format==1 then
- local nofglyphs=datatable.length/4-2
+ if not nofglyphs then
+ nofglyphs=idiv(datatable.length,4)-1
+ end
for i=0,nofglyphs do
locations[i]=offset+readulong(f)
end
fontdata.nofglyphs=nofglyphs
else
- local nofglyphs=datatable.length/2-2
+ if not nofglyphs then
+ nofglyphs=idiv(datatable.length,2)-1
+ end
for i=0,nofglyphs do
locations[i]=offset+readushort(f)*2
end
- fontdata.nofglyphs=nofglyphs
end
+ fontdata.nofglyphs=nofglyphs
fontdata.locations=locations
end
end
@@ -16860,15 +17113,16 @@ function readers.glyf(f,fontdata,specification)
local filesize=fontdata.filesize
local nothing={ 0,0,0,0 }
local shapes={}
- local loadshapes=specification.shapes or specification.instance
- for index=0,nofglyphs do
+ local loadshapes=specification.shapes or specification.instance or specification.streams
+ for index=0,nofglyphs-1 do
local location=locations[index]
+ local length=locations[index+1]-location
if location>=filesize then
report("discarding %s glyphs due to glyph location bug",nofglyphs-index+1)
fontdata.nofglyphs=index-1
fontdata.badfont=true
break
- elseif location>0 then
+ elseif length>0 then
setposition(f,location)
local nofcontours=readshort(f)
glyphs[index].boundingbox={
@@ -16879,7 +17133,7 @@ function readers.glyf(f,fontdata,specification)
}
if not loadshapes then
elseif nofcontours==0 then
- shapes[index]=readnothing(f,nofcontours)
+ shapes[index]=readnothing(f)
elseif nofcontours>0 then
shapes[index]=readglyph(f,nofcontours)
else
@@ -16887,7 +17141,7 @@ function readers.glyf(f,fontdata,specification)
end
else
if loadshapes then
- shapes[index]={}
+ shapes[index]=readnothing(f)
end
glyphs[index].boundingbox=nothing
end
@@ -16904,7 +17158,13 @@ function readers.glyf(f,fontdata,specification)
contours2outlines_shaped(glyphs,shapes,specification.shapes)
end
elseif specification.shapes then
- contours2outlines_normal(glyphs,shapes)
+ if specification.streams then
+ repackpoints(glyphs,shapes)
+ else
+ contours2outlines_normal(glyphs,shapes)
+ end
+ elseif specification.streams then
+ repackpoints(glyphs,shapes)
end
end
end
@@ -19117,7 +19377,7 @@ do
end
local function loadvariations(f,fontdata,variationsoffset,lookuptypes,featurehash,featureorder)
setposition(f,variationsoffset)
- local version=readulong(f)
+ local version=readulong(f)
local nofrecords=readulong(f)
local records={}
for i=1,nofrecords do
@@ -19986,8 +20246,7 @@ function readers.avar(f,fontdata,specification)
end
return false
end
- local majorversion=readushort(f)
- local minorversion=readushort(f)
+ local version=readulong(f)
local reserved=readushort(f)
local nofaxis=readushort(f)
local segments={}
@@ -26345,22 +26604,17 @@ function handlers.gsub_ligature(head,start,dataset,sequence,ligature,rlmode,skip
else
end
end
- else
+ else
local discfound=false
- local lastdisc=nil
local hasmarks=marks[startchar]
while current do
local char,id=ischar(current,currentfont)
if char then
if skiphash and skiphash[char] then
current=getnext(current)
- else
- local lg=ligature[char]
+ else
+ local lg=ligature[char]
if lg then
- if not discfound and lastdisc then
- discfound=lastdisc
- lastdisc=nil
- end
if marks[char] then
hasmarks=true
end
@@ -26374,42 +26628,82 @@ function handlers.gsub_ligature(head,start,dataset,sequence,ligature,rlmode,skip
elseif char==false then
break
elseif id==disc_code then
- local replace=getfield(current,"replace")
- if replace then
- while replace do
- local char,id=ischar(replace,currentfont)
- if char then
- local lg=ligature[char]
- if lg then
- if marks[char] then
- hasmarks=true
- end
- ligature=lg
- replace=getnext(replace)
- else
- return head,start,false,false
- end
- else
- return head,start,false,false
- end
- end
- stop=current
- end
- lastdisc=current
- current=getnext(current)
+ discfound=current
+ break
else
break
end
end
+ if discfound then
+ local pre,post,replace=getdisc(discfound)
+ local match
+ if replace then
+ local char=ischar(replace,currentfont)
+ if char and ligature[char] then
+ match=true
+ end
+ end
+ if not match and pre then
+ local char=ischar(pre,currentfont)
+ if char and ligature[char] then
+ match=true
+ end
+ end
+ if not match and not pre or not replace then
+ local n=getnext(discfound)
+ local char=ischar(n,currentfont)
+ if char and ligature[char] then
+ match=true
+ end
+ end
+ if match then
+ local ishead=head==start
+ local prev=getprev(start)
+ if stop then
+ setnext(stop)
+ local tail=getprev(stop)
+ local copy=copy_node_list(start)
+ local liat=find_node_tail(copy)
+ if pre and replace then
+ setlink(liat,pre)
+ end
+ if replace then
+ setlink(tail,replace)
+ end
+ pre=copy
+ replace=start
+ else
+ setnext(start)
+ local copy=copy_node(start)
+ if pre then
+ setlink(copy,pre)
+ end
+ if replace then
+ setlink(start,replace)
+ end
+ pre=copy
+ replace=start
+ end
+ setdisc(discfound,pre,post,replace)
+ if prev then
+ setlink(prev,discfound)
+ else
+ setprev(discfound)
+ head=discfound
+ end
+ start=discfound
+ return head,start,true,true
+ end
+ end
local lig=ligature.ligature
if lig then
if stop then
if trace_ligatures then
local stopchar=getchar(stop)
- head,start=toligature(head,start,stop,lig,dataset,sequence,skiphash,discfound,hasmarks)
+ head,start=toligature(head,start,stop,lig,dataset,sequence,skiphash,false,hasmarks)
logprocess("%s: replacing %s upto %s by ligature %s case 2",pref(dataset,sequence),gref(startchar),gref(stopchar),gref(lig))
else
- head,start=toligature(head,start,stop,lig,dataset,sequence,skiphash,discfound,hasmarks)
+ head,start=toligature(head,start,stop,lig,dataset,sequence,skiphash,false,hasmarks)
end
else
resetinjection(start)
@@ -26418,11 +26712,11 @@ function handlers.gsub_ligature(head,start,dataset,sequence,ligature,rlmode,skip
logprocess("%s: replacing %s by (no real) ligature %s case 3",pref(dataset,sequence),gref(startchar),gref(lig))
end
end
- return head,start,true,discfound
+ return head,start,true,false
else
end
end
- return head,start,false,discfound
+ return head,start,false,false
end
function handlers.gpos_single(head,start,dataset,sequence,kerns,rlmode,skiphash,step,injection)
local startchar=getchar(start)
@@ -28901,9 +29195,10 @@ do
a=true
end
if a then
- local ok
- head,start,ok=handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step)
- if start then
+ local ok,df
+ head,start,ok,df=handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step)
+ if df then
+ elseif start then
start=getnext(start)
end
else
@@ -28957,21 +29252,24 @@ do
a=true
end
if a then
+ local ok,df
for i=m[1],m[2] do
local step=steps[i]
local lookupcache=step.coverage
local lookupmatch=lookupcache[char]
if lookupmatch then
- local ok
- head,start,ok=handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step)
- if ok then
+ head,start,ok,df=handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step)
+ if df then
+ break
+ elseif ok then
break
elseif not start then
break
end
end
end
- if start then
+ if df then
+ elseif start then
start=getnext(start)
end
else
@@ -31472,7 +31770,7 @@ do
done=f_used(n)
hashed[pdf]=done
end
- return nil,done,nil
+ return done
end
else
local openpdf=pdfe.new
@@ -31485,7 +31783,7 @@ do
done=f_used(n)
hashed[pdf]=done
end
- return nil,done,nil
+ return done
end
end
end
@@ -31506,6 +31804,10 @@ local function pdftovirtual(tfmdata,pdfshapes,kind)
local b,e=getactualtext(tounicode(0xFFFD))
local actualb={ "pdf","page",b }
local actuale={ "pdf","page",e }
+ local vfimage=lpdf and lpdf.vfimage or function(wd,ht,dp,data,name)
+ local name=storepdfdata(data)
+ return { "image",{ filename=name,width=wd,height=ht,depth=dp } }
+ end
for unicode,character in sortedhash(characters) do
local index=character.index
if index then
@@ -31524,21 +31826,18 @@ local function pdftovirtual(tfmdata,pdfshapes,kind)
dy=0
end
if data then
- local setcode,name,nilcode=storepdfdata(data)
- if name then
- local bt=unicode and getactualtext(unicode)
- local wd=character.width or 0
- local ht=character.height or 0
- local dp=character.depth or 0
- character.commands={
- not unicode and actualb or { "pdf","page",(getactualtext(unicode)) },
- downcommand[dp+dy*hfactor],
- rightcommand[dx*hfactor],
- { "image",{ filename=name,width=wd,height=ht,depth=dp } },
- actuale,
- }
- character[kind]=true
- end
+ local bt=unicode and getactualtext(unicode)
+ local wd=character.width or 0
+ local ht=character.height or 0
+ local dp=character.depth or 0
+ character.commands={
+ not unicode and actualb or { "pdf","page",(getactualtext(unicode)) },
+ downcommand[dp+dy*hfactor],
+ rightcommand[dx*hfactor],
+ vfimage(wd,ht,dp,data,name),
+ actuale,
+ }
+ character[kind]=true
end
end
end
@@ -32508,7 +32807,7 @@ local match,lower,gsub,strip,find=string.match,string.lower,string.gsub,string.s
local char,byte,sub=string.char,string.byte,string.sub
local abs=math.abs
local bxor,rshift=bit32.bxor,bit32.rshift
-local P,S,R,Cmt,C,Ct,Cs,Carg,Cf,Cg=lpeg.P,lpeg.S,lpeg.R,lpeg.Cmt,lpeg.C,lpeg.Ct,lpeg.Cs,lpeg.Carg,lpeg.Cf,lpeg.Cg
+local P,S,R,V,Cmt,C,Ct,Cs,Carg,Cf,Cg,Cc=lpeg.P,lpeg.S,lpeg.R,lpeg.V,lpeg.Cmt,lpeg.C,lpeg.Ct,lpeg.Cs,lpeg.Carg,lpeg.Cf,lpeg.Cg,lpeg.Cc
local lpegmatch,patterns=lpeg.match,lpeg.patterns
local trace_indexing=false trackers.register("afm.indexing",function(v) trace_indexing=v end)
local trace_loading=false trackers.register("afm.loading",function(v) trace_loading=v end)
@@ -32551,14 +32850,21 @@ do
local routines,vector,chars,n,m
local initialize=function(str,position,size)
n=0
- m=size
+ m=size
return position+1
end
local setroutine=function(str,position,index,size,filename)
- local forward=position+tonumber(size)
+ if routines[index] then
+ return false
+ end
+ local forward=position+size
local stream=decrypt(sub(str,position+1,forward),4330,4)
routines[index]={ byte(stream,1,#stream) }
- return forward
+ n=n+1
+ if n>=m then
+ return #str
+ end
+ return forward+1
end
local setvector=function(str,position,name,size,filename)
local forward=position+tonumber(size)
@@ -32598,7 +32904,7 @@ do
local p_np=spacing*(P("NP")+P("|"))
local p_nd=spacing*(P("ND")+P("|"))
local p_filterroutines=
- (1-subroutines)^0*subroutines*spaces*Cmt(cardinal,initialize)*(Cmt(cardinal*spaces*cardinal*p_rd*Carg(1),setroutine)*p_np+P(1))^1
+ (1-subroutines)^0*subroutines*spaces*Cmt(cardinal,initialize)*(Cmt(cardinal*spaces*cardinal*p_rd*Carg(1),setroutine)*p_np+(1-p_nd))^1
local p_filtershapes=
(1-charstrings)^0*charstrings*spaces*Cmt(cardinal,initialize)*(Cmt(name*spaces*cardinal*p_rd*Carg(1),setshapes)*p_nd+P(1))^1
local p_filternames=Ct (
@@ -32607,7 +32913,18 @@ do
local p_filterencoding=(1-encoding)^0*encoding*spaces*digits*spaces*array*(1-dup)^0*Cf(
Ct("")*Cg(spacing*dup*spaces*cardinal*spaces*name*spaces*put)^1
,rawset)
- local function loadpfbvector(filename,shapestoo)
+ local key=spacing*P("/")*R("az","AZ")
+ local str=spacing*Cs { (P("(")/"")*((1-P("\\(")-P("\\)")-S("()"))+V(1))^0*(P(")")/"") }
+ local num=spacing*(R("09")+S("+-."))^1/tonumber
+ local arr=spacing*Ct (S("[{")*(num)^0*spacing*S("]}"))
+ local boo=spacing*(P("true")*Cc(true)+P("false")*Cc(false))
+ local nam=spacing*P("/")*Cs(R("az","AZ")^1)
+ local p_filtermetadata=(
+ P("/")*Carg(1)*((
+ C("version")*str+C("Copyright")*str+C("Notice")*str+C("FullName")*str+C("FamilyName")*str+C("Weight")*str+C("ItalicAngle")*num+C("isFixedPitch")*boo+C("UnderlinePosition")*num+C("UnderlineThickness")*num+C("FontName")*nam+C("FontMatrix")*arr+C("FontBBox")*arr
+ ) )/function(t,k,v) t[lower(k)]=v end+P(1)
+ )^0*Carg(1)
+ local function loadpfbvector(filename,shapestoo,streams)
local data=io.loaddata(resolvers.findfile(filename))
if not data then
report_pfb("no data in %a",filename)
@@ -32625,9 +32942,10 @@ do
binary=decrypt(binary,55665,4)
local names={}
local encoding=lpegmatch(p_filterencoding,ascii)
+ local metadata=lpegmatch(p_filtermetadata,ascii,1,{})
local glyphs={}
routines,vector,chars={},{},{}
- if shapestoo then
+ if shapestoo or streams then
lpegmatch(p_filterroutines,binary,1,filename)
lpegmatch(p_filtershapes,binary,1,filename)
local data={
@@ -32639,13 +32957,13 @@ do
}
},
}
- fonts.handlers.otf.readers.parsecharstrings(false,data,glyphs,true,true)
+ fonts.handlers.otf.readers.parsecharstrings(false,data,glyphs,true,"cff",streams)
else
lpegmatch(p_filternames,binary,1,filename)
end
names=vector
routines,vector,chars=nil,nil,nil
- return names,encoding,glyphs
+ return names,encoding,glyphs,metadata
end
local pfb=handlers.pfb or {}
handlers.pfb=pfb
@@ -33731,6 +34049,7 @@ if not modules then modules={} end modules ['font-tfm']={
local next,type=next,type
local match,format=string.match,string.format
local concat,sortedhash=table.concat,table.sortedhash
+local idiv=number.idiv
local trace_defining=false trackers.register("fonts.defining",function(v) trace_defining=v end)
local trace_features=false trackers.register("tfm.features",function(v) trace_features=v end)
local report_defining=logs.reporter("fonts","defining")
@@ -33793,7 +34112,8 @@ local function read_from_tfm(specification)
properties.psname=tfmdata.psname
properties.fullname=tfmdata.fullname
properties.filename=specification.filename
- properties.format=fonts.formats.tfm
+ properties.format=tfmdata.format or fonts.formats.tfm
+ properties.usedbitmap=tfmdata.usedbitmap
tfmdata.properties=properties
tfmdata.resources=resources
tfmdata.parameters=parameters
@@ -33837,6 +34157,9 @@ local function read_from_tfm(specification)
end
end
shared.processes=next(features) and tfm.setfeatures(tfmdata,features) or nil
+if size<0 then
+ size=idiv(65536*-size,100)
+end
parameters.factor=1
parameters.size=size
parameters.slant=parameters.slant or parameters[1] or 0
@@ -33994,7 +34317,7 @@ do
local originals=tfmdata.characters
local indices={}
local parentfont={ "font",1 }
- local private=tfmdata or fonts.constructors.privateoffset
+ local private=tfmdata.privateoffset or fonts.constructors.privateoffset
local reported=encdone[tfmfile][encfile]
local backmap=vector and table.swapped(vector)
local done={}
@@ -34084,21 +34407,16 @@ CMapName currentdict /CMap defineresource pop end
end
end
]]
- local flushstreamobject=lpdf and lpdf.flushstreamobject
- local setfontattributes=pdf.setfontattributes
- if flushstreamobject then
- else
+ local flushstreamobject=lpdf and lpdf.flushstreamobject
+ local setfontattributes=lpdf and lpdf.setfontattributes
+ if not flushstreamobject then
flushstreamobject=function(data)
- return pdf.obj {
- immediate=true,
- type="stream",
- string=data,
- }
+ return pdf.obj { immediate=true,type="stream",string=data }
end
end
if not setfontattributes then
setfontattributes=function(id,data)
- print(format("your luatex is too old so no tounicode bitmap font%i",id))
+ return pdf.setfontattributes(id,data)
end
end
function tfm.addtounicode(tfmdata)