d7689d434c
This is a reland of 77c53087c1
Original change's description:
> Introduce SkGlyphSourceBuffer
>
> SkGlyphSourceBuffer provides a system for taking rejected glyphs from
> one glyph drawing stage, and turns them into the source for the next stage.
> It is rarely used, so it tries to conserve memory.
>
> Change-Id: I5275ffa3e804fc494eb2f5803e0cf2d148a755f7
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/248260
> Reviewed-by: Ben Wagner <bungeman@google.com>
> Commit-Queue: Herb Derby <herb@google.com>
Change-Id: Ib90508a21993b12c71ee86cbdeb51c4d4c2ec913
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/249128
Reviewed-by: Herb Derby <herb@google.com>
Commit-Queue: Herb Derby <herb@google.com>
130 lines
5.2 KiB
C++
130 lines
5.2 KiB
C++
/*
|
|
* Copyright 2019 Google Inc.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
* found in the LICENSE file.
|
|
*/
|
|
|
|
#include "src/core/SkEnumerate.h"
|
|
#include "src/core/SkGlyphBuffer.h"
|
|
#include "src/core/SkGlyphRunPainter.h"
|
|
#include "src/core/SkScalerContext.h"
|
|
#include "tests/Test.h"
|
|
|
|
|
|
DEF_TEST(SkSourceGlyphBufferBasic, reporter) {
|
|
SkSourceGlyphBuffer rejects;
|
|
// Positions are picked to avoid precision problems.
|
|
const SkPoint positions[] = {{10.25,10.25}, {20.5,10.25}, {30.75,10.25}, {40,10.25}};
|
|
const SkGlyphID glyphIDs[] = {1, 2, 3, 4};
|
|
auto source = SkMakeZip(glyphIDs, positions);
|
|
|
|
rejects.setSource(source);
|
|
for (auto t : SkMakeEnumerate(rejects.source())) {
|
|
size_t i; SkGlyphID glyphID; SkPoint pos;
|
|
std::forward_as_tuple(i, std::tie(glyphID, pos)) = t;
|
|
REPORTER_ASSERT(reporter, glyphID == std::get<0>(source[i]));
|
|
REPORTER_ASSERT(reporter, pos == std::get<1>(source[i]));
|
|
}
|
|
// Reject a couple of glyphs.
|
|
rejects.reject(1);
|
|
rejects.reject(2, 100);
|
|
rejects.flipRejectsToSource();
|
|
REPORTER_ASSERT(reporter, rejects.rejectedMaxDimension() == 100);
|
|
for (auto t : SkMakeEnumerate(rejects.source())) {
|
|
size_t i; SkGlyphID glyphID; SkPoint pos;
|
|
std::forward_as_tuple(i, std::tie(glyphID, pos)) = t;
|
|
// This will index 1 and 2 from the original source.
|
|
size_t j = i + 1;
|
|
REPORTER_ASSERT(reporter, glyphID == std::get<0>(source[j]));
|
|
REPORTER_ASSERT(reporter, pos == std::get<1>(source[j]));
|
|
}
|
|
|
|
// Reject an additional glyph
|
|
rejects.reject(0, 10);
|
|
rejects.flipRejectsToSource();
|
|
REPORTER_ASSERT(reporter, rejects.rejectedMaxDimension() == 10);
|
|
for (auto t : SkMakeEnumerate(rejects.source())) {
|
|
size_t i; SkGlyphID glyphID; SkPoint pos;
|
|
std::forward_as_tuple(i, std::tie(glyphID, pos)) = t;
|
|
// This will index 1 from the original source.
|
|
size_t j = i + 1;
|
|
REPORTER_ASSERT(reporter, glyphID == std::get<0>(source[j]));
|
|
REPORTER_ASSERT(reporter, pos == std::get<1>(source[j]));
|
|
}
|
|
|
|
// Start all over
|
|
rejects.setSource(source);
|
|
for (auto t : SkMakeEnumerate(rejects.source())) {
|
|
size_t i; SkGlyphID glyphID; SkPoint pos;
|
|
std::forward_as_tuple(i, std::tie(glyphID, pos)) = t;
|
|
REPORTER_ASSERT(reporter, glyphID == std::get<0>(source[i]));
|
|
REPORTER_ASSERT(reporter, pos == std::get<1>(source[i]));
|
|
}
|
|
|
|
// Check that everything is working after calling setSource.
|
|
rejects.reject(1);
|
|
rejects.reject(2, 100);
|
|
rejects.flipRejectsToSource();
|
|
REPORTER_ASSERT(reporter, rejects.rejectedMaxDimension() == 100);
|
|
for (auto t : SkMakeEnumerate(rejects.source())) {
|
|
size_t i; SkGlyphID glyphID; SkPoint pos;
|
|
std::forward_as_tuple(i, std::tie(glyphID, pos)) = t;
|
|
// This will index 1 and 2 from the original source.
|
|
size_t j = i + 1;
|
|
REPORTER_ASSERT(reporter, glyphID == std::get<0>(source[j]));
|
|
REPORTER_ASSERT(reporter, pos == std::get<1>(source[j]));
|
|
}
|
|
}
|
|
|
|
DEF_TEST(SkDrawableGlyphBufferBasic, reporter) {
|
|
// Positions are picked to avoid precision problems.
|
|
const SkPoint positions[] = {{10.25,10.25}, {20.5,10.25}, {30.75,10.25}, {40,10.25}};
|
|
const SkGlyphID glyphIDs[] = {1, 2, 3, 4};
|
|
SkGlyph glyphs[100];
|
|
auto source = SkMakeZip(glyphIDs, positions);
|
|
|
|
{
|
|
SkDrawableGlyphBuffer drawable;
|
|
drawable.ensureSize(100);
|
|
drawable.startSource(source, {100, 100});
|
|
for (auto t : SkMakeEnumerate(drawable.input())) {
|
|
size_t i; SkGlyphVariant packedID; SkPoint pos;
|
|
std::forward_as_tuple(i, std::tie(packedID, pos)) = t;
|
|
REPORTER_ASSERT(reporter, packedID.packedID().value() == glyphIDs[i]);
|
|
REPORTER_ASSERT(reporter, pos == positions[i] + SkPoint::Make(100, 100));
|
|
}
|
|
}
|
|
|
|
{
|
|
SkDrawableGlyphBuffer drawable;
|
|
drawable.ensureSize(100);
|
|
SkMatrix matrix = SkMatrix::MakeScale(0.5);
|
|
SkGlyphPositionRoundingSpec rounding{true, kX_SkAxisAlignment};
|
|
drawable.startDevice(source, {100, 100}, matrix, rounding);
|
|
for (auto t : SkMakeEnumerate(drawable.input())) {
|
|
size_t i; SkGlyphVariant packedID; SkPoint pos;
|
|
std::forward_as_tuple(i, std::tie(packedID, pos)) = t;
|
|
REPORTER_ASSERT(reporter, glyphIDs[i] == packedID.packedID().code());
|
|
REPORTER_ASSERT(reporter, pos.x() == positions[i].x() * 0.5 + 50 + 0.125);
|
|
REPORTER_ASSERT(reporter, pos.y() == positions[i].y() * 0.5 + 50 + 0.5);
|
|
}
|
|
}
|
|
|
|
{
|
|
SkDrawableGlyphBuffer drawable;
|
|
drawable.ensureSize(100);
|
|
drawable.startSource(source, {100, 100});
|
|
for (auto t : SkMakeEnumerate(drawable.input())) {
|
|
size_t i; SkGlyphVariant packedID; SkPoint pos;
|
|
std::forward_as_tuple(i, std::tie(packedID, pos)) = t;
|
|
drawable.push_back(&glyphs[i], i);
|
|
}
|
|
for (auto t : SkMakeEnumerate(drawable.drawable())) {
|
|
size_t i; SkGlyphVariant glyph; SkPoint pos;
|
|
std::forward_as_tuple(i, std::tie(glyph, pos)) = t;
|
|
REPORTER_ASSERT(reporter, glyph.glyph() == &glyphs[i]);
|
|
}
|
|
}
|
|
}
|