Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Classes | Functions
SkGlyphTest.cpp File Reference
#include "include/core/SkCanvas.h"
#include "include/core/SkData.h"
#include "include/core/SkDrawable.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPath.h"
#include "include/core/SkPicture.h"
#include "include/core/SkPictureRecorder.h"
#include "include/core/SkPoint.h"
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkString.h"
#include "include/core/SkTypes.h"
#include "include/effects/SkRuntimeEffect.h"
#include "src/base/SkArenaAlloc.h"
#include "src/core/SkCanvasPriv.h"
#include "src/core/SkGlyph.h"
#include "src/core/SkMask.h"
#include "src/core/SkReadBuffer.h"
#include "src/core/SkWriteBuffer.h"
#include "tests/Test.h"
#include <cstddef>
#include <cstdint>
#include <initializer_list>
#include <iterator>
#include <optional>

Go to the source code of this file.

Classes

class  SkGlyphTestPeer
 

Functions

 DEF_TEST (SkGlyphRectBasic, reporter)
 
 DEF_TEST (SkGlyph_SendMetrics, reporter)
 
 DEF_TEST (SkGlyph_SendWithImage, reporter)
 
 DEF_TEST (SkGlyph_SendWithPath, reporter)
 
 DEF_TEST (SkGlyph_SendWithDrawable, reporter)
 
 DEF_TEST (SkPictureBackedGlyphDrawable_Basic, reporter)
 
static sk_sp< SkDrawablemake_sksl_drawable ()
 
static sk_sp< SkDrawablemake_nested_sksl_drawable ()
 
 DEF_TEST (SkPictureBackedGlyphDrawable_SkSL, reporter)
 

Function Documentation

◆ DEF_TEST() [1/7]

DEF_TEST ( SkGlyph_SendMetrics  ,
reporter   
)

Definition at line 87 of file SkGlyphTest.cpp.

87 {
88 {
89 SkGlyph srcGlyph{SkPackedGlyphID{(SkGlyphID)12}};
91
92 SkBinaryWriteBuffer writeBuffer({});
93 srcGlyph.flattenMetrics(writeBuffer);
94
95 sk_sp<SkData> data = writeBuffer.snapshotAsData();
96
97 SkReadBuffer readBuffer{data->data(), data->size()};
98 std::optional<SkGlyph> dstGlyph = SkGlyph::MakeFromBuffer(readBuffer);
99 REPORTER_ASSERT(reporter, readBuffer.isValid());
100 REPORTER_ASSERT(reporter, dstGlyph.has_value());
101 REPORTER_ASSERT(reporter, srcGlyph.advanceVector() == dstGlyph->advanceVector());
102 REPORTER_ASSERT(reporter, srcGlyph.rect() == dstGlyph->rect());
103 REPORTER_ASSERT(reporter, srcGlyph.maskFormat() == dstGlyph->maskFormat());
104 }
105 {
106 SkGlyph srcGlyph{SkPackedGlyphID{(SkGlyphID)12}};
108
109 SkBinaryWriteBuffer writeBuffer({});
110 srcGlyph.flattenMetrics(writeBuffer);
111
112 sk_sp<SkData> data = writeBuffer.snapshotAsData();
113
114 SkReadBuffer readBuffer{data->data(), data->size()};
115 std::optional<SkGlyph> dstGlyph = SkGlyph::MakeFromBuffer(readBuffer);
116 REPORTER_ASSERT(reporter, readBuffer.isValid());
117 REPORTER_ASSERT(reporter, dstGlyph.has_value());
118 REPORTER_ASSERT(reporter, srcGlyph.advanceVector() == dstGlyph->advanceVector());
119 REPORTER_ASSERT(reporter, srcGlyph.rect() == dstGlyph->rect());
120 REPORTER_ASSERT(reporter, srcGlyph.maskFormat() == dstGlyph->maskFormat());
121 }
122
123 uint8_t badData[] = {1, 2, 3, 4, 5, 6, 7, 8};
124 SkReadBuffer badBuffer{badData, std::size(badData)};
125 std::optional<SkGlyph> dstGlyph = SkGlyph::MakeFromBuffer(badBuffer);
126 REPORTER_ASSERT(reporter, !badBuffer.isValid());
127 REPORTER_ASSERT(reporter, !dstGlyph.has_value());
128}
reporter
uint16_t SkGlyphID
Definition SkTypes.h:179
#define REPORTER_ASSERT(r, cond,...)
Definition Test.h:286
static void SetGlyph2(SkGlyph *glyph)
static void SetGlyph1(SkGlyph *glyph)
static std::optional< SkGlyph > MakeFromBuffer(SkReadBuffer &)
Definition SkGlyph.cpp:95
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot data
Definition switches.h:41

