Index: gm/typeface.cpp |
diff --git a/gm/typeface.cpp b/gm/typeface.cpp |
index e4e0d24867bde99524c45b0901e29373dc5f27d4..8b6a64866bb259291f3e7c2557a12e205a3ccffe 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 @@ private: |
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(); ) |