Properly scale text

This change does not apply to drawPosText() and drawTextOnPath() yet.

Prior to this change, glyphs were always rasterized based on the
font size specified in the paint. All transforms were then applied
on the resulting texture. This creates rather ugly results when
text is scaled and/or rotated.

With this change, the font renderer will apply the current transform
matrix to the glyph before they are rasterized. This generates much
better looking results.

Change-Id: I0141b6ff18db35e1213e7a3ab9db1ecaf03d7a9c
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index d683c27..fb77ef6 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -1657,13 +1657,13 @@
         mCaches.currentProgram->set(mOrthoMatrix, mModelView, *mSnapshot->transform);
         if (mTrackDirtyRegions) dirtyLayer(left, top, right, bottom, *mSnapshot->transform);
     } else {
-        mCaches.currentProgram->set(mOrthoMatrix, mModelView, mIdentity);
+        mCaches.currentProgram->set(mOrthoMatrix, mModelView, mat4::identity());
         if (mTrackDirtyRegions) dirtyLayer(left, top, right, bottom);
     }
 }
 
 void OpenGLRenderer::setupDrawModelViewIdentity(bool offset) {
-    mCaches.currentProgram->set(mOrthoMatrix, mIdentity, *mSnapshot->transform, offset);
+    mCaches.currentProgram->set(mOrthoMatrix, mat4::identity(), *mSnapshot->transform, offset);
 }
 
 void OpenGLRenderer::setupDrawModelView(float left, float top, float right, float bottom,
@@ -1681,7 +1681,7 @@
             dirtyLayer(left, top, right, bottom, *mSnapshot->transform);
         }
     } else {
-        mCaches.currentProgram->set(mOrthoMatrix, mModelView, mIdentity);
+        mCaches.currentProgram->set(mOrthoMatrix, mModelView, mat4::identity());
         if (mTrackDirtyRegions && dirty) dirtyLayer(left, top, right, bottom);
     }
 }
@@ -1716,7 +1716,7 @@
 void OpenGLRenderer::setupDrawShaderIdentityUniforms() {
     if (mDrawModifiers.mShader) {
         mDrawModifiers.mShader->setupProgram(mCaches.currentProgram,
-                mIdentity, *mSnapshot, &mTextureUnit);
+                mat4::identity(), *mSnapshot, &mTextureUnit);
     }
 }
 
@@ -2587,7 +2587,7 @@
     }
 
     FontRenderer& fontRenderer = mCaches.fontRenderer->getFontRenderer(paint);
-    fontRenderer.setFont(paint, *mSnapshot->transform);
+    fontRenderer.setFont(paint, mat4::identity());
 
     int alpha;
     SkXfermode::Mode mode;
@@ -2663,17 +2663,10 @@
         return DrawGlInfo::kStatusDone;
     }
 
-#if DEBUG_GLYPHS
-    ALOGD("OpenGLRenderer drawText() with FontID=%d",
-            SkTypeface::UniqueID(paint->getTypeface()));
-#endif
-
-    FontRenderer& fontRenderer = mCaches.fontRenderer->getFontRenderer(paint);
-    fontRenderer.setFont(paint, *mSnapshot->transform);
-
     const float oldX = x;
     const float oldY = y;
     const bool pureTranslate = mSnapshot->transform->isPureTranslate();
+
     if (CC_LIKELY(pureTranslate)) {
         x = (int) floorf(x + mSnapshot->transform->getTranslateX() + 0.5f);
         y = (int) floorf(y + mSnapshot->transform->getTranslateY() + 0.5f);
@@ -2683,16 +2676,19 @@
     SkXfermode::Mode mode;
     getAlphaAndMode(paint, &alpha, &mode);
 
+    FontRenderer& fontRenderer = mCaches.fontRenderer->getFontRenderer(paint);
+
     if (CC_UNLIKELY(mDrawModifiers.mHasShadow)) {
-        drawTextShadow(paint, text, bytesCount, count, positions, fontRenderer, alpha, mode,
-                oldX, oldY);
+        fontRenderer.setFont(paint, mat4::identity());
+        drawTextShadow(paint, text, bytesCount, count, positions, fontRenderer,
+                alpha, mode, oldX, oldY);
     }
 
+    fontRenderer.setFont(paint, pureTranslate ? mat4::identity() : *mSnapshot->transform);
+
     // Pick the appropriate texture filtering
-    bool linearFilter = mSnapshot->transform->changesBounds();
-    if (pureTranslate && !linearFilter) {
-        linearFilter = fabs(y - (int) y) > 0.0f || fabs(x - (int) x) > 0.0f;
-    }
+    bool linearFilter = !mSnapshot->transform->isPureTranslate() ||
+            fabs(y - (int) y) > 0.0f || fabs(x - (int) x) > 0.0f;
 
     // The font renderer will always use texture unit 0
     mCaches.activeTexture(0);
@@ -2705,17 +2701,16 @@
     setupDrawShader();
     setupDrawBlending(true, mode);
     setupDrawProgram();
-    setupDrawModelView(x, y, x, y, pureTranslate, true);
+    setupDrawModelView(x, y, x, y, true, true);
     // See comment above; the font renderer must use texture unit 0
     // assert(mTextureUnit == 0)
     setupDrawTexture(fontRenderer.getTexture(linearFilter));
     setupDrawPureColorUniforms();
     setupDrawColorFilterUniforms();
-    setupDrawShaderUniforms(pureTranslate);
+    setupDrawShaderUniforms(true);
     setupDrawTextGammaUniforms();
 
-    const Rect* clip = pureTranslate ? mSnapshot->clipRect :
-            (mSnapshot->hasPerspectiveTransform() ? NULL : &mSnapshot->getLocalClip());
+    const Rect* clip = mSnapshot->hasPerspectiveTransform() ? NULL : mSnapshot->clipRect;
     Rect bounds(FLT_MAX / 2.0f, FLT_MAX / 2.0f, FLT_MIN / 2.0f, FLT_MIN / 2.0f);
 
     const bool hasActiveLayer = hasLayer();
@@ -2732,9 +2727,6 @@
     }
 
     if (status && hasActiveLayer) {
-        if (!pureTranslate) {
-            mSnapshot->transform->mapRect(bounds);
-        }
         dirtyLayerUnchecked(bounds, getRegion());
     }
 
@@ -2750,7 +2742,7 @@
     }
 
     FontRenderer& fontRenderer = mCaches.fontRenderer->getFontRenderer(paint);
-    fontRenderer.setFont(paint, *mSnapshot->transform);
+    fontRenderer.setFont(paint, mat4::identity());
 
     int alpha;
     SkXfermode::Mode mode;