1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
if not modules then modules = { } end modules ['font-prv'] = {
version = 1.001,
comment = "companion to font-ini.mkiv and hand-ini.mkiv",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
copyright = "PRAGMA ADE / ConTeXt Development Team",
license = "see context related readme files"
}
local type, rawget = type, rawget
local formatters = string.formatters
local fonts = fonts
local helpers = fonts.helpers
local fontdata = fonts.hashes.identifiers
local setmetatableindex = table.setmetatableindex
-- if we run out of space we can think of another range but by sharing we can
-- use these privates for mechanisms like alignments-on-character and such
local currentprivate = fonts.privateoffsets.textextrabase
local maximumprivate = currentprivate + 0xFFF
local extraprivates = utilities.storage.allocate()
local sharedprivates = utilities.storage.allocate()
helpers.extraprivates = extraprivates
helpers.sharedprivates = sharedprivates
function fonts.helpers.addextraprivate(name,f)
extraprivates[#extraprivates+1] = { name, f }
end
setmetatableindex(sharedprivates,function(t,k)
local v = currentprivate
if currentprivate < maximumprivate then
currentprivate = currentprivate + 1
else
-- reuse last slot, todo: warning
end
t[k] = v
return v
end)
function helpers.addprivate(tfmdata,name,characterdata)
local properties = tfmdata.properties
local characters = tfmdata.characters
local privates = properties.privates
if not privates then
privates = { }
properties.privates = privates
end
if not name then
name = formatters["anonymous_private_0x%05X"](currentprivate)
end
local usedprivate = sharedprivates[name]
privates[name] = usedprivate
characters[usedprivate] = characterdata
return usedprivate
end
function helpers.getprivates(tfmdata)
if type(tfmdata) == "number" then
tfmdata = fontdata[tfmdata]
end
local properties = tfmdata.properties
return properties and properties.privates
end
function helpers.hasprivate(tfmdata,name)
if type(tfmdata) == "number" then
tfmdata = fontdata[tfmdata]
end
local properties = tfmdata.properties
local privates = properties and properties.privates
return privates and privates[name] or false
end
function helpers.privateslot(name)
return rawget(sharedprivates,name)
end
function helpers.newprivateslot(name)
return sharedprivates[name]
end
function helpers.isprivate(unicode)
if unicode < 0xD7FF or (unicode > 0xDFFF and unicode <= 0xFFFF) then
return false
elseif unicode >= 0x00E000 and unicode <= 0x00F8FF then
return true
elseif unicode >= 0x0F0000 and unicode <= 0x0FFFFF then
return true
elseif unicode >= 0x100000 and unicode <= 0x10FFFF then
return true
elseif unicode >= 0x00D800 and unicode <= 0x00DFFF then
return true
else
return false
end
end
do
local context = context
local utfchar = utf.char
interfaces.implement {
name = "privatecharacter",
public = true,
-- protected = true,
arguments = "string",
actions = function(name)
local c = sharedprivates[name]
if c then
context(utfchar(c))
end
end
}
interfaces.implement {
name = "privatecharactercode",
public = true,
-- protected = true,
arguments = "string",
actions = function(name)
local c = sharedprivates[name]
if c then
context(c) -- serialized, not a number
end
end
}
end
|