summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Build/source/texk/web2c/mfluadir/mfluac.c8
-rw-r--r--Build/source/texk/web2c/mfluadir/mfluac.h5
-rw-r--r--Build/source/texk/web2c/mfluadir/mfluaextra.h3
-rw-r--r--Build/source/texk/web2c/mfluadir/mfluatrap/mflua.lua7
-rw-r--r--Build/source/texk/web2c/mfluadir/mfluatrap/mflua_ttx_backend.lua653
5 files changed, 587 insertions, 89 deletions
diff --git a/Build/source/texk/web2c/mfluadir/mfluac.c b/Build/source/texk/web2c/mfluadir/mfluac.c
index aea6a8a7e96..391e157c76c 100644
--- a/Build/source/texk/web2c/mfluadir/mfluac.c
+++ b/Build/source/texk/web2c/mfluadir/mfluac.c
@@ -13,6 +13,11 @@
#if defined(JIT)
#include <luajit.h>
#endif
+
+/* See shell_cmd_is_allowed below */
+shellenabledp = 1;
+restrictedshell = 0;
+
/**************************************************************/
/* */
/* private functions */
@@ -1414,3 +1419,6 @@ int mfluarunscript(halfword j, halfword first, halfword limit)
}
return 0;
}
+
+/* TODO: check if shell_cmd_is_allowed make se sense */
+int shell_cmd_is_allowed(const char *cmd, char **safecmd, char **cmdname){return 1;}
diff --git a/Build/source/texk/web2c/mfluadir/mfluac.h b/Build/source/texk/web2c/mfluadir/mfluac.h
index 10f7240c51e..ed793cfc5c0 100644
--- a/Build/source/texk/web2c/mfluadir/mfluac.h
+++ b/Build/source/texk/web2c/mfluadir/mfluac.h
@@ -46,6 +46,11 @@ extern int mfluaprinttransitionlineto(integer, integer);
extern int mfluaPREmakeellipse(integer, integer, integer, integer, integer, integer);
extern int mfluaPOSTmakeellipse(integer, integer, integer, integer, integer, integer);
+/* TODO: check if shell_cmd_is_allowed makes sense */
+extern int shellenabledp;
+extern int restrictedshell;
+extern int shell_cmd_is_allowed(const char *, char **, char **);
+
#include <lauxlib.h>
extern int luaopen_kpse(lua_State * L);
diff --git a/Build/source/texk/web2c/mfluadir/mfluaextra.h b/Build/source/texk/web2c/mfluadir/mfluaextra.h
index f1753c94054..4e5fb50aa2e 100644
--- a/Build/source/texk/web2c/mfluadir/mfluaextra.h
+++ b/Build/source/texk/web2c/mfluadir/mfluaextra.h
@@ -21,4 +21,5 @@
#define INPUT_FORMAT kpse_mf_format
#define INI_PROGRAM "inimflua"
#define VIR_PROGRAM "virmflua"
-#define MFLua \ No newline at end of file
+#define MFLua
+
diff --git a/Build/source/texk/web2c/mfluadir/mfluatrap/mflua.lua b/Build/source/texk/web2c/mfluadir/mfluatrap/mflua.lua
index 1f8cd8c175b..ec9864a18bd 100644
--- a/Build/source/texk/web2c/mfluadir/mfluatrap/mflua.lua
+++ b/Build/source/texk/web2c/mfluadir/mfluatrap/mflua.lua
@@ -441,7 +441,6 @@ chMF(mflua.MF,print_scaled);mflua.MF.print_scaled = print_scaled
local function print_two(x,y) -- {prints `|(x,y)|'}
local res
-- debug
- -- print("print_two(x,y)",x,y)
res = '(' .. print_scaled(x) .. ',' .. print_scaled(y) .. ')'
return res
end
@@ -1544,12 +1543,12 @@ local function _store_current_contour()
if (#bezier_octant_contour == 0) then
local _t = {}
for i,v in ipairs(bezier_octant_I) do _t[i] = v end
- bezier_octant_contour[1] = _t
+ bezier_octant_contour[1] = _t;
else
local _cnt=0
for i,v in ipairs(bezier_octant_contour) do _cnt=_cnt+#v end
local _t = {}
- for i,v in ipairs(bezier_octant_I) do if i>_cnt then _t[#_t+1] = v end end
+ for i,v in ipairs(bezier_octant_I) do if i>_cnt then _t[#_t+1] = v; end end
bezier_octant_contour[#bezier_octant_contour+1] = _t
end
mflua.do_add_to.bezier_octant_contour = bezier_octant_contour
@@ -1754,7 +1753,7 @@ local function print_specification_contour(h)
end_loop_2=true
else
bezier_contour['p'] = print_two_true(x_coord(p),y_coord(p),octant);
- bezier_contour['control1'] = print_two_true(right_x(p),right_y(p),octant)
+ bezier_contour['control1'] = print_two_true(right_x(p),right_y(p),octant)
bezier_contour['control2'] = print_two_true(left_x(q),left_y(q),octant)
bezier_contour['q'] = print_two_true(x_coord(q),y_coord(q),octant)
beziers_contour[#beziers_contour+1] = bezier_contour
diff --git a/Build/source/texk/web2c/mfluadir/mfluatrap/mflua_ttx_backend.lua b/Build/source/texk/web2c/mfluadir/mfluatrap/mflua_ttx_backend.lua
index 851ff284ef3..2f3f36fa095 100644
--- a/Build/source/texk/web2c/mfluadir/mfluatrap/mflua_ttx_backend.lua
+++ b/Build/source/texk/web2c/mfluadir/mfluatrap/mflua_ttx_backend.lua
@@ -1,21 +1,26 @@
---
---
--- Experimental ttx back end
---
---
-
-
local format = string.format
local table_insert = table.insert
+local table_remove = table.remove
local table_concat = table.concat
+local table_sort = table.sort
local print_int = mflua.MF.print_int
local abs = math.abs
+local math_floor = math.floor
+local math_tointeger = math.tointeger or math.floor
+
+local print_scaled = mflua.MF.print_scaled
+local unity = mflua.MF.unity
+
+local GF = mflua.GF
+local GF_chars = GF.chars
local ttx = {}
local xmlstream = {}
-
local scrt = {} -- general table for local use
+
+
+
local function DUMP(t)
if type(t) == 'table' then
print("table",#table)
@@ -23,6 +28,64 @@ local function DUMP(t)
end
end
+local function print_err(msg)
+ print(format("! ttx backend: %s",tostring(msg)))
+end
+
+local function tointeger(n)
+ return math_tointeger(n)
+end
+
+local function _normalize(w,n)
+ n = tonumber(n) or 5
+ n = math_floor(abs(n))
+ n = (n<25 and n) or 24
+ local fmt = format("%%0.%sf", n)
+ local W = tonumber(format(fmt,w))
+ nx = tointeger(W)
+ if nx==W then
+ return nx
+ else
+ return w
+ end
+end
+
+local function normalize(w,n)
+ return print_scaled(w)
+end
+
+local function _normalize_and_simplify(w,n)
+ n = tonumber(n) or 2
+ n = math_floor(abs(n))
+ n = (n<25 and n) or 24
+ local fmt = format("%%0.%sf", n)
+ local W = tonumber(format(fmt,w))
+ nx = tointeger(W)
+ if nx==W then
+ return nx
+ else
+ return W
+ end
+end
+
+local function normalize_and_simplify(w,n)
+ return print_scaled(w)
+end
+
+
+local function toscaled(n)
+ return tonumber(format("%0.0f",n*unity))
+end
+
+local function table_sorted(t)
+ if type(t)=='table' then
+ table_sort(t)
+ return t
+ else
+ return {t}
+ end
+end
+
local xml_comment = 'c'
local xml_processing_instruction = 'p'
@@ -153,6 +216,38 @@ local function get_children(source,target)
return res
end
+--
+-- remove the first xml_element inserted
+-- with name. Return the element removed
+-- false otherwise
+local function remove_child(t,name)
+ for i=1,#t do
+ if t[i][0]==xml_element and t[i][1]==tostring(name) then
+ return table.remove(t,i)
+ end
+ end
+ return false
+end
+
+--
+-- call remove_child on all elements of
+-- names
+
+local function remove_children(t,names)
+ local res = {}
+ local name, r
+ for _,v in pairs(names) do
+ name = tostring(v)
+ r = remove_child(t,name)
+ if r then
+ table_insert(res,r)
+ end
+ end
+ return res
+end
+
+
+
--------------------------------------------------------------------------------
--
-- Serialization
@@ -189,7 +284,7 @@ local function serialize_processing_instruction(t)
end
end
for j=1,#_t do
- elem[#elem+1]=format([[ %s="%s"]],_t[j],toattr(t[_t[j]]))
+ elem[#elem+1]=format([[ %s="%s"]],_t[j],toattr(t[_t[j]]))
end
elem[#elem+1]='?>'
elem[#elem+1]="\n"
@@ -247,7 +342,9 @@ local function serialize_elem(t)
elem[#elem+1]=format([[ %s="%s"]],_t[j],toattr(t[_t[j]])) --
end
elem[#elem+1]='>'
+ if type(t[2])~= 'string' then
elem[#elem+1]="\n"
+ end
xmlstream[#xmlstream+1] = table_concat(elem)
elem = {}
for j=2,#t do
@@ -281,11 +378,18 @@ local OS_2,panose -- handy to have
local name
local cmap
local post
-local CFF, CFFFont, Private -- handy to have
+local CFF, CFFFont, Private -- only a single CFFFont, for the moment
local FFTM
local GDEF
local hmtx
+-- For variable fonts
+local extranames -- handy to have
+local CFF2
+local HVAR,VarStore,VarRegionList,Regions,VarRegionAxis,VarData,AdvWidthMap
+local fvar
+
+
-- Important, child of CFFFont
local CharStrings
@@ -325,6 +429,11 @@ local function put_CFF(name,value)
table_insert(CFF,new_element(name, {['value']=tostring(value)}))
end
+local function put_CFF2(name,value)
+ table_insert(CFF2,new_element(name, {['value']=tostring(value)}))
+end
+
+
local function put_CFFFont(name,value)
table_insert(CFFFont,new_element(name, {['value']=tostring(value)}))
end
@@ -371,18 +480,68 @@ end
---for i=1,255 do table_insert(GlyphOrder,new_element('GlyphID', {['id']=i, ['name']="uni"..tostring(i)})) end
---local ttFont = dofile('ttx_sample.lua')
---savettfont(ttFont)
-
-
--------------------------------------------------------------------------------
--
-- Create & save xml font
--------------------------------------------------------------------------------
local function checkall(tfm)
- -- several checks here
+ -- several checks & fixes here
+ local gf_chars = {}
+ if GF then
+ for k,_ in pairs(GF.chars) do
+ if type(k)=='number' then
+ table_insert(gf_chars,k)
+ end
+ end
+ table_sort(gf_chars)
+ end
+ --
+ -- fix head
+ if ttx.userdata.update_head and
+ type(ttx.userdata.update_head)=='function' then
+ ttx.userdata.update_head(tfm)
+ elseif GF then
+ remove_children(head,{'xMin', 'xMax','yMin','yMax','modified'})
+ put_head('xMin',GF_chars.min_m);
+ put_head('yMin',GF_chars.min_n);
+ put_head('xMax',GF_chars.max_m-GF_chars.min_m+1);
+ put_head('yMax',GF_chars.max_n-GF_chars.min_n+1);
+ -- Date is UTC
+ put_head('modified',os.date("!%c"));
+ end
+ --
+ -- fix CFFFont, only one for the moment
+ if ttx.userdata.update_CFFFont and
+ type(ttx.userdata.update_CFFFont)=='function' then
+ ttx.userdata.update_CFFFont(CFFont)
+ elseif GF then
+ remove_child(CFFFont,'FontBBox')
+ put_CFFFont('FontBBox',
+ format("%s %s %s %s",GF_chars.min_m,GF_chars.min_n,
+ GF_chars.max_m-GF_chars.min_m+1,
+ GF_chars.max_n-GF_chars.min_n+1))
+ end
+ --
+ -- fix OS_2
+ if ttx.userdata.update_OS_2 and
+ type(ttx.userdata.update_OS_2)=='function' then
+ ttx.userdata.update_CFFFont(OS_2)
+ elseif mflua.chartable then
+ local design_size=tonumber ( print_scaled(MFbuiltin.designsize()) ) --pt
+ local emsize = ttx.emsize or 1000
+ local avgx = 0
+ local avgx_cnt=0
+ for k,v in pairs(mflua.chartable) do
+ if tonumber(v.char_wd) > 0 then
+ avgx = tonumber(v.char_wd)*emsize/design_size+avgx
+ avgx_cnt=avgx_cnt+1
+ end
+ end
+ avgx = math_floor(avgx/avgx_cnt+0.5)
+ remove_child(OS_2,'xAvgCharWidth')
+ put_OS_2('xAvgCharWidth',avgx)
+ end
-- fix cmap0
-- local t = {}
-- for k,_ in pairs(scrt.cmap.rawcmap0) do t[#t+1]=k end
@@ -427,7 +586,7 @@ local function _eval_tonumber(q,offset)
end
local function setup(tfm,index,chartable)
- -- Default emsize is 1000 of CFF
+ -- Default emsize is 1000 for CFF and CFF2
ttx.emsize = ttx.emsize or 1000
scrt.font_space = tfm.printfloat(ttx.emsize*(tfm.font.space),3)
@@ -442,14 +601,27 @@ local function setup(tfm,index,chartable)
name = new_element('name')
cmap = new_element('cmap')
post = new_element('post')
- CFF = new_element('CFF')
+ if ttx.cffver==1 then
+ CFF = new_element('CFF')
+ CFF2 = nil
+ elseif ttx.cffver==2 then
+ CFF2 = new_element('CFF2')
+ CFF = nil
+ end
-- FFTM = new_element('FFTM') --FontForge TimeStamp table
GDEF = new_element('GDEF')
+ if ttx.cffver==2 then
+ HVAR = new_element('HVAR')
+ end
hmtx = new_element('hmtx')
-- handy
panose = new_element('panose')
- CFFFont = new_element('CFFFont',{['name']="SourceCode"})
+ if ttx.cffver==1 then
+ CFFFont = new_element('CFFFont',{['name']= (ttx.userdata.CFFFont['FullName'] or "mfluatestfont"..tostring(math.random(0,1000000)))})
+ elseif ttx.cffver==2 then
+ CFFFont = new_element('CFFFont',{['name']="CFF2Font"})
+ end
Private = new_element('Private')
CharStrings= new_element('CharStrings')
@@ -462,9 +634,43 @@ local function setup(tfm,index,chartable)
table_insert(ttFont,name)
table_insert(ttFont,cmap)
table_insert(ttFont,post)
- table_insert(ttFont,CFF)
--- table_insert(ttFont,FFTM)
+ if ttx.cffver==1 then
+ table_insert(ttFont,CFF)
+ elseif ttx.cffver==2 then
+ table_insert(ttFont,CFF2)
+ end
+ -- table_insert(ttFont,FFTM)
table_insert(ttFont,GDEF)
+
+ if ttx.cffver==2 then
+ table_insert(ttFont,HVAR)
+ insert_child(HVAR,{'Version', ['value']="0x00010000"})
+ VarStore = new_element('VarStore',{['Format']="1"})
+ insert_child(VarStore,{'Format',['value']="1"})
+ VarRegionList = new_element('VarRegionList')
+ -- For the moment, 1 axis and 1 region
+ Regions = {new_element('Region',{['index']="0"})}
+ VarRegionAxis = new_element('VarRegionAxis',{['index']="0"})
+ insert_child(VarRegionAxis,new_element('StartCoord',{['value']="-1.0"}))
+ insert_child(VarRegionAxis,new_element('PeakCoord',{['value']="-1.0"}))
+ insert_child(VarRegionAxis,new_element('EndCoord',{['value']="0.0"}))
+ -- insert_child(VarRegionAxis,new_element('StartCoord',{['value']="0.0"}))
+ -- insert_child(VarRegionAxis,new_element('PeakCoord',{['value']="1.0"}))
+ -- insert_child(VarRegionAxis,new_element('EndCoord',{['value']="1.0"}))
+ insert_child(Regions[1],VarRegionAxis)
+ insert_children(VarRegionList,Regions)
+ insert_child(VarStore,VarRegionList)
+ VarData = new_element('VarData',{['index']="0"})
+ insert_child(VarData,new_element('NumShorts',{['value']="1"}))
+ insert_child(VarData,new_element('VarRegionIndex',{['value']="0"}))
+ insert_child(VarData,new_element('Item',{['index']="0", ['value']="[-125]"}))
+ insert_child(VarStore,VarData)
+ AdvWidthMap = new_element('AdvWidthMap')
+ insert_child(AdvWidthMap,new_element('Map', {['index']="0", ['outer']="0", ['inner']="0"}))
+ insert_child(HVAR,VarStore)
+ --insert_child(HVAR,AdvWidthMap)
+ end
+
table_insert(ttFont,hmtx)
table_insert(GlyphOrder,GlyphID)
@@ -539,61 +745,88 @@ local function setup(tfm,index,chartable)
put_post(k,v)
end
end
-
- put_CFF('major',"1")
- put_CFF('minor',"0")
- insert_child(CFF,CFFFont)
-
- if ttx.userdata.CFFFont then
- for k,v in pairs(mflua.ttx.userdata.CFFFont) do
- put_CFFFont(k,v)
- end
+ if ttx.cffver==2 then
+ insert_child(post,{'psNames'})
+ extranames = new_element('extraNames')
+ insert_child(post,extranames)
end
- insert_child(CFFFont,{'Encoding', ['name']=mflua.ttx.userdata.CFFFont.Encoding})
+ if ttx.cffver==1 then
+ put_CFF('major',"1")
+ put_CFF('minor',"0")
+ insert_child(CFF,CFFFont)
+ elseif ttx.cffver==2 then
+ put_CFF2('major',"2")
+ put_CFF2('minor',"0")
+ insert_child(CFF2,CFFFont)
+ end
- insert_child(CFFFont,Private)
- if ttx.userdata.CFFFont.Private then
- for k,v in pairs(ttx.userdata.CFFFont.Private) do
- put_Private(k,v)
+ if ttx.cffver==1 then
+ if ttx.userdata.CFFFont then
+ for k,v in pairs(mflua.ttx.userdata.CFFFont) do
+ put_CFFFont(k,v)
+ end
end
- end
- local subrs = new_element('Subrs')
- scrt.subrs = subrs
- if ttx.userdata.CFFFont.Private.Subrs then
- for k,v in pairs(ttx.userdata.CFFFont.Private.Subrs) do
- insert_child(subrs,{'CharString', ['index']=k, v})
+ insert_child(CFFFont,{'Encoding', ['name']=mflua.ttx.userdata.CFFFont.Encoding})
+
+ insert_child(CFFFont,Private)
+ if ttx.userdata.CFFFont.Private then
+ for k,v in pairs(ttx.userdata.CFFFont.Private) do
+ put_Private(k,v)
+ end
+ end
+
+ local subrs = new_element('Subrs')
+ scrt.subrs = subrs
+ if ttx.userdata.CFFFont.Private.Subrs then
+ for k,v in pairs(ttx.userdata.CFFFont.Private.Subrs) do
+ insert_child(subrs,{'CharString', ['index']=k, v})
+ end
end
- end
insert_child(Private,subrs)
+ elseif ttx.cffver==2 then
+ insert_child(CFFFont,{'FontMatrix', ['value']=mflua.ttx.userdata.CFF2Font['FontMatrix']})
+ local FDArray = new_element('FDArray')
+ local FontDict = new_element('FontDict', {['index']="0"})
+ insert_child(FontDict,{'FontMatrix', ['value']=mflua.ttx.userdata.CFF2Font['FontMatrix']})
+ insert_child(FontDict,{'Private'})
+ insert_child(FDArray,FontDict)
+ insert_child(CFFFont,FDArray)
+ end
+
-- .notdef char
local notdef = new_element('CharString', {['name']=".notdef"})
- insert_child(notdef,"107 endchar\n")
+ if ttx.cffver == 1 then
+ insert_child(notdef,"endchar\n")
+ elseif ttx.cffver == 2 then
+ insert_child(notdef,"0 0 0 0 0 0 rrcurveto \n")
+ end
+
insert_child_at_beginning(CharStrings, notdef)
insert_child(CFFFont,CharStrings)
+ if CFF2 and mflua.ttx.userdata.varstore then
+ insert_child(CFFFont,mflua.ttx.userdata.varstore)
+ end
+
+
--
-- TODO: check GlobalSubrs!!
--
local globsubrs = new_element('GlobalSubrs')
- insert_child(CFF,globsubrs)
+ if ttx.cffver==1 then
+ insert_child(CFF,globsubrs)
+ elseif ttx.cffver==2 then
+ insert_child(CFF2,globsubrs)
+ end
if ttx.userdata.CFF.GlobalSubrs then
for k,v in pairs(ttx.userdata.CFF.GlobalSubrs) do
insert_child(globsubrs,{'CharString', ['index']=k, v})
end
end
-
- --
- -- fontforge timestamp table.
- --
- -- put_FFTM('version', "1")
- -- put_FFTM('FFTimeStamp', "Fri Oct 7 21:32:10 2016")
- -- put_FFTM('sourceCreated', "Tue Apr 4 13:38:00 2017")
- -- put_FFTM('sourceModified', "Wed Apr 5 16:26:11 2017")
-
local glyphclassdef = new_element('GlyphClassDef',{['Format']="2"})
insert_child(GDEF,{'Version',['value']="0x00010000"})
@@ -605,7 +838,27 @@ local function setup(tfm,index,chartable)
insert_child(LigCaretList,new_element('Coverage',{['Format']="2"}))
insert_child(GDEF,LigCaretList)
- insert_child(hmtx, get_mtx('.notdef',scrt.font_space,"0"))
+
+ insert_child(hmtx, get_mtx('.notdef',
+ ttx.userdata.char_notdef['width'],
+ ttx.userdata.char_notdef['lsb']))
+
+ if CFF2 and ttx.userdata.fvar then
+ local fvar = new_element('fvar')
+ local v, axis, _e
+ for i=1,#ttx.userdata.fvar.Axis do
+ v = ttx.userdata.fvar.Axis[i]
+ axis = new_element('Axis')
+ _e = new_element('AxisTag'); _e[2] = v['AxisTag']; insert_child(axis,_e)
+ _e = new_element('MinValue'); _e[2] = v['MinValue']; insert_child(axis,_e)
+ _e = new_element('DefaultValue'); _e[2] = v['DefaultValue']; insert_child(axis,_e)
+ _e = new_element('MaxValue'); _e[2] = v['MaxValue']; insert_child(axis,_e)
+ _e = new_element('AxisNameID'); _e[2] = v['AxisNameID']; insert_child(axis,_e)
+ end
+ insert_child(fvar,axis)
+ insert_child(ttFont,fvar)
+ end
+
end
@@ -622,6 +875,33 @@ local function reverse(cycle)
return t
end
+
+local function sort(cycle)
+ local t={}
+ local curve
+ local p,q, index
+ local xmin,ymin = 4096,4096
+ index = 1
+ for i=1,#cycle do
+ curve=cycle[i]
+ p=curve[1];
+ t = _eval_tonumber(p)
+ -- Align to leftmost x and y
+ --if t[1]<=xmin and t[2]<=ymin then index = i;xmin,ymin=t[1],t[2] end
+ -- Align to the leftmost x
+ if t[1]<=xmin then index = i;xmin,ymin=t[1],t[2] end
+ end
+ t={}
+ for i=index,#cycle do t[#t+1]=cycle[i] end
+ for i=1,index-1 do t[#t+1]=cycle[i] end
+ for i=1,#t do
+ curve=t[i]
+ p,c1,c2,q=curve[1],curve[2],curve[3],curve[4]
+ end
+ return t
+end
+
+
local function _reverse(cycle)
local cv1, cv2
local p,c1,c2,q
@@ -639,20 +919,101 @@ local function _reverse(cycle)
end
+-- local function updateminmax(p,c1,c2,q)
+-- ttx = ttx or {}
+-- ttx.userdata = ttx.userdata or {}
+-- ttx.userdata.head = ttx.userdata.head or {}
+-- local t;
+-- -- hm not ok, too raw
+-- -- we need at least 3 bisections
+-- t = {p[1],c1[1],c2[1],q[1]}
+-- table_sort(t)
+-- ttx.userdata.head['xMin']= math_floor(t[1])
+-- ttx.userdata.head['xMax']= math_floor(t[4])
+-- t = {p[2],c1[2],c2[2],q[2]}
+-- table_sort(t)
+-- ttx.userdata.head['yMin']= math_floor(t[1])
+-- ttx.userdata.head['yMax']= math_floor(t[4])
+-- end
+
+
+local function update_char_lsb(glyph_name,char_wd_emunit,index)
+ local err = true
+ if ttx.userdata.update_char_lsb and
+ type(ttx.userdata.update_char_lsb)=='function' then
+ ttx.userdata.update_char_lsb(glyph_name,char_wd_emunit,index)
+ return
+ end
+ if GF_chars[index] then
+ insert_child(hmtx, get_mtx(glyph_name,
+ char_wd_emunit,GF_chars[index].min_m))
+ return
+ end
+ if err then print_err("update_char_lsb failed") end
+end
+
+
+
+
+
+local function isvhline(py,c1y,c2y,qy)
+ if (py==c1y) and (c1y==c2y) and (c2y==qy) then
+ return true
+ end
+ --local abs = math.abs
+ local eps = ttx.eps or 0.01
+ local d1,d2,d3,d4 = abs(py-c1y), abs(c1y-c2y), abs(c2y-qy),abs(py-qy)
+ if d1<eps and d2<eps and d3<eps and d4<eps then
+ return true
+ end
+ return false
+end
+
+
+local function isline(px,py,c1x,c1y,c2x,c2y,qx,qy)
+ local px,py,c1x,c1y,c2x,c2y,qx,qy = 0,0,c1x-px,c1y-py,c2x-px,c2y-py,qx-px,qy-py
+ local eps = ttx.deps or 0.01
+ local atan2,abs = math.atan2, math.abs
+ a = atan2(qy,qx)
+ a1 = atan2(c1y,c1x)
+ a2 = atan2(c2y,c2x)
+ if abs(a-a1)<eps and abs(a-a2)<eps and abs(a1-a2)<eps then
+ return true
+ end
+ return false
+end
+
+
+local function insert_stem(index,stem_type)
+ if mflua and mflua.userdata and mflua.userdata.char and mflua.userdata.char[index] and mflua.userdata.char[index][stem_type] then
+ -- stem[i]={base, delta}
+ local stem = mflua.userdata.char[index][stem_type]
+ local content = {}
+ for i=1,#stem do
+ --table_insert(content, format("%s %s", normalize(stem[i][1]),normalize(stem[i][2])))
+ table_insert(content, format("%s %s",stem[i][1],stem[i][2]))
+ end
+ table_insert(content,stem_type)
+ return table_concat(content, " ")
+ end
+ return nil
+end
+
+
local function make_glyph(valid_curves,char,cycles,tfm)
-- Write the ttx
- --
- -- print('BEZ MFbuiltin.hppp='..print_scaled(MFbuiltin.hppp()))
- -- print('BEZ MFbuiltin.vppp='..print_scaled(MFbuiltin.vppp()))
- -- print('BEZ MFbuiltin.designsize='..print_scaled(MFbuiltin.designsize()))
+
+ if #cycles == 0 and #valid_curves==0 then
+ print("no outlines ")
+ --return
+ end
local tfm = tfm
- local mflua_index = tonumber( char['index'] ) -- better a string or a number
+ local mflua_index = tointeger( char['index'] ) -- better a string or a number
local index = mflua_index
if mflua.ttx.userdata.charindex and mflua.ttx.userdata.charindex[index] then
index = mflua.ttx.userdata.charindex[index]
end
-
local design_size=tonumber ( print_scaled(MFbuiltin.designsize()) ) --pt
local char_wd=tonumber( char['char_wd'] ) -- pt
local char_ht=tonumber( char['char_ht'] ) -- pt
@@ -664,36 +1025,44 @@ local function make_glyph(valid_curves,char,cycles,tfm)
local glyphclassdef = scrt.gdef.glyphclassdef
- --local xheight = 0.458333 * design_size -- must be read from tfm !!
- local x_resolution = math.floor(0.5+tonumber( print_scaled(MFbuiltin.hppp()) )* 72.27)
- local y_resolution = math.floor(0.5+tonumber( print_scaled(MFbuiltin.vppp()) )* 72.27)
+ local x_resolution = math_floor(0.5+tonumber( print_scaled(MFbuiltin.hppp()) )* 72.27)
+ local y_resolution = math_floor(0.5+tonumber( print_scaled(MFbuiltin.vppp()) )* 72.27)
assert(x_resolution==y_resolution, format('Error on _make_glyph x_res=%d and y_res=%d differ',x_resolution,y_resolution))
local resolution = x_resolution
local emsize = ttx.emsize -- 1000, type 1, also known as em_unit: 1000 emsize = 1em
local em_unit = emsize
-
local em_unit_for_pixel = (72.27/design_size) * (emsize / resolution)
local bp_for_pt = 72/72.27
- local char_wd_emunit = (char_wd/design_size) *em_unit
- local char_ht_emunit = (char_ht/design_size) *em_unit
- local char_dp_emunit = (char_dp/design_size) *em_unit
-
+ local char_wd_emunit = tonumber(format("%0.0f", (char_wd/design_size) *em_unit))
+ local char_ht_emunit = tonumber(format("%0.0f", (char_ht/design_size) *em_unit))
+ local char_dp_emunit = tonumber(format("%0.0f", (char_dp/design_size) *em_unit))
local glyph_name = tostring(char['charname'])
+
if glyph_name and glyph_name ~= '' and not(index==0) then
table_insert(GlyphOrder,get_GlyphID(index,glyph_name))
end
+
local content = {}
- if (abs(char_wd_emunit-scrt.font_space)>1e-4) then
- table_insert(content,format("%0.3f w",char_wd_emunit-scrt.font_space,print_int(1000*(tfm.font.space))))
+ table_insert(content," ")
+ if CFF2 and (abs(char_wd_emunit-scrt.font_space)>1e-4) then
+ table_insert(content,format("%0.3f w",char_wd_emunit-scrt.font_space))
end
- --table_insert(content,"stem ?") -- TODO
+
+
+ table_insert(content,insert_stem(mflua_index,"hstem"))
+ table_insert(content,insert_stem(mflua_index,"vstem"))
--table_insert(content,"mask ?") -- TODO
+
local origin = {0,0}
- for i,cycle in pairs(cycles) do
+ for i,_cycle in pairs(cycles) do
+ local cycle
local p,c1,c2,q,offset
- cycle = reverse(cycle)
+ --cycle = reverse(_cycle)
+ cycle = _cycle
+ -- do we need a sort ?
+ --cycle = sort(cycle)
for i1,curve in ipairs(cycle) do
p,c1,c2,q,offset=curve[1],curve[2],curve[3],curve[4],curve[5]
p =_eval_tonumber(p ,offset)
@@ -705,18 +1074,119 @@ local function make_glyph(valid_curves,char,cycles,tfm)
q[1],q[2] = q[1] *em_unit_for_pixel, q[2]*em_unit_for_pixel
c1[1],c1[2] = c1[1]*em_unit_for_pixel, c1[2]*em_unit_for_pixel
c2[1],c2[2] = c2[1]*em_unit_for_pixel, c2[2]*em_unit_for_pixel
- if i1==1 then
- table_insert(content,format("%0.2f %0.2f rmoveto",p[1]-origin[1],p[2]-origin[2]))
- origin = {p[1],p[2]}
+
+
+ p[1],p[2] = toscaled(p[1]), toscaled(p[2])
+ q[1],q[2] = toscaled(q[1]), toscaled(q[2])
+ c1[1],c1[2] = toscaled(c1[1]), toscaled(c1[2])
+ c2[1],c2[2] = toscaled(c2[1]), toscaled(c2[2])
+
+
+ if CFF then
+ -- print(format("p1 %s path=(%0.14f,%0.14f) (%0.14f,%0.14f) (%0.14f,%0.14f) (%0.14f,%0.14f)", index,
+ -- p[1], p[2],
+ -- c1[1], c1[2],
+ -- c2[1], c2[2],
+ -- q[1],q[2]))
+ -- print(format("p2 %s path=(%0.4f,%0.4f) (%0.4f,%0.4f) (%0.4f,%0.4f) (%0.4f,%0.4f)", index,
+ -- p[1], p[2],
+ -- c1[1], c1[2],
+ -- c2[1], c2[2],
+ -- q[1],q[2]))
+ -- print(format("p3 %s path=(%s,%s) (%s,%s) (%s,%s) (%s,%s)", index,
+ -- normalize(p[1]), normalize(p[2]),
+ -- normalize(c1[1]), normalize(c1[2]),
+ -- normalize(c2[1]), normalize(c2[2]),
+ -- normalize(q[1]), normalize(q[2])))
+
+ if i1==1 then
+ --print(format("m %s %s %s rmoveto",index, normalize(p[1]-origin[1]),normalize(p[2]-origin[2])))
+ table_insert(content,format("%s %s rmoveto",normalize(p[1]-origin[1]),normalize(p[2]-origin[2])))
+ origin = {p[1],p[2]}
+ end
+ if isvhline(p[2],c1[2],c2[2], q[2]) then -- check horizontal line
+ --print(format("h %s %s hlineto", index, normalize(q[1]-p[1])))
+ table_insert(content,format("%s hlineto", normalize(q[1]-p[1])))
+ elseif isvhline(p[1],c1[1],c2[1], q[1]) then -- check vertical line
+ --print(format("v %s %s vlineto", index,normalize(q[2]-p[2])))
+ table_insert(content,format("%s vlineto", normalize(q[2]-p[2])))
+ elseif isline(p[1],p[2],c1[1],c1[2],c2[1],c2[2],q[1],q[2]) then -- check a line
+ --print(format("r %s %s %s rlineto", index, normalize(q[1]-p[1]), normalize(q[2]-p[2])))
+ table_insert(content,format("%s %s rlineto", normalize(q[1]-p[1]), normalize(q[2]-p[2])))
+ else
+ local prec = 3;
+ -- p[1] = normalize_and_simplify(p[1],prec);p[2] = normalize_and_simplify(p[2],prec);
+ -- c1[1] = normalize_and_simplify(c1[1],prec);c1[2] = normalize_and_simplify(c1[2],prec);
+ -- c2[1] = normalize_and_simplify(c2[1],prec);c2[2] = normalize_and_simplify(c2[2],prec);
+ -- q[1] = normalize_and_simplify(q[1],prec);q[2] = normalize_and_simplify(q[2],prec);
+
+
+ table_insert(content,(format("%s %s %s %s %s %s rrcurveto",
+ normalize_and_simplify(c1[1] -p[1],prec), normalize_and_simplify(c1[2]-p[2],prec),
+ normalize_and_simplify(c2[1]-c1[1],prec), normalize_and_simplify(c2[2]-c1[2],prec),
+ normalize_and_simplify(q[1] -c2[1],prec), normalize_and_simplify(q[2]-c2[2],prec))))
+
+ end
+
+ elseif CFF2 then --
+ -- reverse the key, because we reverse the cycle
+ local kp = table.concat({curve[4],curve[3],curve[2],curve[1]})
+ local deltas_width = {{0,0},{0,0}, {0,0},{0,0}, {0,0},{0,0}, {0,0},{0,0}}
+ local origin_deltas_width = {0,0}
+ local a, b, c, d, da, Da, db, Db, dc, Dc, dd, Dd
+ if mflua.userdata.deltas_width[glyph_name] then
+ deltas_width = mflua.userdata.deltas_width[glyph_name][kp]
+ -- Original from MF, we have to reverse it; d..c..b..a is the key,
+ -- da and Da are the delta min and delta max,
+ -- where delta is (variated_instance - reference_instance)
+ -- delta are not affected by offset, but scaling are cannot be discarded
+ a, b, c, d, da, Da, db, Db, dc, Dc, dd, Dd = table.unpack(deltas_width)
+ deltas_width = {dd, Dd,dc, Dc,db, Db,da, Da}
+ for _,v in ipairs(deltas_width) do
+ v[1],v[2]=v[1]*em_unit_for_pixel, v[2]*em_unit_for_pixel
+ end
+ end
+ da, Da, db, Db, dc, Dc, dd, Dd = table.unpack(deltas_width)
+ -- One axis only, width
+ -- Condensed Regular (still not Extended)
+ local blend
+ if i1==1 then
+ blend = format("%0.2f %0.2f 2 blend",da[1]-origin_deltas_width[1],da[2]-origin_deltas_width[2]) ;
+ table_insert(content,format("%0.0f %0.0f %s rmoveto",p[1]-origin[1],p[2]-origin[2],blend))
+ origin = {p[1],p[2]}
+ origin_deltas_width ={da[1],da[2]}
+ end
+ blend = format("%0.2f %0.2f %0.2f %0.2f %0.2f %0.2f 6 blend",
+ db[1]-da[1],db[2]-da[2],
+ dc[1]-db[1],dc[2]-db[2],
+ dd[1]-dc[1],dd[2]-dc[2])
+
+ table_insert(content,format("%0.0f %0.0f %0.0f %0.0f %0.0f %0.0f %s rrcurveto",
+ c1[1] -p[1], c1[2]-p[2],
+ c2[1]-c1[1], c2[2]-c1[2],
+ q[1] -c2[1], q[2]-c2[2],blend))
+
+
+
+ -- if i1==1 then
+ -- blend = '0 0 2 blend' ;
+ -- table_insert(content,format("%0.0f %0.0f %s rmoveto",p[1]-origin[1],p[2]-origin[2],blend))
+ -- origin = {p[1],p[2]}
+ -- end
+ -- --table_insert(content,format("%0.2f %0.2f %0.2f %0.2f %0.2f %0.2f rrcurveto",
+ -- if i1==1 then blend = '0 0 0 0 0 0 6 blend' ; else blend = '0 0 0 0 -10 0 6 blend' end
+ -- table_insert(content,format("%0.0f %0.0f %0.0f %0.0f %0.0f %0.0f %s rrcurveto",
+ -- c1[1] -p[1], c1[2]-p[2],
+ -- c2[1]-c1[1], c2[2]-c1[2],
+ -- q[1] -c2[1], q[2]-c2[2],blend))
end
- --table_insert(content,format("%0.2f %0.2f %0.2f %0.2f %0.2f %0.2f rrcurveto",
- table_insert(content,format("%0.0f %0.0f %0.0f %0.0f %0.0f %0.0f rrcurveto",
- c1[1] -p[1], c1[2]-p[2],
- c2[1]-c1[1], c2[2]-c1[2],
- q[1] -c2[1], q[2]-c2[2],p[1],p[2],c1[1],c1[2],c2[1],c2[2],q[1],q[2]))
end
end
- table_insert(content,"endchar\n")
+ if ttx.cffver == 1 then
+ table_insert(content,"endchar\n")
+ elseif ttx.cffver == 2 then
+ table_insert(content,"")
+ end
local CharString = new_element('CharString', {['name']=glyph_name})
insert_child(CharString,table_concat(content,"\n"))
@@ -726,8 +1196,21 @@ local function make_glyph(valid_curves,char,cycles,tfm)
insert_child(cmap4_3,get_map(format("0x%x",index),glyph_name))
insert_child(glyphclassdef, get_ClassDef(glyph_name,"1"))
- insert_child(hmtx, get_mtx(glyph_name,char_wd_emunit,"80"))
+ update_char_lsb(glyph_name,char_wd_emunit,mflua_index)
+
+ if ttx.cffver==2 then
+ local psName = new_element('psName', {['name']=glyph_name})
+ local Item = new_element('Item', {['index']=format("%d",index), ['value']="[-125]"})
+ local Map = new_element('Map', {['index']=format("%d",index), ['outer']="0", ['inner']="0"})
+ local VarStore = get_children(HVAR,{'VarStore'})
+ local VarData = get_children(VarStore[1],{'VarData'})
+ --local AdvWidthMap = get_children(HVAR,{'AdvWidthMap'})
+ insert_child(VarData[1],Item)
+ --insert_child(AdvWidthMap[1],Map)
+ insert_child(extranames,psName)
+
+ end
end -- make_glyph
@@ -739,5 +1222,7 @@ ttx.make_glyph = make_glyph
ttx.makefont = makefont
ttx.setup = setup
ttx.userdata = {}
-
+ttx.cffver = 1
+ttx.eps = 0.01
+ttx.deps = 0.01
return ttx