introduce SkGlyphRect specialized for union & intersect
SkGlyphRect is a rectangle encoding specialized for union and intersect. It will be used for calculating the bounding boxes of glyph runs, and clipping glyphs for GPU. Change-Id: Icab826b51dc2254ee4006ada84f7fc09e112a933 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/319697 Reviewed-by: Ben Wagner <bungeman@google.com> Commit-Queue: Herb Derby <herb@google.com>
This commit is contained in:
parent
bc0c29ead3
commit
f0b5644e6b
@ -255,6 +255,7 @@ tests_sources = [
|
||||
"$_tests/SkFixed15Test.cpp",
|
||||
"$_tests/SkGaussFilterTest.cpp",
|
||||
"$_tests/SkGlyphBufferTest.cpp",
|
||||
"$_tests/SkGlyphTest.cpp",
|
||||
"$_tests/SkImageTest.cpp",
|
||||
"$_tests/SkNxTest.cpp",
|
||||
"$_tests/SkPEGTest.cpp",
|
||||
|
@ -175,6 +175,56 @@ private:
|
||||
uint32_t fID;
|
||||
};
|
||||
|
||||
class SkGlyphRect;
|
||||
namespace skglyph {
|
||||
SkGlyphRect rect_union(SkGlyphRect, SkGlyphRect);
|
||||
SkGlyphRect rect_intersection(SkGlyphRect, SkGlyphRect);
|
||||
} // namespace skglyph
|
||||
|
||||
// SkGlyphRect encodes rectangles with coordinates on [-32767, 32767]. It is specialized for
|
||||
// rectangle union and intersection operations.
|
||||
class SkGlyphRect {
|
||||
public:
|
||||
SkGlyphRect(int16_t left, int16_t top, int16_t right, int16_t bottom)
|
||||
: fRect{left, top, (int16_t)-right, (int16_t)-bottom} {
|
||||
SkDEBUGCODE(const int32_t min = std::numeric_limits<int16_t>::min());
|
||||
SkASSERT(left != min && top != min && right != min && bottom != min);
|
||||
}
|
||||
bool empty() const {
|
||||
return fRect[0] >= -fRect[2] || fRect[1] >= -fRect[3];
|
||||
}
|
||||
SkRect rect() const {
|
||||
return SkRect::MakeLTRB(fRect[0], fRect[1], -fRect[2], -fRect[3]);
|
||||
}
|
||||
SkIRect iRect() const {
|
||||
return SkIRect::MakeLTRB(fRect[0], fRect[1], -fRect[2], -fRect[3]);
|
||||
}
|
||||
friend SkGlyphRect skglyph::rect_union(SkGlyphRect, SkGlyphRect);
|
||||
friend SkGlyphRect skglyph::rect_intersection(SkGlyphRect, SkGlyphRect);
|
||||
|
||||
private:
|
||||
using Storage = skvx::Vec<4, int16_t>;
|
||||
SkGlyphRect(Storage rect) : fRect{rect} { }
|
||||
Storage fRect;
|
||||
};
|
||||
|
||||
namespace skglyph {
|
||||
inline SkGlyphRect empty_rect() {
|
||||
constexpr int16_t max = std::numeric_limits<int16_t>::max();
|
||||
return {max, max, -max, -max};
|
||||
}
|
||||
inline SkGlyphRect full_rect() {
|
||||
constexpr int16_t max = std::numeric_limits<int16_t>::max();
|
||||
return {-max, -max, max, max};
|
||||
}
|
||||
inline SkGlyphRect rect_union(SkGlyphRect a, SkGlyphRect b) {
|
||||
return skvx::min(a.fRect, b.fRect);
|
||||
}
|
||||
inline SkGlyphRect rect_intersection(SkGlyphRect a, SkGlyphRect b) {
|
||||
return skvx::max(a.fRect, b.fRect);
|
||||
}
|
||||
} // namespace skglyph
|
||||
|
||||
struct SkGlyphPrototype;
|
||||
|
||||
class SkGlyph {
|
||||
|
36
tests/SkGlyphTest.cpp
Normal file
36
tests/SkGlyphTest.cpp
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2020 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/SkGlyph.h"
|
||||
#include "tests/Test.h"
|
||||
|
||||
DEF_TEST(SkGlyphRectBasic, reporter) {
|
||||
using namespace skglyph;
|
||||
SkGlyphRect r{1, 1, 10, 10};
|
||||
REPORTER_ASSERT(reporter, !r.empty());
|
||||
SkGlyphRect a = rect_union(r, empty_rect());
|
||||
REPORTER_ASSERT(reporter, a.iRect() == SkIRect::MakeLTRB(1, 1, 10, 10));
|
||||
|
||||
a = rect_intersection(r, full_rect());
|
||||
REPORTER_ASSERT(reporter, a.iRect() == SkIRect::MakeLTRB(1, 1, 10, 10));
|
||||
|
||||
SkGlyphRect acc = full_rect();
|
||||
for (int x = -10; x < 10; x++) {
|
||||
for(int y = -10; y < 10; y++) {
|
||||
acc = rect_intersection(acc, SkGlyphRect(x, y, x + 20, y + 20));
|
||||
}
|
||||
}
|
||||
REPORTER_ASSERT(reporter, acc.iRect() == SkIRect::MakeLTRB(9, 9, 10, 10));
|
||||
|
||||
acc = empty_rect();
|
||||
for (int x = -10; x < 10; x++) {
|
||||
for(int y = -10; y < 10; y++) {
|
||||
acc = rect_union(acc, SkGlyphRect(x, y, x + 20, y + 20));
|
||||
}
|
||||
}
|
||||
REPORTER_ASSERT(reporter, acc.iRect() == SkIRect::MakeLTRB(-10, -10, 29, 29));
|
||||
}
|
Loading…
Reference in New Issue
Block a user