38#define SkRegion_gEmptyRunHeadPtr ((SkRegionPriv::RunHead*)-1)
39#define SkRegion_gRectRunHeadPtr nullptr
54 int count()
const {
return fCount; }
85 int intervals = runs[-1];
95 runs += intervals * 2 + 1;
99bool SkRegion::RunsAreARect(
const SkRegion::RunType runs[],
int count,
104 if (
count == kRectRegionRuns) {
115 bounds->setLTRB(runs[3], runs[0], runs[4], runs[1]);
142void SkRegion::freeRuns() {
145 if (--fRunHead->
fRefCnt == 0) {
151void SkRegion::allocateRuns(
int count,
int ySpanCount,
int intervalCount) {
155void SkRegion::allocateRuns(
int count) {
159void SkRegion::allocateRuns(
const RunHead&
head) {
161 head.getYSpanCount(),
162 head.getIntervalCount());
173 swap(fRunHead, other.fRunHead);
179 }
else if (this->
isRect()) {
209 fRunHead =
src.fRunHead;
220 return this->
op(tmp, rgn,
op);
226 return this->
op(rgn, tmp,
op);
231#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
233char* SkRegion::toString() {
236 while (!iter.done()) {
241 const int max = (
count*((11*4)+5))+11+1;
248 while (!iter.done()) {
249 const SkIRect& r = iter.rect();
261int SkRegion::count_runtype_values(
int* itop,
int* ibot)
const {
279bool SkRegion::setRuns(RunType runs[],
int count) {
291 if (count > kRectRegionRuns) {
292 RunType* stop = runs +
count;
333 this->allocateRuns(
count);
354 RunType runs[kRectRegionRuns]) {
404 return runs + 2 + runs[1] * 2 + 1;
467const SkRegion::RunType* SkRegion::getRuns(RunType tmpStorage[],
468 int* intervals)
const {
470 const RunType* runs = tmpStorage;
475 }
else if (this->
isRect()) {
476 BuildRectRuns(
fBounds, tmpStorage);
540 bool weAreARect = this->
isRect();
541 bool theyAreARect = rgn.
isRect();
543 if (weAreARect && theyAreARect) {
583 ah->
fRunCount *
sizeof(SkRegion::RunType));
599 if (
nullptr ==
dst) {
614 dst->fRunHead =
dst->fRunHead->ensureWritable();
617 tmp.allocateRuns(*fRunHead);
623 dst->fBounds.offset(
dx, dy);
626 RunType* druns =
dst->fRunHead->writable_runs();
628 *druns++ = (SkRegion::RunType)(*sruns++ + dy);
630 int bottom = *sruns++;
634 *druns++ = (SkRegion::RunType)(bottom + dy);
641 *druns++ = (SkRegion::RunType)(
x +
dx);
642 *druns++ = (SkRegion::RunType)(*sruns++ +
dx);
649 SkASSERT(druns -
dst->fRunHead->readonly_runs() ==
dst->fRunHead->fRunCount);
672#pragma warning ( push )
673#pragma warning ( disable : 4701 )
682 #define assert_valid_pair(left, rite)
714 bool a_flush =
false;
715 bool b_flush =
false;
722 if (a_left < b_left) {
725 if (a_rite <= b_left) {
729 rite = a_left = b_left;
731 }
else if (b_left < a_left) {
734 if (b_rite <= a_left) {
738 rite = b_left = a_left;
743 if (a_rite <= b_rite) {
744 rite = b_left = a_rite;
747 if (b_rite <= a_rite) {
748 rite = a_left = b_rite;
792 bool firstInterval =
true;
794 rec.
init(a_runs, b_runs);
796 while (!rec.
done()) {
800 int rite = rec.
fRite;
805 if (firstInterval || *(
dst - 1) <
left) {
808 firstInterval =
false;
817 return dst - &(*array)[0];
821#pragma warning ( pop )
851 int start = fPrevDst + fPrevLen + 2;
860 if (fPrevLen ==
len &&
861 (1 ==
len || !memcmp(&(*fArray)[fPrevDst],
867 if (
len == 1 && fPrevLen == 0) {
879 (*fArray)[fStartDst] = fTop;
883 return (
int)(fPrevDst - fStartDst + fPrevLen + 1);
886 bool isEmpty()
const {
return 0 == fPrevLen; }
899#define QUICK_EXIT_TRUE_COUNT (-1)
919 int a_top = *a_runs++;
920 int a_bot = *a_runs++;
921 int b_top = *b_runs++;
922 int b_bot = *b_runs++;
943 bool a_flush =
false;
944 bool b_flush =
false;
949 if (a_bot <= b_top) {
955 }
else if (b_top < a_top) {
958 if (b_bot <= a_top) {
968 if (a_bot <= b_bot) {
972 if (b_bot <= a_bot) {
979 oper.
addSpan(top, gSentinel, gSentinel);
983 if (quickExit && !oper.
isEmpty()) {
1008 return oper.
flush();
1022static int count_to_intervals(
int count) {
1024 return (
count - 4) >> 1;
1061 bool a_empty = rgna->
isEmpty();
1062 bool b_empty = rgnb->
isEmpty();
1063 bool a_rect = rgna->
isRect();
1064 bool b_rect = rgnb->
isRect();
1074 if (b_rect && rgnb->fBounds.containsNoEmptyCheck(rgna->fBounds)) {
1080 if ((a_empty | b_empty)
1081 || !
bounds.intersect(rgna->fBounds, rgnb->fBounds)) {
1084 if (a_rect & b_rect) {
1087 if (a_rect && rgna->fBounds.
contains(rgnb->fBounds)) {
1090 if (b_rect && rgnb->fBounds.
contains(rgna->fBounds)) {
1102 if (a_rect && rgna->fBounds.
contains(rgnb->fBounds)) {
1105 if (b_rect && rgnb->fBounds.
contains(rgna->fBounds)) {
1123 RunType tmpA[kRectRegionRuns];
1124 RunType tmpB[kRectRegionRuns];
1126 int a_intervals, b_intervals;
1127 const RunType* a_runs = rgna->getRuns(tmpA, &a_intervals);
1128 const RunType* b_runs = rgnb->getRuns(tmpB, &b_intervals);
1144 return SkRegion::Oper(rgna, rgnb,
op,
this);
1150 if (
nullptr == storage) {
1151 size_t size =
sizeof(int32_t);
1155 size += 2 *
sizeof(int32_t);
1184 if (ySpanCount < 1 || intervalCount < 2) {
1189 sum = safeMath.
addInt(sum, ySpanCount);
1190 sum = safeMath.
addInt(sum, ySpanCount);
1191 sum = safeMath.
addInt(sum, ySpanCount);
1192 sum = safeMath.
addInt(sum, intervalCount);
1193 sum = safeMath.
addInt(sum, intervalCount);
1194 return safeMath && sum == runCount;
1204 int32_t intervalCount) {
1216 const int32_t*
const end = runs + runCount;
1219 rect.fTop = *runs++;
1223 if (
rect.fTop != givenBounds.
fTop) {
1228 if (ySpanCount < 0) {
1231 rect.fBottom = *runs++;
1242 int32_t xIntervals = *runs++;
1244 if (xIntervals < 0 || xIntervals > intervalCount || runs + 1 + 2 * xIntervals >
end) {
1247 intervalCount -= xIntervals;
1248 bool firstInterval =
true;
1249 int32_t lastRight = 0;
1250 while (xIntervals-- > 0) {
1251 rect.fLeft = *runs++;
1252 rect.fRight = *runs++;
1256 (!firstInterval &&
rect.fLeft <= lastRight)) {
1259 lastRight =
rect.fRight;
1260 firstInterval =
false;
1270 if (ySpanCount != 0 || intervalCount != 0 || givenBounds !=
bounds) {
1292 if (!
buffer.read(&tmp.fBounds,
sizeof(tmp.fBounds)) || tmp.fBounds.
isEmpty()) {
1298 int32_t ySpanCount, intervalCount;
1299 if (!
buffer.readS32(&ySpanCount) ||
1300 !
buffer.readS32(&intervalCount) ||
1305 tmp.fBounds, ySpanCount, intervalCount)) {
1308 tmp.allocateRuns(
count, ySpanCount, intervalCount);
1321bool SkRegion::isValid()
const {
1331 return fRunHead && fRunHead->
fRefCnt > 0 &&
1376 fRect = rgn.fBounds;
1392 if (fRuns ==
nullptr) {
1397 const RunType* runs = fRuns;
1406 int intervals = runs[1];
1407 if (0 == intervals) {
1431 while (!fIter.
done()) {
1452 while (!
fIter.done()) {
1453 if (r.
fTop >= fClip.fBottom) {
1487 const SkRegion::RunType* runs = rgn.fRunHead->
findScanline(
y);
1491 if (runs[0] >=
right) {
1495 if (runs[1] <=
left) {
1515 if (fRuns ==
nullptr) {
1526 const SkRegion::RunType* runs = fRuns;
1528 if (runs[0] >= fRight) {
1549 for (
int i = 0;
i < pairCount; ++
i) {
1550 visitor({ pairs[0],
y, pairs[1],
y + 1 });
1567 int pairCount = *
p++;
1568 if (pairCount == 1) {
1569 visitor({
p[0], top,
p[1], bot });
1571 }
else if (pairCount > 1) {
1573 for (
int y = top;
y < bot; ++
y) {
SkAssertResult(font.textToGlyphs("Hello", 5, SkTextEncoding::kUTF8, glyphs, std::size(glyphs))==count)
std::unique_ptr< SkLatticeIter > fIter
#define SkDEBUGFAIL(message)
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
#define SK_INIT_TO_AVOID_WARNING
SK_API void sk_free(void *)
static void * sk_malloc_throw(size_t size)
static constexpr int32_t SK_MaxS32
static SkPath clip(const SkPath &path, const SkHalfPlane &plane)
static bool left(const SkPoint &p0, const SkPoint &p1)
static bool right(const SkPoint &p0, const SkPoint &p1)
void swap(sk_sp< T > &a, sk_sp< T > &b)
#define assert_sentinel(value, isSentinel)
static constexpr int SkRegion_kRunTypeSentinel
bool SkRegionValueIsSentinel(int32_t value)
static bool validate_run(const int32_t *runs, int runCount, const SkIRect &givenBounds, int32_t ySpanCount, int32_t intervalCount)
static int operate_on_span(const SkRegionPriv::RunType a_runs[], const SkRegionPriv::RunType b_runs[], RunArray *array, int dstOffset, int min, int max)
static bool scanline_intersects(const SkRegionPriv::RunType runs[], SkRegionPriv::RunType L, SkRegionPriv::RunType R)
static bool validate_run_count(int ySpanCount, int intervalCount, int runCount)
static bool setEmptyCheck(SkRegion *result)
static const SkRegionPriv::RunType * scanline_next(const SkRegionPriv::RunType runs[])
static void visit_pairs(int pairCount, int y, const int32_t pairs[], const std::function< void(const SkIRect &)> &visitor)
static int32_t pin_offset_s32(int32_t min, int32_t max, int32_t offset)
static int distance_to_sentinel(const SkRegionPriv::RunType *runs)
static int operate(const SkRegionPriv::RunType a_runs[], const SkRegionPriv::RunType b_runs[], RunArray *dst, SkRegion::Op op, bool quickExit)
static SkRegionPriv::RunType scanline_bottom(const SkRegionPriv::RunType runs[])
static bool scanline_contains(const SkRegionPriv::RunType runs[], SkRegionPriv::RunType L, SkRegionPriv::RunType R)
static const struct @335 gOpMinMax[]
#define SkRegion_gEmptyRunHeadPtr
#define QUICK_EXIT_TRUE_COUNT
static SkRegionPriv::RunType * skip_intervals(const SkRegionPriv::RunType runs[])
constexpr int kRunArrayStackCount
static bool setRegionCheck(SkRegion *result, const SkRegion &rgn)
#define assert_valid_pair(left, rite)
static bool isRunCountEmpty(int count)
#define SkRegion_gRectRunHeadPtr
static bool setRectCheck(SkRegion *result, const SkIRect &rect)
constexpr size_t SkToSizeT(S x)
constexpr int32_t SkToS32(S x)
constexpr int SkToInt(S x)
static void dump(const float m[20], SkYUVColorSpace cs, bool rgb2yuv)
void addSpan(int bottom, const SkRegionPriv::RunType a_runs[], const SkRegionPriv::RunType b_runs[])
RgnOper(int top, RunArray *array, SkRegion::Op op)
void resizeToAtLeast(int count)
SkRegionPriv::RunType & operator[](int i)
static void VisitSpans(const SkRegion &rgn, const std::function< void(const SkIRect &)> &)
SkRegion::RunType RunType
Cliperator(const SkRegion ®ion, const SkIRect &clip)
const SkIRect & rect() const
void reset(const SkRegion ®ion)
bool next(int *left, int *right)
Spanerator(const SkRegion ®ion, int y, int left, int right)
void translate(int dx, int dy)
size_t readFromMemory(const void *buffer, size_t length)
bool contains(int32_t x, int32_t y) const
bool operator==(const SkRegion &other) const
@ kReverseDifference_Op
operand minus target
@ kUnion_Op
target unioned with operand
@ kReplace_Op
replace target with operand
@ kIntersect_Op
target intersected with operand
@ kDifference_Op
target minus operand
@ kXOR_Op
target exclusive or with operand
bool setRects(const SkIRect rects[], int count)
int computeRegionComplexity() const
SkRegion & operator=(const SkRegion ®ion)
const SkIRect & getBounds() const
bool op(const SkIRect &rect, Op op)
bool setRect(const SkIRect &rect)
void swap(SkRegion &other)
bool setRegion(const SkRegion ®ion)
size_t writeToMemory(void *buffer) const
bool intersects(const SkIRect &rect) const
void realloc(size_t count)
Dart_NativeFunction function
static float max(float r, float g, float b)
static float min(float r, float g, float b)
Optional< SkRect > bounds
sk_sp< SkBlender > blender SkRect rect
skia_private::AutoTArray< sk_sp< SkImageFilter > > filters TypedMatrix matrix TypedMatrix matrix SkScalar dx
void Validate(const Table &table)
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
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
bool intersect(const SkIRect &r)
static bool Intersects(const SkIRect &a, const SkIRect &b)
int32_t fBottom
larger y-axis bounds
constexpr int32_t bottom() const
constexpr int32_t right() const
int32_t fTop
smaller y-axis bounds
int32_t fLeft
smaller x-axis bounds
int32_t fRight
larger x-axis bounds
SkScalar fBottom
larger y-axis bounds
constexpr SkRect makeOffset(float dx, float dy) const
bool intersect(const SkRect &r)
SkScalar fLeft
smaller x-axis bounds
SkScalar fRight
larger x-axis bounds
bool contains(SkScalar x, SkScalar y) const
void setLTRB(float left, float top, float right, float bottom)
SkScalar fTop
smaller y-axis bounds
SkRegion::RunType * writable_runs()
static RunHead * Alloc(int count)
const SkRegion::RunType * readonly_runs() const
void computeRunBounds(SkIRect *bounds)
RunHead * ensureWritable()
int getYSpanCount() const
int getIntervalCount() const
SkRegion::RunType * findScanline(int y) const
std::atomic< int32_t > fRefCnt
const SkRegionPriv::RunType * fB_runs
void init(const SkRegionPriv::RunType a_runs[], const SkRegionPriv::RunType b_runs[])
const SkRegionPriv::RunType * fA_runs