Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
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)
void clipRect(const SkRect &rect, SkClipOp op, bool doAntiAlias)
void restore()
Definition SkCanvas.cpp:465
void drawSimpleText(const void *text, size_t byteLength, SkTextEncoding encoding, SkScalar x, SkScalar y, const SkFont &font, const SkPaint &paint)
void translate(SkScalar dx, SkScalar dy)
int save()
Definition SkCanvas.cpp:451
static constexpr SkFontStyle Bold()
Definition SkFontStyle.h:69
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
void onDraw(SkCanvas *canvas) override
void onOnceBeforeDraw() override
SkString getName() const override
SkISize getISize() override
VariedTextGM(bool effectiveClip, bool lcd)
@ kBench_Mode
Definition gm.h:121
Mode getMode() const
Definition gm.h:125
float SkScalar
Definition extension.cpp:12
const char * name
Definition fuchsia.cc:50
#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)
SkScalar w
SkScalar h
static constexpr SkISize Make(int32_t w, int32_t h)
Definition SkSize.h:20
float fX
x-axis value
float fY
y-axis value
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