add script to scrape glyph usage in drawText calls

git-svn-id: http://skia.googlecode.com/svn/trunk@9353 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
reed@google.com 2013-05-30 18:55:14 +00:00
parent 9166bf57d8
commit e3823fd901
4 changed files with 190 additions and 0 deletions

View File

@ -41,8 +41,11 @@ public:
void pushBool(bool, const char tableKey[] = NULL);
void pushString(const char[], const char tableKey[] = NULL);
void pushString(const char[], size_t len, const char tableKey[] = NULL);
void pushString(const SkString&, const char tableKey[] = NULL);
void pushArrayU16(const uint16_t[], int count, const char tableKey[] = NULL);
void pushColor(SkColor, const char tableKey[] = NULL);
void pushU32(uint32_t, const char tableKey[] = NULL);
void pushScalar(SkScalar, const char tableKey[] = NULL);
void pushRect(const SkRect&, const char tableKey[] = NULL);
void pushRRect(const SkRRect&, const char tableKey[] = NULL);

View File

@ -12,6 +12,7 @@
#include "SkMatrix.h"
#include "SkRRect.h"
#include "SkString.h"
#include "SkTypeface.h"
extern "C" {
#include "lua.h"
@ -120,6 +121,11 @@ static void setfield_function(lua_State* L,
lua_setfield(L, -2, key);
}
static void setarray_number(lua_State* L, int index, double value) {
lua_pushnumber(L, value);
lua_rawseti(L, -2, index);
}
void SkLua::pushBool(bool value, const char key[]) {
lua_pushboolean(fL, value);
CHECK_SETFIELD(key);
@ -130,6 +136,13 @@ void SkLua::pushString(const char str[], const char key[]) {
CHECK_SETFIELD(key);
}
void SkLua::pushString(const char str[], size_t length, const char key[]) {
// TODO: how to do this w/o making a copy?
SkString s(str, length);
lua_pushstring(fL, s.c_str());
CHECK_SETFIELD(key);
}
void SkLua::pushString(const SkString& str, const char key[]) {
lua_pushstring(fL, str.c_str());
CHECK_SETFIELD(key);
@ -144,11 +157,25 @@ void SkLua::pushColor(SkColor color, const char key[]) {
CHECK_SETFIELD(key);
}
void SkLua::pushU32(uint32_t value, const char key[]) {
lua_pushnumber(fL, (double)value);
CHECK_SETFIELD(key);
}
void SkLua::pushScalar(SkScalar value, const char key[]) {
lua_pushnumber(fL, SkScalarToLua(value));
CHECK_SETFIELD(key);
}
void SkLua::pushArrayU16(const uint16_t array[], int count, const char key[]) {
lua_newtable(fL);
for (int i = 0; i < count; ++i) {
// make it base-1 to match lua convention
setarray_number(fL, i + 1, (double)array[i]);
}
CHECK_SETFIELD(key);
}
void SkLua::pushRect(const SkRect& r, const char key[]) {
lua_newtable(fL);
setfield_number(fL, "left", SkScalarToLua(r.fLeft));
@ -314,6 +341,22 @@ static int lpaint_setColor(lua_State* L) {
return 0;
}
static int lpaint_getTextSize(lua_State* L) {
SkLua(L).pushScalar(get_obj<SkPaint>(L, 1)->getTextSize());
return 1;
}
static int lpaint_setTextSize(lua_State* L) {
get_obj<SkPaint>(L, 1)->setTextSize(lua2scalar(L, 2));
return 0;
}
static int lpaint_getFontID(lua_State* L) {
SkTypeface* face = get_obj<SkPaint>(L, 1)->getTypeface();
SkLua(L).pushU32(SkTypeface::UniqueID(face));
return 1;
}
static int lpaint_gc(lua_State* L) {
get_obj<SkPaint>(L, 1)->~SkPaint();
return 0;
@ -324,6 +367,9 @@ static const struct luaL_Reg gSkPaint_Methods[] = {
{ "setAntiAlias", lpaint_setAntiAlias },
{ "getColor", lpaint_getColor },
{ "setColor", lpaint_setColor },
{ "getTextSize", lpaint_getTextSize },
{ "setTextSize", lpaint_setTextSize },
{ "getFontID", lpaint_getFontID },
{ "__gc", lpaint_gc },
{ NULL, NULL }
};

View File

@ -34,12 +34,36 @@ public:
lua_settop(L, -1);
}
void pushEncodedText(SkPaint::TextEncoding, const void*, size_t);
private:
typedef SkLua INHERITED;
};
#define AUTO_LUA(verb) AutoCallLua lua(fL, fFunc.c_str(), verb)
///////////////////////////////////////////////////////////////////////////////
void AutoCallLua::pushEncodedText(SkPaint::TextEncoding enc, const void* text,
size_t length) {
switch (enc) {
case SkPaint::kUTF8_TextEncoding:
this->pushString((const char*)text, length, "text");
break;
case SkPaint::kUTF16_TextEncoding: {
SkString str;
str.setUTF16((const uint16_t*)text, length);
this->pushString(str, "text");
} break;
case SkPaint::kGlyphID_TextEncoding:
this->pushArrayU16((const uint16_t*)text, length >> 1, "glyphs");
break;
case SkPaint::kUTF32_TextEncoding:
break;
}
}
///////////////////////////////////////////////////////////////////////////////
void SkLuaCanvas::pushThis() {
@ -216,12 +240,14 @@ void SkLuaCanvas::drawSprite(const SkBitmap& bitmap, int x, int y,
void SkLuaCanvas::drawText(const void* text, size_t byteLength, SkScalar x,
SkScalar y, const SkPaint& paint) {
AUTO_LUA("drawText");
lua.pushEncodedText(paint.getTextEncoding(), text, byteLength);
lua.pushPaint(paint, "paint");
}
void SkLuaCanvas::drawPosText(const void* text, size_t byteLength,
const SkPoint pos[], const SkPaint& paint) {
AUTO_LUA("drawPosText");
lua.pushEncodedText(paint.getTextEncoding(), text, byteLength);
lua.pushPaint(paint, "paint");
}
@ -229,6 +255,7 @@ void SkLuaCanvas::drawPosTextH(const void* text, size_t byteLength,
const SkScalar xpos[], SkScalar constY,
const SkPaint& paint) {
AUTO_LUA("drawPosTextH");
lua.pushEncodedText(paint.getTextEncoding(), text, byteLength);
lua.pushPaint(paint, "paint");
}
@ -237,6 +264,7 @@ void SkLuaCanvas::drawTextOnPath(const void* text, size_t byteLength,
const SkPaint& paint) {
AUTO_LUA("drawTextOnPath");
lua.pushPath(path, "path");
lua.pushEncodedText(paint.getTextEncoding(), text, byteLength);
lua.pushPaint(paint, "paint");
}

113
tools/lua/glyph-usage.lua Normal file
View File

@ -0,0 +1,113 @@
function tostr(t)
local str = ""
for k, v in next, t do
if #str > 0 then
str = str .. ", "
end
if type(k) == "number" then
str = str .. "[" .. k .. "] = "
else
str = str .. tostring(k) .. " = "
end
if type(v) == "table" then
str = str .. "{ " .. tostr(v) .. " }"
else
str = str .. tostring(v)
end
end
return str
end
local canvas -- holds the current canvas (from startcanvas())
--[[
startcanvas() is called at the start of each picture file, passing the
canvas that we will be drawing into, and the name of the file.
Following this call, there will be some number of calls to accumulate(t)
where t is a table of parameters that were passed to that draw-op.
t.verb is a string holding the name of the draw-op (e.g. "drawRect")
when a given picture is done, we call endcanvas(canvas, fileName)
]]
function sk_scrape_startcanvas(c, fileName)
canvas = c
end
--[[
Called when the current canvas is done drawing.
]]
function sk_scrape_endcanvas(c, fileName)
canvas = nil
end
--[[
Called with the parameters to each canvas.draw call, where canvas is the
current canvas as set by startcanvas()
]]
function round(x, mul)
mul = mul or 1
return math.floor(x * mul + 0.5) / mul
end
local strikes = {} -- [fontID_pointsize] = [] unique glyphs
function make_strike_key(paint)
return paint:getFontID() * 1000 + paint:getTextSize()
end
-- array is an array of bools (true), using glyphID as the index
-- other is just an array[1...N] of numbers (glyphIDs)
function array_union(array, other)
for k, v in next, other do
array[v] = true;
end
end
function array_count(array)
local n = 0
for k in next, array do
n = n + 1
end
return n
end
function sk_scrape_accumulate(t)
verb = t.verb;
if verb == "drawPosText" or verb == "drawPosTextH" then
if t.glyphs then
local key = make_strike_key(t.paint)
strikes[key] = strikes[key] or {}
array_union(strikes[key], t.glyphs)
end
end
end
--[[
lua_pictures will call this function after all of the pictures have been
"accumulated".
]]
function sk_scrape_summarize()
local totalCount = 0
local strikeCount = 0
local min, max = 0, 0
for k, v in next, strikes do
local fontID = round(k / 1000)
local size = k - fontID * 1000
local count = array_count(v)
io.write("fontID = ", fontID, ", size = ", size, ", entries = ", count, "\n");
min = math.min(min, count)
max = math.max(max, count)
totalCount = totalCount + count
strikeCount = strikeCount + 1
end
local ave = round(totalCount / strikeCount)
io.write("\n", "unique glyphs: min = ", min, ", max = ", max, ", ave = ", ave, "\n");
end