Hack to fix issue #2125365: Sports Trivia compatability with Eclair

Adds a mechanism to tell Paint the scaling factor its target
canvas will have, for it to compute font metrics based on the
correct font size.  Only TextView uses this, but that is enough
for the large majority of apps.

Change-Id: I6cacaa0dd26d40ee3ad959bed0028678d6e9016e
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 37ef153..bf3d26e 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -328,11 +328,16 @@
 
         mTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
         mTextPaint.density = getResources().getDisplayMetrics().density;
+        mTextPaint.setCompatibilityScaling(
+                getResources().getCompatibilityInfo().applicationScale);
+        
         // If we get the paint from the skin, we should set it to left, since
         // the layout always wants it to be left.
         // mTextPaint.setTextAlign(Paint.Align.LEFT);
 
         mHighlightPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+        mHighlightPaint.setCompatibilityScaling(
+                getResources().getCompatibilityInfo().applicationScale);
 
         mMovement = getDefaultMovementMethod();
         mTransformation = null;
diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp
index 6b7f045..780badc 100644
--- a/core/jni/android/graphics/Paint.cpp
+++ b/core/jni/android/graphics/Paint.cpp
@@ -569,11 +569,11 @@
     {"descent","()F", (void*) SkPaintGlue::descent},
     {"getFontMetrics", "(Landroid/graphics/Paint$FontMetrics;)F", (void*)SkPaintGlue::getFontMetrics},
     {"getFontMetricsInt", "(Landroid/graphics/Paint$FontMetricsInt;)I", (void*)SkPaintGlue::getFontMetricsInt},
-    {"measureText","([CII)F", (void*) SkPaintGlue::measureText_CII},
-    {"measureText","(Ljava/lang/String;)F", (void*) SkPaintGlue::measureText_String},
-    {"measureText","(Ljava/lang/String;II)F", (void*) SkPaintGlue::measureText_StringII},
-    {"breakText","([CIIF[F)I", (void*) SkPaintGlue::breakTextC},
-    {"breakText","(Ljava/lang/String;ZF[F)I", (void*) SkPaintGlue::breakTextS},
+    {"native_measureText","([CII)F", (void*) SkPaintGlue::measureText_CII},
+    {"native_measureText","(Ljava/lang/String;)F", (void*) SkPaintGlue::measureText_String},
+    {"native_measureText","(Ljava/lang/String;II)F", (void*) SkPaintGlue::measureText_StringII},
+    {"native_breakText","([CIIF[F)I", (void*) SkPaintGlue::breakTextC},
+    {"native_breakText","(Ljava/lang/String;ZF[F)I", (void*) SkPaintGlue::breakTextS},
     {"native_getTextWidths","(I[CII[F)I", (void*) SkPaintGlue::getTextWidths___CII_F},
     {"native_getTextWidths","(ILjava/lang/String;II[F)I", (void*) SkPaintGlue::getTextWidths__StringII_F},
     {"native_getTextPath","(I[CIIFFI)V", (void*) SkPaintGlue::getTextPath___CIIFFPath},
diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java
index 862e827..3d6d273 100644
--- a/graphics/java/android/graphics/Paint.java
+++ b/graphics/java/android/graphics/Paint.java
@@ -36,6 +36,10 @@
     private Typeface    mTypeface;
     private Xfermode    mXfermode;
 
+    private boolean     mHasCompatScaling;
+    private float       mCompatScaling;
+    private float       mInvCompatScaling;
+    
     private static final Style[] sStyleArray = {
         Style.FILL, Style.STROKE, Style.FILL_AND_STROKE
     };
@@ -189,6 +193,7 @@
     public Paint(int flags) {
         mNativePaint = native_init();
         setFlags(flags | DEFAULT_PAINT_FLAGS);
+        mCompatScaling = mInvCompatScaling = 1;
     }
 
     /**
@@ -200,12 +205,17 @@
      */
     public Paint(Paint paint) {
         mNativePaint = native_initWithPaint(paint.mNativePaint);
+        mHasCompatScaling = paint.mHasCompatScaling;
+        mCompatScaling = paint.mCompatScaling;
+        mInvCompatScaling = paint.mInvCompatScaling;
     }
 
     /** Restores the paint to its default settings. */
     public void reset() {
         native_reset(mNativePaint);
         setFlags(DEFAULT_PAINT_FLAGS);
+        mHasCompatScaling = false;
+        mCompatScaling = mInvCompatScaling = 1;
     }
     
     /**
@@ -225,9 +235,24 @@
             mShader         = src.mShader;
             mTypeface       = src.mTypeface;
             mXfermode       = src.mXfermode;
+            mHasCompatScaling = src.mHasCompatScaling;
+            mCompatScaling    = src.mCompatScaling;
+            mInvCompatScaling = src.mInvCompatScaling;
         }
     }
 
+    /** @hide */
+    public void setCompatibilityScaling(float factor) {
+        if (factor == 1.0) {
+            mHasCompatScaling = false;
+            mCompatScaling = mInvCompatScaling = 1.0f;
+        } else {
+            mHasCompatScaling = true;
+            mCompatScaling = factor;
+            mInvCompatScaling = 1.0f/factor;
+        }
+    }
+    
     /**
      * Return the paint's flags. Use the Flag enum to test flag values.
      *
@@ -972,8 +997,17 @@
      * @param count THe number of characters to measure, beginning with start
      * @return      The width of the text
      */
