202c506873
Currently, the SkRemoteGlyphCache can't convert an SkTextBlob to a Slug because it holds minimal glyph information. For GlyphVector the remote cache has enough information to serialize the GlyphVector, but not enough to draw it. In this first step allow GlyphVector to work with either an SkStrike or a RemoteStrike. Change-Id: I8c261d84b40a6a69ac0077aaaeed9d318ae72c23 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/551890 Reviewed-by: John Stiles <johnstiles@google.com> Commit-Queue: Herb Derby <herb@google.com>
121 lines
4.0 KiB
C++
121 lines
4.0 KiB
C++
/*
|
|
* Copyright 2022 Google LLC
|
|
*
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
* found in the LICENSE file.
|
|
*/
|
|
|
|
#include "src/core/SkGlyph.h"
|
|
#include "src/gpu/ganesh/GrResourceProvider.h"
|
|
|
|
#include "src/core/SkGlyphBuffer.h"
|
|
#include "src/core/SkReadBuffer.h"
|
|
#include "src/core/SkStrikeCache.h"
|
|
#include "src/core/SkStrikeSpec.h"
|
|
#include "src/core/SkWriteBuffer.h"
|
|
#include "src/text/gpu/GlyphVector.h"
|
|
#include "src/text/gpu/SubRunAllocator.h"
|
|
#include "tests/Test.h"
|
|
|
|
using GlyphVector = sktext::gpu::GlyphVector;
|
|
using SubRunAllocator = sktext::gpu::SubRunAllocator;
|
|
|
|
namespace sktext::gpu {
|
|
|
|
class TestingPeer {
|
|
public:
|
|
static const SkDescriptor& GetDescriptor(const GlyphVector& v) {
|
|
return std::get<sk_sp<SkStrike>>(v.fStrike)->getDescriptor();
|
|
}
|
|
static SkSpan<GlyphVector::Variant> GetGlyphs(const GlyphVector& v) {
|
|
return v.fGlyphs;
|
|
}
|
|
};
|
|
|
|
DEF_TEST(GlyphVector_Serialization, r) {
|
|
SkFont font;
|
|
auto [strikeSpec, _] = SkStrikeSpec::MakeCanonicalized(font);
|
|
|
|
SubRunAllocator alloc;
|
|
|
|
SkBulkGlyphMetricsAndImages glyphFinder{strikeSpec};
|
|
const int N = 10;
|
|
SkGlyphVariant* glyphs = alloc.makePODArray<SkGlyphVariant>(N);
|
|
for (int i = 0; i < N; i++) {
|
|
glyphs[i] = glyphFinder.glyph(SkPackedGlyphID(SkTo<SkGlyphID>(i + 1)));
|
|
}
|
|
|
|
GlyphVector src = GlyphVector::Make(
|
|
strikeSpec.findOrCreateStrike(), SkSpan(glyphs, N), &alloc);
|
|
|
|
SkBinaryWriteBuffer wBuffer;
|
|
src.flatten(wBuffer);
|
|
|
|
auto data = wBuffer.snapshotAsData();
|
|
SkReadBuffer rBuffer{data->data(), data->size()};
|
|
auto dst = GlyphVector::MakeFromBuffer(rBuffer, nullptr, &alloc);
|
|
REPORTER_ASSERT(r, dst.has_value());
|
|
REPORTER_ASSERT(r, TestingPeer::GetDescriptor(src) == TestingPeer::GetDescriptor(*dst));
|
|
|
|
auto srcGlyphs = TestingPeer::GetGlyphs(src);
|
|
auto dstGlyphs = TestingPeer::GetGlyphs(*dst);
|
|
for (auto [srcGlyphID, dstGlyphID] : SkMakeZip(srcGlyphs, dstGlyphs)) {
|
|
REPORTER_ASSERT(r, srcGlyphID.packedGlyphID == dstGlyphID.packedGlyphID);
|
|
}
|
|
}
|
|
|
|
DEF_TEST(GlyphVector_BadLengths, r) {
|
|
{
|
|
SkFont font;
|
|
auto [strikeSpec, _] = SkStrikeSpec::MakeCanonicalized(font);
|
|
|
|
// Make broken stream by hand - zero length
|
|
SkBinaryWriteBuffer wBuffer;
|
|
strikeSpec.descriptor().flatten(wBuffer);
|
|
wBuffer.write32(0); // length
|
|
auto data = wBuffer.snapshotAsData();
|
|
SkReadBuffer rBuffer{data->data(), data->size()};
|
|
SubRunAllocator alloc;
|
|
auto dst = GlyphVector::MakeFromBuffer(rBuffer, nullptr, &alloc);
|
|
REPORTER_ASSERT(r, !dst.has_value());
|
|
}
|
|
|
|
{
|
|
SkFont font;
|
|
auto [strikeSpec, _] = SkStrikeSpec::MakeCanonicalized(font);
|
|
|
|
// Make broken stream by hand - stream is too short
|
|
SkBinaryWriteBuffer wBuffer;
|
|
strikeSpec.descriptor().flatten(wBuffer);
|
|
wBuffer.write32(5); // length
|
|
wBuffer.writeUInt(12); // random data
|
|
wBuffer.writeUInt(12); // random data
|
|
wBuffer.writeUInt(12); // random data
|
|
auto data = wBuffer.snapshotAsData();
|
|
SkReadBuffer rBuffer{data->data(), data->size()};
|
|
SubRunAllocator alloc;
|
|
auto dst = GlyphVector::MakeFromBuffer(rBuffer, nullptr, &alloc);
|
|
REPORTER_ASSERT(r, !dst.has_value());
|
|
}
|
|
|
|
{
|
|
SkFont font;
|
|
auto [strikeSpec, _] = SkStrikeSpec::MakeCanonicalized(font);
|
|
|
|
// Make broken stream by hand - length out of range of safe calculations
|
|
SkBinaryWriteBuffer wBuffer;
|
|
strikeSpec.descriptor().flatten(wBuffer);
|
|
wBuffer.write32(INT_MAX - 10); // length
|
|
wBuffer.writeUInt(12); // random data
|
|
wBuffer.writeUInt(12); // random data
|
|
wBuffer.writeUInt(12); // random data
|
|
auto data = wBuffer.snapshotAsData();
|
|
SkReadBuffer rBuffer{data->data(), data->size()};
|
|
SubRunAllocator alloc;
|
|
auto dst = GlyphVector::MakeFromBuffer(rBuffer, nullptr, &alloc);
|
|
REPORTER_ASSERT(r, !dst.has_value());
|
|
}
|
|
}
|
|
|
|
} // namespace sktext::gpu
|