Merge "Added support for colored / thick underlined text."
diff --git a/core/java/android/text/TextLine.java b/core/java/android/text/TextLine.java
index 3e5f32e..376e4f5 100644
--- a/core/java/android/text/TextLine.java
+++ b/core/java/android/text/TextLine.java
@@ -16,8 +16,6 @@
 
 package android.text;
 
-import com.android.internal.util.ArrayUtils;
-
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.Paint;
@@ -30,6 +28,8 @@
 import android.text.style.ReplacementSpan;
 import android.util.Log;
 
+import com.android.internal.util.ArrayUtils;
+
 /**
  * Represents a line of styled text, for measuring in visual order and
  * for rendering.
@@ -720,7 +720,7 @@
         float ret = 0;
 
         int contextLen = contextEnd - contextStart;
-        if (needWidth || (c != null && (wp.bgColor != 0 || runIsRtl))) {
+        if (needWidth || (c != null && (wp.bgColor != 0 || wp.underlineColor !=0 || runIsRtl))) {
             int flags = runIsRtl ? Paint.DIRECTION_RTL : Paint.DIRECTION_LTR;
             if (mCharsValid) {
                 ret = wp.getTextRunAdvances(mChars, start, runLen,
@@ -739,15 +739,32 @@
             }
 
             if (wp.bgColor != 0) {
-                int color = wp.getColor();
-                Paint.Style s = wp.getStyle();
+                int previousColor = wp.getColor();
+                Paint.Style previousStyle = wp.getStyle();
+
                 wp.setColor(wp.bgColor);
                 wp.setStyle(Paint.Style.FILL);
-
                 c.drawRect(x, top, x + ret, bottom, wp);
 
-                wp.setStyle(s);
-                wp.setColor(color);
+                wp.setStyle(previousStyle);
+                wp.setColor(previousColor);
+            }
+
+            if (wp.underlineColor != 0) {
+                // kStdUnderline_Offset = 1/9, defined in SkTextFormatParams.h
+                float middle = y + wp.baselineShift + (1.0f / 9.0f) * wp.getTextSize();
+                // kStdUnderline_Thickness = 1/18, defined in SkTextFormatParams.h
+                float halfHeight = wp.underlineThickness * (1.0f / 18.0f / 2.0f) * wp.getTextSize();
+
+                int previousColor = wp.getColor();
+                Paint.Style previousStyle = wp.getStyle();
+
+                wp.setColor(wp.underlineColor);
+                wp.setStyle(Paint.Style.FILL);
+                c.drawRect(x, middle - halfHeight, x + ret, middle + halfHeight, wp);
+
+                wp.setStyle(previousStyle);
+                wp.setColor(previousColor);
             }
 
             drawTextRun(c, wp, start, end, contextStart, contextEnd, runIsRtl,
diff --git a/core/java/android/text/TextPaint.java b/core/java/android/text/TextPaint.java
index f9e7cac..de57dfa 100644
--- a/core/java/android/text/TextPaint.java
+++ b/core/java/android/text/TextPaint.java
@@ -23,11 +23,22 @@
  * data used during text measuring and drawing.
  */
 public class TextPaint extends Paint {
+    // Special value 0 means no background paint
     public int bgColor;
     public int baselineShift;
     public int linkColor;
     public int[] drawableState;
     public float density = 1.0f;
+    /**
+     * Special value 0 means no custom underline
+     * @hide
+     */
+    public int underlineColor;
+    /**
+     * Defined as a multiplier of the default underline thickness. Use 1.0f for default thickness.
+     * @hide
+     */
+    public float underlineThickness;
 
     public TextPaint() {
         super();
@@ -53,5 +64,24 @@
         linkColor = tp.linkColor;
         drawableState = tp.drawableState;
         density = tp.density;
+        underlineColor = tp.underlineColor;
+        underlineThickness = tp.underlineThickness;
+    }
+
+    /**
+     * Defines a custom underline for this Paint.
+     * @param color underline solid color
+     * @param thickness underline thickness, defined as a multiplier of the default underline
+     * thickness.
+     * @hide
+     */
+    public void setUnderlineText(boolean isUnderlined, int color, float thickness) {
+        setUnderlineText(false);
+        if (isUnderlined) {
+            underlineColor = color;
+            underlineThickness = thickness;
+        } else {
+            underlineColor = 0;
+        }
     }
 }