Flutter Engine
The Flutter Engine
variedtext.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2014 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"
11#include "include/core/SkFont.h"
16#include "include/core/SkRect.h"
19#include "include/core/SkSize.h"
23#include "src/base/SkRandom.h"
24#include "tools/ToolUtils.h"
26
27/**
28 * Draws text with random parameters. The text draws each get their own clip rect. It is also
29 * used as a bench to measure how well the GPU backend combines draw ops for text draws.
30 */
31
32class VariedTextGM : public skiagm::GM {
33public:
34 VariedTextGM(bool effectiveClip, bool lcd)
35 : fEffectiveClip(effectiveClip)
36 , fLCD(lcd) {
37 }
38
39protected:
40 SkString getName() const override {
41 SkString name("varied_text");
42 if (fEffectiveClip) {
43 name.append("_clipped");
44 } else {
45 name.append("_ignorable_clip");
46 }
47 if (fLCD) {
48 name.append("_lcd");
49 } else {
50 name.append("_no_lcd");
51 }
52 return name;
53 }
54
55 SkISize getISize() override { return SkISize::Make(640, 480); }
56
57 void onOnceBeforeDraw() override {
58 fPaint.setAntiAlias(true);
60
61 SkISize size = this->getISize();
62 SkScalar w = SkIntToScalar(size.fWidth);
63 SkScalar h = SkIntToScalar(size.fHeight);
64
65 SkASSERTF(4 == std::size(fTypefaces), "typeface_cnt");
66 fTypefaces[0] = ToolUtils::CreatePortableTypeface("sans-serif", SkFontStyle());
67 fTypefaces[1] = ToolUtils::CreatePortableTypeface("sans-serif", SkFontStyle::Bold());
68 fTypefaces[2] = ToolUtils::CreatePortableTypeface("serif", SkFontStyle());
69 fTypefaces[3] = ToolUtils::CreatePortableTypeface("serif", SkFontStyle::Bold());
70
71 SkRandom random;
72 for (int i = 0; i < kCnt; ++i) {
73 int length = random.nextRangeU(kMinLength, kMaxLength);
74 char text[kMaxLength];
75 for (int j = 0; j < length; ++j) {
76 text[j] = (char)random.nextRangeU('!', 'z');
77 }
78 fStrings[i].set(text, length);
79
80 fColors[i] = random.nextU();
81 fColors[i] |= 0xFF000000;
82 fColors[i] = ToolUtils::color_to_565(fColors[i]);
83
84 constexpr SkScalar kMinPtSize = 8.f;
85 constexpr SkScalar kMaxPtSize = 32.f;
86
87 fPtSizes[i] = random.nextRangeScalar(kMinPtSize, kMaxPtSize);
88
89 fTypefaceIndices[i] = random.nextULessThan(std::size(fTypefaces));
90
91 SkRect r;
92 fPaint.setColor(fColors[i]);
93 fFont.setTypeface(fTypefaces[fTypefaceIndices[i]]);
94 fFont.setSize(fPtSizes[i]);
95
96 fFont.measureText(fStrings[i].c_str(), fStrings[i].size(), SkTextEncoding::kUTF8, &r);
97 // The set of x,y offsets which place the bounding box inside the GM's border.
98 SkRect safeRect = SkRect::MakeLTRB(-r.fLeft, -r.fTop, w - r.fRight, h - r.fBottom);
99 if (safeRect.isEmpty()) {
100 // If the bounds don't fit then allow any offset in the GM's border.
101 safeRect = SkRect::MakeWH(w, h);
102 }
103 fOffsets[i].fX = random.nextRangeScalar(safeRect.fLeft, safeRect.fRight);
104 fOffsets[i].fY = random.nextRangeScalar(safeRect.fTop, safeRect.fBottom);
105
106 fClipRects[i] = r;
107 fClipRects[i].offset(fOffsets[i].fX, fOffsets[i].fY);
108 fClipRects[i].outset(2.f, 2.f);
109
110 if (fEffectiveClip) {
111 fClipRects[i].fRight -= 0.25f * fClipRects[i].width();
112 }
113 }
114 }
115
116 void onDraw(SkCanvas* canvas) override {
117 for (int i = 0; i < kCnt; ++i) {
118 fPaint.setColor(fColors[i]);
119 fFont.setSize(fPtSizes[i]);
120 fFont.setTypeface(fTypefaces[fTypefaceIndices[i]]);
121
122 canvas->save();
123 canvas->clipRect(fClipRects[i]);
124 canvas->translate(fOffsets[i].fX, fOffsets[i].fY);
125 canvas->drawSimpleText(fStrings[i].c_str(), fStrings[i].size(), SkTextEncoding::kUTF8,
126 0, 0, fFont, fPaint);
127 canvas->restore();
128 }
129
130 // Visualize the clips, but not in bench mode.
131 if (kBench_Mode != this->getMode()) {
132 SkPaint wirePaint;
133 wirePaint.setAntiAlias(true);
134 wirePaint.setStrokeWidth(0);
136 for (int i = 0; i < kCnt; ++i) {
137 canvas->drawRect(fClipRects[i], wirePaint);
138 }
139 }
140 }
141
142 bool runAsBench() const override { return true; }
143
144private:
145 inline static constexpr int kCnt = 30;
146 inline static constexpr int kMinLength = 15;
147 inline static constexpr int kMaxLength = 40;
148
149 bool fEffectiveClip;
150 bool fLCD;
151 sk_sp<SkTypeface> fTypefaces[4];
152 SkPaint fPaint;
153 SkFont fFont;
154
155 // precomputed for each text draw
156 SkString fStrings[kCnt];
157 SkColor fColors[kCnt];
158 SkScalar fPtSizes[kCnt];
159 int fTypefaceIndices[kCnt];
160 SkPoint fOffsets[kCnt];
161 SkRect fClipRects[kCnt];
162
163 using INHERITED = skiagm::GM;
164};
165
166DEF_GM(return new VariedTextGM(false, false);)
167DEF_GM(return new VariedTextGM(true, false);)
168DEF_GM(return new VariedTextGM(false, true);)
169DEF_GM(return new VariedTextGM(true, true);)
#define SkASSERTF(cond, fmt,...)
Definition: SkAssert.h:117
uint32_t SkColor
Definition: SkColor.h:37
@ kUTF8
uses bytes to represent UTF-8 or ASCII
#define SkIntToScalar(x)
Definition: SkScalar.h:57
void drawRect(const SkRect &rect, const SkPaint &paint)
Definition: SkCanvas.cpp:1673
void clipRect(const SkRect &rect, SkClipOp op, bool doAntiAlias)
Definition: SkCanvas.cpp:1361
void restore()
Definition: SkCanvas.cpp:461
void drawSimpleText(const void *text, size_t byteLength, SkTextEncoding encoding, SkScalar x, SkScalar y, const SkFont &font, const SkPaint &paint)
Definition: SkCanvas.cpp:2413
void translate(SkScalar dx, SkScalar dy)
Definition: SkCanvas.cpp:1278
int save()
Definition: SkCanvas.cpp:447
static constexpr SkFontStyle Bold()
Definition: SkFontStyle.h:69
Definition: SkFont.h:35
void setTypeface(sk_sp< SkTypeface > tf)
Definition: SkFont.cpp:90
SkScalar measureText(const void *text, size_t byteLength, SkTextEncoding encoding, SkRect *bounds=nullptr) const
Definition: SkFont.h:336
void setEdging(Edging edging)
Definition: SkFont.cpp:121
void setSize(SkScalar textSize)
Definition: SkFont.cpp:129
@ kAntiAlias
may have transparent pixels on glyph edges
@ kSubpixelAntiAlias
glyph positioned in pixel using transparency
void setStyle(Style style)
Definition: SkPaint.cpp:105
void setColor(SkColor color)
Definition: SkPaint.cpp:119
void setAntiAlias(bool aa)
Definition: SkPaint.h:170
@ kStroke_Style
set to stroke geometry
Definition: SkPaint.h:194
void setStrokeWidth(SkScalar width)
Definition: SkPaint.cpp:159
uint32_t nextU()
Definition: SkRandom.h:42
SkScalar nextRangeScalar(SkScalar min, SkScalar max)
Definition: SkRandom.h:106
uint32_t nextULessThan(uint32_t count)
Definition: SkRandom.h:93
uint32_t nextRangeU(uint32_t min, uint32_t max)
Definition: SkRandom.h:80
void set(const SkString &src)
Definition: SkString.h:186
bool runAsBench() const override
Definition: variedtext.cpp:142
void onDraw(SkCanvas *canvas) override
Definition: variedtext.cpp:116
void onOnceBeforeDraw() override
Definition: variedtext.cpp:57
SkString getName() const override
Definition: variedtext.cpp:40
SkISize getISize() override
Definition: variedtext.cpp:55
VariedTextGM(bool effectiveClip, bool lcd)
Definition: variedtext.cpp:34
Definition: gm.h:110
@ kBench_Mode
Definition: gm.h:121
Mode getMode() const
Definition: gm.h:125
float SkScalar
Definition: extension.cpp:12
#define DEF_GM(CODE)
Definition: gm.h:40
size_t length
std::u16string text
sk_sp< SkTypeface > CreatePortableTypeface(const char *name, SkFontStyle style)
SkColor color_to_565(SkColor color)
Definition: ToolUtils.cpp:139
DEF_SWITCHES_START aot vmservice shared library name
Definition: switches.h:32
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259
SkScalar w
SkScalar h
Definition: SkSize.h:16
static constexpr SkISize Make(int32_t w, int32_t h)
Definition: SkSize.h:20
float fX
x-axis value
Definition: SkPoint_impl.h:164
float fY
y-axis value
Definition: SkPoint_impl.h:165
SkScalar fBottom
larger y-axis bounds
Definition: extension.cpp:17
SkScalar fLeft
smaller x-axis bounds
Definition: extension.cpp:14
void outset(float dx, float dy)
Definition: SkRect.h:1077
SkScalar fRight
larger x-axis bounds
Definition: extension.cpp:16
void offset(float dx, float dy)
Definition: SkRect.h:1016
constexpr float width() const
Definition: SkRect.h:762
bool isEmpty() const
Definition: SkRect.h:693
static constexpr SkRect MakeWH(float w, float h)
Definition: SkRect.h:609
static constexpr SkRect MakeLTRB(float l, float t, float r, float b)
Definition: SkRect.h:646
SkScalar fTop
smaller y-axis bounds
Definition: extension.cpp:15