1/*
2 * Copyright 2013 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.h"
9#include "SkCanvas.h"
10#include "SkGraphics.h"
11#include "SkTypeface.h"
12
13// GM to stress the GPU font cache
14
15const char* gFamilyNames[] = {
16    "sans-serif", "serif"
17};
18
19const SkTypeface::Style gStyles[] = {
20    SkTypeface::kNormal, SkTypeface::kItalic, SkTypeface::kBold
21};
22
23const SkScalar gTextSizes[] = {
24    192, 194, 196, 198, 200, 202, 204, 206
25};
26
27#define TYPEFACE_COUNT (SK_ARRAY_COUNT(gFamilyNames)*SK_ARRAY_COUNT(gStyles))
28
29static SkScalar draw_string(SkCanvas* canvas, const SkString& text, SkScalar x,
30                           SkScalar y, const SkPaint& paint) {
31    canvas->drawText(text.c_str(), text.size(), x, y, paint);
32    return x + paint.measureText(text.c_str(), text.size());
33}
34
35class FontCacheGM : public skiagm::GM {
36public:
37    FontCacheGM() {
38        for (size_t i = 0; i < TYPEFACE_COUNT; ++i) {
39            fTypefaces[i] = NULL;
40        }
41    }
42
43    virtual ~FontCacheGM() {
44        for (size_t i = 0; i < TYPEFACE_COUNT; ++i) {
45            SkSafeUnref(fTypefaces[i]);
46        }
47    }
48
49protected:
50    virtual SkString onShortName() SK_OVERRIDE {
51        return SkString("fontcache");
52    }
53
54    virtual SkISize onISize() SK_OVERRIDE {
55        return SkISize::Make(1280, 640);
56    }
57
58    virtual void onOnceBeforeDraw() SK_OVERRIDE {
59        int typefaceCount = 0;
60        for (size_t i = 0; i < SK_ARRAY_COUNT(gFamilyNames); ++i) {
61            for (size_t j = 0; j < SK_ARRAY_COUNT(gStyles); ++j) {
62                fTypefaces[typefaceCount++] = sk_tool_utils::create_portable_typeface(gFamilyNames[i],
63                                                                               gStyles[j]);
64            }
65        }
66    }
67
68    virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
69        SkScalar y = 32;
70        SkPaint paint;
71        paint.setAntiAlias(true);
72        paint.setLCDRenderText(true);
73        paint.setSubpixelText(true);
74
75        SkString text("H");
76
77        // draw enough to overflow the cache
78        for (size_t i = 0; i < TYPEFACE_COUNT; ++i) {
79            paint.setTypeface(fTypefaces[i]);
80            SkScalar x = 20;
81
82            for (size_t j = 0; j < SK_ARRAY_COUNT(gTextSizes); ++j) {
83                paint.setTextSize(gTextSizes[j]);
84                x = draw_string(canvas, text, x, y, paint) + 10;
85            }
86            y += 128;
87        }
88
89    }
90
91    virtual uint32_t onGetFlags() const SK_OVERRIDE {
92        // this GM is meant only for the GPU
93        return kGPUOnly_Flag;
94    }
95
96private:
97    SkTypeface* fTypefaces[TYPEFACE_COUNT];
98    typedef GM INHERITED;
99};
100
101
102//////////////////////////////////////////////////////////////////////////////
103
104DEF_GM( return SkNEW(FontCacheGM); )
105