Update HWUI tests to use minikin to layout fonts.

This update is a precondition for landing additional tests
that depend on the minkin layout implementation.

bug: 27675371
Change-Id: I9bb98bae6b39462246e42cf8acb968b7df05292d
diff --git a/libs/hwui/RecordingCanvas.h b/libs/hwui/RecordingCanvas.h
index 1eb4fa0..acb88e2 100644
--- a/libs/hwui/RecordingCanvas.h
+++ b/libs/hwui/RecordingCanvas.h
@@ -191,13 +191,16 @@
             const SkPaint* paint) override;
 
     // Text
-    virtual void drawGlyphs(const uint16_t* glyphs, const float* positions, int glyphCount,
-            const SkPaint& paint, float x, float y, float boundsLeft, float boundsTop,
-            float boundsRight, float boundsBottom, float totalAdvance) override;
-    virtual void drawGlyphsOnPath(const uint16_t* glyphs, int glyphCount, const SkPath& path,
-            float hOffset, float vOffset, const SkPaint& paint) override;
     virtual bool drawTextAbsolutePos() const override { return false; }
 
+protected:
+    virtual void drawGlyphs(const uint16_t* text, const float* positions, int count,
+            const SkPaint& paint, float x, float y,
+            float boundsLeft, float boundsTop, float boundsRight, float boundsBottom,
+            float totalAdvance) override;
+    virtual void drawGlyphsOnPath(const uint16_t* glyphs, int count, const SkPath& path,
+            float hOffset, float vOffset, const SkPaint& paint) override;
+
 private:
     const ClipBase* getRecordedClip() {
         return mState.writableSnapshot()->mutateClipArea().serializeClip(alloc());
diff --git a/libs/hwui/SkiaCanvas.cpp b/libs/hwui/SkiaCanvas.cpp
index b1ecb71..5d24fa0 100644
--- a/libs/hwui/SkiaCanvas.cpp
+++ b/libs/hwui/SkiaCanvas.cpp
@@ -147,13 +147,6 @@
             float dstLeft, float dstTop, float dstRight, float dstBottom,
             const SkPaint* paint) override;
 
-    virtual void drawGlyphs(const uint16_t* text, const float* positions, int count,
-            const SkPaint& paint, float x, float y,
-            float boundsLeft, float boundsTop, float boundsRight, float boundsBottom,
-            float totalAdvance) override;
-    virtual void drawGlyphsOnPath(const uint16_t* glyphs, int count, const SkPath& path,
-            float hOffset, float vOffset, const SkPaint& paint) override;
-
     virtual bool drawTextAbsolutePos() const  override { return true; }
     virtual void drawVectorDrawable(VectorDrawableRoot* vectorDrawable) override;
 
@@ -169,6 +162,14 @@
     virtual void drawRenderNode(uirenderer::RenderNode* renderNode) override;
     virtual void callDrawGLFunction(Functor* functor) override;
 
+protected:
+    virtual void drawGlyphs(const uint16_t* text, const float* positions, int count,
+            const SkPaint& paint, float x, float y,
+            float boundsLeft, float boundsTop, float boundsRight, float boundsBottom,
+            float totalAdvance) override;
+    virtual void drawGlyphsOnPath(const uint16_t* glyphs, int count, const SkPath& path,
+            float hOffset, float vOffset, const SkPaint& paint) override;
+
 private:
     struct SaveRec {
         int              saveCount;
@@ -761,14 +762,8 @@
         const SkPaint& paint, float x, float y,
         float boundsLeft, float boundsTop, float boundsRight, float boundsBottom,
         float totalAdvance) {
-    // Set align to left for drawing, as we don't want individual
-    // glyphs centered or right-aligned; the offset above takes
-    // care of all alignment.
-    SkPaint paintCopy(paint);
-    paintCopy.setTextAlign(SkPaint::kLeft_Align);
-
     static_assert(sizeof(SkPoint) == sizeof(float)*2, "SkPoint is no longer two floats");
-    mCanvas->drawPosText(text, count << 1, reinterpret_cast<const SkPoint*>(positions), paintCopy);
+    mCanvas->drawPosText(text, count << 1, reinterpret_cast<const SkPoint*>(positions), paint);
     drawTextDecorations(x, y, totalAdvance, paint);
 }
 
diff --git a/libs/hwui/hwui/Canvas.cpp b/libs/hwui/hwui/Canvas.cpp
index 8c3eea3..7bfa15a 100644
--- a/libs/hwui/hwui/Canvas.cpp
+++ b/libs/hwui/hwui/Canvas.cpp
@@ -166,6 +166,11 @@
         bounds.offset(x, y);
     }
 
