summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/context/base/mkiv/font-prv.lua
blob: 15057e2554ef28b99f41dae40ec9c375f5f76702 (plain)
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
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

local currentprivate    = fonts.privateoffsets.textextrabase
local maximumprivate    = currentprivate + 0xFFF

local extraprivates     = { }
helpers.extraprivates   = extraprivates

function fonts.helpers.addextraprivate(name,f)
    extraprivates[#extraprivates+1] = { name, f }
end

-- 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 sharedprivates = setmetatableindex(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

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