summaryrefslogtreecommitdiff
path: root/tex/context/base/mkxl/math-fnt.lmt
blob: d829c342ef5e4d3ca52be6772cb92229f71f86d7 (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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
if not modules then modules = { } end modules ['math-fnt'] = {
    version   = 1.001,
    comment   = "companion to math-ini.mkiv",
    author    = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
    copyright = "PRAGMA ADE / ConTeXt Development Team",
    license   = "see context related readme files"
}

-- It is a pitty that we don't have a unicode character that can be used but that never
-- gets copied when we cut and paste. Not all pdf viewers ignore 0xFFFD for instance.

local round = math.round
local setmetatableindex = table.setmetatableindex

local nuts          = nodes.nuts
local tonut         = nodes.tonut
local tonode        = nodes.tonode
local nodepool      = nuts.pool

local vlist_code    = nodes.nodecodes.vlist

local new_hlist     = nodepool.hlist
local new_vlist     = nodepool.vlist
----- new_glyph     = nodepool.glyph
local new_glyph     = nuts.newmathglyph

local getattrlst    = nuts.getattributelist
local setattrlst    = nuts.setattributelist
local setwhd        = nuts.setwhd
local getwhd        = nuts.getwhd
local getid         = nuts.getid

local chardata      = fonts.hashes.characters
local addcharacters = font.addcharacters

-- not yet ok for compact fonts .. needs checking .. or just make this non-compact only
-- there's also an inaccuracy creeping in: \sqrt{\quad\blackrule[height=25pt,depth=25pt]}

local cache = setmetatableindex(function(t,width)
    local v = setmetatableindex(function(t,height)
        local v = setmetatableindex(function(t,depth)
            local v = setmetatableindex(function(t,font)
                local v = setmetatableindex(function(t,char)
                    t[char] = v
                    return v
                end)
                t[font] = v
                return v
            end)
            t[depth] = v
            return v
        end)
        t[height] = v
        return v
    end)
    t[width] = v
    return v
end)

local enabled = "vertical"  directives.register("math.extensibles", function(v) enabled = v end) -- default per 2022-08-25

local function register_extensible(font,char,style,box)
    if enabled then
        -- We don't share (yet)!
        local fontdata = chardata[font]
        local oldchar  = fontdata[char]
        if oldchar and not oldchar.keepvirtual then
            if enabled == true or enabled == "both" or oldchar.partsorientation == enabled then
                -- we're okay
            else
                return
            end
            local bx = tonut(box)
            -- actually we don't want colors and such so if we do finalize we
            -- should be more selctive:
    --         updaters.apply("tagging.state.disable")
    --         nodes.handlers.finalizelist(bx)
    --         updaters.apply("tagging.state.enable")
            local id = getid(bx)
            local al = getattrlst(bx)
            local wd, ht, dp = getwhd(bx)
            local unicode = oldchar.unicode or char
            -- we cannot have self referencing t3 fonts .. see devirtualize code
            local oldcommands = oldchar.oldcommands
            local newcommands = oldchar.commands
            if oldcommands then
                oldchar.commands = oldcommands
            end
            --
            local p  = fonts.hashes.parameters[font]
            local sx = round(1000/p.extendfactor)
            local sy = round(1000/p.squeezefactor)
            -- we saved a scaled glyph stream so we now use an unscaled one ... horrible hack:
            if sx ~= 1000 then
                wd = wd * 7200/7227
            end
            if sy ~= 1000 then
                ht = ht * 7200/7227
                dp = dp * 7200/7227
            end
            --
        --  local private = fonts.helpers.setboxdirectly(font,unicode,box)
            local private = cache[wd][ht][dp][font][unicode]
            if not private then
                private = fonts.helpers.setboxdirectly(font,unicode,box)
                cache[wd][ht][dp][font][unicode] = private
            end
            local glyph = new_glyph(font,private,al)
            nuts.setscales(glyph,1000,sx,sy)
            --
         -- if fonts.hashes.properties[font].compactmath then
         --     nuts.setscales(g,1000,1000,1000)
         -- end
            --
            -- nasty, testcase: bold math sqrt extensible
            --
            local n = new_hlist(glyph)
            --
            if newcommands then
                oldchar.commands = newcommands
            end
            --
         -- local newchar = {
         --     unicode = unicode,
         --     width   = wd,
         --     height  = ht,
         --     depth  =  dp,
         -- }
         -- local p = oldchar.parts
         -- if p then
         --     local first = fontdata[p[#p].glyph]
         --     local last  = fontdata[p[ 1].glyph]
         --     if first then
         --         newchar.topleft  = first.topleft
         --         newchar.topright = first.topright
         --     end
         --     if last then
         --         newchar.bottomleft  = last.bottomleft
         --         newchar.bottomright = last.bottomright
         --     end
         -- end
         -- addcharacters(font, { [private] = newchar })
            -- so the dimensions of the box don't match the glyph scale!
            setwhd(n,wd,ht,dp)
            setattrlst(n,al)
            if id == vlist_code then
                n = new_vlist(n)
                setwhd(n,wd,ht,dp)
                setattrlst(n,al)
            end
            return tonode(n)
        end
    end
end

callbacks.register("register_extensible",register_extensible,"register math extensible construct")