◆ DEF_TEST() [2/7]

DEF_TEST ( SkGlyph_SendWithDrawable  ,
reporter   
)

Definition at line 267 of file SkGlyphTest.cpp.

267 {
268 SkArenaAlloc alloc{256};
269 SkGlyph srcGlyph{SkPackedGlyphID{(SkGlyphID)12}};
271
272 class TestDrawable final : public SkDrawable {
273 public:
274 TestDrawable(SkRect rect) : fRect(rect) {}
275 private:
276 const SkRect fRect;
277 SkRect onGetBounds() override { return fRect; }
278 size_t onApproximateBytesUsed() override {
279 return 0;
280 }
281 void onDraw(SkCanvas* canvas) override {
283 canvas->drawRect(fRect, paint);
284 }
285 };
286
287 sk_sp<SkDrawable> srcDrawable = sk_make_sp<TestDrawable>(srcGlyph.rect());
288 srcGlyph.setDrawable(&alloc, srcDrawable);
289 REPORTER_ASSERT(reporter, srcGlyph.setDrawableHasBeenCalled());
290
291 SkBinaryWriteBuffer writeBuffer({});
292 srcGlyph.flattenMetrics(writeBuffer);
293 srcGlyph.flattenDrawable(writeBuffer);
294
295 sk_sp<SkData> data = writeBuffer.snapshotAsData();
296
297 SkReadBuffer readBuffer{data->data(), data->size()};
298 std::optional<SkGlyph> dstGlyph = SkGlyph::MakeFromBuffer(readBuffer);
299 REPORTER_ASSERT(reporter, readBuffer.isValid());
300 REPORTER_ASSERT(reporter, dstGlyph.has_value());
301 REPORTER_ASSERT(reporter, srcGlyph.advanceVector() == dstGlyph->advanceVector());
302 REPORTER_ASSERT(reporter, srcGlyph.rect() == dstGlyph->rect());
303 REPORTER_ASSERT(reporter, srcGlyph.maskFormat() == dstGlyph->maskFormat());
304
305 dstGlyph->addDrawableFromBuffer(readBuffer, &alloc);
306 REPORTER_ASSERT(reporter, readBuffer.isValid());
307 REPORTER_ASSERT(reporter, dstGlyph->setDrawableHasBeenCalled());
308 SkDrawable* dstDrawable = dstGlyph->drawable();
309 REPORTER_ASSERT(reporter, dstDrawable->getBounds() == srcDrawable->getBounds());
310
311 // Add good metrics, but mess up drawable data
312 SkBinaryWriteBuffer badWriteBuffer({});
313 srcGlyph.flattenMetrics(badWriteBuffer);
314 badWriteBuffer.writeInt(7);
315 badWriteBuffer.writeInt(8);
316
317 data = badWriteBuffer.snapshotAsData();
318
319 SkReadBuffer badReadBuffer{data->data(), data->size()};
320 dstGlyph = SkGlyph::MakeFromBuffer(badReadBuffer);
321 REPORTER_ASSERT(reporter, badReadBuffer.isValid()); // Reading glyph metrics is okay.
322 REPORTER_ASSERT(reporter, dstGlyph.has_value());
323 REPORTER_ASSERT(reporter, srcGlyph.advanceVector() == dstGlyph->advanceVector());
324 REPORTER_ASSERT(reporter, srcGlyph.rect() == dstGlyph->rect());
325 REPORTER_ASSERT(reporter, srcGlyph.maskFormat() == dstGlyph->maskFormat());
326
327 dstGlyph->addDrawableFromBuffer(badReadBuffer, &alloc);
328 REPORTER_ASSERT(reporter, !badReadBuffer.isValid());
329 REPORTER_ASSERT(reporter, !dstGlyph->setDrawableHasBeenCalled());
330}
SkRect fRect
void writeInt(int32_t value) override
void drawRect(const SkRect &rect, const SkPaint &paint)
virtual SkRect onGetBounds()=0
SkRect getBounds()
virtual void onDraw(SkCanvas *)=0
virtual size_t onApproximateBytesUsed()
const Paint & paint
sk_sp< SkBlender > blender SkRect rect
Definition SkRecords.h:350

