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