158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerfunction tostr(t)
258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    local str = ""
358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    for k, v in next, t do
458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        if #str > 0 then
558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            str = str .. ", "
658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        end
758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        if type(k) == "number" then
858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            str = str .. "[" .. k .. "] = "
958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        else
1058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            str = str .. tostring(k) .. " = "
1158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        end
1258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        if type(v) == "table" then
1358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            str = str .. "{ " .. tostr(v) .. " }"
1458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        else
1558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            str = str .. tostring(v)
1658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        end
1758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    end
1858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    return str
1958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerend
2058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
2158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerlocal canvas        -- holds the current canvas (from startcanvas())
2258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
2358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger--[[
2458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    startcanvas() is called at the start of each picture file, passing the
2558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    canvas that we will be drawing into, and the name of the file.
2658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    
2758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    Following this call, there will be some number of calls to accumulate(t)
2858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    where t is a table of parameters that were passed to that draw-op.
2958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    
3058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        t.verb is a string holding the name of the draw-op (e.g. "drawRect")
3158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    
3258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    when a given picture is done, we call endcanvas(canvas, fileName)
3358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger]]
3458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerfunction sk_scrape_startcanvas(c, fileName)
3558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    canvas = c
3658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerend
3758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
3858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger--[[
3958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    Called when the current canvas is done drawing.
4058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger]]
4158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerfunction sk_scrape_endcanvas(c, fileName)
4258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    canvas = nil
4358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerend
4458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
4558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger--[[
4658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    Called with the parameters to each canvas.draw call, where canvas is the
4758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    current canvas as set by startcanvas()
4858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger]]
4958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
5058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerfunction round(x, mul)
5158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    mul = mul or 1
5258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    return math.floor(x * mul + 0.5) / mul
5358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerend
5458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
5558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerdump_glyph_array_p = false
5658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
5758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerfunction dump_array_as_C(array)
5858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    for k, v in next, array do
5958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        io.write(tostring(v), ", ");
6058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    end
6158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    io.write("-1,\n")
6258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerend
6358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
6458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerlocal strikes = {}  -- [fontID_pointsize] = [] unique glyphs
6558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
6658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerfunction make_strike_key(paint)
6758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    return paint:getFontID() * 1000 + paint:getTextSize()
6858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerend
6958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
7058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger-- array is an array of bools (true), using glyphID as the index
7158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger-- other is just an array[1...N] of numbers (glyphIDs)
7258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerfunction array_union(array, other)
7358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    for k, v in next, other do
7458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        array[v] = true;
7558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    end
7658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerend
7758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
7858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger-- take a table of bools, indexed by values, and return a sorted table of values
7958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerfunction bools_to_values(t)
8058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    local array = {}
8158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    for k, v in next, t do
8258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        array[#array + 1] = k
8358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    end
8458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    table.sort(array)
8558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    return array
8658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerend
8758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
8858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerfunction array_count(array)
8958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    local n = 0
9058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    for k in next, array do
9158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        n = n + 1
9258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    end
9358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    return n
9458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerend
9558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
9658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerfunction sk_scrape_accumulate(t)
9758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    verb = t.verb;
9858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    if verb == "drawPosText" or verb == "drawPosTextH" then
9958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        if t.glyphs then
10058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            local key = make_strike_key(t.paint)
10158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            strikes[key] = strikes[key] or {}
10258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            array_union(strikes[key], t.glyphs)
10358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            
10458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            if dump_glyph_array_p then
10558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                dump_array_as_C(t.glyphs)
10658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            end
10758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        end
10858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    end
10958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerend
11058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
11158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger--[[
11258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    lua_pictures will call this function after all of the pictures have been
11358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    "accumulated".
11458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger]]
11558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerfunction sk_scrape_summarize()
11658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    local totalCount = 0
11758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    local strikeCount = 0
11858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    local min, max = 0, 0
11958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
12058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    local histogram = {}
12158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
12258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    for k, v in next, strikes do
12358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        local fontID = round(k / 1000)
12458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        local size = k - fontID * 1000
12558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        local count = array_count(v)
12658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
12758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger--        io.write("fontID,", fontID, ", size,", size, ", entries,", count, "\n");
12858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        
12958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        min = math.min(min, count)
13058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        max = math.max(max, count)
13158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        totalCount = totalCount + count
13258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        strikeCount = strikeCount + 1
13358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        
13458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        histogram[count] = (histogram[count] or 0) + 1
13558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    end
13658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    local ave = round(totalCount / strikeCount)
13758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
13858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    io.write("\n", "unique glyphs: min = ", min, ", max = ", max, ", ave = ", ave, "\n");
13958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    
14058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    for k, v in next, histogram do
14158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        io.write("glyph_count,", k, ",frequency,", v, "\n")
14258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    end
14358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerend
14458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
14558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerfunction test_summary()
14658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    io.write("just testing test_summary\n")
14758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerend
14858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
14958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerfunction summarize_unique_glyphIDs()
15058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    io.write("/* runs of unique glyph IDs, with a -1 sentinel between different runs */\n")
15158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    io.write("static const int gUniqueGlyphIDs[] = {\n");
15258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    for k, v in next, strikes do
15358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        dump_array_as_C(bools_to_values(v))
15458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    end
15558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    io.write("-1 };\n")
15658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerend
15758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
158