summaryrefslogtreecommitdiff
path: root/tex/context/base/mkiv/font-prv.lua
blob: 59b793444d882d0acaf3c9bd1766ede654e458c9 (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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
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)

fonts.helpers.sharedprivates = sharedprivates

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