font-imp-tracing.lua /size: 4612 b    last modification: 2021-10-28 13:50
1if not modules then modules = { } end modules ['font-imp-tracing'] = {
2    version   = 1.001,
3    comment   = "companion to font-ini.mkiv and hand-ini.mkiv",
4    author    = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
5    copyright = "PRAGMA ADE / ConTeXt Development Team",
6    license   = "see context related readme files"
7}
8
9if not context then return end
10
11local next, type = next, type
12local concat = table.concat
13local formatters = string.formatters
14
15local fonts              = fonts
16
17local handlers           = fonts.handlers
18local registerotffeature = handlers.otf.features.register
19local registerafmfeature = handlers.afm.features.register
20
21local settings_to_array  = utilities.parsers.settings_to_array
22local setmetatableindex  = table.setmetatableindex
23
24local helpers            = fonts.helpers
25local appendcommandtable = helpers.appendcommandtable
26local prependcommands    = helpers.prependcommands
27local charcommand        = helpers.commands.char
28
29local variables          = interfaces.variables
30
31local v_background       = variables.background
32local v_frame            = variables.frame
33local v_empty            = variables.empty
34local v_none             = variables.none
35
36-- for zhichu chen (see mailing list archive): we might add a few more variants
37-- in due time
38--
39-- \definefontfeature[boxed][default][boundingbox=yes] % paleblue
40--
41-- maybe:
42--
43-- \definecolor[DummyColor][s=.75,t=.5,a=1] {\DummyColor test} \nopdfcompression
44--
45-- local gray  = { "pdf", "origin", "/Tr1 gs .75 g" }
46-- local black = { "pdf", "origin", "/Tr0 gs 0 g" }
47
48-- boundingbox={yes|background|frame|empty|<color>}
49
50local backgrounds = nil
51local outlines    = nil
52local startcolor  = nil
53local stopcolor   = nil
54
55local function initialize(tfmdata,key,value)
56    if value then
57        if not backgrounds then
58            local vfspecials = backends.pdf.tables.vfspecials
59            startcolor  = vfspecials.startcolor
60            stopcolor   = vfspecials.stopcolor
61            backgrounds = vfspecials.backgrounds
62            outlines    = vfspecials.outlines
63        end
64        local characters = tfmdata.characters
65        local rulecache  = backgrounds
66        local showchar   = true
67        local color      = "palegray"
68        if type(value) == "string" then
69            value = settings_to_array(value)
70            for i=1,#value do
71                local v = value[i]
72                if v == v_frame then
73                    rulecache = outlines
74                elseif v == v_background then
75                    rulecache = backgrounds
76                elseif v == v_empty then
77                    showchar = false
78                elseif v == v_none then
79                    color = nil
80                else
81                    color = v
82                end
83            end
84        end
85        local gray  = color and startcolor(color) or nil
86        local black = gray and stopcolor or nil
87        for unicode, character in next, characters do
88            local width  = character.width  or 0
89            local height = character.height or 0
90            local depth  = character.depth  or 0
91            local rule   = rulecache[height][depth][width]
92            if showchar then
93                local commands = character.commands
94                if commands then
95                    if gray then
96                        character.commands = prependcommands (
97                            commands, gray, rule, black
98                        )
99                    else
100                        character.commands = prependcommands (
101                            commands, rule
102                        )
103                    end
104                else
105                    local char = charcommand[unicode]
106                    if gray then
107                        character.commands = {
108                            gray, rule, black, char
109                        }
110                     else
111                        character.commands = {
112                            rule, char
113                        }
114                    end
115                end
116            else
117                if gray then
118                    character.commands = {
119                        gray, rule, black
120                    }
121                else
122                    character.commands = {
123                        rule
124                    }
125                end
126            end
127        end
128    end
129end
130
131local specification = {
132    name        = "boundingbox",
133    description = "show boundingbox",
134    manipulators = {
135        base = initialize,
136        node = initialize,
137    }
138}
139
140registerotffeature(specification)
141registerafmfeature(specification)
142