grph-swf.lua /size: 3337 b    last modification: 2020-07-01 14:35
1if not modules then modules = { } end modules ['grph-swf'] = {
2    version   = 1.001,
3    comment   = "companion to grph-inc.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
9-- maybe: backends.codeinjections.insertswf
10
11local sub, format, match, byte = string.sub, string.format, string.match, string.byte
12local concat = table.concat
13local floor = math.floor
14local tonumber = tonumber
15
16local readstring     = io.readstring
17local readnumber     = io.readnumber
18local tobitstring    = number.tobitstring
19local todimen        = number.todimen
20local nodeinjections = backends.nodeinjections
21local figures        = figures
22local context        = context
23
24local function getheader(name)
25    local f = io.open(name,"rb")
26    if not f then
27        return
28    end
29    local signature  = readstring(f,3) -- F=uncompressed, C=compressed (zlib)
30    local version    = readnumber(f,1)
31    local filelength = readnumber(f,-4)
32    local compressed = sub(signature,1,1) == "C"
33    local buffer
34    if compressed then
35        buffer = zlib.decompress(f:read('*a'))
36    else
37        buffer = f:read(20) -- ('*a')
38    end
39    f:close()
40    -- can be done better now that we have stream readers
41    buffer = { match(buffer,"(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)") }
42    for i=1,9 do
43        buffer[i] = tobitstring(byte(buffer[i]),8,8)
44    end
45    local framebits = concat(buffer,"",1,9)
46    local n = tonumber(sub(framebits,1,5),2)
47    local frame = { } -- xmin xmax ymin ymax
48    local xmin = tonumber(sub(framebits,6,      5 +   n),2)
49    local xmax = tonumber(sub(framebits,6 + 1*n,5 + 2*n),2)
50    local ymin = tonumber(sub(framebits,6 + 2*n,5 + 3*n),2)
51    local ymax = tonumber(sub(framebits,6 + 3*n,5 + 4*n),2)
52    return {
53        filename   = name,
54        version    = version,
55        filelength = filelength,
56        framerate  = tonumber(byte(buffer[10]) * 256 + byte(buffer[11])),
57        framecount = tonumber(byte(buffer[12]) * 256 + byte(buffer[13])),
58     -- framebits  = framebits,
59        compressed = compressed,
60        width      = floor((xmax - xmin) / 20),
61        height     = floor((ymax - ymin) / 20),
62        rectangle  = {
63            xmin = xmin,
64            xmax = xmax,
65            ymin = ymin,
66            ymax = ymax,
67        }
68    }
69end
70
71function figures.checkers.swf(data)
72    local dr, du, ds = data.request, data.used, data.status
73    local foundname = du.fullname
74    local header = getheader(foundname)
75    local width, height = figures.applyratio(dr.width,dr.height,header.width,header.height)
76    dr.width, dr.height = width, height
77    du.width, du.height, du.foundname = width, height, foundname
78    context.startfoundexternalfigure(todimen(width),todimen(height))
79        nodeinjections.insertswf {
80            foundname = foundname,
81            width     = width,
82            height    = height,
83        --  factor    = number.dimenfactors.bp,
84            display   = dr.display,
85            controls  = dr.controls,
86        --  label     = dr.label,
87            resources = dr.resources,
88            arguments = dr.arguments,
89        }
90    context.stopfoundexternalfigure()
91    return data
92end
93
94figures.includers.swf = figures.includers.nongeneric
95
96figures.registersuffix("swf","swf")
97