blob: 17799422b64d8e5b004ca20565b37ee505332c01 [file] [log] [blame]
epoger@google.com213c42b2011-06-28 16:20:27 +00001/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00002 * Copyright 2011 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
epoger@google.com213c42b2011-06-28 16:20:27 +00006 */
7
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "gm/gm.h"
9#include "include/core/SkCanvas.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040010#include "include/core/SkColor.h"
11#include "include/core/SkFont.h"
12#include "include/core/SkMatrix.h"
13#include "include/core/SkPaint.h"
14#include "include/core/SkPoint.h"
15#include "include/core/SkRefCnt.h"
16#include "include/core/SkScalar.h"
17#include "include/core/SkSize.h"
18#include "include/core/SkString.h"
19#include "include/core/SkTypeface.h"
20#include "include/core/SkTypes.h"
epoger@google.com213c42b2011-06-28 16:20:27 +000021
reed4942e752014-10-01 13:59:33 -070022class LcdTextGM : public skiagm::GM {
Hal Canaryfa3305a2019-07-18 12:36:54 -040023 static constexpr SkScalar kTextHeight = 36;
24 SkScalar fY = kTextHeight;
halcanary9d524f22016-03-29 09:03:52 -070025
Hal Canaryfa3305a2019-07-18 12:36:54 -040026 SkString onShortName() override { return SkString("lcdtext"); }
halcanary9d524f22016-03-29 09:03:52 -070027
Hal Canaryfa3305a2019-07-18 12:36:54 -040028 SkISize onISize() override { return {640, 480}; }
halcanary9d524f22016-03-29 09:03:52 -070029
Hal Canaryfa3305a2019-07-18 12:36:54 -040030 void onDraw(SkCanvas* canvas) override {
31 fY = kTextHeight;
epoger@google.com213c42b2011-06-28 16:20:27 +000032 drawText(canvas, SkString("TEXT: SubpixelTrue LCDRenderTrue"),
33 true, true);
34 drawText(canvas, SkString("TEXT: SubpixelTrue LCDRenderFalse"),
35 true, false);
36 drawText(canvas, SkString("TEXT: SubpixelFalse LCDRenderTrue"),
37 false, true);
38 drawText(canvas, SkString("TEXT: SubpixelFalse LCDRenderFalse"),
39 false, false);
40 }
halcanary9d524f22016-03-29 09:03:52 -070041
epoger@google.com213c42b2011-06-28 16:20:27 +000042 void drawText(SkCanvas* canvas, const SkString& string,
43 bool subpixelTextEnabled, bool lcdRenderTextEnabled) {
44 SkPaint paint;
45 paint.setColor(SK_ColorBLACK);
46 paint.setDither(true);
Hal Canaryfa3305a2019-07-18 12:36:54 -040047 SkFont font(nullptr, kTextHeight);
Hal Canary6ac0df82019-01-07 16:01:22 -050048 if (subpixelTextEnabled) {
49 font.setSubpixel(true);
50 }
51 if (lcdRenderTextEnabled) {
52 font.setEdging(SkFont::Edging::kSubpixelAntiAlias);
53 }
Hal Canaryfa3305a2019-07-18 12:36:54 -040054 canvas->drawString(string, 0, fY, font, paint);
55 fY += kTextHeight;
epoger@google.com213c42b2011-06-28 16:20:27 +000056 }
reed4942e752014-10-01 13:59:33 -070057};
58
59/*
60 * Skia will automatically disable LCD requests if the total size exceeds some limit
61 * (hard coded in this test for now, as it is now avaiable as an API)
62 *
63 * Test this both by changing "textsize" and by changing the computed size (textsize * CTM)
64 */
65class LcdTextSizeGM : public skiagm::GM {
reed4942e752014-10-01 13:59:33 -070066 static void ScaleAbout(SkCanvas* canvas, SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) {
67 SkMatrix m;
68 m.setScale(sx, sy, px, py);
69 canvas->concat(m);
70 }
71
Hal Canaryfa3305a2019-07-18 12:36:54 -040072 SkString onShortName() override { return SkString("lcdtextsize"); }
halcanary9d524f22016-03-29 09:03:52 -070073
Hal Canaryfa3305a2019-07-18 12:36:54 -040074 SkISize onISize() override { return {320, 120}; }
halcanary9d524f22016-03-29 09:03:52 -070075
Hal Canaryfa3305a2019-07-18 12:36:54 -040076 void onDraw(SkCanvas* canvas) override {
reed4942e752014-10-01 13:59:33 -070077 const char* lcd_text = "LCD";
78 const char* gray_text = "GRAY";
79
Hal Canaryfa3305a2019-07-18 12:36:54 -040080 constexpr static float kLCDTextSizeLimit = 48;
81
reed4942e752014-10-01 13:59:33 -070082 const struct {
83 SkPoint fLoc;
84 SkScalar fTextSize;
85 SkScalar fScale;
86 const char* fText;
87 } rec[] = {
88 { { 10, 50 }, kLCDTextSizeLimit - 1, 1, lcd_text },
89 { { 160, 50 }, kLCDTextSizeLimit + 1, 1, gray_text },
90 { { 10, 100 }, kLCDTextSizeLimit / 2, 1.99f, lcd_text },
91 { { 160, 100 }, kLCDTextSizeLimit / 2, 2.01f, gray_text },
92 };
93
94 for (size_t i = 0; i < SK_ARRAY_COUNT(rec); ++i) {
95 const SkPoint loc = rec[i].fLoc;
96 SkAutoCanvasRestore acr(canvas, true);
97
Hal Canary6ac0df82019-01-07 16:01:22 -050098 SkFont font(nullptr, rec[i].fTextSize);
99 font.setEdging(SkFont::Edging::kSubpixelAntiAlias);
100
reed4942e752014-10-01 13:59:33 -0700101 ScaleAbout(canvas, rec[i].fScale, rec[i].fScale, loc.x(), loc.y());
Hal Canary6ac0df82019-01-07 16:01:22 -0500102 canvas->drawString(rec[i].fText, loc.x(), loc.y(), font, SkPaint());
reed4942e752014-10-01 13:59:33 -0700103 }
104 }
epoger@google.com213c42b2011-06-28 16:20:27 +0000105};
Xianzhu Wanga91e4782020-05-01 09:34:57 -0700106
107class SaveLayerPreserveLCDTextGM : public skiagm::GM {
108 static constexpr SkScalar kTextHeight = 36;
109
110 SkString onShortName() override { return SkString("savelayerpreservelcdtext"); }
111
112 SkISize onISize() override { return {620, 300}; }
113
114 void onDraw(SkCanvas* canvas) override {
115 drawText(canvas, SkString("SaveLayer PreserveLCDText"), 50,
116 SkCanvas::kPreserveLCDText_SaveLayerFlag);
117 drawText(canvas, SkString("SaveLayer Default (LCDText not preserved)"), 150, 0);
118 }
119
120 void drawText(SkCanvas* canvas,
121 const SkString& string,
122 int y,
123 SkCanvas::SaveLayerFlags saveLayerFlags) {
124 SkCanvas::SaveLayerRec rec(nullptr, nullptr, saveLayerFlags);
125 canvas->saveLayer(rec);
126 SkPaint paint;
127 paint.setColor(SK_ColorWHITE);
128 canvas->drawRect(SkRect::MakeXYWH(0, y - 10, 640, kTextHeight + 20), paint);
129 paint.setColor(SK_ColorBLACK);
130 SkFont font(nullptr, kTextHeight);
131 font.setEdging(SkFont::Edging::kSubpixelAntiAlias);
132 canvas->drawString(string, 10, y, font, paint);
133 canvas->restore();
134 }
135};
136
137DEF_GM(return new LcdTextGM;)
138DEF_GM(return new LcdTextSizeGM;)
139DEF_GM(return new SaveLayerPreserveLCDTextGM;)