Test font created from paint

This is meant to allow clients to migrate over to a SkFont api on canvas (e.g. drawText(text, font, paint)) while still permitting the current setters in paint (e.g. setTextSize, setFlags).

R=bungeman@google.com, eae@chromium.org, fmalita@google.com, fmalita@chromium.org

Author: reed@google.com

Review URL: https://codereview.chromium.org/245953003

git-svn-id: http://skia.googlecode.com/svn/trunk@14997 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gyp/tests.gypi b/gyp/tests.gypi
index 90d7c1f..46d40fc 100644
--- a/gyp/tests.gypi
+++ b/gyp/tests.gypi
@@ -78,6 +78,7 @@
     '../tests/FlateTest.cpp',
     '../tests/FontHostStreamTest.cpp',
     '../tests/FontHostTest.cpp',
+    '../tests/FontObjTest.cpp',
     '../tests/FontMgrTest.cpp',
     '../tests/FontNamesTest.cpp',
     '../tests/FrontBufferedStreamTest.cpp',
diff --git a/include/core/SkFont.h b/include/core/SkFont.h
index 4891926..9bdecd6 100644
--- a/include/core/SkFont.h
+++ b/include/core/SkFont.h
@@ -5,6 +5,9 @@
  * found in the LICENSE file.
  */
 
+#ifndef SkFont_DEFINED
+#define SkFont_DEFINED
+
 #include "SkRefCnt.h"
 #include "SkScalar.h"
 
@@ -125,6 +128,12 @@
     uint32_t    getFlags() const { return fFlags; }
     MaskType    getMaskType() const { return (MaskType)fMaskType; }
 
+    bool isVertical() const { return SkToBool(fFlags & kVertical_Flag); }
+    bool isEmbolden() const { return SkToBool(fFlags & kEmbolden_Flag); }
+    bool isEnableAutoHints() const { return SkToBool(fFlags & kEnableAutoHints_Flag); }
+    bool isEnableByteCodeHints() const { return SkToBool(fFlags & kEnableByteCodeHints_Flag); }
+    bool isUseNonLinearMetrics() const { return SkToBool(fFlags & kUseNonlinearMetrics_Flag); }
+
     int textToGlyphs(const void* text, size_t byteLength, SkTextEncoding,
                      uint16_t glyphs[], int maxGlyphCount) const;
 
@@ -148,3 +157,5 @@
     uint8_t     fMaskType;
 //  uint8_t     fPad;
 };
