Flutter Engine
The Flutter Engine
textblobrandomfont.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2015 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"
17#include "include/core/SkRect.h"
20#include "include/core/SkSize.h"
28#include "tools/ToolUtils.h"
31
32#include <string.h>
33#include <utility>
34
35namespace skiagm {
36class TextBlobRandomFont : public GM {
37public:
38 // This gm tests that textblobs can be translated and scaled with a font that returns random
39 // but deterministic masks
41
42protected:
43 void onOnceBeforeDraw() override {
45
46 const char* text = "The quick brown fox jumps over the lazy dog.";
47
49 paint.setAntiAlias(true);
50 paint.setColor(SK_ColorMAGENTA);
51
52 // make textbloben
54 font.setSize(32);
56
57 // Setup our random scaler context
58 auto typeface = ToolUtils::CreatePortableTypeface("sans-serif", SkFontStyle::Bold());
59 SkASSERT(typeface);
60 font.setTypeface(sk_make_sp<SkRandomTypeface>(std::move(typeface), paint, false));
61
62 SkScalar y = 0;
64 font.measureText(text, strlen(text), SkTextEncoding::kUTF8, &bounds);
65 y -= bounds.fTop;
67 y += bounds.fBottom;
68
69 // A8
70 const char* bigtext1 = "The quick brown fox";
71 const char* bigtext2 = "jumps over the lazy dog.";
72 font.setSize(160);
73 font.setSubpixel(false);
75 font.measureText(bigtext1, strlen(bigtext1), SkTextEncoding::kUTF8, &bounds);
76 y -= bounds.fTop;
78 y += bounds.fBottom;
79
80 font.measureText(bigtext2, strlen(bigtext2), SkTextEncoding::kUTF8, &bounds);
81 y -= bounds.fTop;
83 y += bounds.fBottom;
84
85 // color emoji
87 if (sample.typeface) {
88 font.setTypeface(sk_make_sp<SkRandomTypeface>(sample.typeface, paint, false));
89 font.measureText(sample.sampleText, strlen(sample.sampleText), SkTextEncoding::kUTF8, &bounds);
90 y -= bounds.fTop;
92 y += bounds.fBottom;
93 }
94
95 // build
96 fBlob = builder.make();
97 }
98
99 SkString getName() const override { return SkString("textblobrandomfont"); }
100
101 SkISize getISize() override { return SkISize::Make(kWidth, kHeight); }
102
103 DrawResult onDraw(SkCanvas* canvas, SkString* errorMsg) override {
105 bool isGPU = SkToBool(dContext);
106
107#if defined(SK_GRAPHITE)
108 skgpu::graphite::Recorder* recorder = canvas->recorder();
109 isGPU = isGPU || SkToBool(recorder);
110#endif
111
112 if (!isGPU) {
115 }
116
117 // This GM uses ToolUtils::makeSurface which doesn't work well with vias.
118 // This GM uses SkRandomTypeface which doesn't work well with serialization.
119 canvas->drawColor(SK_ColorWHITE);
120
121 SkImageInfo info = SkImageInfo::Make(kWidth, kHeight, canvas->imageInfo().colorType(),
123 canvas->imageInfo().refColorSpace());
125 auto surface(ToolUtils::makeSurface(canvas, info, &props));
126 if (!surface) {
127 *errorMsg = "This test requires a surface";
128 return DrawResult::kFail;
129 }
130
132 paint.setAntiAlias(true);
133
134 SkCanvas* surfaceCanvas = surface->getCanvas();
135
136 SkScalar stride = SkScalarCeilToScalar(fBlob->bounds().height());
137 SkScalar yOffset = 5;
138
139 canvas->save();
140 // Originally we would alternate between rotating and not to force blob regeneration,
141 // but that code seems to have rotted. Keeping the rotate to match the old GM as
142 // much as possible, and it seems like a reasonable stress test for transformed
143 // color emoji.
144 canvas->rotate(-0.05f);
145 canvas->drawTextBlob(fBlob, 10, yOffset, paint);
146 yOffset += stride;
147 canvas->restore();
148
149 // Rotate in the surface canvas, not the final canvas, to avoid aliasing
150 surfaceCanvas->rotate(-0.05f);
151 surfaceCanvas->drawTextBlob(fBlob, 10, yOffset, paint);
152 surface->draw(canvas, 0, 0);
153 yOffset += stride;
154
155 if (dContext) {
156 // free gpu resources and verify
157 dContext->freeGpuResources();
158 }
159
160 canvas->rotate(-0.05f);
161 canvas->drawTextBlob(fBlob, 10, yOffset, paint);
162 yOffset += stride;
163 return DrawResult::kOk;
164 }
165
166private:
167 sk_sp<SkTextBlob> fBlob;
168
169 inline static constexpr int kWidth = 2000;
170 inline static constexpr int kHeight = 1600;
171
172 using INHERITED = GM;
173};
174
175//////////////////////////////////////////////////////////////////////////////
176
177DEF_GM(return new TextBlobRandomFont;)
178} // namespace skiagm
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition: DM.cpp:213
static GrDirectContext * GrAsDirectContext(GrContext_Base *base)
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
Definition: SkAlphaType.h:29
#define SkASSERT(cond)
Definition: SkAssert.h:116
constexpr SkColor SK_ColorMAGENTA
Definition: SkColor.h:147
constexpr SkColor SK_ColorWHITE
Definition: SkColor.h:122
@ kUTF8
uses bytes to represent UTF-8 or ASCII
#define SkScalarCeilToScalar(x)
Definition: SkScalar.h:31
@ kUnknown_SkPixelGeometry
static constexpr bool SkToBool(const T &x)
Definition: SkTo.h:35
void restore()
Definition: SkCanvas.cpp:461
void drawColor(SkColor color, SkBlendMode mode=SkBlendMode::kSrcOver)
Definition: SkCanvas.h:1182
virtual GrRecordingContext * recordingContext() const
Definition: SkCanvas.cpp:1637
virtual skgpu::graphite::Recorder * recorder() const
Definition: SkCanvas.cpp:1641
void rotate(SkScalar degrees)
Definition: SkCanvas.cpp:1300
int save()
Definition: SkCanvas.cpp:447
SkImageInfo imageInfo() const
Definition: SkCanvas.cpp:1206
void drawTextBlob(const SkTextBlob *blob, SkScalar x, SkScalar y, const SkPaint &paint)
Definition: SkCanvas.cpp:2484
static constexpr SkFontStyle Bold()
Definition: SkFontStyle.h:69
Definition: SkFont.h:35
@ kAntiAlias
may have transparent pixels on glyph edges
@ kSubpixelAntiAlias
glyph positioned in pixel using transparency
const SkRect & bounds() const
Definition: SkTextBlob.h:53
Definition: gm.h:110
GM(SkColor backgroundColor=SK_ColorWHITE)
Definition: gm.cpp:81
static constexpr char kErrorMsg_DrawSkippedGpuOnly[]
Definition: gm.h:127
SkString getName() const override
DrawResult onDraw(SkCanvas *canvas, SkString *errorMsg) override
const Paint & paint
Definition: color_source.cc:38
VkSurfaceKHR surface
Definition: main.cc:49
float SkScalar
Definition: extension.cpp:12
std::u16string text
double y
Optional< SkRect > bounds
Definition: SkRecords.h:189
sk_sp< SkSurface > makeSurface(SkCanvas *canvas, const SkImageInfo &info, const SkSurfaceProps *props)
Definition: ToolUtils.cpp:512
sk_sp< SkTypeface > CreatePortableTypeface(const char *name, SkFontStyle style)
void add_to_text_blob(SkTextBlobBuilder *builder, const char *text, const SkFont &font, SkScalar x, SkScalar y)
Definition: ToolUtils.cpp:228
EmojiTestSample EmojiSample()
font
Font Metadata and Metrics.
DEF_GM(return F(C(clipbox), 0.0f, 0.0f, {})) DEF_GM(return F(C(clipbox)
DrawResult
Definition: gm.h:104
Definition: SkSize.h:16
static constexpr SkISize Make(int32_t w, int32_t h)
Definition: SkSize.h:20
sk_sp< SkColorSpace > refColorSpace() const
static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at)
SkColorType colorType() const
Definition: SkImageInfo.h:373
constexpr float height() const
Definition: SkRect.h:769
sk_sp< SkTypeface > typeface
Definition: FontToolUtils.h:48