Flutter Engine
The Flutter Engine
SerializationTest.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2013 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
14#include "include/core/SkData.h"
16#include "include/core/SkFont.h"
26#include "include/core/SkPath.h"
33#include "include/core/SkRect.h"
58#include "tests/Test.h"
59#include "tools/Resources.h"
60#include "tools/ToolUtils.h"
62
63#include <algorithm>
64#include <array>
65#include <cstdint>
66#include <cstring>
67#include <memory>
68#include <utility>
69
70using namespace skia_private;
71
72static const uint32_t kArraySize = 64;
73static const int kBitmapSize = 256;
74
76public:
77
78template<typename T>
79static void TestAlignment(T* testObj, skiatest::Reporter* reporter) {
80 // Test memory read/write functions directly
81 unsigned char dataWritten[1024];
82 size_t bytesWrittenToMemory = testObj->writeToMemory(dataWritten);
83 REPORTER_ASSERT(reporter, SkAlign4(bytesWrittenToMemory) == bytesWrittenToMemory);
84 size_t bytesReadFromMemory = testObj->readFromMemory(dataWritten, bytesWrittenToMemory);
85 REPORTER_ASSERT(reporter, SkAlign4(bytesReadFromMemory) == bytesReadFromMemory);
86}
87};
88
89template<typename T> struct SerializationUtils {
90 // Generic case for flattenables
91 static void Write(SkWriteBuffer& writer, const T* flattenable) {
92 writer.writeFlattenable(flattenable);
93 }
94 static void Read(SkReadBuffer& reader, T** flattenable) {
95 *flattenable = (T*)reader.readFlattenable(T::GetFlattenableType());
96 }
97};
98
99template<> struct SerializationUtils<SkMatrix> {
100 static void Write(SkWriteBuffer& writer, const SkMatrix* matrix) {
101 writer.writeMatrix(*matrix);
102 }
103 static void Read(SkReadBuffer& reader, SkMatrix* matrix) {
104 reader.readMatrix(matrix);
105 }
106};
107
108template<> struct SerializationUtils<SkPath> {
109 static void Write(SkWriteBuffer& writer, const SkPath* path) {
110 writer.writePath(*path);
111 }
112 static void Read(SkReadBuffer& reader, SkPath* path) {
113 reader.readPath(path);
114 }
115};
116
117template<> struct SerializationUtils<SkRegion> {
118 static void Write(SkWriteBuffer& writer, const SkRegion* region) {
119 writer.writeRegion(*region);
120 }
121 static void Read(SkReadBuffer& reader, SkRegion* region) {
122 reader.readRegion(region);
123 }
124};
125
126template<> struct SerializationUtils<SkString> {
127 static void Write(SkWriteBuffer& writer, const SkString* string) {
128 writer.writeString(string->c_str());
129 }
130 static void Read(SkReadBuffer& reader, SkString* string) {
131 reader.readString(string);
132 }
133};
134
135template<> struct SerializationUtils<unsigned char> {
136 static void Write(SkWriteBuffer& writer, unsigned char* data, uint32_t arraySize) {
137 writer.writeByteArray(data, arraySize);
138 }
139 static bool Read(SkReadBuffer& reader, unsigned char* data, uint32_t arraySize) {
140 return reader.readByteArray(data, arraySize);
141 }
142};
143
144template<> struct SerializationUtils<SkColor> {
145 static void Write(SkWriteBuffer& writer, SkColor* data, uint32_t arraySize) {
146 writer.writeColorArray(data, arraySize);
147 }
148 static bool Read(SkReadBuffer& reader, SkColor* data, uint32_t arraySize) {
149 return reader.readColorArray(data, arraySize);
150 }
151};
152
153template<> struct SerializationUtils<SkColor4f> {
154 static void Write(SkWriteBuffer& writer, SkColor4f* data, uint32_t arraySize) {
155 writer.writeColor4fArray(data, arraySize);
156 }
157 static bool Read(SkReadBuffer& reader, SkColor4f* data, uint32_t arraySize) {
158 return reader.readColor4fArray(data, arraySize);
159 }
160};
161
162template<> struct SerializationUtils<int32_t> {
163 static void Write(SkWriteBuffer& writer, int32_t* data, uint32_t arraySize) {
164 writer.writeIntArray(data, arraySize);
165 }
166 static bool Read(SkReadBuffer& reader, int32_t* data, uint32_t arraySize) {
167 return reader.readIntArray(data, arraySize);
168 }
169};
170
171template<> struct SerializationUtils<SkPoint> {
172 static void Write(SkWriteBuffer& writer, SkPoint* data, uint32_t arraySize) {
173 writer.writePointArray(data, arraySize);
174 }
175 static bool Read(SkReadBuffer& reader, SkPoint* data, uint32_t arraySize) {
176 return reader.readPointArray(data, arraySize);
177 }
178};
179
180template<> struct SerializationUtils<SkPoint3> {
181 static void Write(SkWriteBuffer& writer, const SkPoint3* data) {
182 writer.writePoint3(*data);
183 }
184 static void Read(SkReadBuffer& reader, SkPoint3* data) {
185 reader.readPoint3(data);
186 }
187};
188
189template<> struct SerializationUtils<SkScalar> {
190 static void Write(SkWriteBuffer& writer, SkScalar* data, uint32_t arraySize) {
191 writer.writeScalarArray(data, arraySize);
192 }
193 static bool Read(SkReadBuffer& reader, SkScalar* data, uint32_t arraySize) {
194 return reader.readScalarArray(data, arraySize);
195 }
196};
197
198template<typename T, bool testInvalid> struct SerializationTestUtils {
199 static void InvalidateData(unsigned char* data) {}
200};
201
203 static void InvalidateData(unsigned char* data) {
204 data[3] |= 0x80; // Reverse sign of 1st integer
205 }
206};
207
208template<typename T, bool testInvalid>
210 SkBinaryWriteBuffer writer({});
211 SerializationUtils<T>::Write(writer, testObj);
212 size_t bytesWritten = writer.bytesWritten();
213 REPORTER_ASSERT(reporter, SkAlign4(bytesWritten) == bytesWritten);
214
215 unsigned char dataWritten[1024];
216 writer.writeToMemory(dataWritten);
217
219
220 // Make sure this fails when it should (test with smaller size, but still multiple of 4)
221 SkReadBuffer buffer(dataWritten, bytesWritten - 4);
222 T obj;
224 REPORTER_ASSERT(reporter, !buffer.isValid());
225
226 // Make sure this succeeds when it should
227 SkReadBuffer buffer2(dataWritten, bytesWritten);
228 size_t offsetBefore = buffer2.offset();
229 T obj2;
230 SerializationUtils<T>::Read(buffer2, &obj2);
231 size_t offsetAfter = buffer2.offset();
232 // This should have succeeded, since there are enough bytes to read this
233 REPORTER_ASSERT(reporter, buffer2.isValid() == !testInvalid);
234 // Note: This following test should always succeed, regardless of whether the buffer is valid,
235 // since if it is invalid, it will simply skip to the end, as if it had read the whole buffer.
236 REPORTER_ASSERT(reporter, offsetAfter - offsetBefore == bytesWritten);
237}
238
239template<typename T>
241 TestObjectSerializationNoAlign<T, false>(testObj, reporter);
243}
244
245template<typename T>
246static T* TestFlattenableSerialization(T* testObj, bool shouldSucceed,
248 SkBinaryWriteBuffer writer({});
249 SerializationUtils<T>::Write(writer, testObj);
250 size_t bytesWritten = writer.bytesWritten();
251 REPORTER_ASSERT(reporter, SkAlign4(bytesWritten) == bytesWritten);
252
253 SkASSERT(bytesWritten <= 4096);
254 unsigned char dataWritten[4096];
255 writer.writeToMemory(dataWritten);
256
257 // Make sure this fails when it should (test with smaller size, but still multiple of 4)
258 SkReadBuffer buffer(dataWritten, bytesWritten - 4);
259 T* obj = nullptr;
261 REPORTER_ASSERT(reporter, !buffer.isValid());
262 REPORTER_ASSERT(reporter, nullptr == obj);
263
264 // Make sure this succeeds when it should
265 SkReadBuffer buffer2(dataWritten, bytesWritten);
266 const unsigned char* peekBefore = static_cast<const unsigned char*>(buffer2.skip(0));
267 T* obj2 = nullptr;
268 SerializationUtils<T>::Read(buffer2, &obj2);
269 const unsigned char* peekAfter = static_cast<const unsigned char*>(buffer2.skip(0));
270 if (shouldSucceed) {
271 // This should have succeeded, since there are enough bytes to read this
272 REPORTER_ASSERT(reporter, buffer2.isValid());
273 REPORTER_ASSERT(reporter, static_cast<size_t>(peekAfter - peekBefore) == bytesWritten);
275 } else {
276 // If the deserialization was supposed to fail, make sure it did
277 REPORTER_ASSERT(reporter, !buffer.isValid());
278 REPORTER_ASSERT(reporter, nullptr == obj2);
279 }
280
281 return obj2; // Return object to perform further validity tests on it
282}
283
284template<typename T>
286 SkBinaryWriteBuffer writer({});
288 size_t bytesWritten = writer.bytesWritten();
289 // This should write the length (in 4 bytes) and the array
290 REPORTER_ASSERT(reporter, (4 + kArraySize * sizeof(T)) == bytesWritten);
291
292 unsigned char dataWritten[2048];
293 writer.writeToMemory(dataWritten);
294
295 // Make sure this fails when it should
296 SkReadBuffer buffer(dataWritten, bytesWritten);
297 T dataRead[kArraySize];
298 bool success = SerializationUtils<T>::Read(buffer, dataRead, kArraySize / 2);
299 // This should have failed, since the provided size was too small
300 REPORTER_ASSERT(reporter, !success);
301
302 // Make sure this succeeds when it should
303 SkReadBuffer buffer2(dataWritten, bytesWritten);
304 success = SerializationUtils<T>::Read(buffer2, dataRead, kArraySize);
305 // This should have succeeded, since there are enough bytes to read this
306 REPORTER_ASSERT(reporter, success);
307}
308
309static void TestBitmapSerialization(const SkBitmap& validBitmap,
310 const SkBitmap& invalidBitmap,
311 bool shouldSucceed,
313 sk_sp<SkImage> validImage(validBitmap.asImage());
314 sk_sp<SkImageFilter> validBitmapSource(SkImageFilters::Image(std::move(validImage),
316 sk_sp<SkImage> invalidImage(invalidBitmap.asImage());
317 sk_sp<SkImageFilter> invalidBitmapSource(SkImageFilters::Image(std::move(invalidImage),
319 sk_sp<SkImageFilter> xfermodeImageFilter(
321 std::move(invalidBitmapSource),
322 std::move(validBitmapSource), nullptr));
323
324 sk_sp<SkImageFilter> deserializedFilter(
325 TestFlattenableSerialization<SkImageFilter_Base>(
326 (SkImageFilter_Base*)xfermodeImageFilter.get(), shouldSucceed, reporter));
327
328 // Try to render a small bitmap using the invalid deserialized filter
329 // to make sure we don't crash while trying to render it
330 if (shouldSucceed) {
332 bitmap.allocN32Pixels(24, 24);
333 SkCanvas canvas(bitmap);
334 canvas.clear(0x00000000);
336 paint.setImageFilter(deserializedFilter);
338 canvas.drawImage(bitmap.asImage(), 0, 0, SkSamplingOptions(), &paint);
339 }
340}
341
343 uint8_t table[256];
344 for (int i = 0; i < 256; ++i) {
345 table[i] = (i * 41) % 256;
346 }
347 auto filter = SkColorFilters::Table(table);
349 TestFlattenableSerialization(as_CFB(filter.get()), true, reporter));
350}
351
354 bitmap.allocN32Pixels(SkScalarCeilToInt(picture.cullRect().width()),
355 SkScalarCeilToInt(picture.cullRect().height()));
356 SkCanvas canvas(bitmap);
357 picture.playback(&canvas);
358 return bitmap;
359}
360
362 const SkBitmap& b1, const SkBitmap& b2) {
363 REPORTER_ASSERT(reporter, b1.width() == b2.width());
364 REPORTER_ASSERT(reporter, b1.height() == b2.height());
365
366 if ((b1.width() != b2.width()) ||
367 (b1.height() != b2.height())) {
368 return;
369 }
370
371 int pixelErrors = 0;
372 for (int y = 0; y < b2.height(); ++y) {
373 for (int x = 0; x < b2.width(); ++x) {
374 if (b1.getColor(x, y) != b2.getColor(x, y))
375 ++pixelErrors;
376 }
377 }
378 REPORTER_ASSERT(reporter, 0 == pixelErrors);
379}
380
382 // Write out typeface ID followed by entire typeface.
385 uint32_t typeface_id = typeface->uniqueID();
386 stream.write(&typeface_id, sizeof(typeface_id));
387 stream.write(data->data(), data->size());
388 return stream.detachAsData();
389}
390
391static sk_sp<SkTypeface> deserialize_typeface_proc(const void* data, size_t length, void* ctx) {
393 if (length < sizeof(stream)) {
394 return nullptr;
395 }
396 memcpy(&stream, data, sizeof(stream));
397
399 if (!stream->read(&id, sizeof(id))) {
400 return nullptr;
401 }
402
404 return typeface;
405}
406
408 const char* text,
409 const SkSerialProcs* serial_procs,
410 const SkDeserialProcs* deserial_procs,
412 // Create a font with the typeface.
414 paint.setColor(SK_ColorGRAY);
415 SkFont font(std::move(typeface), 30);
416
417 // Paint some text.
418 SkPictureRecorder recorder;
420 SkCanvas* canvas = recorder.beginRecording(SkIntToScalar(canvasRect.width()),
421 SkIntToScalar(canvasRect.height()));
422 canvas->drawColor(SK_ColorWHITE);
423 canvas->drawString(text, 24, 32, font, paint);
425
426 // Serlialize picture and create its clone from stream.
428 picture->serialize(&stream, serial_procs);
429 std::unique_ptr<SkStream> inputStream(stream.detachAsStream());
430 sk_sp<SkPicture> loadedPicture(SkPicture::MakeFromStream(inputStream.get(), deserial_procs));
431
432 // Draw both original and clone picture and compare bitmaps -- they should be identical.
433 SkBitmap origBitmap = draw_picture(*picture);
434 SkBitmap destBitmap = draw_picture(*loadedPicture);
435 compare_bitmaps(reporter, origBitmap, destBitmap);
436}
437
439 std::unique_ptr<SkStreamAsset> distortable(GetResourceAsStream("fonts/Distortable.ttf"));
440 if (!distortable) {
441 REPORT_FAILURE(reporter, "distortable", SkString());
442 return nullptr;
443 }
444
446 { SkSetFourByteTag('w','g','h','t'), SK_ScalarSqrt2 },
447 };
449 params.setVariationDesignPosition({position, std::size(position)});
450
452
453 sk_sp<SkTypeface> typeface = fm->makeFromStream(std::move(distortable), params);
454 if (!typeface) {
455 return nullptr; // Not all SkFontMgr can makeFromStream().
456 }
457
458 int count = typeface->getVariationDesignPosition(nullptr, 0);
459 if (count == -1) {
460 return nullptr; // The number of axes is unknown.
461 }
462
463 return typeface;
464}
465
467 std::unique_ptr<SkStreamAsset> colr(GetResourceAsStream("fonts/colr.ttf"));
468 if (!colr) {
469 REPORT_FAILURE(reporter, "colr", SkString());
470 return nullptr;
471 }
472
473 const SkFontArguments::Palette::Override paletteOverride[] = {
474 { 1, SK_ColorGRAY },
475 };
477 params.setPalette({0, paletteOverride, std::size(paletteOverride)});
478
480
481 sk_sp<SkTypeface> typeface = fm->makeFromStream(std::move(colr), params);
482 if (!typeface) {
483 return nullptr; // Not all SkFontMgr can makeFromStream().
484 }
485
486 return typeface;
487}
488
489static void TestPictureTypefaceSerialization(const SkSerialProcs* serial_procs,
490 const SkDeserialProcs* deserial_procs,
492 {
493 // Load typeface from file to test CreateFromFile with index.
494 auto typeface = ToolUtils::CreateTypefaceFromResource("fonts/test.ttc", 1);
495 if (!typeface) {
496 INFOF(reporter, "Could not run test because test.ttc not found.");
497 } else {
498 serialize_and_compare_typeface(std::move(typeface), "A!", serial_procs, deserial_procs,
499 reporter);
500 }
501 }
502
503 {
504 // Load typeface as stream to create with axis settings.
506 if (!typeface) {
507 INFOF(reporter, "Could not run test because Distortable.ttf not created.");
508 } else {
509 serialize_and_compare_typeface(std::move(typeface), "ab", serial_procs,
510 deserial_procs, reporter);
511 }
512 }
513
514 {
515 // Load typeface as stream to create with palette settings.
517 if (!typeface) {
518 INFOF(reporter, "Could not run test because colr.ttf not created.");
519 } else {
520 serialize_and_compare_typeface(std::move(typeface), "😀♢", serial_procs,
521 deserial_procs, reporter);
522 }
523 }
524}
525
527 int index;
528 std::unique_ptr<SkStreamAsset> typefaceStream = typeface.openStream(&index);
529 if (!typefaceStream) {
530 return SkString("No Stream");
531 }
532 size_t length = typefaceStream->getLength();
533
534 SkString s;
535 s.appendf("Index: %d\n", index);
536 s.appendf("Length: %zu\n", length);
537 return s;
538}
540 SkString m("Flags:\n");
541
542 if (metrics.fFlags == 0) {
543 m += " No flags\n";
544 } else {
546 m += " UnderlineThicknessIsValid\n";
547 }
549 m += " kUnderlinePositionIsValid\n";
550 }
552 m += " kStrikeoutThicknessIsValid\n";
553 }
555 m += " kStrikeoutPositionIsValid\n";
556 }
558 m += " kBoundsInvalid\n";
559 }
560 }
561
562 m.appendf("Top: %f\n", metrics.fTop);
563 m.appendf("Ascent: %f\n", metrics.fAscent);
564 m.appendf("Descent: %f\n", metrics.fDescent);
565 m.appendf("Bottom: %f\n", metrics.fBottom);
566 m.appendf("Leading: %f\n", metrics.fLeading);
567 m.appendf("AvgCharWidth: %f\n", metrics.fAvgCharWidth);
568 m.appendf("MaxCharWidth: %f\n", metrics.fMaxCharWidth);
569 m.appendf("XMin: %f\n", metrics.fXMin);
570 m.appendf("XMax: %f\n", metrics.fXMax);
571 m.appendf("XHeight: %f\n", metrics.fXHeight);
572 m.appendf("CapHeight: %f\n", metrics.fCapHeight);
573 m.appendf("UnderlineThickness: %f\n", metrics.fUnderlineThickness);
574 m.appendf("UnderlinePosition: %f\n", metrics.fUnderlinePosition);
575 m.appendf("StrikeoutThickness: %f\n", metrics.fStrikeoutThickness);
576 m.appendf("StrikeoutPosition: %f\n", metrics.fStrikeoutPosition);
577 return m;
578}
580 const sk_sp<SkTypeface>& typeface) {
581 SkDynamicMemoryWStream typefaceWStream;
582 typeface->serialize(&typefaceWStream);
583
584 std::unique_ptr<SkStream> typefaceStream = typefaceWStream.detachAsStream();
585 sk_sp<SkTypeface> cloneTypeface =
587 SkASSERT(cloneTypeface);
588
589 SkString name, cloneName;
590 typeface->getFamilyName(&name);
591 cloneTypeface->getFamilyName(&cloneName);
592
593 REPORTER_ASSERT(reporter, typeface->countGlyphs() == cloneTypeface->countGlyphs(),
594 "Typeface: \"%s\" CloneTypeface: \"%s\"", name.c_str(), cloneName.c_str());
595 REPORTER_ASSERT(reporter, typeface->fontStyle() == cloneTypeface->fontStyle(),
596 "Typeface: \"%s\" CloneTypeface: \"%s\"", name.c_str(), cloneName.c_str());
597
598 SkFont font(typeface, 12);
599 SkFont clone(cloneTypeface, 12);
600 SkFontMetrics fontMetrics, cloneMetrics;
601 font.getMetrics(&fontMetrics);
602 clone.getMetrics(&cloneMetrics);
603 REPORTER_ASSERT(reporter, fontMetrics == cloneMetrics,
604 "Typeface: \"%s\"\n-Metrics---\n%s-Data---\n%s\n\n"
605 "CloneTypeface: \"%s\"\n-Metrics---\n%s-Data---\n%s",
606 name.c_str(),
607 DumpFontMetrics(fontMetrics).c_str(),
608 DumpTypeface(*typeface).c_str(),
609 cloneName.c_str(),
610 DumpFontMetrics(cloneMetrics).c_str(),
611 DumpTypeface(*cloneTypeface).c_str());
612}
613DEF_TEST(Serialization_Typeface, reporter) {
616}
617
619 bitmap->allocN32Pixels(kBitmapSize, kBitmapSize);
620}
621
625
626 SkCanvas canvas(bitmap);
627 canvas.clear(0x00000000);
628 SkPaint darkPaint;
629 darkPaint.setColor(0xFF804020);
630 SkPaint lightPaint;
631 lightPaint.setColor(0xFF244484);
632 const int i = kBitmapSize / 8;
633 const SkScalar f = SkIntToScalar(i);
634 for (int y = 0; y < kBitmapSize; y += i) {
635 for (int x = 0; x < kBitmapSize; x += i) {
636 canvas.save();
638 canvas.drawRect(SkRect::MakeXYWH(0, 0, f, f), darkPaint);
639 canvas.drawRect(SkRect::MakeXYWH(f, 0, f, f), lightPaint);
640 canvas.drawRect(SkRect::MakeXYWH(0, f, f, f), lightPaint);
641 canvas.drawRect(SkRect::MakeXYWH(f, f, f, f), darkPaint);
642 canvas.restore();
643 }
644 }
645 return bitmap.asImage();
646}
647
648static void draw_something(SkCanvas* canvas) {
649 canvas->save();
650 canvas->scale(0.5f, 0.5f);
651 canvas->drawImage(make_checkerboard_image(), 0, 0);
652 canvas->restore();
653
655 paint.setAntiAlias(true);
656 paint.setColor(SK_ColorRED);
658 paint.setColor(SK_ColorBLACK);
659
661 font.setSize(kBitmapSize/3);
663}
664
667 SkScalarRoundToInt(p.cullRect().width()), SkScalarRoundToInt(p.cullRect().height())));
668 if (!surf) {
669 return nullptr; // bounds are empty?
670 }
671 surf->getCanvas()->clear(SK_ColorWHITE);
672 p.playback(surf->getCanvas());
673 return surf->makeImageSnapshot();
674}
675
676DEF_TEST(Serialization, reporter) {
677 // Test matrix serialization
678 {
681 }
682
683 // Test point3 serialization
684 {
685 SkPoint3 point;
686 TestObjectSerializationNoAlign<SkPoint3, false>(&point, reporter);
687 }
688
689 // Test path serialization
690 {
691 SkPath path;
693 }
694
695 // Test region serialization
696 {
699 }
700
701 // Test color filter serialization
702 {
704 }
705
706 // Test string serialization
707 {
708 SkString string("string");
709 TestObjectSerializationNoAlign<SkString, false>(&string, reporter);
710 TestObjectSerializationNoAlign<SkString, true>(&string, reporter);
711 }
712
713 // Test rrect serialization
714 {
715 // SkRRect does not initialize anything.
716 // An uninitialized SkRRect can be serialized,
717 // but will branch on uninitialized data when deserialized.
719 SkRect rect = SkRect::MakeXYWH(1, 2, 20, 30);
720 SkVector corners[4] = { {1, 2}, {2, 3}, {3,4}, {4,5} };
721 rrect.setRectRadii(rect, corners);
723 }
724
725 // Test readByteArray
726 {
727 unsigned char data[kArraySize] = { 1, 2, 3 };
729 }
730
731 // Test readColorArray
732 {
735 }
736
737 // Test readColor4fArray
738 {
740 SkColor4f::FromColor(SK_ColorBLACK),
741 SkColor4f::FromColor(SK_ColorWHITE),
742 SkColor4f::FromColor(SK_ColorRED),
743 { 1.f, 2.f, 4.f, 8.f }
744 };
746 }
747
748 // Test readIntArray
749 {
750 int32_t data[kArraySize] = { 1, 2, 4, 8 };
752 }
753
754 // Test readPointArray
755 {
756 SkPoint data[kArraySize] = { {6, 7}, {42, 128} };
758 }
759
760 // Test readScalarArray
761 {
764 }
765
766 // Test skipByteArray
767 {
768 // Valid case with non-empty array:
769 {
770 unsigned char data[kArraySize] = { 1, 2, 3 };
771 SkBinaryWriteBuffer writer({});
773 SkAutoMalloc buf(writer.bytesWritten());
774 writer.writeToMemory(buf.get());
775
776 SkReadBuffer reader(buf.get(), writer.bytesWritten());
777 size_t len = ~0;
778 const void* arr = reader.skipByteArray(&len);
781 REPORTER_ASSERT(reporter, memcmp(arr, data, len) == 0);
782 }
783
784 // Writing a zero length array (can be detected as valid by non-nullptr return):
785 {
786 SkBinaryWriteBuffer writer({});
787 writer.writeByteArray(nullptr, 0);
788 SkAutoMalloc buf(writer.bytesWritten());
789 writer.writeToMemory(buf.get());
790
791 SkReadBuffer reader(buf.get(), writer.bytesWritten());
792 size_t len = ~0;
793 const void* arr = reader.skipByteArray(&len);
796 }
797
798 // If the array can't be safely read, should return nullptr:
799 {
800 SkBinaryWriteBuffer writer({});
801 writer.writeUInt(kArraySize);
802 SkAutoMalloc buf(writer.bytesWritten());
803 writer.writeToMemory(buf.get());
804
805 SkReadBuffer reader(buf.get(), writer.bytesWritten());
806 size_t len = ~0;
807 const void* arr = reader.skipByteArray(&len);
810 }
811 }
812
813 // Test invalid deserializations
814 {
816
817 SkBitmap validBitmap;
818 validBitmap.setInfo(info);
819
820 // Create a bitmap with a really large height
821 SkBitmap invalidBitmap;
822 invalidBitmap.setInfo(info.makeWH(info.width(), 1000000000));
823
824 // The deserialization should succeed, and the rendering shouldn't crash,
825 // even when the device fails to initialize, due to its size
826 TestBitmapSerialization(validBitmap, invalidBitmap, true, reporter);
827 }
828
829 // Test simple SkPicture serialization
830 {
831 skiatest::ReporterContext subtest(reporter, "simple SkPicture");
832 SkPictureRecorder recorder;
836
837 // Serialize picture. The default typeface proc should result in a non-empty
838 // typeface when deserializing.
839 SkSerialProcs sProcs;
840 sProcs.fImageProc = [](SkImage* img, void*) -> sk_sp<SkData> {
841 return SkPngEncoder::Encode(nullptr, img, SkPngEncoder::Options{});
842 };
843 sk_sp<SkData> data = pict->serialize(&sProcs);
845
846 // Deserialize picture using the default procs.
847 // TODO(kjlubick) Specify a proc for decoding image data.
849 REPORTER_ASSERT(reporter, readPict);
850 sk_sp<SkImage> img0 = render(*pict);
851 sk_sp<SkImage> img1 = render(*readPict);
852 if (img0 && img1) {
853 bool ok = ToolUtils::equal_pixels(img0.get(), img1.get());
854 REPORTER_ASSERT(reporter, ok, "before and after image did not match");
855 if (!ok) {
856 auto left = SkFILEWStream("before_serialize.png");
857 sk_sp<SkData> d = SkPngEncoder::Encode(nullptr, img0.get(), {});
858 left.write(d->data(), d->size());
859 left.fsync();
860 auto right = SkFILEWStream("after_serialize.png");
861 d = SkPngEncoder::Encode(nullptr, img1.get(), {});
862 right.write(d->data(), d->size());
863 right.fsync();
864 }
865 }
866 }
867
869
870 SkSerialProcs serial_procs;
872 SkDeserialProcs deserial_procs;
874 TestPictureTypefaceSerialization(&serial_procs, &deserial_procs, reporter);
875}
876
877///////////////////////////////////////////////////////////////////////////////////////////////////
878
881 src->serialize(&wstream, nullptr); // default is fine, no SkImages to encode
882 std::unique_ptr<SkStreamAsset> rstream(wstream.detachAsStream());
883 return SkPicture::MakeFromStream(rstream.get());
884}
885
888 const char* fKey;
890};
891
893 skiatest::Reporter* fReporter;
894 const AnnotationRec* fRec;
895 int fCount;
896 int fCurrIndex;
897
898public:
900 : SkCanvas(100, 100)
901 , fReporter(reporter)
902 , fRec(rec)
903 , fCount(count)
904 , fCurrIndex(0)
905 {}
906
908 REPORTER_ASSERT(fReporter, fCount == fCurrIndex);
909 }
910
911protected:
912 void onDrawAnnotation(const SkRect& rect, const char key[], SkData* value) override {
913 REPORTER_ASSERT(fReporter, fCurrIndex < fCount);
914 REPORTER_ASSERT(fReporter, rect == fRec[fCurrIndex].fRect);
915 REPORTER_ASSERT(fReporter, !strcmp(key, fRec[fCurrIndex].fKey));
916 REPORTER_ASSERT(fReporter, value->equals(fRec[fCurrIndex].fValue.get()));
917 fCurrIndex += 1;
918 }
919};
920
921/*
922 * Test the 3 annotation types by recording them into a picture, serializing, and then playing
923 * them back into another canvas.
924 */
925DEF_TEST(Annotations, reporter) {
926 SkPictureRecorder recorder;
927 SkCanvas* recordingCanvas = recorder.beginRecording(SkRect::MakeWH(100, 100));
928
929 const char* str0 = "rect-with-url";
930 const SkRect r0 = SkRect::MakeWH(10, 10);
932 SkAnnotateRectWithURL(recordingCanvas, r0, d0.get());
933
934 const char* str1 = "named-destination";
935 const SkRect r1 = SkRect::MakeXYWH(5, 5, 0, 0); // collapsed to a point
937 SkAnnotateNamedDestination(recordingCanvas, {r1.x(), r1.y()}, d1.get());
938
939 const char* str2 = "link-to-destination";
940 const SkRect r2 = SkRect::MakeXYWH(20, 20, 5, 6);
942 SkAnnotateLinkToDestination(recordingCanvas, r2, d2.get());
943
944 const AnnotationRec recs[] = {
945 { r0, SkAnnotationKeys::URL_Key(), std::move(d0) },
946 { r1, SkAnnotationKeys::Define_Named_Dest_Key(), std::move(d1) },
947 { r2, SkAnnotationKeys::Link_Named_Dest_Key(), std::move(d2) },
948 };
949
952
953 TestAnnotationCanvas canvas(reporter, recs, std::size(recs));
954 canvas.drawPicture(pict1);
955}
956
957DEF_TEST(WriteBuffer_storage, reporter) {
958 enum {
959 kSize = 32
960 };
961 int32_t storage[kSize/4];
962 char src[kSize];
964
965 SkBinaryWriteBuffer writer(storage, kSize, {});
966 REPORTER_ASSERT(reporter, writer.usingInitialStorage());
967 REPORTER_ASSERT(reporter, writer.bytesWritten() == 0);
968 writer.write(src, kSize - 4);
969 REPORTER_ASSERT(reporter, writer.usingInitialStorage());
970 REPORTER_ASSERT(reporter, writer.bytesWritten() == kSize - 4);
971 writer.writeInt(0);
972 REPORTER_ASSERT(reporter, writer.usingInitialStorage());
973 REPORTER_ASSERT(reporter, writer.bytesWritten() == kSize);
974
975 writer.reset(storage, kSize-4);
976 REPORTER_ASSERT(reporter, writer.usingInitialStorage());
977 REPORTER_ASSERT(reporter, writer.bytesWritten() == 0);
978 writer.write(src, kSize - 4);
979 REPORTER_ASSERT(reporter, writer.usingInitialStorage());
980 REPORTER_ASSERT(reporter, writer.bytesWritten() == kSize - 4);
981 writer.writeInt(0);
982 REPORTER_ASSERT(reporter, !writer.usingInitialStorage()); // this is the change
983 REPORTER_ASSERT(reporter, writer.bytesWritten() == kSize);
984}
985
986DEF_TEST(WriteBuffer_external_memory_textblob, reporter) {
988
990 int glyph_count = 5;
991 const auto& run = builder.allocRun(font, glyph_count, 1.2f, 2.3f);
992 // allocRun() allocates only the glyph buffer.
993 std::fill(run.glyphs, run.glyphs + glyph_count, 0);
994 auto blob = builder.make();
995 SkSerialProcs procs;
996 AutoTMalloc<uint8_t> storage;
997 size_t blob_size = 0u;
998 size_t storage_size = 0u;
999
1000 blob_size = SkAlign4(blob->serialize(procs)->size());
1001 REPORTER_ASSERT(reporter, blob_size > 4u);
1002 storage_size = blob_size - 4;
1003 storage.realloc(storage_size);
1004 REPORTER_ASSERT(reporter, blob->serialize(procs, storage.get(), storage_size) == 0u);
1005 storage_size = blob_size;
1006 storage.realloc(storage_size);
1007 REPORTER_ASSERT(reporter, blob->serialize(procs, storage.get(), storage_size) != 0u);
1008}
1009
1010DEF_TEST(WriteBuffer_external_memory_flattenable, reporter) {
1011 SkScalar intervals[] = {1.f, 1.f};
1012 auto path_effect = SkDashPathEffect::Make(intervals, 2, 0);
1013 size_t path_size = SkAlign4(path_effect->serialize()->size());
1014 REPORTER_ASSERT(reporter, path_size > 4u);
1015 AutoTMalloc<uint8_t> storage;
1016
1017 size_t storage_size = path_size - 4;
1018 storage.realloc(storage_size);
1019 REPORTER_ASSERT(reporter, path_effect->serialize(storage.get(), storage_size) == 0u);
1020
1021 storage_size = path_size;
1022 storage.realloc(storage_size);
1023 REPORTER_ASSERT(reporter, path_effect->serialize(storage.get(), storage_size) != 0u);
1024}
1025
1026DEF_TEST(ReadBuffer_empty, reporter) {
1027 SkBinaryWriteBuffer writer({});
1028 writer.writeInt(123);
1029 writer.writeDataAsByteArray(SkData::MakeEmpty().get());
1030 writer.writeInt(321);
1031
1032 size_t size = writer.bytesWritten();
1033 SkAutoMalloc storage(size);
1034 writer.writeToMemory(storage.get());
1035
1036 SkReadBuffer reader(storage.get(), size);
1037 REPORTER_ASSERT(reporter, reader.readInt() == 123);
1038 auto data = reader.readByteArrayAsData();
1039 REPORTER_ASSERT(reporter, data->size() == 0);
1040 REPORTER_ASSERT(reporter, reader.readInt() == 321);
1041}
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition: DM.cpp:213
SkRect fRect
Definition: FillRRectOp.cpp:73
sk_bzero(glyphs, sizeof(glyphs))
reporter
Definition: FontMgrTest.cpp:39
int count
Definition: FontMgrTest.cpp:50
std::unique_ptr< SkStreamAsset > GetResourceAsStream(const char *resource, bool useFileStream)
Definition: Resources.cpp:31
static void TestObjectSerializationNoAlign(T *testObj, skiatest::Reporter *reporter)
static void TestPictureTypefaceSerialization(const SkSerialProcs *serial_procs, const SkDeserialProcs *deserial_procs, skiatest::Reporter *reporter)
static sk_sp< SkPicture > copy_picture_via_serialization(SkPicture *src)
static void setup_bitmap_for_canvas(SkBitmap *bitmap)
static sk_sp< SkTypeface > makeDistortableWithNonDefaultAxes(skiatest::Reporter *reporter)
static void compare_bitmaps(skiatest::Reporter *reporter, const SkBitmap &b1, const SkBitmap &b2)
SkString DumpFontMetrics(const SkFontMetrics &metrics)
static void TestArraySerialization(T *data, skiatest::Reporter *reporter)
static sk_sp< SkImage > make_checkerboard_image()
static void serialize_and_compare_typeface(sk_sp< SkTypeface > typeface, const char *text, const SkSerialProcs *serial_procs, const SkDeserialProcs *deserial_procs, skiatest::Reporter *reporter)
static const int kBitmapSize
static void TestTypefaceSerialization(skiatest::Reporter *reporter, const sk_sp< SkTypeface > &typeface)
static void TestObjectSerialization(T *testObj, skiatest::Reporter *reporter)
static SkBitmap draw_picture(SkPicture &picture)
SkString DumpTypeface(const SkTypeface &typeface)
DEF_TEST(Serialization_Typeface, reporter)
static const uint32_t kArraySize
static void TestBitmapSerialization(const SkBitmap &validBitmap, const SkBitmap &invalidBitmap, bool shouldSucceed, skiatest::Reporter *reporter)
static sk_sp< SkTypeface > makeColrWithNonDefaultPalette(skiatest::Reporter *reporter)
static sk_sp< SkTypeface > deserialize_typeface_proc(const void *data, size_t length, void *ctx)
static sk_sp< SkImage > render(const SkPicture &p)
static void TestColorFilterSerialization(skiatest::Reporter *reporter)
static sk_sp< SkData > serialize_typeface_proc(SkTypeface *typeface, void *ctx)
static void draw_something(SkCanvas *canvas)
static T * TestFlattenableSerialization(T *testObj, bool shouldSucceed, skiatest::Reporter *reporter)
static constexpr T SkAlign4(T x)
Definition: SkAlign.h:16
SK_API void SkAnnotateRectWithURL(SkCanvas *, const SkRect &, SkData *)
SK_API void SkAnnotateNamedDestination(SkCanvas *, const SkPoint &, SkData *)
SK_API void SkAnnotateLinkToDestination(SkCanvas *, const SkRect &, SkData *)
#define SkASSERT(cond)
Definition: SkAssert.h:116
@ kSrcOver
r = s + (1-sa)*d
static SkColorFilterBase * as_CFB(SkColorFilter *filter)
uint32_t SkColor
Definition: SkColor.h:37
constexpr SkColor SK_ColorGRAY
Definition: SkColor.h:113
constexpr SkColor SK_ColorRED
Definition: SkColor.h:126
constexpr SkColor SK_ColorBLACK
Definition: SkColor.h:103
constexpr SkColor SK_ColorWHITE
Definition: SkColor.h:122
static bool ok(int result)
static bool left(const SkPoint &p0, const SkPoint &p1)
static bool right(const SkPoint &p0, const SkPoint &p1)
#define SK_ScalarMax
Definition: SkScalar.h:24
#define SK_Scalar1
Definition: SkScalar.h:18
#define SK_ScalarHalf
Definition: SkScalar.h:19
#define SkScalarRoundToInt(x)
Definition: SkScalar.h:37
#define SkScalarCeilToInt(x)
Definition: SkScalar.h:36
#define SkIntToScalar(x)
Definition: SkScalar.h:57
#define SK_ScalarSqrt2
Definition: SkScalar.h:20
static void copy(void *dst, const uint8_t *src, int width, int bpp, int deltaSrc, int offset, const SkPMColor ctable[])
Definition: SkSwizzler.cpp:31
uint32_t SkTypefaceID
Definition: SkTypeface.h:38
static constexpr SkFourByteTag SkSetFourByteTag(char a, char b, char c, char d)
Definition: SkTypes.h:167
#define REPORTER_ASSERT(r, cond,...)
Definition: Test.h:286
#define INFOF(REPORTER,...)
Definition: Test.h:298
#define REPORT_FAILURE(reporter, cond, message)
Definition: Test.h:90
SI F table(const skcms_Curve *curve, F v)
static void TestAlignment(T *testObj, skiatest::Reporter *reporter)
static const char * Define_Named_Dest_Key()
static const char * Link_Named_Dest_Key()
static const char * URL_Key()
void * get()
Definition: SkAutoMalloc.h:64
void writeByteArray(const void *data, size_t size) override
void writeUInt(uint32_t value) override
void writeInt(int32_t value) override
sk_sp< SkImage > asImage() const
Definition: SkBitmap.cpp:645
SkColor getColor(int x, int y) const
Definition: SkBitmap.h:874
int width() const
Definition: SkBitmap.h:149
bool setInfo(const SkImageInfo &imageInfo, size_t rowBytes=0)
Definition: SkBitmap.cpp:114
int height() const
Definition: SkBitmap.h:158
void drawRect(const SkRect &rect, const SkPaint &paint)
Definition: SkCanvas.cpp:1673
void clipRect(const SkRect &rect, SkClipOp op, bool doAntiAlias)
Definition: SkCanvas.cpp:1361
void restore()
Definition: SkCanvas.cpp:461
void translate(SkScalar dx, SkScalar dy)
Definition: SkCanvas.cpp:1278
void drawColor(SkColor color, SkBlendMode mode=SkBlendMode::kSrcOver)
Definition: SkCanvas.h:1182
void clear(SkColor color)
Definition: SkCanvas.h:1199
int save()
Definition: SkCanvas.cpp:447
void scale(SkScalar sx, SkScalar sy)
Definition: SkCanvas.cpp:1289
void drawString(const char str[], SkScalar x, SkScalar y, const SkFont &font, const SkPaint &paint)
Definition: SkCanvas.h:1803
void drawPicture(const SkPicture *picture)
Definition: SkCanvas.h:1961
void drawImage(const SkImage *image, SkScalar left, SkScalar top)
Definition: SkCanvas.h:1528
void drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, const SkPaint &paint)
Definition: SkCanvas.cpp:2707
static sk_sp< SkColorFilter > Table(const uint8_t table[256])
static sk_sp< SkPathEffect > Make(const SkScalar intervals[], int count, SkScalar phase)
Definition: SkData.h:25
static sk_sp< SkData > MakeWithCString(const char cstr[])
Definition: SkData.cpp:195
static sk_sp< SkData > MakeEmpty()
Definition: SkData.cpp:94
std::unique_ptr< SkStreamAsset > detachAsStream()
Definition: SkStream.cpp:876
sk_sp< SkTypeface > makeFromStream(std::unique_ptr< SkStreamAsset >, int ttcIndex=0) const
Definition: SkFontMgr.cpp:127
Definition: SkFont.h:35
SkScalar getMetrics(SkFontMetrics *metrics) const
Definition: SkFont.cpp:316
static sk_sp< SkImageFilter > Image(sk_sp< SkImage > image, const SkRect &srcRect, const SkRect &dstRect, const SkSamplingOptions &sampling)
static sk_sp< SkImageFilter > Blend(SkBlendMode mode, sk_sp< SkImageFilter > background, sk_sp< SkImageFilter > foreground=nullptr, const CropRect &cropRect={})
static const SkMatrix & I()
Definition: SkMatrix.cpp:1544
void setColor(SkColor color)
Definition: SkPaint.cpp:119
Definition: SkPath.h:59
SkCanvas * beginRecording(const SkRect &bounds, sk_sp< SkBBoxHierarchy > bbh)
sk_sp< SkPicture > finishRecordingAsPicture()
sk_sp< SkData > serialize(const SkSerialProcs *procs=nullptr) const
Definition: SkPicture.cpp:249
static sk_sp< SkPicture > MakeFromData(const SkData *data, const SkDeserialProcs *procs=nullptr)
Definition: SkPicture.cpp:160
static sk_sp< SkPicture > MakeFromStream(SkStream *stream, const SkDeserialProcs *procs=nullptr)
Definition: SkPicture.cpp:147
void setRectRadii(const SkRect &rect, const SkVector radii[4])
Definition: SkRRect.cpp:189
bool readColor4fArray(SkColor4f *colors, size_t size)
const void * skipByteArray(size_t *size)
void readMatrix(SkMatrix *matrix)
SkFlattenable * readFlattenable(SkFlattenable::Type)
bool readByteArray(void *value, size_t size)
bool readIntArray(int32_t *values, size_t size)
bool isValid() const
Definition: SkReadBuffer.h:208
const void * skip(size_t size)
sk_sp< SkData > readByteArrayAsData()
bool readPointArray(SkPoint *points, size_t size)
int32_t readInt()
void readString(SkString *string)
bool readColorArray(SkColor *colors, size_t size)
size_t offset() const
Definition: SkReadBuffer.h:78
bool readScalarArray(SkScalar *values, size_t size)
void readPoint3(SkPoint3 *point)
void readRegion(SkRegion *region)
void readPath(SkPath *path)
const char * c_str() const
Definition: SkString.h:133
int countGlyphs() const
Definition: SkTypeface.cpp:432
SkTypefaceID uniqueID() const
Definition: SkTypeface.h:101
void getFamilyName(SkString *name) const
Definition: SkTypeface.cpp:459
SkFontStyle fontStyle() const
Definition: SkTypeface.h:55
void serialize(SkWStream *, SerializeBehavior=SerializeBehavior::kIncludeDataIfLocal) const
Definition: SkTypeface.cpp:202
int getVariationDesignPosition(SkFontArguments::VariationPosition::Coordinate coordinates[], int coordinateCount) const
Definition: SkTypeface.cpp:289
static sk_sp< SkTypeface > MakeDeserialize(SkStream *, sk_sp< SkFontMgr > lastResortMgr)
Definition: SkTypeface.cpp:241
std::unique_ptr< SkStreamAsset > openStream(int *ttcIndex) const
Definition: SkTypeface.cpp:332
virtual void writeScalarArray(const SkScalar *value, uint32_t count)=0
virtual void writeRegion(const SkRegion &region)=0
virtual void writePointArray(const SkPoint *point, uint32_t count)=0
virtual void writeColor4fArray(const SkColor4f *color, uint32_t count)=0
virtual void writeFlattenable(const SkFlattenable *flattenable)=0
virtual void writeMatrix(const SkMatrix &matrix)=0
virtual void writeByteArray(const void *data, size_t size)=0
virtual void writePoint3(const SkPoint3 &point)=0
virtual void writePath(const SkPath &path)=0
virtual void writeColorArray(const SkColor *color, uint32_t count)=0
virtual void writeIntArray(const int32_t *value, uint32_t count)=0
virtual void writeString(std::string_view value)=0
TestAnnotationCanvas(skiatest::Reporter *reporter, const AnnotationRec rec[], int count)
void onDrawAnnotation(const SkRect &rect, const char key[], SkData *value) override
T * get() const
Definition: SkRefCnt.h:303
void realloc(size_t count)
Definition: SkTemplates.h:291
const Paint & paint
Definition: color_source.cc:38
const EmbeddedViewParams * params
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
Definition: main.cc:19
float SkScalar
Definition: extension.cpp:12
struct MyStruct s
uint8_t value
size_t length
std::u16string text
constexpr int kSize
double y
double x
SK_API bool Encode(SkWStream *dst, const SkPixmap &src, const Options &options)
unsigned useCenter Optional< SkMatrix > matrix
Definition: SkRecords.h:258
ClipOpAndAA opAA SkRegion region
Definition: SkRecords.h:238
sk_sp< const SkPicture > picture
Definition: SkRecords.h:299
SkRRect rrect
Definition: SkRecords.h:232
sk_sp< SkBlender > blender SkRect rect
Definition: SkRecords.h:350
SK_API sk_sp< SkSurface > Raster(const SkImageInfo &imageInfo, size_t rowBytes, const SkSurfaceProps *surfaceProps)
SkFont DefaultFont()
sk_sp< SkTypeface > SampleUserTypeface()
bool equal_pixels(const SkPixmap &a, const SkPixmap &b)
Definition: ToolUtils.cpp:456
sk_sp< SkTypeface > CreateTypefaceFromResource(const char *resource, int ttcIndex)
sk_sp< SkTypeface > DefaultTypeface()
sk_sp< SkFontMgr > TestFontMgr()
Definition: bitmap.py:1
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition: switches.h:57
DEF_SWITCHES_START aot vmservice shared library name
Definition: switches.h:32
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace buffer
Definition: switches.h:126
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.
const myers::Point & get(const myers::Segment &)
Definition: run.py:1
#define T
Definition: precompiler.cc:65
const SkRect fRect
sk_sp< SkData > fValue
static void InvalidateData(unsigned char *data)
static void InvalidateData(unsigned char *data)
static void Write(SkWriteBuffer &writer, SkColor4f *data, uint32_t arraySize)
static bool Read(SkReadBuffer &reader, SkColor4f *data, uint32_t arraySize)
static void Write(SkWriteBuffer &writer, SkColor *data, uint32_t arraySize)
static bool Read(SkReadBuffer &reader, SkColor *data, uint32_t arraySize)
static void Read(SkReadBuffer &reader, SkMatrix *matrix)
static void Write(SkWriteBuffer &writer, const SkMatrix *matrix)
static void Write(SkWriteBuffer &writer, const SkPath *path)
static void Read(SkReadBuffer &reader, SkPath *path)
static void Write(SkWriteBuffer &writer, const SkPoint3 *data)
static void Read(SkReadBuffer &reader, SkPoint3 *data)
static bool Read(SkReadBuffer &reader, SkPoint *data, uint32_t arraySize)
static void Write(SkWriteBuffer &writer, SkPoint *data, uint32_t arraySize)
static void Write(SkWriteBuffer &writer, const SkRegion *region)
static void Read(SkReadBuffer &reader, SkRegion *region)
static void Write(SkWriteBuffer &writer, SkScalar *data, uint32_t arraySize)
static bool Read(SkReadBuffer &reader, SkScalar *data, uint32_t arraySize)
static void Read(SkReadBuffer &reader, SkString *string)
static void Write(SkWriteBuffer &writer, const SkString *string)
static bool Read(SkReadBuffer &reader, int32_t *data, uint32_t arraySize)
static void Write(SkWriteBuffer &writer, int32_t *data, uint32_t arraySize)
static void Write(SkWriteBuffer &writer, unsigned char *data, uint32_t arraySize)
static bool Read(SkReadBuffer &reader, unsigned char *data, uint32_t arraySize)
static void Read(SkReadBuffer &reader, T **flattenable)
static void Write(SkWriteBuffer &writer, const T *flattenable)
SkDeserialTypefaceProc fTypefaceProc
SkScalar fTop
greatest extent above origin of any glyph bounding box, typically negative; deprecated with variable ...
Definition: SkFontMetrics.h:53
SkScalar fLeading
distance to add between lines, typically positive or zero
Definition: SkFontMetrics.h:57
SkScalar fAvgCharWidth
average character width, zero if unknown
Definition: SkFontMetrics.h:58
SkScalar fStrikeoutPosition
distance from baseline to bottom of stroke, typically negative
Definition: SkFontMetrics.h:67
SkScalar fStrikeoutThickness
strikeout thickness
Definition: SkFontMetrics.h:66
SkScalar fMaxCharWidth
maximum character width, zero if unknown
Definition: SkFontMetrics.h:59
SkScalar fBottom
greatest extent below origin of any glyph bounding box, typically positive; deprecated with variable ...
Definition: SkFontMetrics.h:56
uint32_t fFlags
FontMetricsFlags indicating which metrics are valid.
Definition: SkFontMetrics.h:52
SkScalar fAscent
distance to reserve above baseline, typically negative
Definition: SkFontMetrics.h:54
SkScalar fXHeight
height of lower-case 'x', zero if unknown, typically negative
Definition: SkFontMetrics.h:62
SkScalar fUnderlineThickness
underline thickness
Definition: SkFontMetrics.h:64
@ kStrikeoutPositionIsValid_Flag
set if fStrikeoutPosition is valid
Definition: SkFontMetrics.h:48
@ kStrikeoutThicknessIsValid_Flag
set if fStrikeoutThickness is valid
Definition: SkFontMetrics.h:47
@ kUnderlinePositionIsValid_Flag
set if fUnderlinePosition is valid
Definition: SkFontMetrics.h:46
@ kUnderlineThicknessIsValid_Flag
set if fUnderlineThickness is valid
Definition: SkFontMetrics.h:45
@ kBoundsInvalid_Flag
set if fTop, fBottom, fXMin, fXMax invalid
Definition: SkFontMetrics.h:49
SkScalar fDescent
distance to reserve below baseline, typically positive
Definition: SkFontMetrics.h:55
SkScalar fCapHeight
height of an upper-case letter, zero if unknown, typically negative
Definition: SkFontMetrics.h:63
SkScalar fXMin
greatest extent to left of origin of any glyph bounding box, typically negative; deprecated with vari...
Definition: SkFontMetrics.h:60
SkScalar fUnderlinePosition
distance from baseline to top of stroke, typically positive
Definition: SkFontMetrics.h:65
SkScalar fXMax
greatest extent to right of origin of any glyph bounding box, typically positive; deprecated with var...
Definition: SkFontMetrics.h:61
Definition: SkRect.h:32
constexpr int32_t height() const
Definition: SkRect.h:165
constexpr int32_t width() const
Definition: SkRect.h:158
static constexpr SkIRect MakeWH(int32_t w, int32_t h)
Definition: SkRect.h:56
static SkImageInfo MakeN32Premul(int width, int height)
constexpr float x() const
Definition: SkRect.h:720
constexpr float y() const
Definition: SkRect.h:727
static constexpr SkRect MakeXYWH(float x, float y, float w, float h)
Definition: SkRect.h:659
static constexpr SkRect MakeWH(float w, float h)
Definition: SkRect.h:609
SkSerialImageProc fImageProc
Definition: SkSerialProcs.h:90
SkSerialTypefaceProc fTypefaceProc
Definition: SkSerialProcs.h:93
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:63
const uintptr_t id