Add plumbing for better text scaling

Fonts are now described by a transform matrix. This lead to switching
from a vector to a hashmap. This change therefore adds new comparators
and hash computations to Font.

Change-Id: I2daffa7d6287c18554c606b8bfa06640d28b4530
diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp
index 47784a4..5c1eb38 100644
--- a/libs/hwui/FontRenderer.cpp
+++ b/libs/hwui/FontRenderer.cpp
@@ -36,7 +36,9 @@
 
 static bool sLogFontRendererCreate = true;
 
-FontRenderer::FontRenderer() {
+FontRenderer::FontRenderer() :
+        mActiveFonts(LruCache<Font::FontDescription, Font*>::kUnlimitedCapacity) {
+
     if (sLogFontRendererCreate) {
         INIT_LOGD("Creating FontRenderer");
     }
@@ -107,10 +109,11 @@
         delete[] mTextMesh;
     }
 
-    Vector<Font*> fontsToDereference = mActiveFonts;
-    for (uint32_t i = 0; i < fontsToDereference.size(); i++) {
-        delete fontsToDereference[i];
+    LruCache<Font::FontDescription, Font*>::Iterator it(mActiveFonts);
+    while (it.next()) {
+        delete it.value();
     }
+    mActiveFonts.clear();
 }
 
 void FontRenderer::flushAllAndInvalidate() {
@@ -118,8 +121,9 @@
         issueDrawCommand();
     }
 
-    for (uint32_t i = 0; i < mActiveFonts.size(); i++) {
-        mActiveFonts[i]->invalidateTextureCache();
+    LruCache<Font::FontDescription, Font*>::Iterator it(mActiveFonts);
+    while (it.next()) {
+        it.value()->invalidateTextureCache();
     }
 
     for (uint32_t i = 0; i < mCacheTextures.size(); i++) {
@@ -146,8 +150,9 @@
         CacheTexture* cacheTexture = mCacheTextures[i];
         if (cacheTexture->getTexture()) {
             cacheTexture->init();
-            for (uint32_t j = 0; j < mActiveFonts.size(); j++) {
-                mActiveFonts[j]->invalidateTextureCache(cacheTexture);
+            LruCache<Font::FontDescription, Font*>::Iterator it(mActiveFonts);
+            while (it.next()) {
+                it.value()->invalidateTextureCache(cacheTexture);
             }
             cacheTexture->releaseTexture();
         }
@@ -480,22 +485,8 @@
     }
 }
 
-void FontRenderer::setFont(SkPaint* paint, uint32_t fontId, float fontSize) {
-    int flags = 0;
-    if (paint->isFakeBoldText()) {
-        flags |= Font::kFakeBold;
-    }
-
-    const float skewX = paint->getTextSkewX();
-    uint32_t italicStyle = *(uint32_t*) &skewX;
-    const float scaleXFloat = paint->getTextScaleX();
-    uint32_t scaleX = *(uint32_t*) &scaleXFloat;
-    SkPaint::Style style = paint->getStyle();
-    const float strokeWidthFloat = paint->getStrokeWidth();
-    uint32_t strokeWidth = *(uint32_t*) &strokeWidthFloat;
-    mCurrentFont = Font::create(this, fontId, fontSize, flags, italicStyle,
-            scaleX, style, strokeWidth);
-
+void FontRenderer::setFont(SkPaint* paint, const mat4& matrix) {
+    mCurrentFont = Font::create(this, paint, matrix);
 }
 
 FontRenderer::DropShadow FontRenderer::renderDropShadow(SkPaint* paint, const char *text,
@@ -561,39 +552,11 @@
     }
 }
 
-void FontRenderer::precache(SkPaint* paint, const char* text, int numGlyphs) {
-    int flags = 0;
-    if (paint->isFakeBoldText()) {
-        flags |= Font::kFakeBold;
-    }
-    const float skewX = paint->getTextSkewX();
-    uint32_t italicStyle = *(uint32_t*) &skewX;
-    const float scaleXFloat = paint->getTextScaleX();
-    uint32_t scaleX = *(uint32_t*) &scaleXFloat;
-    SkPaint::Style style = paint->getStyle();
-    const float strokeWidthFloat = paint->getStrokeWidth();
-    uint32_t strokeWidth = *(uint32_t*) &strokeWidthFloat;
-    float fontSize = paint->getTextSize();
-    Font* font = Font::create(this, SkTypeface::UniqueID(paint->getTypeface()),
-            fontSize, flags, italicStyle, scaleX, style, strokeWidth);
-
+void FontRenderer::precache(SkPaint* paint, const char* text, int numGlyphs, const mat4& matrix) {
+    Font* font = Font::create(this, paint, matrix);
     font->precache(paint, text, numGlyphs);
 }
 
-bool FontRenderer::renderText(SkPaint* paint, const Rect* clip, const char *text,
-        uint32_t startIndex, uint32_t len, int numGlyphs, int x, int y, Rect* bounds) {
-    if (!mCurrentFont) {
-        ALOGE("No font set");
-        return false;
-    }
-
-    initRender(clip, bounds);
-    mCurrentFont->render(paint, text, startIndex, len, numGlyphs, x, y);
-    finishRender();
-
-    return mDrawn;
-}
-
 bool FontRenderer::renderPosText(SkPaint* paint, const Rect* clip, const char *text,
         uint32_t startIndex, uint32_t len, int numGlyphs, int x, int y,
         const float* positions, Rect* bounds) {
@@ -625,12 +588,7 @@
 }
 
 void FontRenderer::removeFont(const Font* font) {
-    for (uint32_t ct = 0; ct < mActiveFonts.size(); ct++) {
-        if (mActiveFonts[ct] == font) {
-            mActiveFonts.removeAt(ct);
-            break;
-        }
-    }
+    mActiveFonts.remove(font->getDescription());
 
     if (mCurrentFont == font) {
         mCurrentFont = NULL;