◆ DEF_TEST() [3/7]

DEF_TEST ( SkGlyph_SendWithImage  ,
reporter   
)

Definition at line 130 of file SkGlyphTest.cpp.

130 {
131 SkArenaAlloc alloc{256};
132 SkGlyph srcGlyph{SkPackedGlyphID{(SkGlyphID)12}};
134
135 static constexpr uint8_t X = 0xff;
136 static constexpr uint8_t O = 0x00;
137 uint8_t imageData[][8] = {
138 {X,X,X,X,X,X,X,X},
139 {X,O,O,O,O,O,O,X},
140 {X,O,O,O,O,O,O,X},
141 {X,O,O,O,O,O,O,X},
142 {X,O,O,X,X,O,O,X},
143 {X,O,O,O,O,O,O,X},
144 {X,O,O,O,O,O,O,X},
145 {X,O,O,O,O,O,O,X},
146 {X,X,X,X,X,X,X,X},
147 };
148
149 srcGlyph.setImage(&alloc, imageData);
150
151 SkBinaryWriteBuffer writeBuffer({});
152 srcGlyph.flattenMetrics(writeBuffer);
153 srcGlyph.flattenImage(writeBuffer);
154
155 sk_sp<SkData> data = writeBuffer.snapshotAsData();
156
157 SkReadBuffer readBuffer{data->data(), data->size()};
158 std::optional<SkGlyph> dstGlyph = SkGlyph::MakeFromBuffer(readBuffer);
159 REPORTER_ASSERT(reporter, readBuffer.isValid());
160 REPORTER_ASSERT(reporter, dstGlyph.has_value());
161 REPORTER_ASSERT(reporter, srcGlyph.advanceVector() == dstGlyph->advanceVector());
162 REPORTER_ASSERT(reporter, srcGlyph.rect() == dstGlyph->rect());
163 REPORTER_ASSERT(reporter, srcGlyph.maskFormat() == dstGlyph->maskFormat());
164
165 dstGlyph->addImageFromBuffer(readBuffer, &alloc);
166 REPORTER_ASSERT(reporter, readBuffer.isValid());
167 const uint8_t* dstImage = (const uint8_t*)dstGlyph->image();
168 for (int y = 0; y < dstGlyph->height(); ++y) {
169 for (int x = 0; x < dstGlyph->width(); ++x) {
170 REPORTER_ASSERT(reporter, imageData[y][x] == dstImage[y * dstGlyph->rowBytes() + x]);
171 }
172 }
173
174 // Add good metrics, but mess up image data
175 SkBinaryWriteBuffer badWriteBuffer({});
176 srcGlyph.flattenMetrics(badWriteBuffer);
177 badWriteBuffer.writeInt(7);
178 badWriteBuffer.writeInt(8);
179
180 data = badWriteBuffer.snapshotAsData();
181
182 SkReadBuffer badReadBuffer{data->data(), data->size()};
183 dstGlyph = SkGlyph::MakeFromBuffer(badReadBuffer);
184 REPORTER_ASSERT(reporter, badReadBuffer.isValid()); // Reading glyph metrics is okay.
185 REPORTER_ASSERT(reporter, dstGlyph.has_value());
186 REPORTER_ASSERT(reporter, srcGlyph.advanceVector() == dstGlyph->advanceVector());
187 REPORTER_ASSERT(reporter, srcGlyph.rect() == dstGlyph->rect());
188 REPORTER_ASSERT(reporter, srcGlyph.maskFormat() == dstGlyph->maskFormat());
189
190 dstGlyph->addImageFromBuffer(badReadBuffer, &alloc);
191 REPORTER_ASSERT(reporter, !badReadBuffer.isValid());
192 REPORTER_ASSERT(reporter, !dstGlyph->setImageHasBeenCalled());
193}
static const SkScalar X
double y
double x

