Add a few simple tests of StaticLayout.
diff --git a/core/tests/coretests/src/android/text/StaticLayoutTest.java b/core/tests/coretests/src/android/text/StaticLayoutTest.java
new file mode 100644
index 0000000..1e4db3d
--- /dev/null
+++ b/core/tests/coretests/src/android/text/StaticLayoutTest.java
@@ -0,0 +1,319 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package android.text;
+
+import android.graphics.Paint.FontMetricsInt;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.text.Layout.Alignment;
+import static android.text.Layout.Alignment.*;
+import android.util.Log;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests StaticLayout vertical metrics behavior.
+ */
+public class StaticLayoutTest extends TestCase {
+
+    /**
+     * Basic test showing expected behavior and relationship between font
+     * metrics and line metrics.
+     */
+    @SmallTest
+    public void testGetters1() {
+        LayoutBuilder b = builder();
+        FontMetricsInt fmi = b.paint.getFontMetricsInt();
+
+        // check default paint
+        Log.i("TG1:paint", fmi.toString());
+
+        Layout l = b.build();
+        assertVertMetrics(l, 0, 0,
+                fmi.ascent, fmi.descent);
+
+        // other quick metrics
+        assertEquals(0, l.getLineStart(0));
+        assertEquals(Layout.DIR_LEFT_TO_RIGHT, l.getParagraphDirection(0));
+        assertEquals(false, l.getLineContainsTab(0));
+        assertEquals(Layout.DIRS_ALL_LEFT_TO_RIGHT, l.getLineDirections(0));
+        assertEquals(0, l.getEllipsisCount(0));
+        assertEquals(0, l.getEllipsisStart(0));
+        assertEquals(b.width, l.getEllipsizedWidth());
+    }
+
+    /**
+     * Basic test showing effect of includePad = true with 1 line.
+     * Top and bottom padding are affected, as is the line descent and height.
+     */
+    @SmallTest
+    public void testGetters2() {
+        LayoutBuilder b = builder()
+            .setIncludePad(true);
+        FontMetricsInt fmi = b.paint.getFontMetricsInt();
+
+        Layout l = b.build();
+        assertVertMetrics(l, fmi.top - fmi.ascent, fmi.bottom - fmi.descent,
+                fmi.top, fmi.bottom);
+    }
+
+    /**
+     * Basic test showing effect of includePad = true wrapping to 2 lines.
+     * Ascent of top line and descent of bottom line are affected.
+     */
+    @SmallTest
+    public void testGetters3() {
+        LayoutBuilder b = builder()
+            .setIncludePad(true)
+            .setWidth(50);
+        FontMetricsInt fmi = b.paint.getFontMetricsInt();
+
+        Layout l =  b.build();
+        assertVertMetrics(l, fmi.top - fmi.ascent, fmi.bottom - fmi.descent,
+            fmi.top, fmi.descent,
+            fmi.ascent, fmi.bottom);
+    }
+
+    /**
+     * Basic test showing effect of includePad = true wrapping to 3 lines.
+     * First line ascent is top, bottom line descent is bottom.
+     */
+    @SmallTest
+    public void testGetters4() {
+        LayoutBuilder b = builder()
+            .setText("This is a longer test")
+            .setIncludePad(true)
+            .setWidth(50);
+        FontMetricsInt fmi = b.paint.getFontMetricsInt();
+
+        Layout l = b.build();
+        assertVertMetrics(l, fmi.top - fmi.ascent, fmi.bottom - fmi.descent,
+                fmi.top, fmi.descent,
+                fmi.ascent, fmi.descent,
+                fmi.ascent, fmi.bottom);
+    }
+
+    /**
+     * Basic test showing effect of includePad = true wrapping to 3 lines and
+     * large text. See effect of leading. Currently, we don't expect there to
+     * even be non-zero leading.
+     */
+    @SmallTest
+    public void testGetters5() {
+        LayoutBuilder b = builder()
+            .setText("This is a longer test")
+            .setIncludePad(true)
+            .setWidth(150);
+        b.paint.setTextSize(36);
+        FontMetricsInt fmi = b.paint.getFontMetricsInt();
+
+        if (fmi.leading == 0) { // nothing to test
+            Log.i("TG5", "leading is 0, skipping test");
+            return;
+        }
+
+        // So far, leading is not used, so this is the same as TG4.  If we start
+        // using leading, this will fail.
+        Layout l = b.build();
+        assertVertMetrics(l, fmi.top - fmi.ascent, fmi.bottom - fmi.descent,
+                fmi.top, fmi.descent,
+                fmi.ascent, fmi.descent,
+                fmi.ascent, fmi.bottom);
+    }
+
+    /**
+     * Basic test showing effect of includePad = true, spacingAdd = 2, wrapping
+     * to 3 lines.
+     */
+    @SmallTest
+    public void testGetters6() {
+        int spacingAdd = 2; // int so expressions return int
+        LayoutBuilder b = builder()
+            .setText("This is a longer test")
+            .setIncludePad(true)
+            .setWidth(50)
+            .setSpacingAdd(spacingAdd);
+        FontMetricsInt fmi = b.paint.getFontMetricsInt();
+
+        Layout l = b.build();
+        assertVertMetrics(l, fmi.top - fmi.ascent, fmi.bottom - fmi.descent,
+                fmi.top, fmi.descent + spacingAdd,
+                fmi.ascent, fmi.descent + spacingAdd,
+                fmi.ascent, fmi.bottom + spacingAdd);
+    }
+
+    /**
+     * Basic test showing effect of includePad = true, spacingAdd = 2,
+     * spacingMult = 1.5, wrapping to 3 lines.
+     */
+    @SmallTest
+    public void testGetters7() {
+        LayoutBuilder b = builder()
+            .setText("This is a longer test")
+            .setIncludePad(true)
+            .setWidth(50)
+            .setSpacingAdd(2)
+            .setSpacingMult(1.5f);
+        FontMetricsInt fmi = b.paint.getFontMetricsInt();
+        Scaler s = new Scaler(b.spacingMult, b.spacingAdd);
+
+        Layout l = b.build();
+        assertVertMetrics(l, fmi.top - fmi.ascent, fmi.bottom - fmi.descent,
+                fmi.top, fmi.descent + s.scale(fmi.descent - fmi.top),
+                fmi.ascent, fmi.descent + s.scale(fmi.descent - fmi.ascent),
+                fmi.ascent, fmi.bottom + s.scale(fmi.bottom - fmi.ascent));
+    }
+
+    /**
+     * Basic test showing effect of includePad = true, spacingAdd = 0,
+     * spacingMult = 0.8 when wrapping to 3 lines.
+     */
+    @SmallTest
+    public void testGetters8() {
+        LayoutBuilder b = builder()
+            .setText("This is a longer test")
+            .setIncludePad(true)
+            .setWidth(50)
+            .setSpacingAdd(2)
+            .setSpacingMult(.8f);
+        FontMetricsInt fmi = b.paint.getFontMetricsInt();
+        Scaler s = new Scaler(b.spacingMult, b.spacingAdd);
+
+        Layout l = b.build();
+        assertVertMetrics(l, fmi.top - fmi.ascent, fmi.bottom - fmi.descent,
+                fmi.top, fmi.descent + s.scale(fmi.descent - fmi.top),
+                fmi.ascent, fmi.descent + s.scale(fmi.descent - fmi.ascent),
+                fmi.ascent, fmi.bottom + s.scale(fmi.bottom - fmi.ascent));
+    }
+
+    // ----- test utility classes and methods -----
+
+    // Models the effect of the scale and add parameters.  I think the current
+    // implementation misbehaves.
+    private static class Scaler {
+        private final float sMult;
+        private final float sAdd;
+
+        Scaler(float sMult, float sAdd) {
+            this.sMult = sMult - 1;
+            this.sAdd = sAdd;
+        }
+
+        public int scale(float height) {
+            int altVal = (int)(height * sMult + sAdd + 0.5); // existing impl
+            int rndVal = Math.round(height * sMult + sAdd);
+            if (altVal != rndVal) {
+                Log.i("Scale", "expected scale: " + rndVal +
+                        " != returned scale: " + altVal);
+            }
+            return altVal; // existing implementation
+        }
+    }
+
+    private static LayoutBuilder builder() {
+        return new LayoutBuilder();
+    }
+
+    private static class LayoutBuilder {
+        String text = "This is a test";
+        TextPaint paint = new TextPaint(); // default
+        int width = 100;
+        Alignment align = ALIGN_NORMAL;
+        float spacingMult = 1;
+        float spacingAdd = 0;
+        boolean includePad = false;
+
+        LayoutBuilder setText(String text) {
+            this.text = text;
+            return this;
+        }
+
+        LayoutBuilder setPaint(TextPaint paint) {
+            this.paint = paint;
+            return this;
+        }
+
+        LayoutBuilder setWidth(int width) {
+            this.width = width;
+            return this;
+        }
+
+        LayoutBuilder setAlignment(Alignment align) {
+            this.align = align;
+            return this;
+        }
+
+        LayoutBuilder setSpacingMult(float spacingMult) {
+            this.spacingMult = spacingMult;
+            return this;
+        }
+
+        LayoutBuilder setSpacingAdd(float spacingAdd) {
+            this.spacingAdd = spacingAdd;
+            return this;
+        }
+
+        LayoutBuilder setIncludePad(boolean includePad) {
+            this.includePad = includePad;
+            return this;
+        }
+
+       Layout build() {
+            return  new StaticLayout(text, paint, width, align, spacingMult,
+                spacingAdd, includePad);
+        }
+    }
+
+    private void assertVertMetrics(Layout l, int topPad, int botPad, int... values) {
+        assertTopBotPadding(l, topPad, botPad);
+        assertLinesMetrics(l, values);
+    }
+
+    private void assertLinesMetrics(Layout l, int... values) {
+        // sanity check
+        if ((values.length & 0x1) != 0) {
+            throw new IllegalArgumentException(String.valueOf(values.length));
+        }
+
+        int lines = values.length >> 1;
+        assertEquals(lines, l.getLineCount());
+
+        int t = 0;
+        for (int i = 0, n = 0; i < lines; ++i, n += 2) {
+            int a = values[n];
+            int d = values[n+1];
+            int h = -a + d;
+            assertLineMetrics(l, i, t, a, d, h);
+            t += h;
+        }
+
+        assertEquals(t, l.getHeight());
+    }
+
+    private void assertLineMetrics(Layout l, int line,
+            int top, int ascent, int descent, int height) {
+        String info = "line " + line;
+        assertEquals(info, top, l.getLineTop(line));
+        assertEquals(info, ascent, l.getLineAscent(line));
+        assertEquals(info, descent, l.getLineDescent(line));
+        assertEquals(info, height, l.getLineBottom(line) - top);
+    }
+
+    private void assertTopBotPadding(Layout l, int topPad, int botPad) {
+        assertEquals(topPad, l.getTopPadding());
+        assertEquals(botPad, l.getBottomPadding());
+    }
+}