summaryrefslogtreecommitdiff
path: root/otfl-font-cid.lua
diff options
context:
space:
mode:
Diffstat (limited to 'otfl-font-cid.lua')
-rw-r--r--otfl-font-cid.lua100
1 files changed, 57 insertions, 43 deletions
diff --git a/otfl-font-cid.lua b/otfl-font-cid.lua
index a9bd3c5..4a4c4d2 100644
--- a/otfl-font-cid.lua
+++ b/otfl-font-cid.lua
@@ -8,18 +8,19 @@ if not modules then modules = { } end modules ['font-cid'] = {
local format, match, lower = string.format, string.match, string.lower
local tonumber = tonumber
-local lpegmatch = lpeg.match
+local P, S, R, C, V, lpegmatch = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.V, lpeg.match
-local trace_loading = false trackers.register("otf.loading", function(v) trace_loading = v end)
+local trace_loading = false trackers.register("otf.loading", function(v) trace_loading = v end)
local report_otf = logs.reporter("fonts","otf loading")
-local fonts = fonts
+local fonts = fonts
-fonts.cid = fonts.cid or { }
-local cid = fonts.cid
-cid.map = cid.map or { }
-cid.max = cid.max or 10
+local cid = { }
+fonts.cid = cid
+
+local cidmap = { }
+local cidmax = 10
-- original string parser: 0.109, lpeg parser: 0.036 seconds for Adobe-CNS1-4.cidmap
--
@@ -28,8 +29,6 @@ cid.max = cid.max or 10
-- 1..95 0020
-- 99 3000
-local P, S, R, C = lpeg.P, lpeg.S, lpeg.R, lpeg.C
-
local number = C(R("09","af","AF")^1)
local space = S(" \n\r\t")
local spaces = space^0
@@ -37,7 +36,7 @@ local period = P(".")
local periods = period * period
local name = P("/") * C((1-space)^1)
-local unicodes, names = { }, { }
+local unicodes, names = { }, { } -- we could use Carg now
local function do_one(a,b)
unicodes[tonumber(a)] = tonumber(b,16)
@@ -55,15 +54,15 @@ local function do_name(a,b)
names[tonumber(a)] = b
end
-local grammar = lpeg.P { "start",
- start = number * spaces * number * lpeg.V("series"),
- series = (spaces * (lpeg.V("one") + lpeg.V("range") + lpeg.V("named")) )^1,
+local grammar = P { "start",
+ start = number * spaces * number * V("series"),
+ series = (spaces * (V("one") + V("range") + V("named")))^1,
one = (number * spaces * number) / do_one,
range = (number * periods * number * spaces * number) / do_range,
named = (number * spaces * name) / do_name
}
-function cid.load(filename)
+local function loadcidfile(filename)
local data = io.loaddata(filename)
if data then
unicodes, names = { }, { }
@@ -77,75 +76,90 @@ function cid.load(filename)
unicodes = unicodes,
names = names
}
- else
- return nil
end
end
+cid.loadfile = loadcidfile -- we use the frozen variant
+
local template = "%s-%s-%s.cidmap"
local function locate(registry,ordering,supplement)
local filename = format(template,registry,ordering,supplement)
local hashname = lower(filename)
- local cidmap = cid.map[hashname]
- if not cidmap then
+ local found = cidmap[hashname]
+ if not found then
if trace_loading then
report_otf("checking cidmap, registry: %s, ordering: %s, supplement: %s, filename: %s",registry,ordering,supplement,filename)
end
local fullname = resolvers.findfile(filename,'cid') or ""
if fullname ~= "" then
- cidmap = cid.load(fullname)
- if cidmap then
+ found = loadcidfile(fullname)
+ if found then
if trace_loading then
report_otf("using cidmap file %s",filename)
end
- cid.map[hashname] = cidmap
- cidmap.usedname = file.basename(filename)
- return cidmap
+ cidmap[hashname] = found
+ found.usedname = file.basename(filename)
end
end
end
- return cidmap
+ return found
end
-function cid.getmap(registry,ordering,supplement)
- -- cf Arthur R. we can safely scan upwards since cids are downward compatible
- local supplement = tonumber(supplement)
+-- cf Arthur R. we can safely scan upwards since cids are downward compatible
+
+function cid.getmap(specification)
+ if not specification then
+ report_otf("invalid cidinfo specification (table expected)")
+ return
+ end
+ local registry = specification.registry
+ local ordering = specification.ordering
+ local supplement = specification.supplement
+ -- check for already loaded file
+ local filename = format(registry,ordering,supplement)
+ local found = cidmap[lower(filename)]
+ if found then
+ return found
+ end
if trace_loading then
report_otf("needed cidmap, registry: %s, ordering: %s, supplement: %s",registry,ordering,supplement)
end
- local cidmap = locate(registry,ordering,supplement)
- if not cidmap then
+ found = locate(registry,ordering,supplement)
+ if not found then
+ local supnum = tonumber(supplement)
local cidnum = nil
-- next highest (alternatively we could start high)
- if supplement < cid.max then
- for supplement=supplement+1,cid.max do
- local c = locate(registry,ordering,supplement)
+ if supnum < cidmax then
+ for s=supnum+1,cidmax do
+ local c = locate(registry,ordering,s)
if c then
- cidmap, cidnum = c, supplement
+ found, cidnum = c, s
break
end
end
end
-- next lowest (least worse fit)
- if not cidmap and supplement > 0 then
- for supplement=supplement-1,0,-1 do
- local c = locate(registry,ordering,supplement)
+ if not found and supnum > 0 then
+ for s=supnum-1,0,-1 do
+ local c = locate(registry,ordering,s)
if c then
- cidmap, cidnum = c, supplement
+ found, cidnum = c, s
break
end
end
end
- -- prevent further lookups
- if cidmap and cidnum > 0 then
+ -- prevent further lookups -- somewhat tricky
+ registry = lower(registry)
+ ordering = lower(ordering)
+ if found and cidnum > 0 then
for s=0,cidnum-1 do
- filename = format(template,registry,ordering,s)
- if not cid.map[filename] then
- cid.map[filename] = cidmap -- copy of ref
+ local filename = format(template,registry,ordering,s)
+ if not cidmap[filename] then
+ cidmap[filename] = found
end
end
end
end
- return cidmap
+ return found
end