Add gm for various font rendering combinations.
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2080453002

Review-Url: https://codereview.chromium.org/2080453002
diff --git a/gm/typeface.cpp b/gm/typeface.cpp
index e4e0d24..8b6a648 100644
--- a/gm/typeface.cpp
+++ b/gm/typeface.cpp
@@ -6,8 +6,10 @@
  */
 
 #include "gm.h"
+#include "Resources.h"
 #include "SkCanvas.h"
 #include "SkString.h"
+#include "SkSurfaceProps.h"
 #include "SkTypeface.h"
 #include "SkTypes.h"
 
@@ -152,7 +154,128 @@
     typedef skiagm::GM INHERITED;
 };
 
+static void rotate_about(SkCanvas* canvas,
+                         SkScalar degrees,
+                         SkScalar px, SkScalar py) {
+    canvas->translate(px, py);
+    canvas->rotate(degrees);
+    canvas->translate(-px, -py);
+}
+
+class TypefaceRenderingGM : public skiagm::GM {
+    sk_sp<SkTypeface> fFace;
+
+public:
+    TypefaceRenderingGM() { }
+
+protected:
+    void onOnceBeforeDraw() override {
+        fFace = MakeResourceAsTypeface("/fonts/hintgasp.ttf");
+    }
+
+    SkString onShortName() override {
+        SkString name("typefacerendering");
+        name.append(sk_tool_utils::major_platform_os_name());
+        return name;
+    }
+
+    SkISize onISize() override {
+        return SkISize::Make(640, 480);
+    }
+
+    void onDraw(SkCanvas* canvas) override {
+        struct AliasType {
+            bool antiAlias;
+            bool subpixelAntitalias;
+            bool inLayer;
+        } constexpr aliasTypes[] {
+            { false, false, false },  // aliased
+            { true,  false, false },  // anti-aliased
+            { true,  true , false },  // subpixel anti-aliased
+            { true,  false, true  },  // anti-aliased in layer (flat pixel geometry)
+            { true,  true , true  },  // subpixel anti-aliased in layer (flat pixel geometry)
+        };
+
+        // The hintgasp.ttf is designed for the following sizes to be different.
+        // GASP_DOGRAY                                      0x0002   0<=ppem<=10
+        // GASP_SYMMETRIC_SMOOTHING                         0x0008   0<=ppem<=10
+        // GASP_GRIDFIT                                     0x0001  11<=ppem<=12
+        // GASP_SYMMETRIC_GRIDFIT                           0x0004  11<=ppem<=12
+        // GASP_DOGRAY|GASP_GRIDFIT                         0x0003  13<=ppem<=14
+        // GASP_SYMMETRIC_SMOOTHING|GASP_SYMMETRIC_GRIDFIT  0x000C  13<=ppem<=14
+        // (neither)                                        0x0000  15<=ppem
+        constexpr SkScalar textSizes[] = { 10, 12, 14, 16 };
+
+        constexpr SkPaint::Hinting hintingTypes[] = { SkPaint::kNo_Hinting,
+                                                      SkPaint::kSlight_Hinting,
+                                                      SkPaint::kNormal_Hinting,
+                                                      SkPaint::kFull_Hinting };
+
+        struct SubpixelType {
+            bool requested;
+            SkVector offset;
+        } constexpr subpixelTypes[] = {
+            { false, { 0.00, 0.00 } },
+            { true , { 0.00, 0.00 } },
+            { true , { 0.25, 0.00 } },
+            { true , { 0.25, 0.25 } },
+        };
+
+        constexpr bool rotateABitTypes[] = { false, true };
+
+        SkPaint paint;
+        SkScalar x = 0;
+        SkScalar xMax = x;
+        SkScalar xBase = 0;
+        SkScalar y = 0;  // The baseline of the previous output
+        for (const SubpixelType subpixel : subpixelTypes) {
+            y = 0;
+            paint.setSubpixelText(subpixel.requested);
+
+            for (const AliasType& alias : aliasTypes) {
+                paint.setAntiAlias(alias.antiAlias);
+                paint.setLCDRenderText(alias.subpixelAntitalias);
+                SkAutoCanvasRestore acr(canvas, false);
+                if (alias.inLayer) {
+                    canvas->saveLayer(nullptr, &paint);
+                }
+
+                for (const SkScalar& textSize : textSizes) {
+                    x = xBase + 5;
+                    paint.setTextSize(textSize);
+
+                    SkScalar dy = SkScalarCeilToScalar(paint.getFontMetrics(nullptr));
+                    y += dy;
+                    for (const SkPaint::Hinting& hinting : hintingTypes) {
+                        paint.setHinting(hinting);
+
+                        for (const bool& rotateABit : rotateABitTypes) {
+                            SkAutoCanvasRestore acr(canvas, true);
+                            if (rotateABit) {
+                                rotate_about(canvas, 2, x + subpixel.offset.x(),
+                                                        y + subpixel.offset.y());
+                            }
+                            canvas->drawText("A", 1, x + subpixel.offset.x(),
+                                                     y + subpixel.offset.y(), paint);
+
+                            SkScalar dx = SkScalarCeilToScalar(paint.measureText("A", 1)) + 5;
+                            x += dx;
+                            xMax = SkTMax(x, xMax);
+                        }
+                    }
+                }
+                y += 10;
+            }
+            xBase = xMax;
+        }
+    }
+
+private:
+    typedef skiagm::GM INHERITED;
+};
+
 ///////////////////////////////////////////////////////////////////////////////
 
 DEF_GM( return new TypefaceStylesGM(false); )
 DEF_GM( return new TypefaceStylesGM(true); )
+DEF_GM( return new TypefaceRenderingGM(); )
diff --git a/resources/fonts/hintgasp.ttf b/resources/fonts/hintgasp.ttf
new file mode 100644
index 0000000..f533643
--- /dev/null
+++ b/resources/fonts/hintgasp.ttf
Binary files differ