• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * 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.
6  */
7 
8 #include "gm/gm.h"
9 #include "include/core/SkCanvas.h"
10 #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"
21 
22 class LcdTextGM : public skiagm::GM {
23     static constexpr SkScalar kTextHeight = 36;
24     SkScalar fY = kTextHeight;
25 
onShortName()26     SkString onShortName() override { return SkString("lcdtext"); }
27 
onISize()28     SkISize onISize() override { return {640, 480}; }
29 
onDraw(SkCanvas * canvas)30     void onDraw(SkCanvas* canvas) override {
31         fY = kTextHeight;
32         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     }
41 
drawText(SkCanvas * canvas,const SkString & string,bool subpixelTextEnabled,bool lcdRenderTextEnabled)42     void drawText(SkCanvas* canvas, const SkString& string,
43                   bool subpixelTextEnabled, bool lcdRenderTextEnabled) {
44         SkPaint paint;
45         paint.setColor(SK_ColorBLACK);
46         paint.setDither(true);
47         SkFont font(nullptr, kTextHeight);
48         if (subpixelTextEnabled) {
49             font.setSubpixel(true);
50         }
51         if (lcdRenderTextEnabled) {
52             font.setEdging(SkFont::Edging::kSubpixelAntiAlias);
53         }
54         canvas->drawString(string, 0, fY, font, paint);
55         fY += kTextHeight;
56     }
57 };
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  */
65 class LcdTextSizeGM : public skiagm::GM {
ScaleAbout(SkCanvas * canvas,SkScalar sx,SkScalar sy,SkScalar px,SkScalar py)66     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 
onShortName()72     SkString onShortName() override { return SkString("lcdtextsize"); }
73 
onISize()74     SkISize onISize() override { return {320, 120}; }
75 
onDraw(SkCanvas * canvas)76     void onDraw(SkCanvas* canvas) override {
77         const char* lcd_text = "LCD";
78         const char* gray_text = "GRAY";
79 
80         constexpr static float kLCDTextSizeLimit = 48;
81 
82         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 
98             SkFont font(nullptr, rec[i].fTextSize);
99             font.setEdging(SkFont::Edging::kSubpixelAntiAlias);
100 
101             ScaleAbout(canvas, rec[i].fScale, rec[i].fScale, loc.x(), loc.y());
102             canvas->drawString(rec[i].fText, loc.x(), loc.y(), font, SkPaint());
103         }
104     }
105 };
106 
107 class SaveLayerPreserveLCDTextGM : public skiagm::GM {
108     static constexpr SkScalar kTextHeight = 36;
109 
onShortName()110     SkString onShortName() override { return SkString("savelayerpreservelcdtext"); }
111 
onISize()112     SkISize onISize() override { return {620, 300}; }
113 
onDraw(SkCanvas * canvas)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 
drawText(SkCanvas * canvas,const SkString & string,int y,SkCanvas::SaveLayerFlags saveLayerFlags)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 
137 DEF_GM(return new LcdTextGM;)
138 DEF_GM(return new LcdTextSizeGM;)
139 DEF_GM(return new SaveLayerPreserveLCDTextGM;)
140