1function tostr(t)
2    local str = ""
3    for k, v in next, t do
4        if #str > 0 then
5            str = str .. ", "
6        end
7        if type(k) == "number" then
8            str = str .. "[" .. k .. "] = "
9        else
10            str = str .. tostring(k) .. " = "
11        end
12        if type(v) == "table" then
13            str = str .. "{ " .. tostr(v) .. " }"
14        else
15            str = str .. tostring(v)
16        end
17    end
18    return str
19end
20
21local canvas        -- holds the current canvas (from startcanvas())
22
23--[[
24    startcanvas() is called at the start of each picture file, passing the
25    canvas that we will be drawing into, and the name of the file.
26    
27    Following this call, there will be some number of calls to accumulate(t)
28    where t is a table of parameters that were passed to that draw-op.
29    
30        t.verb is a string holding the name of the draw-op (e.g. "drawRect")
31    
32    when a given picture is done, we call endcanvas(canvas, fileName)
33]]
34function sk_scrape_startcanvas(c, fileName)
35    canvas = c
36end
37
38--[[
39    Called when the current canvas is done drawing.
40]]
41function sk_scrape_endcanvas(c, fileName)
42    canvas = nil
43end
44
45--[[
46    Called with the parameters to each canvas.draw call, where canvas is the
47    current canvas as set by startcanvas()
48]]
49
50function round(x, mul)
51    mul = mul or 1
52    return math.floor(x * mul + 0.5) / mul
53end
54
55dump_glyph_array_p = false
56
57function dump_array_as_C(array)
58    for k, v in next, array do
59        io.write(tostring(v), ", ");
60    end
61    io.write("-1,\n")
62end
63
64local strikes = {}  -- [fontID_pointsize] = [] unique glyphs
65
66function make_strike_key(paint)
67    return paint:getFontID() * 1000 + paint:getTextSize()
68end
69
70-- array is an array of bools (true), using glyphID as the index
71-- other is just an array[1...N] of numbers (glyphIDs)
72function array_union(array, other)
73    for k, v in next, other do
74        array[v] = true;
75    end
76end
77
78-- take a table of bools, indexed by values, and return a sorted table of values
79function bools_to_values(t)
80    local array = {}
81    for k, v in next, t do
82        array[#array + 1] = k
83    end
84    table.sort(array)
85    return array
86end
87
88function array_count(array)
89    local n = 0
90    for k in next, array do
91        n = n + 1
92    end
93    return n
94end
95
96function sk_scrape_accumulate(t)
97    verb = t.verb;
98    if verb == "drawPosText" or verb == "drawPosTextH" then
99        if t.glyphs then
100            local key = make_strike_key(t.paint)
101            strikes[key] = strikes[key] or {}
102            array_union(strikes[key], t.glyphs)
103            
104            if dump_glyph_array_p then
105                dump_array_as_C(t.glyphs)
106            end
107        end
108    end
109end
110
111--[[
112    lua_pictures will call this function after all of the pictures have been
113    "accumulated".
114]]
115function sk_scrape_summarize()
116    local totalCount = 0
117    local strikeCount = 0
118    local min, max = 0, 0
119
120    local histogram = {}
121
122    for k, v in next, strikes do
123        local fontID = round(k / 1000)
124        local size = k - fontID * 1000
125        local count = array_count(v)
126
127--        io.write("fontID,", fontID, ", size,", size, ", entries,", count, "\n");
128        
129        min = math.min(min, count)
130        max = math.max(max, count)
131        totalCount = totalCount + count
132        strikeCount = strikeCount + 1
133        
134        histogram[count] = (histogram[count] or 0) + 1
135    end
136    local ave = round(totalCount / strikeCount)
137
138    io.write("\n", "unique glyphs: min = ", min, ", max = ", max, ", ave = ", ave, "\n");
139    
140    for k, v in next, histogram do
141        io.write("glyph_count,", k, ",frequency,", v, "\n")
142    end
143end
144
145function test_summary()
146    io.write("just testing test_summary\n")
147end
148
149function summarize_unique_glyphIDs()
150    io.write("/* runs of unique glyph IDs, with a -1 sentinel between different runs */\n")
151    io.write("static const int gUniqueGlyphIDs[] = {\n");
152    for k, v in next, strikes do
153        dump_array_as_C(bools_to_values(v))
154    end
155    io.write("-1 };\n")
156end
157
158