◆ DEF_TEST() [4/7]

DEF_TEST ( SkGlyph_SendWithPath  ,
reporter   
)

Definition at line 195 of file SkGlyphTest.cpp.

195 {
196 SkArenaAlloc alloc{256};
197 SkGlyph srcGlyph{SkPackedGlyphID{(SkGlyphID)12}};
199
200 SkPath srcPath;
201 srcPath.addRect(srcGlyph.rect());
202
203 srcGlyph.setPath(&alloc, &srcPath, false);
204
205 SkBinaryWriteBuffer writeBuffer({});
206 srcGlyph.flattenMetrics(writeBuffer);
207 srcGlyph.flattenPath(writeBuffer);
208
209 sk_sp<SkData> data = writeBuffer.snapshotAsData();
210
211 SkReadBuffer readBuffer{data->data(), data->size()};
212 std::optional<SkGlyph> dstGlyph = SkGlyph::MakeFromBuffer(readBuffer);
213 REPORTER_ASSERT(reporter, readBuffer.isValid());
214 REPORTER_ASSERT(reporter, dstGlyph.has_value());
215 REPORTER_ASSERT(reporter, srcGlyph.advanceVector() == dstGlyph->advanceVector());
216 REPORTER_ASSERT(reporter, srcGlyph.rect() == dstGlyph->rect());
217 REPORTER_ASSERT(reporter, srcGlyph.maskFormat() == dstGlyph->maskFormat());
218
219 dstGlyph->addPathFromBuffer(readBuffer, &alloc);
220 REPORTER_ASSERT(reporter, readBuffer.isValid());
221 REPORTER_ASSERT(reporter, dstGlyph->setPathHasBeenCalled());
222 const SkPath* dstPath = dstGlyph->path();
223 REPORTER_ASSERT(reporter, *dstPath == srcPath);
224
225 {
226 // Add good metrics, but mess up path data
227 SkBinaryWriteBuffer badWriteBuffer({});
228 srcGlyph.flattenMetrics(badWriteBuffer);
229 // Force a false value to be read in addPathFromBuffer for hasPath.
230 badWriteBuffer.writeInt(8);
231 badWriteBuffer.writeInt(9);
232
233 data = badWriteBuffer.snapshotAsData();
234
235 SkReadBuffer badReadBuffer{data->data(), data->size()};
236 dstGlyph = SkGlyph::MakeFromBuffer(badReadBuffer);
237 REPORTER_ASSERT(reporter, dstGlyph.has_value());
238 REPORTER_ASSERT(reporter, srcGlyph.advanceVector() == dstGlyph->advanceVector());
239 REPORTER_ASSERT(reporter, srcGlyph.rect() == dstGlyph->rect());
240 REPORTER_ASSERT(reporter, srcGlyph.maskFormat() == dstGlyph->maskFormat());
241
242 dstGlyph->addPathFromBuffer(badReadBuffer, &alloc);
243 REPORTER_ASSERT(reporter, !badReadBuffer.isValid());
244 REPORTER_ASSERT(reporter, !dstGlyph->setPathHasBeenCalled());
245 }
246 {
247 // Add good metrics, but no path data.
248 SkBinaryWriteBuffer badWriteBuffer({});
249 srcGlyph.flattenMetrics(badWriteBuffer);
250
251 data = badWriteBuffer.snapshotAsData();
252
253 SkReadBuffer badReadBuffer{data->data(), data->size()};
254 dstGlyph = SkGlyph::MakeFromBuffer(badReadBuffer);
255 REPORTER_ASSERT(reporter, badReadBuffer.isValid()); // Reading glyph metrics is okay.
256 REPORTER_ASSERT(reporter, dstGlyph.has_value());
257 REPORTER_ASSERT(reporter, srcGlyph.advanceVector() == dstGlyph->advanceVector());
258 REPORTER_ASSERT(reporter, srcGlyph.rect() == dstGlyph->rect());
259 REPORTER_ASSERT(reporter, srcGlyph.maskFormat() == dstGlyph->maskFormat());
260
261 dstGlyph->addPathFromBuffer(badReadBuffer, &alloc);
262 REPORTER_ASSERT(reporter, !badReadBuffer.isValid());
263 REPORTER_ASSERT(reporter, !dstGlyph->setPathHasBeenCalled());
264 }
265}
SkPath & addRect(const SkRect &rect, SkPathDirection dir, unsigned start)
Definition SkPath.cpp:854

