font-cid.lua /size: 5502 b    last modification: 2020-07-01 14:35
1
if
not
modules
then
modules
=
{
}
end
modules
[
'
font-cid
'
]
=
{
2
version
=
1
.
001
,
3
comment
=
"
companion to font-ini.mkiv
"
,
4
author
=
"
Hans Hagen, PRAGMA-ADE, Hasselt NL
"
,
5
copyright
=
"
PRAGMA ADE / ConTeXt Development Team
"
,
6
license
=
"
see context related readme files
"
7
}
8 9
local
format
,
match
,
lower
=
string
.
format
,
string
.
match
,
string
.
lower
10
local
tonumber
=
tonumber
11
local
P
,
S
,
R
,
C
,
V
,
lpegmatch
=
lpeg
.
P
,
lpeg
.
S
,
lpeg
.
R
,
lpeg
.
C
,
lpeg
.
V
,
lpeg
.
match
12 13
local
fonts
,
logs
,
trackers
=
fonts
,
logs
,
trackers
14 15
local
trace_loading
=
false
trackers
.
register
(
"
otf.loading
"
,
function
(
v
)
trace_loading
=
v
end
)
16 17
local
report_otf
=
logs
.
reporter
(
"
fonts
"
,
"
otf loading
"
)
18 19
local
cid
=
{
}
20
fonts
.
cid
=
cid
21 22
local
cidmap
=
{
}
23
local
cidmax
=
10
24 25
-- original string parser: 0.109, lpeg parser: 0.036 seconds for Adobe-CNS1-4.cidmap
26
--
27
-- 18964 18964 (leader)
28
-- 0 /.notdef
29
-- 1..95 0020
30
-- 99 3000
31 32
local
number
=
C
(
R
(
"
09
"
,
"
af
"
,
"
AF
"
)
^
1
)
33
local
space
=
S
(
"
\n\r\t
"
)
34
local
spaces
=
space
^
0
35
local
period
=
P
(
"
.
"
)
36
local
periods
=
period
*
period
37
local
name
=
P
(
"
/
"
)
*
C
(
(
1
-
space
)
^
1
)
38 39
local
unicodes
,
names
=
{
}
,
{
}
-- we could use Carg now
40 41
local
function
do_one
(
a
,
b
)
42
unicodes
[
tonumber
(
a
)
]
=
tonumber
(
b
,
16
)
43
end
44 45
local
function
do_range
(
a
,
b
,
c
)
46
c
=
tonumber
(
c
,
16
)
47
for
i
=
tonumber
(
a
)
,
tonumber
(
b
)
do
48
unicodes
[
i
]
=
c
49
c
=
c
+
1
50
end
51
end
52 53
local
function
do_name
(
a
,
b
)
54
names
[
tonumber
(
a
)
]
=
b
55
end
56 57
local
grammar
=
P
{
"
start
"
,
58
start
=
number
*
spaces
*
number
*
V
(
"
series
"
)
,
59
series
=
(
spaces
*
(
V
(
"
one
"
)
+
V
(
"
range
"
)
+
V
(
"
named
"
)
)
)
^
1
,
60
one
=
(
number
*
spaces
*
number
)
/
do_one
,
61
range
=
(
number
*
periods
*
number
*
spaces
*
number
)
/
do_range
,
62
named
=
(
number
*
spaces
*
name
)
/
do_name
63
}
64 65
local
function
loadcidfile
(
filename
)
66
local
data
=
io
.
loaddata
(
filename
)
67
if
data
then
68
unicodes
,
names
=
{
}
,
{
}
69
lpegmatch
(
grammar
,
data
)
70
local
supplement
,
registry
,
ordering
=
match
(
filename
,
"
^(.-)%-(.-)%-()%.(.-)$
"
)
71
return
{
72
supplement
=
supplement
,
73
registry
=
registry
,
74
ordering
=
ordering
,
75
filename
=
filename
,
76
unicodes
=
unicodes
,
77
names
=
names
,
78
}
79
end
80
end
81 82
cid
.
loadfile
=
loadcidfile
-- we use the frozen variant
83
local
template
=
"
%s-%s-%s.cidmap
"
84 85
local
function
locate
(
registry
,
ordering
,
supplement
)
86
local
filename
=
format
(
template
,
registry
,
ordering
,
supplement
)
87
local
hashname
=
lower
(
filename
)
88
local
found
=
cidmap
[
hashname
]
89
if
not
found
then
90
if
trace_loading
then
91
report_otf
(
"
checking cidmap, registry %a, ordering %a, supplement %a, filename %a
"
,
registry
,
ordering
,
supplement
,
filename
)
92
end
93
local
fullname
=
resolvers
.
findfile
(
filename
,
'
cid
'
)
or
"
"
94
if
fullname
~
=
"
"
then
95
found
=
loadcidfile
(
fullname
)
96
if
found
then
97
if
trace_loading
then
98
report_otf
(
"
using cidmap file %a
"
,
filename
)
99
end
100
cidmap
[
hashname
]
=
found
101
found
.
usedname
=
file
.
basename
(
filename
)
102
end
103
end
104
end
105
return
found
106
end
107 108
-- cf Arthur R. we can safely scan upwards since cids are downward compatible
109 110
function
cid
.
getmap
(
specification
)
111
if
not
specification
then
112
report_otf
(
"
invalid cidinfo specification, table expected
"
)
113
return
114
end
115
local
registry
=
specification
.
registry
116
local
ordering
=
specification
.
ordering
117
local
supplement
=
specification
.
supplement
118
local
filename
=
format
(
registry
,
ordering
,
supplement
)
119
local
lowername
=
lower
(
filename
)
120
local
found
=
cidmap
[
lowername
]
121
if
found
then
122
return
found
123
end
124
if
ordering
=
=
"
Identity
"
then
125
local
found
=
{
126
supplement
=
supplement
,
127
registry
=
registry
,
128
ordering
=
ordering
,
129
filename
=
filename
,
130
unicodes
=
{
}
,
131
names
=
{
}
,
132
}
133
cidmap
[
lowername
]
=
found
134
return
found
135
end
136
-- check for already loaded file
137
if
trace_loading
then
138
report_otf
(
"
cidmap needed, registry %a, ordering %a, supplement %a
"
,
registry
,
ordering
,
supplement
)
139
end
140
found
=
locate
(
registry
,
ordering
,
supplement
)
141
if
not
found
then
142
local
supnum
=
tonumber
(
supplement
)
143
local
cidnum
=
nil
144
-- next highest (alternatively we could start high)
145
if
supnum
<
cidmax
then
146
for
s
=
supnum
+
1
,
cidmax
do
147
local
c
=
locate
(
registry
,
ordering
,
s
)
148
if
c
then
149
found
,
cidnum
=
c
,
s
150
break
151
end
152
end
153
end
154
-- next lowest (least worse fit)
155
if
not
found
and
supnum
>
0
then
156
for
s
=
supnum
-1
,
0
,
-1
do
157
local
c
=
locate
(
registry
,
ordering
,
s
)
158
if
c
then
159
found
,
cidnum
=
c
,
s
160
break
161
end
162
end
163
end
164
-- prevent further lookups -- somewhat tricky
165
registry
=
lower
(
registry
)
166
ordering
=
lower
(
ordering
)
167
if
found
and
cidnum
>
0
then
168
for
s
=
0
,
cidnum
-1
do
169
local
filename
=
format
(
template
,
registry
,
ordering
,
s
)
170
if
not
cidmap
[
filename
]
then
171
cidmap
[
filename
]
=
found
172
end
173
end
174
end
175
end
176
return
found
177
end
178