+    // Set align to left for drawing, as we don't want individual
+    // glyphs centered or right-aligned; the offset above takes
+    // care of all alignment.
+    paint.setTextAlign(Paint::kLeft_Align);
+
     DrawTextFunctor f(layout, this, glyphs.get(), pos.get(),
             paint, x, y, bounds, layout.getAdvance());
     MinikinUtils::forFontRun(layout, &paint, f);
diff --git a/libs/hwui/hwui/Canvas.h b/libs/hwui/hwui/Canvas.h
index dc669f0..5dbda43 100644
--- a/libs/hwui/hwui/Canvas.h
+++ b/libs/hwui/hwui/Canvas.h
@@ -53,6 +53,7 @@
 } // namespace SaveFlags
 
 namespace uirenderer {
+class SkiaCanvasProxy;
 namespace VectorDrawable {
 class Tree;
 };
@@ -205,19 +206,6 @@
             float dstLeft, float dstTop, float dstRight, float dstBottom,
             const SkPaint* paint) = 0;
 
-    // Text
-    /**
-     * drawText: count is of glyphs
-     * totalAdvance: used to define width of text decorations (underlines, strikethroughs).
-     */
-    virtual void drawGlyphs(const uint16_t* glyphs, const float* positions, int count,
-            const SkPaint& paint, float x, float y,
-            float boundsLeft, float boundsTop, float boundsRight, float boundsBottom,
-            float totalAdvance) = 0;
-    /** drawTextOnPath: count is of glyphs */
-    virtual void drawGlyphsOnPath(const uint16_t* glyphs, int count, const SkPath& path,
-            float hOffset, float vOffset, const SkPaint& paint) = 0;
-
     /**
      * Specifies if the positions passed to ::drawText are absolute or relative
      * to the (x,y) value provided.
@@ -244,6 +232,22 @@
 
 protected:
     void drawTextDecorations(float x, float y, float length, const SkPaint& paint);
+
+    /**
+     * drawText: count is of glyphs
+     * totalAdvance: used to define width of text decorations (underlines, strikethroughs).
+     */
+    virtual void drawGlyphs(const uint16_t* glyphs, const float* positions, int count,
+            const SkPaint& paint, float x, float y,
+            float boundsLeft, float boundsTop, float boundsRight, float boundsBottom,
+            float totalAdvance) = 0;
+    /** drawTextOnPath: count is of glyphs */
+    virtual void drawGlyphsOnPath(const uint16_t* glyphs, int count, const SkPath& path,
+            float hOffset, float vOffset, const SkPaint& paint) = 0;
+
+    friend class DrawTextFunctor;
+    friend class DrawTextOnPathFunctor;
+    friend class uirenderer::SkiaCanvasProxy;
 };
 
 }; // namespace android
diff --git a/libs/hwui/hwui/Paint.h b/libs/hwui/hwui/Paint.h
index 69c321c..9599c30 100644
--- a/libs/hwui/hwui/Paint.h
+++ b/libs/hwui/hwui/Paint.h
@@ -30,6 +30,7 @@
 public:
     Paint();
     Paint(const Paint& paint);
+    Paint(const SkPaint& paint);
     ~Paint();
 
     Paint& operator=(const Paint& other);
diff --git a/libs/hwui/hwui/PaintImpl.cpp b/libs/hwui/hwui/PaintImpl.cpp
index 1172a0e..b27672c 100644
--- a/libs/hwui/hwui/PaintImpl.cpp
+++ b/libs/hwui/hwui/PaintImpl.cpp
@@ -29,6 +29,11 @@
         mHyphenEdit(paint.mHyphenEdit) {
 }
 
+Paint::Paint(const SkPaint& paint) : SkPaint(paint),
+        mLetterSpacing(0), mFontFeatureSettings(), mMinikinLangListId(0),
+        mFontVariant(VARIANT_DEFAULT) {
+}
+
 Paint::~Paint() {
 }
 
diff --git a/libs/hwui/tests/common/TestUtils.cpp b/libs/hwui/tests/common/TestUtils.cpp
index a4aee61..e1c9319 100644
--- a/libs/hwui/tests/common/TestUtils.cpp
+++ b/libs/hwui/tests/common/TestUtils.cpp
@@ -16,6 +16,7 @@
 
 #include "TestUtils.h"
 
+#include "hwui/Paint.h"
 #include "DeferredLayerUpdater.h"
 #include "LayerRenderer.h"
 
@@ -87,50 +88,17 @@
     *outTotalAdvance = totalAdvance;
 }
 