◆ DEF_TEST() [5/7]

DEF_TEST ( SkGlyphRectBasic  ,
reporter   
)

Definition at line 35 of file SkGlyphTest.cpp.

35 {
36 using namespace skglyph;
37 SkGlyphRect r{1, 1, 10, 10};
38 REPORTER_ASSERT(reporter, !r.empty());
39 SkGlyphRect a = rect_union(r, empty_rect());
40 REPORTER_ASSERT(reporter, a.rect() == SkRect::MakeLTRB(1, 1, 10, 10));
41 auto widthHeight = a.widthHeight();
42 REPORTER_ASSERT(reporter, widthHeight.x() == 9 && widthHeight.y() == 9);
43
44 a = rect_intersection(r, full_rect());
45 REPORTER_ASSERT(reporter, a.rect() == SkRect::MakeLTRB(1, 1, 10, 10));
46
47 SkGlyphRect acc = full_rect();
48 for (int x = -10; x < 10; x++) {
49 for(int y = -10; y < 10; y++) {
50 acc = rect_intersection(acc, SkGlyphRect(x, y, x + 20, y + 20));
51 }
52 }
53 REPORTER_ASSERT(reporter, acc.rect() == SkRect::MakeLTRB(9, 9, 10, 10));
54
55 acc = empty_rect();
56 for (int x = -10; x < 10; x++) {
57 for(int y = -10; y < 10; y++) {
58 acc = rect_union(acc, SkGlyphRect(x, y, x + 20, y + 20));
59 }
60 }
61 REPORTER_ASSERT(reporter, acc.rect() == SkRect::MakeLTRB(-10, -10, 29, 29));
62}
SkRect rect() const
Definition SkGlyph.h:259
struct MyStruct a[10]
static constexpr SkRect MakeLTRB(float l, float t, float r, float b)
Definition SkRect.h:646

◆ DEF_TEST() [6/7]

DEF_TEST ( SkPictureBackedGlyphDrawable_Basic  ,
reporter   
)

Definition at line 332 of file SkGlyphTest.cpp.

332 {
333 class TestDrawable final : public SkDrawable {
334 public:
335 TestDrawable(SkRect rect) : fRect(rect) {}
336 private:
337 const SkRect fRect;
338 SkRect onGetBounds() override { return fRect; }
339 size_t onApproximateBytesUsed() override {
340 return 0;
341 }
342 void onDraw(SkCanvas* canvas) override {
344 canvas->drawRect(fRect, paint);
345 }
346 };
347
348 sk_sp<SkDrawable> srcDrawable = sk_make_sp<TestDrawable>(SkRect::MakeWH(10, 20));
349 SkBinaryWriteBuffer writeBuffer({});
350 SkPictureBackedGlyphDrawable::FlattenDrawable(writeBuffer, srcDrawable.get());
351
352 sk_sp<SkData> data = writeBuffer.snapshotAsData();
353
354 SkReadBuffer readBuffer{data->data(), data->size()};
355
358
359 REPORTER_ASSERT(reporter, readBuffer.isValid());
360 REPORTER_ASSERT(reporter, dstDrawable != nullptr);
361 REPORTER_ASSERT(reporter, srcDrawable->getBounds() == dstDrawable->getBounds());
362
363 SkBinaryWriteBuffer badWriteBuffer({});
364 badWriteBuffer.writeInt(7);
365 badWriteBuffer.writeInt(8);
366
367 data = badWriteBuffer.snapshotAsData();
368
369 SkReadBuffer badReadBuffer{data->data(), data->size()};
370
373 REPORTER_ASSERT(reporter, badDrawable == nullptr);
374 REPORTER_ASSERT(reporter, !badReadBuffer.isValid());
375}
static sk_sp< SkPictureBackedGlyphDrawable > MakeFromBuffer(SkReadBuffer &buffer)
Definition SkGlyph.cpp:37
static void FlattenDrawable(SkWriteBuffer &buffer, SkDrawable *drawable)
Definition SkGlyph.cpp:59
T * get() const
Definition SkRefCnt.h:303
static constexpr SkRect MakeWH(float w, float h)
Definition SkRect.h:609