+
+#endif
diff --git a/tests/FontObjTest.cpp b/tests/FontObjTest.cpp
new file mode 100644
index 0000000..d6d60c5
--- /dev/null
+++ b/tests/FontObjTest.cpp
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkFont.h"
+#include "SkPaint.h"
+#include "SkTypeface.h"
+#include "Test.h"
+
+static bool is_use_nonlinear_metrics(const SkPaint& paint) {
+    return !paint.isSubpixelText() && !paint.isLinearText();
+}
+
+static bool is_enable_auto_hints(const SkPaint& paint) {
+    return paint.isAutohinted();
+}
+
+static bool is_enable_bytecode_hints(const SkPaint& paint) {
+    return paint.getHinting() >= SkPaint::kFull_Hinting;
+}
+
+static void test_cachedfont(skiatest::Reporter* reporter, const SkPaint& paint) {
+    SkAutoTUnref<SkFont> font(SkFont::Testing_CreateFromPaint(paint));
+
+    REPORTER_ASSERT(reporter, font->getTypeface() == paint.getTypeface());
+    REPORTER_ASSERT(reporter, font->getSize() == paint.getTextSize());
+    REPORTER_ASSERT(reporter, font->getScaleX() == paint.getTextScaleX());
+    REPORTER_ASSERT(reporter, font->getSkewX() == paint.getTextSkewX());
+
+    REPORTER_ASSERT(reporter, font->isVertical() == paint.isVerticalText());
+    REPORTER_ASSERT(reporter, font->isEmbolden() == paint.isFakeBoldText());
+
+    REPORTER_ASSERT(reporter, font->isUseNonLinearMetrics() == is_use_nonlinear_metrics(paint));
+    REPORTER_ASSERT(reporter, font->isEnableAutoHints() == is_enable_auto_hints(paint));
+    REPORTER_ASSERT(reporter, font->isEnableByteCodeHints() == is_enable_bytecode_hints(paint));
+}
+
+static void test_cachedfont(skiatest::Reporter* reporter) {
+    static const char* const faces[] = {
+        NULL,   // default font
+        "Arial", "Times", "Times New Roman", "Helvetica", "Courier",
+        "Courier New", "Verdana", "monospace",
+    };
+
+    static const struct {
+        SkPaint::Hinting    hinting;
+        unsigned            flags;
+    } settings[] = {
+        { SkPaint::kNo_Hinting,     0                               },
+        { SkPaint::kNo_Hinting,     SkPaint::kLinearText_Flag       },
+        { SkPaint::kNo_Hinting,     SkPaint::kSubpixelText_Flag     },
+        { SkPaint::kSlight_Hinting, 0                               },
+        { SkPaint::kSlight_Hinting, SkPaint::kLinearText_Flag       },
+        { SkPaint::kSlight_Hinting, SkPaint::kSubpixelText_Flag     },
+        { SkPaint::kNormal_Hinting, 0                               },
+        { SkPaint::kNormal_Hinting, SkPaint::kLinearText_Flag       },
+        { SkPaint::kNormal_Hinting, SkPaint::kSubpixelText_Flag     },
+    };
+
+    static const struct {
+        SkScalar    fScaleX;
+        SkScalar    fSkewX;
+    } gScaleRec[] = {
+        { SK_Scalar1, 0 },
+        { SK_Scalar1/2, 0 },
+        // these two exercise obliquing (skew)
+        { SK_Scalar1, -SK_Scalar1/4 },
+        { SK_Scalar1/2, -SK_Scalar1/4 },
+    };
+
+    SkPaint paint;
+    char txt[] = "long.text.with.lots.of.dots.";
+
+    for (size_t i = 0; i < SK_ARRAY_COUNT(faces); i++) {
+        SkAutoTUnref<SkTypeface> face(SkTypeface::CreateFromName(faces[i], SkTypeface::kNormal));
+        paint.setTypeface(face);
+
+        for (size_t j = 0; j  < SK_ARRAY_COUNT(settings); j++) {
+            paint.setHinting(settings[j].hinting);
+            paint.setLinearText((settings[j].flags & SkPaint::kLinearText_Flag) != 0);
+            paint.setSubpixelText((settings[j].flags & SkPaint::kSubpixelText_Flag) != 0);
+
+            for (size_t k = 0; k < SK_ARRAY_COUNT(gScaleRec); ++k) {
+                paint.setTextScaleX(gScaleRec[k].fScaleX);
+                paint.setTextSkewX(gScaleRec[k].fSkewX);
+
+                test_cachedfont(reporter, paint);
+
+                SkRect bounds;
+
+                // For no hinting and light hinting this should take the
+                // optimized generateAdvance path.
+                SkScalar width1 = paint.measureText(txt, strlen(txt));
+
+                // Requesting the bounds forces a generateMetrics call.
+                SkScalar width2 = paint.measureText(txt, strlen(txt), &bounds);
+
+                REPORTER_ASSERT(reporter, width1 == width2);
+
+                SkAutoTUnref<SkFont> font(SkFont::Testing_CreateFromPaint(paint));
+                SkScalar font_width1 = font->measureText(txt, strlen(txt), kUTF8_SkTextEncoding);
+                // measureText not yet implemented...
+                REPORTER_ASSERT(reporter, font_width1 == -1);
+//                REPORTER_ASSERT(reporter, width1 == font_width1);
+            }
+        }
+    }
+}
+
+DEF_TEST(FontObj, reporter) {
+    test_cachedfont(reporter);
+}
+
+// need tests for SkStrSearch