Flutter Engine
The Flutter Engine
dftext.cpp
Go to the documentation of this file.
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"
12#include "include/core/SkFont.h"
19#include "include/core/SkRect.h"
22#include "include/core/SkSize.h"
31#if defined(SK_GRAPHITE)
33#endif
36#include "tools/ToolUtils.h"
38
39#include <string.h>
40
41using namespace skia_private;
42
43class DFTextGM : public skiagm::GM {
44public:
46 this->setBGColor(0xFFFFFFFF);
47 }
48
49protected:
50 void onOnceBeforeDraw() override { fEmojiSample = ToolUtils::EmojiSample(); }
51
52 SkString getName() const override { return SkString("dftext"); }
53
54 SkISize getISize() override { return SkISize::Make(1024, 768); }
55
56 void onDraw(SkCanvas* inputCanvas) override {
57 SkScalar textSizes[] = { 9.0f, 9.0f*2.0f, 9.0f*5.0f, 9.0f*2.0f*5.0f };
58 SkScalar scales[] = { 2.0f*5.0f, 5.0f, 2.0f, 1.0f };
59
60 // set up offscreen rendering with distance field text
61 auto ctx = inputCanvas->recordingContext();
62#if defined(SK_GRAPHITE)
63 auto recorder = inputCanvas->recorder();
64#endif
65 SkISize size = this->getISize();
66 if (!inputCanvas->getBaseLayerSize().isEmpty()) {
67 size = inputCanvas->getBaseLayerSize();
68 }
70 inputCanvas->imageInfo().refColorSpace());
71 SkSurfaceProps inputProps;
72 inputCanvas->getProps(&inputProps);
74 inputProps.pixelGeometry());
76#if defined(SK_GRAPHITE)
77 if (recorder) {
79 } else
80#endif
81 {
83 }
84 SkCanvas* canvas = surface ? surface->getCanvas() : inputCanvas;
85 // init our new canvas with the old canvas's matrix
86 canvas->setMatrix(inputCanvas->getLocalToDeviceAs3x3());
87 // apply global scale to test glyph positioning
88 canvas->scale(1.05f, 1.05f);
89 canvas->clear(0xffffffff);
90
92 paint.setAntiAlias(true);
93
95 font.setSubpixel(true);
96
97 const char* text = "Hamburgefons";
98 const size_t textLen = strlen(text);
99
100 // check scaling up
103 for (size_t i = 0; i < std::size(textSizes); ++i) {
104 SkAutoCanvasRestore acr(canvas, true);
105 canvas->translate(x, y);
106 canvas->scale(scales[i], scales[i]);
107 font.setSize(textSizes[i]);
108 canvas->drawSimpleText(text, textLen, SkTextEncoding::kUTF8, 0, 0, font, paint);
109 y += font.getMetrics(nullptr)*scales[i];
110 }
111
112 // check rotation
113 for (size_t i = 0; i < 5; ++i) {
114 SkScalar rotX = SkIntToScalar(10);
115 SkScalar rotY = y;
116
117 SkAutoCanvasRestore acr(canvas, true);
118 canvas->translate(SkIntToScalar(10 + i * 200), -80);
119 canvas->rotate(SkIntToScalar(i * 5), rotX, rotY);
120 for (int ps = 6; ps <= 32; ps += 3) {
121 font.setSize(SkIntToScalar(ps));
122 canvas->drawSimpleText(text, textLen, SkTextEncoding::kUTF8, rotX, rotY, font, paint);
123 rotY += font.getMetrics(nullptr);
124 }
125 }
126
127 // check scaling down
129 x = SkIntToScalar(680);
130 y = SkIntToScalar(20);
131 size_t arraySize = std::size(textSizes);
132 for (size_t i = 0; i < arraySize; ++i) {
133 SkAutoCanvasRestore acr(canvas, true);
134 canvas->translate(x, y);
135 SkScalar scaleFactor = SkScalarInvert(scales[arraySize - i - 1]);
136 canvas->scale(scaleFactor, scaleFactor);
137 font.setSize(textSizes[i]);
138 canvas->drawSimpleText(text, textLen, SkTextEncoding::kUTF8, 0, 0, font, paint);
139 y += font.getMetrics(nullptr)*scaleFactor;
140 }
141
142 // check pos text
143 {
144 SkAutoCanvasRestore acr(canvas, true);
145
146 canvas->scale(2.0f, 2.0f);
147
149 int count = font.textToGlyphs(text, textLen, SkTextEncoding::kUTF8, glyphs.get(), textLen);
151 font.setSize(textSizes[0]);
152 font.getPos(glyphs.get(), count, pos.get(), {340, 75});
153
154 auto blob = SkTextBlob::MakeFromPosText(glyphs.get(), count * sizeof(SkGlyphID),
156 canvas->drawTextBlob(blob, 0, 0, paint);
157 }
158
159
160 // check gamma-corrected blending
161 const SkColor fg[] = {
162 0xFFFFFFFF,
163 0xFFFFFF00, 0xFFFF00FF, 0xFF00FFFF,
164 0xFFFF0000, 0xFF00FF00, 0xFF0000FF,
165 0xFF000000,
166 };
167
168 paint.setColor(0xFFF7F3F7);
169 SkRect r = SkRect::MakeLTRB(670, 215, 820, 397);
170 canvas->drawRect(r, paint);
171
172 x = SkIntToScalar(680);
173 y = SkIntToScalar(235);
174 font.setSize(SkIntToScalar(19));
175 for (size_t i = 0; i < std::size(fg); ++i) {
176 paint.setColor(fg[i]);
177
178 canvas->drawSimpleText(text, textLen, SkTextEncoding::kUTF8, x, y, font, paint);
179 y += font.getMetrics(nullptr);
180 }
181
182 paint.setColor(0xFF181C18);
183 r = SkRect::MakeLTRB(820, 215, 970, 397);
184 canvas->drawRect(r, paint);
185
186 x = SkIntToScalar(830);
187 y = SkIntToScalar(235);
188 font.setSize(SkIntToScalar(19));
189 for (size_t i = 0; i < std::size(fg); ++i) {
190 paint.setColor(fg[i]);
191
192 canvas->drawSimpleText(text, textLen, SkTextEncoding::kUTF8, x, y, font, paint);
193 y += font.getMetrics(nullptr);
194 }
195
196 // check skew
197 {
199 SkAutoCanvasRestore acr(canvas, true);
200 canvas->skew(0.0f, 0.151515f);
201 font.setSize(SkIntToScalar(32));
202 canvas->drawSimpleText(text, textLen, SkTextEncoding::kUTF8, 745, 70, font, paint);
203 }
204 {
206 SkAutoCanvasRestore acr(canvas, true);
207 canvas->skew(0.5f, 0.0f);
208 font.setSize(SkIntToScalar(32));
209 canvas->drawSimpleText(text, textLen, SkTextEncoding::kUTF8, 580, 125, font, paint);
210 }
211
212 // check perspective
213 {
215 SkAutoCanvasRestore acr(canvas, true);
216 SkMatrix persp;
217 persp.setAll(0.9839f, 0, 0,
218 0.2246f, 0.6829f, 0,
219 0.0002352f, -0.0003844f, 1);
220 canvas->concat(persp);
221 canvas->translate(1100, -295);
222 font.setSize(37.5f);
223 canvas->drawSimpleText(text, textLen, SkTextEncoding::kUTF8, 0, 0, font, paint);
224 }
225 {
226 font.setSubpixel(false);
227 font.setEdging(SkFont::Edging::kAlias);
228 SkAutoCanvasRestore acr(canvas, true);
229 SkMatrix persp;
230 persp.setAll(0.9839f, 0, 0,
231 0.2246f, 0.6829f, 0,
232 0.0002352f, -0.0003844f, 1);
233 canvas->concat(persp);
234 canvas->translate(1075, -245);
235 canvas->scale(375, 375);
236 font.setSize(0.1f);
237 canvas->drawSimpleText(text, textLen, SkTextEncoding::kUTF8, 0, 0, font, paint);
238 }
239
240 // check color emoji
241 if (fEmojiSample.typeface) {
242 SkFont emojiFont;
243 emojiFont.setSubpixel(true);
244 emojiFont.setTypeface(fEmojiSample.typeface);
245 emojiFont.setSize(SkIntToScalar(19));
246 canvas->drawSimpleText(fEmojiSample.sampleText,
247 strlen(fEmojiSample.sampleText),
249 670,
250 90,
251 emojiFont,
252 paint);
253 }
254
255 // render offscreen buffer
256 if (surface) {
257 SkAutoCanvasRestore acr(inputCanvas, true);
258 // since we prepended this matrix already, we blit using identity
259 inputCanvas->resetMatrix();
260 inputCanvas->drawImage(surface->makeImageSnapshot().get(), 0, 0);
261 }
262 }
263
264private:
265 ToolUtils::EmojiTestSample fEmojiSample;
266
267 using INHERITED = skiagm::GM;
268};
269
270DEF_GM(return new DFTextGM;)
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition: DM.cpp:213
uint16_t glyphs[5]
Definition: FontMgrTest.cpp:46
int count
Definition: FontMgrTest.cpp:50
SkPoint pos
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
Definition: SkAlphaType.h:29
uint32_t SkColor
Definition: SkColor.h:37
@ kUTF8
uses bytes to represent UTF-8 or ASCII
@ kGlyphID
uses two byte words to represent glyph indices
#define SkScalarInvert(x)
Definition: SkScalar.h:73
#define SkIntToScalar(x)
Definition: SkScalar.h:57
constexpr int SkToInt(S x)
Definition: SkTo.h:29
uint16_t SkGlyphID
Definition: SkTypes.h:179
void onDraw(SkCanvas *inputCanvas) override
Definition: dftext.cpp:56
SkString getName() const override
Definition: dftext.cpp:52
void onOnceBeforeDraw() override
Definition: dftext.cpp:50
DFTextGM()
Definition: dftext.cpp:45
SkISize getISize() override
Definition: dftext.cpp:54
bool getProps(SkSurfaceProps *props) const
Definition: SkCanvas.cpp:1214
void drawRect(const SkRect &rect, const SkPaint &paint)
Definition: SkCanvas.cpp:1673
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
SkMatrix getLocalToDeviceAs3x3() const
Definition: SkCanvas.h:2222
virtual GrRecordingContext * recordingContext() const
Definition: SkCanvas.cpp:1637
virtual skgpu::graphite::Recorder * recorder() const
Definition: SkCanvas.cpp:1641
virtual SkISize getBaseLayerSize() const
Definition: SkCanvas.cpp:369
void clear(SkColor color)
Definition: SkCanvas.h:1199
void rotate(SkScalar degrees)
Definition: SkCanvas.cpp:1300
void resetMatrix()
Definition: SkCanvas.cpp:1355
void setMatrix(const SkM44 &matrix)
Definition: SkCanvas.cpp:1349
void scale(SkScalar sx, SkScalar sy)
Definition: SkCanvas.cpp:1289
void concat(const SkMatrix &matrix)
Definition: SkCanvas.cpp:1318
SkImageInfo imageInfo() const
Definition: SkCanvas.cpp:1206
void skew(SkScalar sx, SkScalar sy)
Definition: SkCanvas.cpp:1312
void drawTextBlob(const SkTextBlob *blob, SkScalar x, SkScalar y, const SkPaint &paint)
Definition: SkCanvas.cpp:2484
void drawImage(const SkImage *image, SkScalar left, SkScalar top)
Definition: SkCanvas.h:1528
Definition: SkFont.h:35
void setSubpixel(bool subpixel)
Definition: SkFont.cpp:109
void setTypeface(sk_sp< SkTypeface > tf)
Definition: SkFont.cpp:90
void setSize(SkScalar textSize)
Definition: SkFont.cpp:129
@ kAntiAlias
may have transparent pixels on glyph edges
@ kAlias
no transparent pixels on glyph edges
@ kSubpixelAntiAlias
glyph positioned in pixel using transparency
SkMatrix & setAll(SkScalar scaleX, SkScalar skewX, SkScalar transX, SkScalar skewY, SkScalar scaleY, SkScalar transY, SkScalar persp0, SkScalar persp1, SkScalar persp2)
Definition: SkMatrix.h:562
@ kUseDeviceIndependentFonts_Flag
uint32_t flags() const
SkPixelGeometry pixelGeometry() const
static sk_sp< SkTextBlob > MakeFromPosText(const void *text, size_t byteLength, const SkPoint pos[], const SkFont &font, SkTextEncoding encoding=SkTextEncoding::kUTF8)
Definition: SkTextBlob.cpp:803
Definition: gm.h:110
void setBGColor(SkColor)
Definition: gm.cpp:159
const Paint & paint
Definition: color_source.cc:38
VkSurfaceKHR surface
Definition: main.cc:49
float SkScalar
Definition: extension.cpp:12
#define DEF_GM(CODE)
Definition: gm.h:40
std::u16string text
double y
double x
SK_API sk_sp< SkSurface > RenderTarget(GrRecordingContext *context, skgpu::Budgeted budgeted, const SkImageInfo &imageInfo, int sampleCount, GrSurfaceOrigin surfaceOrigin, const SkSurfaceProps *surfaceProps, bool shouldCreateWithMips=false, bool isProtected=false)
sk_sp< SkTypeface > CreatePortableTypeface(const char *name, SkFontStyle style)
EmojiTestSample EmojiSample()
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
font
Font Metadata and Metrics.
Definition: SkSize.h:16
bool isEmpty() const
Definition: SkSize.h:31
static constexpr SkISize Make(int32_t w, int32_t h)
Definition: SkSize.h:20
sk_sp< SkColorSpace > refColorSpace() const
static SkImageInfo MakeN32(int width, int height, SkAlphaType at)
static constexpr SkRect MakeLTRB(float l, float t, float r, float b)
Definition: SkRect.h:646
sk_sp< SkTypeface > typeface
Definition: FontToolUtils.h:48