lcdtext.cpp revision a3aff06d83854eb614502e4c45231568ea88a0eb
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
9/* Tests text rendering with LCD and subpixel rendering turned on and off.
10 */
11
12#include "gm.h"
13#include "SkCanvas.h"
14
15class LcdTextGM : public skiagm::GM {
16public:
17    LcdTextGM() {
18        const int pointSize = 36;
19        textHeight = SkIntToScalar(pointSize);
20    }
21
22protected:
23
24    SkString onShortName() {
25        return SkString("lcdtext");
26    }
27
28    SkISize onISize() { return SkISize::Make(640, 480); }
29
30    virtual void onDraw(SkCanvas* canvas) {
31
32        y = textHeight;
33        drawText(canvas, SkString("TEXT: SubpixelTrue LCDRenderTrue"),
34                 true,  true);
35        drawText(canvas, SkString("TEXT: SubpixelTrue LCDRenderFalse"),
36                 true,  false);
37        drawText(canvas, SkString("TEXT: SubpixelFalse LCDRenderTrue"),
38                 false, true);
39        drawText(canvas, SkString("TEXT: SubpixelFalse LCDRenderFalse"),
40                 false, false);
41    }
42
43    void drawText(SkCanvas* canvas, const SkString& string,
44                  bool subpixelTextEnabled, bool lcdRenderTextEnabled) {
45        SkPaint paint;
46        paint.setColor(SK_ColorBLACK);
47        paint.setDither(true);
48        paint.setAntiAlias(true);
49        sk_tool_utils::set_portable_typeface(&paint);
50        paint.setSubpixelText(subpixelTextEnabled);
51        paint.setLCDRenderText(lcdRenderTextEnabled);
52        paint.setTextSize(textHeight);
53
54        canvas->drawText(string.c_str(), string.size(), 0, y, paint);
55        y += textHeight;
56    }
57
58private:
59    typedef skiagm::GM INHERITED;
60    SkScalar y, textHeight;
61};
62
63/*
64 *  Skia will automatically disable LCD requests if the total size exceeds some limit
65 *  (hard coded in this test for now, as it is now avaiable as an API)
66 *
67 *  Test this both by changing "textsize" and by changing the computed size (textsize * CTM)
68 */
69class LcdTextSizeGM : public skiagm::GM {
70    enum {
71        kLCDTextSizeLimit = 48
72    };
73
74    static void ScaleAbout(SkCanvas* canvas, SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) {
75        SkMatrix m;
76        m.setScale(sx, sy, px, py);
77        canvas->concat(m);
78    }
79
80public:
81    LcdTextSizeGM() {}
82
83protected:
84    SkString onShortName() {
85        return SkString("lcdtextsize");
86    }
87
88    SkISize onISize() { return SkISize::Make(320, 120); }
89
90    virtual void onDraw(SkCanvas* canvas) {
91        const char* lcd_text = "LCD";
92        const char* gray_text = "GRAY";
93
94        SkPaint paint;
95        paint.setAntiAlias(true);
96        paint.setLCDRenderText(true);
97
98        const struct {
99            SkPoint     fLoc;
100            SkScalar    fTextSize;
101            SkScalar    fScale;
102            const char* fText;
103        } rec[] = {
104            { {  10,  50 }, kLCDTextSizeLimit - 1,     1,  lcd_text },
105            { { 160,  50 }, kLCDTextSizeLimit + 1,     1,  gray_text },
106            { {  10, 100 }, kLCDTextSizeLimit / 2, 1.99f,  lcd_text },
107            { { 160, 100 }, kLCDTextSizeLimit / 2, 2.01f,  gray_text },
108        };
109
110        for (size_t i = 0; i < SK_ARRAY_COUNT(rec); ++i) {
111            const SkPoint loc = rec[i].fLoc;
112            SkAutoCanvasRestore acr(canvas, true);
113
114            paint.setTextSize(rec[i].fTextSize);
115            ScaleAbout(canvas, rec[i].fScale, rec[i].fScale, loc.x(), loc.y());
116            canvas->drawText(rec[i].fText, strlen(rec[i].fText), loc.x(), loc.y(), paint);
117        }
118    }
119
120private:
121    typedef skiagm::GM INHERITED;
122};
123
124#include "SkSurface.h"
125
126// ensure that we respect the SkPixelGeometry in SurfaceProps
127class LcdTextProps : public skiagm::GM {
128    static void DrawText(SkCanvas* canvas) {
129        canvas->drawColor(SK_ColorWHITE);
130        SkPaint paint;
131        paint.setAntiAlias(true);
132        paint.setLCDRenderText(true);
133        paint.setTextSize(30);
134        canvas->drawText("Base", 4, 4, 30, paint);
135        canvas->saveLayer(NULL, NULL);
136        canvas->drawText("Layer", 5, 4, 70, paint);
137        canvas->restore();
138    }
139
140public:
141    SkString onShortName() SK_OVERRIDE {
142        return SkString("lcdtextprops");
143    }
144
145    SkISize onISize() SK_OVERRIDE { return SkISize::Make(230, 120); }
146
147    virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
148        const SkPixelGeometry geos[] = {
149            kRGB_H_SkPixelGeometry,
150            kUnknown_SkPixelGeometry,
151        };
152
153        const SkImageInfo info = SkImageInfo::MakeN32Premul(100, 100);
154        for (size_t i = 0; i < SK_ARRAY_COUNT(geos); ++i) {
155            SkSurfaceProps props = SkSurfaceProps(0, geos[i]);
156            SkAutoTUnref<SkSurface> surf(canvas->newSurface(info, &props));
157            if (!surf) {
158                surf.reset(SkSurface::NewRaster(info, &props));
159            }
160            DrawText(surf->getCanvas());
161            surf->draw(canvas, SkIntToScalar(i * (info.width() + 10)), 0, NULL);
162        }
163    }
164};
165
166///////////////////////////////////////////////////////////////////////////////
167
168DEF_GM( return new LcdTextGM; )
169DEF_GM( return new LcdTextSizeGM; )
170DEF_GM( return new LcdTextProps; )
171