◆ DEF_TEST() [7/7]

DEF_TEST ( SkPictureBackedGlyphDrawable_SkSL  ,
reporter   
)

Definition at line 417 of file SkGlyphTest.cpp.

417 {
418 for (const sk_sp<SkDrawable>& drawable : {make_sksl_drawable(), make_nested_sksl_drawable()}) {
419 for (bool allowSkSL : {true, false}) {
420 REPORTER_ASSERT(reporter, drawable);
421
422 SkBinaryWriteBuffer writeBuffer({});
423 SkPictureBackedGlyphDrawable::FlattenDrawable(writeBuffer, drawable.get());
424
425 sk_sp<SkData> data = writeBuffer.snapshotAsData();
426
427 SkReadBuffer readBuffer{data->data(), data->size()};
428 readBuffer.setAllowSkSL(allowSkSL);
429
432
433 REPORTER_ASSERT(reporter, readBuffer.isValid() == allowSkSL);
434 REPORTER_ASSERT(reporter, !!dstDrawable == allowSkSL);
435 }
436 }
437}
static sk_sp< SkDrawable > make_sksl_drawable()
static sk_sp< SkDrawable > make_nested_sksl_drawable()

◆ make_nested_sksl_drawable()

static sk_sp< SkDrawable > make_nested_sksl_drawable ( )
static

Definition at line 400 of file SkGlyphTest.cpp.

400 {
401 SkRect rect = SkRect::MakeWH(50, 50);
402
403 SkPictureRecorder recorder;
404 SkCanvas* canvas = recorder.beginRecording(rect);
405
406 auto sksl_drawable = make_sksl_drawable();
407 sk_sp<SkPicture> sksl_picture = sksl_drawable->makePictureSnapshot();
408
409 // We need to ensure that the op count of our picture is larger than this threshold, so we
410 // actually get a nested (embedded) picture, rather than just playing the ops back.
411 SkASSERT(sksl_picture->approximateOpCount() > kMaxPictureOpsToUnrollInsteadOfRef);
412 canvas->drawPicture(sksl_picture);
413
414 return recorder.finishRecordingAsDrawable();
415}
#define SkASSERT(cond)
Definition SkAssert.h:116
constexpr int kMaxPictureOpsToUnrollInsteadOfRef
void drawPicture(const SkPicture *picture)
Definition SkCanvas.h:1961
SkCanvas * beginRecording(const SkRect &bounds, sk_sp< SkBBoxHierarchy > bbh)
sk_sp< SkDrawable > finishRecordingAsDrawable()

◆ make_sksl_drawable()

static sk_sp< SkDrawable > make_sksl_drawable ( )
static

Definition at line 377 of file SkGlyphTest.cpp.

377 {
378 SkRect rect = SkRect::MakeWH(50, 50);
379
380 SkPictureRecorder recorder;
381 SkCanvas* canvas = recorder.beginRecording(rect);
382
383 const sk_sp<SkRuntimeEffect> effect =
385 SkString("half4 main(float2 xy) { return half4(0, 1, 0, 1); }"))
386 .effect;
387 SkASSERT(effect);
388
390 paint.setShader(effect->makeShader(/*uniforms=*/nullptr, /*children=*/{}));
391 // See note in make_nested_sksl_drawable: We include enough ops that this drawable will be
392 // preserved as a sub-picture when we wrap it in a second layer.
393 for (int i = 0; i < kMaxPictureOpsToUnrollInsteadOfRef + 1; ++i) {
394 canvas->drawRect(rect, paint);
395 }
396
397 return recorder.finishRecordingAsDrawable();
398}
static Result MakeForShader(SkString sksl, const Options &)
sk_sp< SkRuntimeEffect > effect