back-trf.lua /size: 4842 b    last modification: 2020-07-01 14:35
1if not modules then modules = { } end modules ['back-trf'] = {
2    version   = 1.001,
3    comment   = "companion to back-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
9local sind, cosd, abs = math.sind, math.cosd, math.abs
10local insert, remove = table.insert, table.remove
11local unpack = unpack
12
13local context           = context
14
15local formatters        = string.formatters
16
17local scanners          = tokens.scanners
18local scankeyword       = scanners.keyword
19local scaninteger       = scanners.integer
20local scannumber        = scanners.number
21local scanstring        = scanners.string
22
23local implement         = interfaces.implement
24
25local nodepool          = nodes.pool
26local savenode          = nodepool.save
27local restorenode       = nodepool.restore
28local setmatrixnode     = nodepool.setmatrix
29local literalnode       = nodepool.literal -- has to become some nodeinjection
30
31local stack             = { }
32local restore           = true -- false
33
34updaters.register("backend.update",function()
35    savenode      = nodepool.save
36    restorenode   = nodepool.restore
37    setmatrixnode = nodepool.setmatrix
38    literalnode   = nodepool.literal -- has to become some nodeinjection
39end)
40
41local function stopsomething()
42    local top = remove(stack)
43    if top == false then
44        -- not wrapped
45    elseif top == true then
46        context(restorenode())
47    elseif top then
48        context(setmatrixnode(unpack(top))) -- not really needed anymore
49        context(restorenode())
50    else
51        -- nesting error
52    end
53end
54
55local function startrotation()
56    local a = scannumber()
57    if a == 0 then
58        insert(stack,false)
59    else
60        local s, c = sind(a), cosd(a)
61        if abs(s) < 0.000001 then
62            s = 0 -- otherwise funny -0.00000
63        end
64        if abs(c) < 0.000001 then
65            c = 0 -- otherwise funny -0.00000
66        end
67        context(savenode())
68        context(setmatrixnode(c,s,-s,c))
69        insert(stack,restore and { c, -s, s, c } or true)
70    end
71end
72
73implement { name = "startrotation", actions = startrotation }
74implement { name = "stoprotation",  actions = stopsomething }
75
76local function startscaling() -- at the tex end we use sx and sy instead of rx and ry
77    local rx, ry = 1, 1
78    while true do
79        if scankeyword("rx") then
80            rx = scannumber()
81        elseif scankeyword("ry") then
82            ry = scannumber()
83     -- elseif scankeyword("revert") then
84     --     local top = stack[#stack]
85     --     if top then
86     --         rx = top[1]
87     --         ry = top[4]
88     --     else
89     --         rx = 1
90     --         ry = 1
91     --     end
92        else
93            break
94        end
95    end
96    if rx == 1 and ry == 1 then
97        insert(stack,false)
98    else
99        if rx == 0 then
100            rx = 0.0001
101        end
102        if ry == 0 then
103            ry = 0.0001
104        end
105        context(savenode())
106        context(setmatrixnode(rx,0,0,ry))
107        insert(stack,restore and { 1/rx, 0, 0, 1/ry } or true)
108    end
109end
110
111implement { name = "startscaling", actions = startscaling }
112implement { name = "stopscaling",  actions = stopsomething }
113
114local function startmatrix() -- rx sx sy ry  -- tx, ty
115    local rx, sx, sy, ry = 1, 0, 0, 1
116    while true do
117            if scankeyword("rx") then rx = scannumber()
118        elseif scankeyword("ry") then ry = scannumber()
119        elseif scankeyword("sx") then sx = scannumber()
120        elseif scankeyword("sy") then sy = scannumber()
121        else   break end
122    end
123    if rx == 1 and sx == 0 and sy == 0 and ry == 1 then
124        insert(stack,false)
125    else
126        context(savenode())
127        context(setmatrixnode(rx,sx,sy,ry))
128        insert(stack,store and { -rx, -sx, -sy, -ry } or true)
129    end
130end
131
132implement { name = "startmatrix", actions = startmatrix }
133implement { name = "stopmatrix",  actions = stopsomething }
134
135local function startmirroring()
136    context(setmatrixnode(-1,0,0,1))
137end
138
139implement { name = "startmirroring", actions = startmirroring }
140implement { name = "stopmirroring",  actions = startmirroring } -- not: stopsomething
141
142-- this could also run on top of pack-rul ... todo
143
144-- local function startclipping()
145--  -- context(savenode())
146--     context(literalnode("origin",formatters["q 0 w %s W n"](scanstring())))
147-- end
148--
149-- local function stopclipping()
150--  -- context(restorenode())
151--     context(literalnode("Q"))
152-- end
153
154local function startclipping()
155    context(savenode())
156    context(literalnode("origin",formatters["0 w %s W n"](scanstring())))
157end
158
159local function stopclipping()
160    context(restorenode())
161end
162
163implement { name = "startclipping", actions = startclipping }
164implement { name = "stopclipping",  actions = stopclipping }
165