summaryrefslogtreecommitdiff
path: root/src/fontloader
diff options
context:
space:
mode:
Diffstat (limited to 'src/fontloader')
-rw-r--r--src/fontloader/misc/fontloader-font-one.lua (renamed from src/fontloader/misc/fontloader-font-afm.lua)336
1 files changed, 175 insertions, 161 deletions
diff --git a/src/fontloader/misc/fontloader-font-afm.lua b/src/fontloader/misc/fontloader-font-one.lua
index 0d6b7cb..3602fd4 100644
--- a/src/fontloader/misc/fontloader-font-afm.lua
+++ b/src/fontloader/misc/fontloader-font-one.lua
@@ -1,4 +1,4 @@
-if not modules then modules = { } end modules ['font-afm'] = {
+if not modules then modules = { } end modules ['font-one'] = {
version = 1.001,
comment = "companion to font-ini.mkiv",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
@@ -7,22 +7,16 @@ if not modules then modules = { } end modules ['font-afm'] = {
}
--[[ldx--
-<p>Some code may look a bit obscure but this has to do with the
-fact that we also use this code for testing and much code evolved
-in the transition from <l n='tfm'/> to <l n='afm'/> to <l
-n='otf'/>.</p>
-
-<p>The following code still has traces of intermediate font support
-where we handles font encodings. Eventually font encoding goes
-away.</p>
-
-<p>The embedding of a font involves creating temporary files and
-depending on your system setup that can fail. It took more than a
-day to figure out why sometimes embedding failed in mingw luatex
-where running on a real path like c:\... failed while running on
-say e:\... being a link worked well. The native windows binaries
-don't have this issue.</p>
+<p>Some code may look a bit obscure but this has to do with the fact that we also use
+this code for testing and much code evolved in the transition from <l n='tfm'/> to
+<l n='afm'/> to <l n='otf'/>.</p>
+<p>The following code still has traces of intermediate font support where we handles
+font encodings. Eventually font encoding went away but we kept some code around in
+other modules.</p>
+
+<p>This version implements a node mode approach so that users can also more easily
+add features.</p>
--ldx]]--
local fonts, logs, trackers, containers, resolvers = fonts, logs, trackers, containers, resolvers
@@ -52,39 +46,25 @@ local constructors = fonts.constructors
local afm = constructors.newhandler("afm")
local pfb = constructors.newhandler("pfb")
+local otf = fonts.handlers.otf
+
+local otfreaders = otf.readers
+local otfenhancers = otf.enhancers
local afmfeatures = constructors.newfeatures("afm")
local registerafmfeature = afmfeatures.register
-afm.version = 1.501 -- incrementing this number one up will force a re-cache
+afm.version = 1.505 -- incrementing this number one up will force a re-cache
afm.cache = containers.define("fonts", "afm", afm.version, true)
afm.autoprefixed = true -- this will become false some day (catches texnansi-blabla.*)
afm.helpdata = { } -- set later on so no local for this
afm.syncspace = true -- when true, nicer stretch values
-afm.addligatures = true -- best leave this set to true
-afm.addtexligatures = true -- best leave this set to true
-afm.addkerns = true -- best leave this set to true
local overloads = fonts.mappings.overloads
local applyruntimefixes = fonts.treatments and fonts.treatments.applyfixes
-local function setmode(tfmdata,value)
- if value then
- tfmdata.properties.mode = lower(value)
- end
-end
-
-registerafmfeature {
- name = "mode",
- description = "mode",
- initializers = {
- base = setmode,
- node = setmode,
- }
-}
-
--[[ldx--
<p>We start with the basic reader which we give a name similar to the
built in <l n='tfm'/> and <l n='otf'/> reader.</p>
@@ -222,61 +202,13 @@ local function get_variables(data,fontmetrics)
end
end
+-- new (unfinished) pfb loader but i see no differences between
+-- old and new (one bad vector with old)
+
local get_indexes
do
- -- old font loader
-
- local fontloader = fontloader
- local get_indexes_old = false
-
- if fontloader then
-
- local font_to_table = fontloader.to_table
- local open_font = fontloader.open
- local close_font = fontloader.close
-
- get_indexes_old = function(data,pfbname)
- local pfbblob = open_font(pfbname)
- if pfbblob then
- local characters = data.characters
- local pfbdata = font_to_table(pfbblob)
- if pfbdata then
- local glyphs = pfbdata.glyphs
- if glyphs then
- if trace_loading then
- report_afm("getting index data from %a",pfbname)
- end
- for index, glyph in next, glyphs do
- local name = glyph.name
- if name then
- local char = characters[name]
- if char then
- if trace_indexing then
- report_afm("glyph %a has index %a",name,index)
- end
- char.index = index
- end
- end
- end
- elseif trace_loading then
- report_afm("no glyph data in pfb file %a",pfbname)
- end
- elseif trace_loading then
- report_afm("no data in pfb file %a",pfbname)
- end
- close_font(pfbblob)
- elseif trace_loading then
- report_afm("invalid pfb file %a",pfbname)
- end
- end
-
- end
-
- -- new (unfinished) font loader but i see no differences between
- -- old and new (one bad vector with old)
-
local n, m
local progress = function(str,position,name,size)
@@ -395,21 +327,6 @@ do
end
end
- if get_indexes_old then
-
- afm.use_new_indexer = true
- get_indexes_new = get_indexes
-
- get_indexes = function(data,pfbname)
- if afm.use_new_indexer then
- return get_indexes_new(data,pfbname)
- else
- return get_indexes_old(data,pfbname)
- end
- end
-
- end
-
end
local function readafm(filename)
@@ -469,15 +386,17 @@ local function readafm(filename)
end
--[[ldx--
-<p>We cache files. Caching is taken care of in the loader. We cheat a bit
-by adding ligatures and kern information to the afm derived data. That
-way we can set them faster when defining a font.</p>
+<p>We cache files. Caching is taken care of in the loader. We cheat a bit by adding
+ligatures and kern information to the afm derived data. That way we can set them faster
+when defining a font.</p>
+
+<p>We still keep the loading two phased: first we load the data in a traditional
+fashion and later we transform it to sequences.</p>
--ldx]]--
-local addkerns, addligatures, addtexligatures, unify, normalize, fixnames -- we will implement these later
+local addkerns, unify, normalize, fixnames, addligatures, addtexligatures
function afm.load(filename)
- -- hm, for some reasons not resolved yet
filename = resolvers.findfile(filename,'afm') or ""
if filename ~= "" and not fonts.names.ignoredfile(filename) then
local name = file.removesuffix(file.basename(filename))
@@ -503,38 +422,55 @@ function afm.load(filename)
if pfbname ~= "" then
data.resources.filename = resolvers.unresolve(pfbname)
get_indexes(data,pfbname)
- elseif trace_loading then
+ elseif trace_loading then
report_afm("no pfb file for %a",filename)
-- data.resources.filename = "unset" -- better than loading the afm file
end
- report_afm("unifying %a",filename)
- unify(data,filename)
- if afm.addligatures then
- report_afm("add ligatures")
- addligatures(data)
+ -- we now have all the data loaded
+ if trace_loading then
+ report_afm("unifying %a",filename)
end
- if afm.addtexligatures then
- report_afm("add tex ligatures")
- addtexligatures(data)
+ unify(data,filename)
+ if trace_loading then
+ report_afm("add ligatures") -- there can be missing ones
end
- if afm.addkerns then
+ addligatures(data)
+ if trace_loading then
report_afm("add extra kerns")
- addkerns(data)
+ end
+ addkerns(data)
+ if trace_loading then
+ report_afm("normalizing")
end
normalize(data)
+ if trace_loading then
+ report_afm("fixing names")
+ end
fixnames(data)
- report_afm("add tounicode data")
+ if trace_loading then
+ report_afm("add tounicode data")
+ end
+ -- otfreaders.addunicodetable(data) -- only when not done yet
fonts.mappings.addtounicode(data,filename)
+ -- otfreaders.extend(data)
+ otfreaders.pack(data)
data.size = size
data.time = time
data.pfbsize = pfbsize
data.pfbtime = pfbtime
report_afm("saving %a in cache",name)
- data.resources.unicodes = nil -- consistent with otf but here we save not much
+ -- data.resources.unicodes = nil -- consistent with otf but here we save not much
data = containers.write(afm.cache, name, data)
data = containers.read(afm.cache,name)
end
- if applyruntimefixes and data then
+ end
+ if data then
+ -- constructors.addcoreunicodes(unicodes)
+ otfreaders.unpack(data)
+ otfreaders.expand(data) -- inline tables
+ otfreaders.addunicodetable(data) -- only when not done yet
+ otfenhancers.apply(data,filename,data)
+ if applyruntimefixes then
applyruntimefixes(filename,data)
end
end
@@ -602,12 +538,105 @@ end
local everywhere = { ["*"] = { ["*"] = true } } -- or: { ["*"] = { "*" } }
local noflags = { false, false, false, false }
-afm.experimental_normalize = false
-
normalize = function(data)
- if type(afm.experimental_normalize) == "function" then
- afm.experimental_normalize(data)
+ local ligatures = setmetatableindex("table")
+ local kerns = setmetatableindex("table")
+ local extrakerns = setmetatableindex("table")
+ for u, c in next, data.descriptions do
+ local l = c.ligatures
+ local k = c.kerns
+ local e = c.extrakerns
+ if l then
+ ligatures[u] = l
+ for u, v in next, l do
+ l[u] = { ligature = v }
+ end
+ c.ligatures = nil
+ end
+ if k then
+ kerns[u] = k
+ for u, v in next, k do
+ k[u] = v -- { v, 0 }
+ end
+ c.kerns = nil
+ end
+ if e then
+ extrakerns[u] = e
+ for u, v in next, e do
+ e[u] = v -- { v, 0 }
+ end
+ c.extrakerns = nil
+ end
+ end
+ local features = {
+ gpos = { },
+ gsub = { },
+ }
+ local sequences = {
+ -- only filled ones
+ }
+ if next(ligatures) then
+ features.gsub.liga = everywhere
+ data.properties.hasligatures = true
+ sequences[#sequences+1] = {
+ features = {
+ liga = everywhere,
+ },
+ flags = noflags,
+ name = "s_s_0",
+ nofsteps = 1,
+ order = { "liga" },
+ type = "gsub_ligature",
+ steps = {
+ {
+ coverage = ligatures,
+ },
+ },
+ }
+ end
+ if next(kerns) then
+ features.gpos.kern = everywhere
+ data.properties.haskerns = true
+ sequences[#sequences+1] = {
+ features = {
+ kern = everywhere,
+ },
+ flags = noflags,
+ name = "p_s_0",
+ nofsteps = 1,
+ order = { "kern" },
+ type = "gpos_pair",
+ steps = {
+ {
+ format = "kern",
+ coverage = kerns,
+ },
+ },
+ }
+ end
+ if next(extrakerns) then
+ features.gpos.extrakerns = everywhere
+ data.properties.haskerns = true
+ sequences[#sequences+1] = {
+ features = {
+ extrakerns = everywhere,
+ },
+ flags = noflags,
+ name = "p_s_1",
+ nofsteps = 1,
+ order = { "extrakerns" },
+ type = "gpos_pair",
+ steps = {
+ {
+ format = "kern",
+ coverage = extrakerns,
+ },
+ },
+ }
end
+ -- todo: compress kerns
+ data.resources.features = features
+ data.resources.sequences = sequences
end
fixnames = function(data)
@@ -982,6 +1011,8 @@ local function afmtotfm(specification)
tfmdata.shared = shared
end
shared.rawdata = rawdata
+ shared.dynamics = { }
+ tfmdata.changed = { }
shared.features = features
shared.processes = afm.setfeatures(tfmdata,features)
end
@@ -1089,53 +1120,36 @@ local function texreplacements(tfmdata,value)
end
end
-local function ligatures (tfmdata,value) prepareligatures(tfmdata,'ligatures', value) end
-local function texligatures(tfmdata,value) prepareligatures(tfmdata,'texligatures',value) end
-local function kerns (tfmdata,value) preparekerns (tfmdata,'kerns', value) end
+-- local function ligatures (tfmdata,value) prepareligatures(tfmdata,'ligatures', value) end
+-- local function texligatures(tfmdata,value) prepareligatures(tfmdata,'texligatures',value) end
+-- local function kerns (tfmdata,value) preparekerns (tfmdata,'kerns', value) end
local function extrakerns (tfmdata,value) preparekerns (tfmdata,'extrakerns', value) end
-registerafmfeature {
- name = "liga",
- description = "traditional ligatures",
- initializers = {
- base = ligatures,
- node = ligatures,
- }
-}
-
-registerafmfeature {
- name = "kern",
- description = "intercharacter kerning",
- initializers = {
- base = kerns,
- node = kerns,
- }
-}
-
-registerafmfeature {
- name = "extrakerns",
- description = "additional intercharacter kerning",
- initializers = {
- base = extrakerns,
- node = extrakerns,
- }
-}
+local function setmode(tfmdata,value)
+ if value then
+ tfmdata.properties.mode = lower(value)
+ end
+end
registerafmfeature {
- name = 'tlig',
- description = 'tex ligatures',
+ name = "mode",
+ description = "mode",
initializers = {
- base = texligatures,
- node = texligatures,
+ base = setmode,
+ node = setmode,
}
}
registerafmfeature {
- name = 'trep',
- description = 'tex replacements',
+ name = "features",
+ description = "features",
+ default = true,
initializers = {
- base = texreplacements,
- node = texreplacements,
+ node = otf.nodemodeinitializer,
+ base = otf.basemodeinitializer,
+ },
+ processors = {
+ node = otf.featuresprocessor,
}
}