diff options
author | reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2013-05-30 18:55:14 +0000 |
---|---|---|
committer | reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2013-05-30 18:55:14 +0000 |
commit | e3823fd901674e22269637a669ac2b3e2667dc9c (patch) | |
tree | f0fa592ea719f95b3ec38a766fab61019d57494c | |
parent | 9166bf57d89b9c2cd2c6f8b7dd99a50bf1f01f81 (diff) |
add script to scrape glyph usage in drawText calls
git-svn-id: http://skia.googlecode.com/svn/trunk@9353 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r-- | include/utils/SkLua.h | 3 | ||||
-rw-r--r-- | src/utils/SkLua.cpp | 46 | ||||
-rw-r--r-- | src/utils/SkLuaCanvas.cpp | 28 | ||||
-rw-r--r-- | tools/lua/glyph-usage.lua | 113 |
4 files changed, 190 insertions, 0 deletions
diff --git a/include/utils/SkLua.h b/include/utils/SkLua.h index f24f8a5d2f..c6097464ef 100644 --- a/include/utils/SkLua.h +++ b/include/utils/SkLua.h @@ -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); diff --git a/src/utils/SkLua.cpp b/src/utils/SkLua.cpp index 9aef50e98c..bd453e3d1b 100644 --- a/src/utils/SkLua.cpp +++ b/src/utils/SkLua.cpp @@ -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 } }; diff --git a/src/utils/SkLuaCanvas.cpp b/src/utils/SkLuaCanvas.cpp index d3ecd74bb0..1299a0e251 100644 --- a/src/utils/SkLuaCanvas.cpp +++ b/src/utils/SkLuaCanvas.cpp @@ -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"); } diff --git a/tools/lua/glyph-usage.lua b/tools/lua/glyph-usage.lua new file mode 100644 index 0000000000..2b0c0e12a0 --- /dev/null +++ b/tools/lua/glyph-usage.lua @@ -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 + |