• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 * Copyright 2022 Google LLC
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 "src/core/SkGlyph.h"
9 #include "src/gpu/GrResourceProvider.h"
10 #include "src/gpu/text/GrGlyphVector.h"
11 
12 #include "src/core/SkGlyphBuffer.h"
13 #include "src/core/SkReadBuffer.h"
14 #include "src/core/SkStrikeCache.h"
15 #include "src/core/SkStrikeSpec.h"
16 #include "src/core/SkWriteBuffer.h"
17 #include "src/gpu/GrSubRunAllocator.h"
18 #include "tests/Test.h"
19 
20 class TestingPeer {
21 public:
GetDescriptor(const GrGlyphVector & v)22     static const SkDescriptor& GetDescriptor(const GrGlyphVector& v) {
23         return v.fStrike->getDescriptor();
24     }
GetGlyphs(const GrGlyphVector & v)25     static SkSpan<GrGlyphVector::Variant> GetGlyphs(const GrGlyphVector& v) {
26         return v.fGlyphs;
27     }
28 };
29 
DEF_TEST(GrGlyphVector_Serialization,r)30 DEF_TEST(GrGlyphVector_Serialization, r) {
31     SkFont font;
32     auto [strikeSpec, _] = SkStrikeSpec::MakeCanonicalized(font);
33 
34     GrSubRunAllocator alloc;
35 
36     SkBulkGlyphMetricsAndImages glyphFinder{strikeSpec};
37     const int N = 10;
38     SkGlyphVariant* glyphs = alloc.makePODArray<SkGlyphVariant>(N);
39     for (int i = 0; i < N; i++) {
40         glyphs[i] = glyphFinder.glyph(SkPackedGlyphID(SkTo<SkGlyphID>(i + 1)));
41     }
42 
43     GrGlyphVector src = GrGlyphVector::Make(
44             strikeSpec.findOrCreateStrike(), SkMakeSpan(glyphs, N), &alloc);
45 
46     SkBinaryWriteBuffer wBuffer;
47     src.flatten(wBuffer);
48 
49     auto data = wBuffer.snapshotAsData();
50     SkReadBuffer rBuffer{data->data(), data->size()};
51     auto dst = GrGlyphVector::MakeFromBuffer(rBuffer, &alloc);
52     REPORTER_ASSERT(r, dst.has_value());
53     REPORTER_ASSERT(r, TestingPeer::GetDescriptor(src) == TestingPeer::GetDescriptor(*dst));
54 
55     auto srcGlyphs = TestingPeer::GetGlyphs(src);
56     auto dstGlyphs = TestingPeer::GetGlyphs(*dst);
57     for (auto [srcGlyphID, dstGlyphID] : SkMakeZip(srcGlyphs, dstGlyphs)) {
58         REPORTER_ASSERT(r, srcGlyphID.packedGlyphID == dstGlyphID.packedGlyphID);
59     }
60 }
61 
DEF_TEST(GrGlyphVector_BadLengths,r)62 DEF_TEST(GrGlyphVector_BadLengths, r) {
63     {
64         SkFont font;
65         auto [strikeSpec, _] = SkStrikeSpec::MakeCanonicalized(font);
66 
67         // Make broken stream by hand - zero length
68         SkBinaryWriteBuffer wBuffer;
69         strikeSpec.descriptor().flatten(wBuffer);
70         wBuffer.write32(0);  // length
71         auto data = wBuffer.snapshotAsData();
72         SkReadBuffer rBuffer{data->data(), data->size()};
73         GrSubRunAllocator alloc;
74         auto dst = GrGlyphVector::MakeFromBuffer(rBuffer, &alloc);
75         REPORTER_ASSERT(r, !dst.has_value());
76     }
77 
78     {
79         SkFont font;
80         auto [strikeSpec, _] = SkStrikeSpec::MakeCanonicalized(font);
81 
82         // Make broken stream by hand - stream is too short
83         SkBinaryWriteBuffer wBuffer;
84         strikeSpec.descriptor().flatten(wBuffer);
85         wBuffer.write32(5);  // length
86         wBuffer.writeUInt(12);  // random data
87         wBuffer.writeUInt(12);  // random data
88         wBuffer.writeUInt(12);  // random data
89         auto data = wBuffer.snapshotAsData();
90         SkReadBuffer rBuffer{data->data(), data->size()};
91         GrSubRunAllocator alloc;
92         auto dst = GrGlyphVector::MakeFromBuffer(rBuffer, &alloc);
93         REPORTER_ASSERT(r, !dst.has_value());
94     }
95 
96     {
97         SkFont font;
98         auto [strikeSpec, _] = SkStrikeSpec::MakeCanonicalized(font);
99 
100         // Make broken stream by hand - length out of range of safe calculations
101         SkBinaryWriteBuffer wBuffer;
102         strikeSpec.descriptor().flatten(wBuffer);
103         wBuffer.write32(INT_MAX - 10);  // length
104         wBuffer.writeUInt(12);  // random data
105         wBuffer.writeUInt(12);  // random data
106         wBuffer.writeUInt(12);  // random data
107         auto data = wBuffer.snapshotAsData();
108         SkReadBuffer rBuffer{data->data(), data->size()};
109         GrSubRunAllocator alloc;
110         auto dst = GrGlyphVector::MakeFromBuffer(rBuffer, &alloc);
111         REPORTER_ASSERT(r, !dst.has_value());
112     }
113 }
114