luatex-math.lua /size: 8934 b    last modification: 2023-12-21 09:45
1if not modules then modules = { } end modules ['luatex-math'] = {
2    version   = 1.001,
3    comment   = "companion to luatex-math.tex",
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 gaps = {
10    [0x1D455] = 0x0210E,
11    [0x1D49D] = 0x0212C,
12    [0x1D4A0] = 0x02130,
13    [0x1D4A1] = 0x02131,
14    [0x1D4A3] = 0x0210B,
15    [0x1D4A4] = 0x02110,
16    [0x1D4A7] = 0x02112,
17    [0x1D4A8] = 0x02133,
18    [0x1D4AD] = 0x0211B,
19    [0x1D4BA] = 0x0212F,
20    [0x1D4BC] = 0x0210A,
21    [0x1D4C4] = 0x02134,
22    [0x1D506] = 0x0212D,
23    [0x1D50B] = 0x0210C,
24    [0x1D50C] = 0x02111,
25    [0x1D515] = 0x0211C,
26    [0x1D51D] = 0x02128,
27    [0x1D53A] = 0x02102,
28    [0x1D53F] = 0x0210D,
29    [0x1D545] = 0x02115,
30    [0x1D547] = 0x02119,
31    [0x1D548] = 0x0211A,
32    [0x1D549] = 0x0211D,
33    [0x1D551] = 0x02124,
34}
35
36local function fixmath(tfmdata,key,value)
37    if value then
38        local characters = tfmdata.characters
39        for gap, mess in pairs(gaps) do
40            characters[gap] = characters[mess]
41        end
42    end
43end
44
45fonts.handlers.otf.features.register {
46    name         = "fixmath",
47    description  = "math font fixing",
48    manipulators = {
49        base = fixmath,
50        node = fixmath,
51    }
52}
53
54-- This emulation is experimental and work in progress. This plain support is
55-- for testing only anyway. If needed disable the feature which is there mostly
56-- for MS and HH (a side effect of their math project).
57
58local emulate = true
59
60local integrals = table.tohash { 8747, 8748, 8749, 8750, 8751, 8752, 8753, 8754,
618755, 8992, 8993, 10763, 10764, 10765, 10766, 10767, 10768, 10769, 10770, 10771,
6210772, 10773, 10774, 10775, 10776, 10777, 10778, 10779, 10780 }
63
64local italics = table.tohash { 8458, 8459, 8462, 8464, 8466, 8475, 8492, 8495,
658496, 8497, 8499, 8500, 119860, 119861, 119862, 119863, 119864, 119865, 119866,
66119867, 119868, 119869, 119870, 119871, 119872, 119873, 119874, 119875, 119876,
67119877, 119878, 119879, 119880, 119881, 119882, 119883, 119884, 119885, 119886,
68119887, 119888, 119889, 119890, 119891, 119892, 119893, 119894, 119895, 119896,
69119897, 119898, 119899, 119900, 119901, 119902, 119903, 119904, 119905, 119906,
70119907, 119908, 119909, 119910, 119911, 119912, 119913, 119914, 119915, 119916,
71119917, 119918, 119919, 119920, 119921, 119922, 119923, 119924, 119925, 119926,
72119927, 119928, 119929, 119930, 119931, 119932, 119933, 119934, 119935, 119936,
73119937, 119938, 119939, 119940, 119941, 119942, 119943, 119944, 119945, 119946,
74119947, 119948, 119949, 119950, 119951, 119952, 119953, 119954, 119955, 119956,
75119957, 119958, 119959, 119960, 119961, 119962, 119963, 119964, 119965, 119966,
76119967, 119968, 119969, 119970, 119971, 119972, 119973, 119974, 119975, 119976,
77119977, 119978, 119979, 119980, 119981, 119982, 119983, 119984, 119985, 119986,
78119987, 119988, 119989, 119990, 119991, 119992, 119993, 119994, 119995, 119996,
79119997, 119998, 119999, 120000, 120001, 120002, 120003, 120004, 120005, 120006,
80120007, 120008, 120009, 120010, 120011, 120012, 120013, 120014, 120015, 120016,
81120017, 120018, 120019, 120020, 120021, 120022, 120023, 120024, 120025, 120026,
82120027, 120028, 120029, 120030, 120031, 120032, 120033, 120034, 120035, 120036,
83120037, 120038, 120039, 120040, 120041, 120042, 120043, 120044, 120045, 120046,
84120047, 120048, 120049, 120050, 120051, 120052, 120053, 120054, 120055, 120056,
85120057, 120058, 120059, 120060, 120061, 120062, 120063, 120064, 120065, 120066,
86120067, 120328, 120329, 120330, 120331, 120332, 120333, 120334, 120335, 120336,
87120337, 120338, 120339, 120340, 120341, 120342, 120343, 120344, 120345, 120346,
88120347, 120348, 120349, 120350, 120351, 120352, 120353, 120354, 120355, 120356,
89120357, 120358, 120359, 120360, 120361, 120362, 120363, 120364, 120365, 120366,
90120367, 120368, 120369, 120370, 120371, 120372, 120373, 120374, 120375, 120376,
91120377, 120378, 120379, 120380, 120381, 120382, 120383, 120384, 120385, 120386,
92120387, 120388, 120389, 120390, 120391, 120392, 120393, 120394, 120395, 120396,
93120397, 120398, 120399, 120400, 120401, 120402, 120403, 120404, 120405, 120406,
94120407, 120408, 120409, 120410, 120411, 120412, 120413, 120414, 120415, 120416,
95120417, 120418, 120419, 120420, 120421, 120422, 120423, 120424, 120425, 120426,
96120427, 120428, 120429, 120430, 120431, 120546, 120547, 120548, 120549, 120550,
97120551, 120552, 120553, 120554, 120555, 120556, 120557, 120558, 120559, 120560,
98120561, 120562, 120563, 120564, 120565, 120566, 120567, 120568, 120569, 120570,
99120571, 120572, 120573, 120574, 120575, 120576, 120577, 120578, 120579, 120580,
100120581, 120582, 120583, 120584, 120585, 120586, 120587, 120588, 120589, 120590,
101120591, 120592, 120593, 120594, 120595, 120596, 120597, 120604, 120605, 120606,
102120607, 120608, 120609, 120610, 120611, 120612, 120613, 120614, 120615, 120616,
103120617, 120618, 120619, 120620, 120621, 120622, 120623, 120624, 120625, 120626,
104120627, 120628, 120629, 120630, 120631, 120632, 120633, 120634, 120635, 120636,
105120637, 120638, 120639, 120640, 120641, 120642, 120643, 120644, 120645, 120646,
106120647, 120648, 120649, 120650, 120651, 120652, 120653, 120654, 120655, 120720,
107120721, 120722, 120723, 120724, 120725, 120726, 120727, 120728, 120729, 120730,
108120731, 120732, 120733, 120734, 120735, 120736, 120737, 120738, 120739, 120740,
109120741, 120742, 120743, 120744, 120745, 120746, 120747, 120748, 120749, 120750,
110120751, 120752, 120753, 120754, 120755, 120756, 120757, 120758, 120759, 120760,
111120761, 120762, 120763, 120764, 120765, 120766, 120767, 120768, 120769, 120770,
112120771 }
113
114local function emulatelmtx(tfmdata,key,value)
115    if tfmdata.mathparameters and not tfmdata.emulatedlmtx then
116        tfmdata.fonts = { { id = 0 } }
117        tfmdata.type = "virtual"
118        tfmdata.properties.virtualized = true
119    end
120end
121
122fonts.handlers.otf.features.register {
123    name         = "emulate lmtx",
124    description  = "emulate lmtx mode",
125    default      = emulate,
126    manipulators = { base = emulatelmtx },
127}
128
129local function emulatelmtx(tfmdata,key,value)
130    if tfmdata.mathparameters and not tfmdata.emulatedlmtx then
131        local targetcharacters   = tfmdata.characters
132        local targetdescriptions = tfmdata.descriptions
133        local factor             = tfmdata.parameters.factor
134        local function getllx(u)
135            local d = targetdescriptions[u]
136            if d then
137                local b = d.boundingbox
138                if b then
139                    local llx = b[1]
140                    if llx < 0 then
141                        return - llx
142                    end
143                end
144            end
145            return false
146        end
147        for u, c in next, targetcharacters do
148            local uc = c.unicode or u
149            if integrals[uc] then
150                -- skip this one
151            else
152                local accent = c.top_accent
153                local italic = c.italic
154                local width  = c.width  or 0
155                local llx    = getllx(u)
156                local bl, br, tl, tr
157                if llx then
158                    llx   = llx * factor
159                    width = width + llx
160                    bl    = - llx
161                    tl    = bl
162                    c.commands = { { "right", llx }, { "slot", 0, u } }
163                    if accent then
164                        accent = accent + llx
165                    end
166                end
167                if accent then
168                    if italics[uc] then
169                        c.top_accent = accent
170                    else
171                        c.top_accent = nil
172                    end
173                end
174                if italic and italic ~= 0 then
175                    width = width + italic
176                    br    = - italic
177                end
178                c.width = width
179                if italic then
180                    c.italic = nil
181                end
182                if bl or br or tl or tr then
183                    -- watch out: singular and _ because we are post copying / scaling
184                    c.mathkern = {
185                        bottom_left  = bl and { { height = 0,             kern = bl } } or nil,
186                        bottom_right = br and { { height = 0,             kern = br } } or nil,
187                        top_left     = tl and { { height = c.height or 0, kern = tl } } or nil,
188                        top_right    = tr and { { height = c.height or 0, kern = tr } } or nil,
189                    }
190                end
191            end
192        end
193        tfmdata.fonts = { { id = 0 } }
194        tfmdata.type = "virtual"
195        tfmdata.properties.virtualized = true
196        tfmdata.emulatedlmtx = true
197    end
198end
199
200fonts.handlers.otf.features.register {
201    name         = "emulate lmtx",
202    description  = "emulate lmtx mode",
203    default      = emulate,
204    manipulators = { base = emulatelmtx },
205}
206