-    public native float measureText(char[] text, int index, int count);
+    public float measureText(char[] text, int index, int count) {
+        if (!mHasCompatScaling) return native_measureText(text, index, count);
+        final float oldSize = getTextSize();
+        setTextSize(oldSize*mCompatScaling);
+        float w = native_measureText(text, index, count);
+        setTextSize(oldSize);
+        return w*mInvCompatScaling;
+    }
 
+    private native float native_measureText(char[] text, int index, int count);
+    
     /**
      * Return the width of the text.
      *
@@ -982,16 +1016,34 @@
      * @param end   1 beyond the index of the last character to measure
      * @return      The width of the text
      */
-    public native float measureText(String text, int start, int end);
+    public float measureText(String text, int start, int end) {
+        if (!mHasCompatScaling) return native_measureText(text, start, end);
+        final float oldSize = getTextSize();
+        setTextSize(oldSize*mCompatScaling);
+        float w = native_measureText(text, start, end);
+        setTextSize(oldSize);
+        return w*mInvCompatScaling;
+    }
 
+    private native float native_measureText(String text, int start, int end);
+    
     /**
      * Return the width of the text.
      *
      * @param text  The text to measure
      * @return      The width of the text
      */
-    public native float measureText(String text);
+    public float measureText(String text) {
+        if (!mHasCompatScaling) return native_measureText(text);
+        final float oldSize = getTextSize();
+        setTextSize(oldSize*mCompatScaling);
+        float w = native_measureText(text);
+        setTextSize(oldSize);
+        return w*mInvCompatScaling;
+    }
 
+    private native float native_measureText(String text);
+    
     /**
      * Return the width of the text.
      *
@@ -1013,10 +1065,10 @@
         }
 
         char[] buf = TemporaryBuffer.obtain(end - start);
-    	TextUtils.getChars(text, start, end, buf, 0);
-    	float result = measureText(buf, 0, end - start);
+        TextUtils.getChars(text, start, end, buf, 0);
+        float result = measureText(buf, 0, end - start);
         TemporaryBuffer.recycle(buf);
-    	return result;
+        return result;
     }
     
     /**
@@ -1036,8 +1088,22 @@
      * @return The number of chars that were measured. Will always be <=
      *         abs(count).
      */
-    public native int breakText(char[] text, int index, int count,
-                                float maxWidth, float[] measuredWidth);
+    public int breakText(char[] text, int index, int count,
+                                float maxWidth, float[] measuredWidth) {
+        if (!mHasCompatScaling) {
+            return native_breakText(text, index, count, maxWidth, measuredWidth);
+        }
+        final float oldSize = getTextSize();
+        setTextSize(oldSize*mCompatScaling);
+        int res = native_breakText(text, index, count, maxWidth*mCompatScaling,
+                measuredWidth);
+        setTextSize(oldSize);
+        if (measuredWidth != null) measuredWidth[0] *= mInvCompatScaling;
+        return res;
+    }
+
+    public native int native_breakText(char[] text, int index, int count,
+                                       float maxWidth, float[] measuredWidth);
 
     /**
      * Measure the text, stopping early if the measured width exceeds maxWidth.
@@ -1094,8 +1160,22 @@
      * @return The number of chars that were measured. Will always be <=
      *         abs(count).
      */
-    public native int breakText(String text, boolean measureForwards,
-                                float maxWidth, float[] measuredWidth);
+    public int breakText(String text, boolean measureForwards,
+                                float maxWidth, float[] measuredWidth) {
+        if (!mHasCompatScaling) {
+            return native_breakText(text, measureForwards, maxWidth, measuredWidth);
+        }
+        final float oldSize = getTextSize();
+        setTextSize(oldSize*mCompatScaling);
+        int res = native_breakText(text, measureForwards, maxWidth*mCompatScaling,
+                measuredWidth);
+        setTextSize(oldSize);
+        if (measuredWidth != null) measuredWidth[0] *= mInvCompatScaling;
+        return res;
+    }
+
+    public native int native_breakText(String text, boolean measureForwards,
+                                       float maxWidth, float[] measuredWidth);
 
     /**
      * Return the advance widths for the characters in the string.
@@ -1113,7 +1193,18 @@
                 || count > widths.length) {
             throw new ArrayIndexOutOfBoundsException();
         }
-        return native_getTextWidths(mNativePaint, text, index, count, widths);
+        
+        if (!mHasCompatScaling) {
+            return native_getTextWidths(mNativePaint, text, index, count, widths);
+        }
+        final float oldSize = getTextSize();
+        setTextSize(oldSize*mCompatScaling);
+        int res = native_getTextWidths(mNativePaint, text, index, count, widths);
+        setTextSize(oldSize);
+        for (int i=0; i<res; i++) {
+            widths[i] *= mInvCompatScaling;
+        }
+        return res;
     }
 
     /**
@@ -1164,7 +1255,18 @@
         if (end - start > widths.length) {
             throw new ArrayIndexOutOfBoundsException();
         }
-        return native_getTextWidths(mNativePaint, text, start, end, widths);
+        
+        if (!mHasCompatScaling) {
+            return native_getTextWidths(mNativePaint, text, start, end, widths);
+        }
+        final float oldSize = getTextSize();
+        setTextSize(oldSize*mCompatScaling);
+        int res = native_getTextWidths(mNativePaint, text, start, end, widths);
+        setTextSize(oldSize);
+        for (int i=0; i<res; i++) {
+            widths[i] *= mInvCompatScaling;
+        }
+        return res;
     }
     
     /**