aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-05-30 18:55:14 +0000
committerGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-05-30 18:55:14 +0000
commite3823fd901674e22269637a669ac2b3e2667dc9c (patch)
treef0fa592ea719f95b3ec38a766fab61019d57494c
parent9166bf57d89b9c2cd2c6f8b7dd99a50bf1f01f81 (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.h3
-rw-r--r--src/utils/SkLua.cpp46
-rw-r--r--src/utils/SkLuaCanvas.cpp28
-rw-r--r--tools/lua/glyph-usage.lua113
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
+