-void TestUtils::drawUtf8ToCanvas(TestCanvas* canvas, const char* text,
+
+void TestUtils::drawUtf8ToCanvas(Canvas* canvas, const char* text,
         const SkPaint& paint, float x, float y) {
-    // drawing text requires GlyphID TextEncoding (which JNI layer would have done)
-    LOG_ALWAYS_FATAL_IF(paint.getTextEncoding() != SkPaint::kGlyphID_TextEncoding,
-            "must use glyph encoding");
-    SkSurfaceProps surfaceProps(0, kUnknown_SkPixelGeometry);
-    SkAutoGlyphCacheNoGamma autoCache(paint, &surfaceProps, &SkMatrix::I());
-
-    std::vector<glyph_t> glyphs;
-    std::vector<float> positions;
-    float totalAdvance;
-    Rect bounds;
-    layoutTextUnscaled(paint, text, &glyphs, &positions, &totalAdvance, &bounds);
-
-    // apply alignment via x parameter (which JNI layer would have done)
-    if (paint.getTextAlign() == SkPaint::kCenter_Align) {
-        x -= totalAdvance / 2;
-    } else if (paint.getTextAlign() == SkPaint::kRight_Align) {
-        x -= totalAdvance;
-    }
-
-    bounds.translate(x, y);
-
-    // Force left alignment, since alignment offset is already baked in
-    SkPaint alignPaintCopy(paint);
-    alignPaintCopy.setTextAlign(SkPaint::kLeft_Align);
-    canvas->drawGlyphs(glyphs.data(), positions.data(), glyphs.size(), alignPaintCopy, x, y,
-                bounds.left, bounds.top, bounds.right, bounds.bottom, totalAdvance);
+    auto utf16 = asciiToUtf16(text);
+    canvas->drawText(utf16.get(), 0, strlen(text), strlen(text), x, y, 0, paint, nullptr);
 }
 
-void TestUtils::drawUtf8ToCanvas(TestCanvas* canvas, const char* text,
+void TestUtils::drawUtf8ToCanvas(Canvas* canvas, const char* text,
         const SkPaint& paint, const SkPath& path) {
-    // drawing text requires GlyphID TextEncoding (which JNI layer would have done)
-    LOG_ALWAYS_FATAL_IF(paint.getTextEncoding() != SkPaint::kGlyphID_TextEncoding,
-            "must use glyph encoding");
-    SkSurfaceProps surfaceProps(0, kUnknown_SkPixelGeometry);
-    SkAutoGlyphCacheNoGamma autoCache(paint, &surfaceProps, &SkMatrix::I());
-
-    std::vector<glyph_t> glyphs;
-    while (*text != '\0') {
-        SkUnichar unichar = SkUTF8_NextUnichar(&text);
-        glyphs.push_back(autoCache.getCache()->unicharToGlyph(unichar));
-    }
-    canvas->drawGlyphsOnPath(glyphs.data(), glyphs.size(), path, 0, 0, paint);
+    auto utf16 = asciiToUtf16(text);
+    canvas->drawTextOnPath(utf16.get(), strlen(text), 0, path, 0, 0, paint, nullptr);
 }
 
 void TestUtils::TestTask::run() {
@@ -143,12 +111,13 @@
     renderState.onGLContextDestroyed();
 }
 
-std::unique_ptr<uint16_t[]> TestUtils::utf8ToUtf16(const char* str) {
-    const size_t strLen = strlen(str);
-    const ssize_t utf16Len = utf8_to_utf16_length((uint8_t*) str, strLen);
-    std::unique_ptr<uint16_t[]> dst(new uint16_t[utf16Len + 1]);
-    utf8_to_utf16((uint8_t*) str, strLen, (char16_t*) dst.get());
-    return dst;
+std::unique_ptr<uint16_t[]> TestUtils::asciiToUtf16(const char* str) {
+    const int length = strlen(str);
+    std::unique_ptr<uint16_t[]> utf16(new uint16_t[length]);
+    for (int i = 0; i < length; i++) {
+        utf16.get()[i] = str[i];
+    }
+    return utf16;
 }
 
 } /* namespace uirenderer */
diff --git a/libs/hwui/tests/common/TestUtils.h b/libs/hwui/tests/common/TestUtils.h
index a5e7a5f..73027e2 100644
--- a/libs/hwui/tests/common/TestUtils.h
+++ b/libs/hwui/tests/common/TestUtils.h
@@ -207,13 +207,13 @@
             std::vector<glyph_t>* outGlyphs, std::vector<float>* outPositions,
             float* outTotalAdvance, Rect* outBounds);
 
-    static void drawUtf8ToCanvas(TestCanvas* canvas, const char* text,
+    static void drawUtf8ToCanvas(Canvas* canvas, const char* text,
             const SkPaint& paint, float x, float y);
 
-    static void drawUtf8ToCanvas(TestCanvas* canvas, const char* text,
+    static void drawUtf8ToCanvas(Canvas* canvas, const char* text,
             const SkPaint& paint, const SkPath& path);
 
-    static std::unique_ptr<uint16_t[]> utf8ToUtf16(const char* str);
+    static std::unique_ptr<uint16_t[]> asciiToUtf16(const char* str);
 
 private:
     static void syncHierarchyPropertiesAndDisplayListImpl(RenderNode* node) {
diff --git a/libs/hwui/tests/common/scenes/GlyphStressAnimation.cpp b/libs/hwui/tests/common/scenes/GlyphStressAnimation.cpp
index 52039ef..63c067b 100644
--- a/libs/hwui/tests/common/scenes/GlyphStressAnimation.cpp
+++ b/libs/hwui/tests/common/scenes/GlyphStressAnimation.cpp
@@ -42,7 +42,7 @@
     }
 
     void doFrame(int frameNr) override {
-        std::unique_ptr<uint16_t[]> text = TestUtils::utf8ToUtf16(
+        std::unique_ptr<uint16_t[]> text = TestUtils::asciiToUtf16(
                 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
         ssize_t textLength = 26 * 2;
 
diff --git a/libs/hwui/tests/unit/FrameBuilderTests.cpp b/libs/hwui/tests/unit/FrameBuilderTests.cpp
index 0aabfb1..99400c6 100644
--- a/libs/hwui/tests/unit/FrameBuilderTests.cpp
+++ b/libs/hwui/tests/unit/FrameBuilderTests.cpp
@@ -344,8 +344,9 @@
             EXPECT_TRUE(stroke.contains(fill));
             EXPECT_FALSE(fill.contains(stroke));
 
+            // outset by half the stroke width
             Rect outsetFill(fill);
-            outsetFill.outset(10);
+            outsetFill.outset(5);
             EXPECT_EQ(stroke, outsetFill);
         }
     };
diff --git a/libs/hwui/tests/unit/RecordingCanvasTests.cpp b/libs/hwui/tests/unit/RecordingCanvasTests.cpp
index ca72673..42dabd3 100644
--- a/libs/hwui/tests/unit/RecordingCanvasTests.cpp
+++ b/libs/hwui/tests/unit/RecordingCanvasTests.cpp
@@ -570,36 +570,30 @@
 
 TEST(RecordingCanvas, refPaint) {
     SkPaint paint;
-    paint.setAntiAlias(true);
-    paint.setTextSize(20);
-    paint.setTextAlign(SkPaint::kLeft_Align);
-    paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
 
     auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [&paint](RecordingCanvas& canvas) {
         paint.setColor(SK_ColorBLUE);
-        // first three should use same paint
+        // first two should use same paint
         canvas.drawRect(0, 0, 200, 10, paint);
         SkPaint paintCopy(paint);
         canvas.drawRect(0, 10, 200, 20, paintCopy);
-        TestUtils::drawUtf8ToCanvas(&canvas, "helloworld", paint, 50, 25);
 
         // only here do we use different paint ptr
         paint.setColor(SK_ColorRED);
         canvas.drawRect(0, 20, 200, 30, paint);
     });
     auto ops = dl->getOps();
-    ASSERT_EQ(4u, ops.size());
+    ASSERT_EQ(3u, ops.size());
 
-    // first three are the same
+    // first two are the same
     EXPECT_NE(nullptr, ops[0]->paint);
     EXPECT_NE(&paint, ops[0]->paint);
     EXPECT_EQ(ops[0]->paint, ops[1]->paint);
-    EXPECT_EQ(ops[0]->paint, ops[2]->paint);
 
     // last is different, but still copied / non-null
-    EXPECT_NE(nullptr, ops[3]->paint);
-    EXPECT_NE(ops[0]->paint, ops[3]->paint);
-    EXPECT_NE(&paint, ops[3]->paint);
+    EXPECT_NE(nullptr, ops[2]->paint);
+    EXPECT_NE(ops[0]->paint, ops[2]->paint);
+    EXPECT_NE(&paint, ops[2]->paint);
 }
 
 TEST(RecordingCanvas, refBitmapInShader_bitmapShader) {
@@ -647,7 +641,7 @@
         paint.setAntiAlias(true);
         paint.setTextSize(20);
         paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
-        std::unique_ptr<uint16_t[]> dst = TestUtils::utf8ToUtf16("HELLO");
+        std::unique_ptr<uint16_t[]> dst = TestUtils::asciiToUtf16("HELLO");
         canvas.drawText(dst.get(), 0, 5, 5, 25, 25, kBidi_Force_LTR, paint, NULL);
     });
 
@@ -671,7 +665,7 @@
         paint.setAntiAlias(true);
         paint.setTextSize(20);
         paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
-        std::unique_ptr<uint16_t[]> dst = TestUtils::utf8ToUtf16("HELLO");
+        std::unique_ptr<uint16_t[]> dst = TestUtils::asciiToUtf16("HELLO");
         canvas.drawText(dst.get(), 0, 5, 5, 25, 25, kBidi_Force_LTR, paint, NULL);
     });