summaryrefslogtreecommitdiff
path: root/tex/context/base/font-pat.lua
blob: b6531abb93a08925a677453f39a69a534f325267 (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
if not modules then modules = { } end modules ['font-pat'] = {
    version   = 1.001,
    comment   = "companion to font-ini.mkiv",
    author    = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
    copyright = "PRAGMA ADE / ConTeXt Development Team",
    license   = "see context related readme files"
}

local match, lower, find = string.match, string.lower, string.find

local trace_loading = false  trackers.register("otf.loading", function(v) trace_loading = v end)

local report_otf = logs.new("load otf")

-- this will become a per font patch file
--
-- older versions of latin modern didn't have the designsize set
-- so for them we get it from the name

local patches = fonts.otf.enhancers.patches

local function patch(data,filename)
    if data.design_size == 0 then
        local ds = match(file.basename(lower(filename)),"(%d+)")
        if ds then
            if trace_loading then
                report_otf("patching design size (%s)",ds)
            end
            data.design_size = tonumber(ds) * 10
        end
    end
    local uni_to_ind = data.map.map
    if not uni_to_ind[0x391] then
        -- beware, this is a hack, features for latin often don't apply to greek
        -- but lm has not much features anyway (and only greek for math)
        if trace_loading then
            report_otf("adding 13 greek capitals")
        end
        uni_to_ind[0x391] = uni_to_ind[0x41]
        uni_to_ind[0x392] = uni_to_ind[0x42]
        uni_to_ind[0x395] = uni_to_ind[0x45]
        uni_to_ind[0x397] = uni_to_ind[0x48]
        uni_to_ind[0x399] = uni_to_ind[0x49]
        uni_to_ind[0x39A] = uni_to_ind[0x4B]
        uni_to_ind[0x39C] = uni_to_ind[0x4D]
        uni_to_ind[0x39D] = uni_to_ind[0x4E]
        uni_to_ind[0x39F] = uni_to_ind[0x4F]
        uni_to_ind[0x3A1] = uni_to_ind[0x52]
        uni_to_ind[0x3A4] = uni_to_ind[0x54]
        uni_to_ind[0x3A7] = uni_to_ind[0x58]
        uni_to_ind[0x396] = uni_to_ind[0x5A]
    end
    -- better make this into a feature
    --
    -- local glyphs = data.glyphs
    -- for i=0x300,0x36F do
    --     local c = glyphs[uni_to_ind[i]]
    --     if c and c.width == 0 then
    --         local boundingbox = c.boundingbox
    --         c.width = boundingbox[3] - boundingbox[1]
    --     end
    -- end
end

patches["^lmroman"]      = patch
patches["^lmsans"]       = patch
patches["^lmtypewriter"] = patch

-- for some reason (either it's a bug in the font, or it's
-- a problem in the library) the palatino arabic fonts don't
-- have the mkmk features properly set up

local function patch(data,filename)
    local gpos = data.gpos
    if gpos then
        for k=1,#gpos do
            local v = gpos[k]
            if not v.features and v.type == "gpos_mark2mark" then
                if trace_loading then
                    report_otf("patching mkmk feature (name: %s)", v.name or "?")
                end
                v.features = {
                    {
                        scripts = {
                            {
                                langs = { "ARA ", "FAR ", "URD ", "dflt" },
                                script = "arab",
                            },
                        },
                        tag = "mkmk"
                    }
                }
            end
        end
    end
end

patches["palatino.*arabic"] = patch

local function patch_domh(data,filename,threshold)
    local m = data.math
    if m then
        local d = m.DisplayOperatorMinHeight or 0
        if d < threshold then
            if trace_loading then
                report_otf("patching DisplayOperatorMinHeight(%s -> %s)",d,threshold)
            end
            m.DisplayOperatorMinHeight = threshold
        end
     end
     if tex.luatexversion < 48 then
        for _, g in next, data.glyphs do
           local name = g.name
           if find(name,"^integral$") or find(name,"^integral%.vsize") then
              local width, italic = g.width or 0, g.italic_correction or 0
              local newwidth = width - italic
              if trace_loading then
                 report_otf("patching width of %s: %s (width) - %s (italic) = %s",name,width,italic,newwidth)
              end
              g.width = newwidth
           end
        end
     end
end

patches["cambria"]  = function(data,filename) patch_domh(data,filename,2800) end
patches["cambmath"] = function(data,filename) patch_domh(data,filename,2800) end
patches["asana"]    = function(data,filename) patch_domh(data,filename,1350) end