Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
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 {
44 SkTextBlobBuilder builder;
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
53 SkFont font;
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;
63 SkRect bounds;
64 font.measureText(text, strlen(text), SkTextEncoding::kUTF8, &bounds);
65 y -= bounds.fTop;
66 ToolUtils::add_to_text_blob(&builder, text, font, 0, y);
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);
74 font.setEdging(SkFont::Edging::kAntiAlias);
75 font.measureText(bigtext1, strlen(bigtext1), SkTextEncoding::kUTF8, &bounds);
76 y -= bounds.fTop;
77 ToolUtils::add_to_text_blob(&builder, bigtext1, font, 0, y);
78 y += bounds.fBottom;
79
80 font.measureText(bigtext2, strlen(bigtext2), SkTextEncoding::kUTF8, &bounds);
81 y -= bounds.fTop;
82 ToolUtils::add_to_text_blob(&builder, bigtext2, font, 0, y);
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;
91 ToolUtils::add_to_text_blob(&builder, sample.sampleText, font, 0, y);
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:465
void drawColor(SkColor color, SkBlendMode mode=SkBlendMode::kSrcOver)
Definition SkCanvas.h:1182
virtual GrRecordingContext * recordingContext() const
virtual skgpu::graphite::Recorder * recorder() const
void rotate(SkScalar degrees)
int save()
Definition SkCanvas.cpp:451
SkImageInfo imageInfo() const
void drawTextBlob(const SkTextBlob *blob, SkScalar x, SkScalar y, const SkPaint &paint)
static constexpr SkFontStyle Bold()
Definition SkFontStyle.h:69
@ kAntiAlias
may have transparent pixels on glyph edges
@ kSubpixelAntiAlias
glyph positioned in pixel using transparency
const SkRect & bounds() const
Definition SkTextBlob.h:53
static constexpr char kErrorMsg_DrawSkippedGpuOnly[]
Definition gm.h:127
SkString getName() const override
DrawResult onDraw(SkCanvas *canvas, SkString *errorMsg) override
const Paint & paint
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
sk_sp< SkSurface > makeSurface(SkCanvas *canvas, const SkImageInfo &info, const SkSurfaceProps *props)
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)
EmojiTestSample EmojiSample()
DrawResult
Definition gm.h:104
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
constexpr float height() const
Definition SkRect.h:769
sk_sp< SkTypeface > typeface