1if 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
9local format , match , lower = string . format , string . match , string . lower
10local tonumber = tonumber
11local P , S , R , C , V , lpegmatch = lpeg . P , lpeg . S , lpeg . R , lpeg . C , lpeg . V , lpeg . match
12
13local fonts , logs , trackers = fonts , logs , trackers
14
15local trace_loading = false trackers . register ( " otf.loading " , function ( v ) trace_loading = v end )
16
17local report_otf = logs . reporter ( " fonts " , " otf loading " )
18
19local cid = { }
20fonts . cid = cid
21
22local cidmap = { }
23local cidmax = 10
24
25
26
27
28
29
30
31
32local number = C ( R ( " 09 " , " af " , " AF " ) ^ 1 )
33local space = S ( " \n\r\t " )
34local spaces = space ^ 0
35local period = P ( " . " )
36local periods = period * period
37local name = P ( " / " ) * C ( ( 1 - space ) ^ 1 )
38
39local unicodes , names = { } , { }
40
41local function do_one ( a , b )
42 unicodes [ tonumber ( a ) ] = tonumber ( b , 16 )
43end
44
45local 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
51end
52
53local function do_name ( a , b )
54 names [ tonumber ( a ) ] = b
55end
56
57local 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
65local 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
80end
81
82cid . loadfile = loadcidfile
83local template = " %s-%s-%s.cidmap "
84
85local 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
106end
107
108
109
110function 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
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
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
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
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
177end
178 |