| OLD | NEW |
| 1 | 1 |
| 2 /* | 2 /* |
| 3 * Copyright 2006 The Android Open Source Project | 3 * Copyright 2006 The Android Open Source Project |
| 4 * | 4 * |
| 5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
| 6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
| 7 */ | 7 */ |
| 8 | 8 |
| 9 | 9 |
| 10 #include "SkAtomics.h" | 10 #include "SkAtomics.h" |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 187 char* SkRegion::toString() { | 187 char* SkRegion::toString() { |
| 188 Iterator iter(*this); | 188 Iterator iter(*this); |
| 189 int count = 0; | 189 int count = 0; |
| 190 while (!iter.done()) { | 190 while (!iter.done()) { |
| 191 count++; | 191 count++; |
| 192 iter.next(); | 192 iter.next(); |
| 193 } | 193 } |
| 194 // 4 ints, up to 10 digits each plus sign, 3 commas, '(', ')', SkRegion() an
d '\0' | 194 // 4 ints, up to 10 digits each plus sign, 3 commas, '(', ')', SkRegion() an
d '\0' |
| 195 const int max = (count*((11*4)+5))+11+1; | 195 const int max = (count*((11*4)+5))+11+1; |
| 196 char* result = (char*)sk_malloc_throw(max); | 196 char* result = (char*)sk_malloc_throw(max); |
| 197 if (result == NULL) { | 197 if (result == nullptr) { |
| 198 return NULL; | 198 return nullptr; |
| 199 } | 199 } |
| 200 count = sprintf(result, "SkRegion("); | 200 count = sprintf(result, "SkRegion("); |
| 201 iter.reset(*this); | 201 iter.reset(*this); |
| 202 while (!iter.done()) { | 202 while (!iter.done()) { |
| 203 const SkIRect& r = iter.rect(); | 203 const SkIRect& r = iter.rect(); |
| 204 count += sprintf(result+count, "(%d,%d,%d,%d)", r.fLeft, r.fTop, r.fRigh
t, r.fBottom); | 204 count += sprintf(result+count, "(%d,%d,%d,%d)", r.fLeft, r.fTop, r.fRigh
t, r.fBottom); |
| 205 iter.next(); | 205 iter.next(); |
| 206 } | 206 } |
| 207 count += sprintf(result+count, ")"); | 207 count += sprintf(result+count, ")"); |
| 208 return result; | 208 return result; |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 401 return true; | 401 return true; |
| 402 } | 402 } |
| 403 if (rgn.isRect()) { | 403 if (rgn.isRect()) { |
| 404 return this->contains(rgn.getBounds()); | 404 return this->contains(rgn.getBounds()); |
| 405 } | 405 } |
| 406 | 406 |
| 407 /* | 407 /* |
| 408 * A contains B is equivalent to | 408 * A contains B is equivalent to |
| 409 * B - A == 0 | 409 * B - A == 0 |
| 410 */ | 410 */ |
| 411 return !Oper(rgn, *this, kDifference_Op, NULL); | 411 return !Oper(rgn, *this, kDifference_Op, nullptr); |
| 412 } | 412 } |
| 413 | 413 |
| 414 const SkRegion::RunType* SkRegion::getRuns(RunType tmpStorage[], | 414 const SkRegion::RunType* SkRegion::getRuns(RunType tmpStorage[], |
| 415 int* intervals) const { | 415 int* intervals) const { |
| 416 SkASSERT(tmpStorage && intervals); | 416 SkASSERT(tmpStorage && intervals); |
| 417 const RunType* runs = tmpStorage; | 417 const RunType* runs = tmpStorage; |
| 418 | 418 |
| 419 if (this->isEmpty()) { | 419 if (this->isEmpty()) { |
| 420 tmpStorage[0] = kRunTypeSentinel; | 420 tmpStorage[0] = kRunTypeSentinel; |
| 421 *intervals = 0; | 421 *intervals = 0; |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 491 return true; | 491 return true; |
| 492 } | 492 } |
| 493 if (weAreARect) { | 493 if (weAreARect) { |
| 494 return rgn.intersects(this->getBounds()); | 494 return rgn.intersects(this->getBounds()); |
| 495 } | 495 } |
| 496 if (theyAreARect) { | 496 if (theyAreARect) { |
| 497 return this->intersects(rgn.getBounds()); | 497 return this->intersects(rgn.getBounds()); |
| 498 } | 498 } |
| 499 | 499 |
| 500 // both of us are complex | 500 // both of us are complex |
| 501 return Oper(*this, rgn, kIntersect_Op, NULL); | 501 return Oper(*this, rgn, kIntersect_Op, nullptr); |
| 502 } | 502 } |
| 503 | 503 |
| 504 /////////////////////////////////////////////////////////////////////////////// | 504 /////////////////////////////////////////////////////////////////////////////// |
| 505 | 505 |
| 506 bool SkRegion::operator==(const SkRegion& b) const { | 506 bool SkRegion::operator==(const SkRegion& b) const { |
| 507 SkDEBUGCODE(validate();) | 507 SkDEBUGCODE(validate();) |
| 508 SkDEBUGCODE(b.validate();) | 508 SkDEBUGCODE(b.validate();) |
| 509 | 509 |
| 510 if (this == &b) { | 510 if (this == &b) { |
| 511 return true; | 511 return true; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 526 return false; | 526 return false; |
| 527 } | 527 } |
| 528 return ah->fRunCount == bh->fRunCount && | 528 return ah->fRunCount == bh->fRunCount && |
| 529 !memcmp(ah->readonly_runs(), bh->readonly_runs(), | 529 !memcmp(ah->readonly_runs(), bh->readonly_runs(), |
| 530 ah->fRunCount * sizeof(SkRegion::RunType)); | 530 ah->fRunCount * sizeof(SkRegion::RunType)); |
| 531 } | 531 } |
| 532 | 532 |
| 533 void SkRegion::translate(int dx, int dy, SkRegion* dst) const { | 533 void SkRegion::translate(int dx, int dy, SkRegion* dst) const { |
| 534 SkDEBUGCODE(this->validate();) | 534 SkDEBUGCODE(this->validate();) |
| 535 | 535 |
| 536 if (NULL == dst) { | 536 if (nullptr == dst) { |
| 537 return; | 537 return; |
| 538 } | 538 } |
| 539 if (this->isEmpty()) { | 539 if (this->isEmpty()) { |
| 540 dst->setEmpty(); | 540 dst->setEmpty(); |
| 541 } else if (this->isRect()) { | 541 } else if (this->isRect()) { |
| 542 dst->setRect(fBounds.fLeft + dx, fBounds.fTop + dy, | 542 dst->setRect(fBounds.fLeft + dx, fBounds.fTop + dy, |
| 543 fBounds.fRight + dx, fBounds.fBottom + dy); | 543 fBounds.fRight + dx, fBounds.fBottom + dy); |
| 544 } else { | 544 } else { |
| 545 if (this == dst) { | 545 if (this == dst) { |
| 546 dst->fRunHead = dst->fRunHead->ensureWritable(); | 546 dst->fRunHead = dst->fRunHead->ensureWritable(); |
| (...skipping 520 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1067 const RunType* b_runs = rgnb->getRuns(tmpB, &b_intervals); | 1067 const RunType* b_runs = rgnb->getRuns(tmpB, &b_intervals); |
| 1068 | 1068 |
| 1069 int dstCount = compute_worst_case_count(a_intervals, b_intervals); | 1069 int dstCount = compute_worst_case_count(a_intervals, b_intervals); |
| 1070 SkAutoSTMalloc<256, RunType> array(dstCount); | 1070 SkAutoSTMalloc<256, RunType> array(dstCount); |
| 1071 | 1071 |
| 1072 #ifdef SK_DEBUG | 1072 #ifdef SK_DEBUG |
| 1073 // Sometimes helpful to seed everything with a known value when debugging | 1073 // Sometimes helpful to seed everything with a known value when debugging |
| 1074 // sk_memset32((uint32_t*)array.get(), 0x7FFFFFFF, dstCount); | 1074 // sk_memset32((uint32_t*)array.get(), 0x7FFFFFFF, dstCount); |
| 1075 #endif | 1075 #endif |
| 1076 | 1076 |
| 1077 int count = operate(a_runs, b_runs, array.get(), op, NULL == result); | 1077 int count = operate(a_runs, b_runs, array.get(), op, nullptr == result); |
| 1078 SkASSERT(count <= dstCount); | 1078 SkASSERT(count <= dstCount); |
| 1079 | 1079 |
| 1080 if (result) { | 1080 if (result) { |
| 1081 SkASSERT(count >= 0); | 1081 SkASSERT(count >= 0); |
| 1082 return result->setRuns(array.get(), count); | 1082 return result->setRuns(array.get(), count); |
| 1083 } else { | 1083 } else { |
| 1084 return (QUICK_EXIT_TRUE_COUNT == count) || !isRunCountEmpty(count); | 1084 return (QUICK_EXIT_TRUE_COUNT == count) || !isRunCountEmpty(count); |
| 1085 } | 1085 } |
| 1086 } | 1086 } |
| 1087 | 1087 |
| 1088 bool SkRegion::op(const SkRegion& rgna, const SkRegion& rgnb, Op op) { | 1088 bool SkRegion::op(const SkRegion& rgna, const SkRegion& rgnb, Op op) { |
| 1089 SkDEBUGCODE(this->validate();) | 1089 SkDEBUGCODE(this->validate();) |
| 1090 return SkRegion::Oper(rgna, rgnb, op, this); | 1090 return SkRegion::Oper(rgna, rgnb, op, this); |
| 1091 } | 1091 } |
| 1092 | 1092 |
| 1093 /////////////////////////////////////////////////////////////////////////////// | 1093 /////////////////////////////////////////////////////////////////////////////// |
| 1094 | 1094 |
| 1095 #include "SkBuffer.h" | 1095 #include "SkBuffer.h" |
| 1096 | 1096 |
| 1097 size_t SkRegion::writeToMemory(void* storage) const { | 1097 size_t SkRegion::writeToMemory(void* storage) const { |
| 1098 if (NULL == storage) { | 1098 if (nullptr == storage) { |
| 1099 size_t size = sizeof(int32_t); // -1 (empty), 0 (rect), runCount | 1099 size_t size = sizeof(int32_t); // -1 (empty), 0 (rect), runCount |
| 1100 if (!this->isEmpty()) { | 1100 if (!this->isEmpty()) { |
| 1101 size += sizeof(fBounds); | 1101 size += sizeof(fBounds); |
| 1102 if (this->isComplex()) { | 1102 if (this->isComplex()) { |
| 1103 size += 2 * sizeof(int32_t); // ySpanCount + intervalCount | 1103 size += 2 * sizeof(int32_t); // ySpanCount + intervalCount |
| 1104 size += fRunHead->fRunCount * sizeof(RunType); | 1104 size += fRunHead->fRunCount * sizeof(RunType); |
| 1105 } | 1105 } |
| 1106 } | 1106 } |
| 1107 return size; | 1107 return size; |
| 1108 } | 1108 } |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1288 } | 1288 } |
| 1289 | 1289 |
| 1290 void SkRegion::Iterator::reset(const SkRegion& rgn) { | 1290 void SkRegion::Iterator::reset(const SkRegion& rgn) { |
| 1291 fRgn = &rgn; | 1291 fRgn = &rgn; |
| 1292 if (rgn.isEmpty()) { | 1292 if (rgn.isEmpty()) { |
| 1293 fDone = true; | 1293 fDone = true; |
| 1294 } else { | 1294 } else { |
| 1295 fDone = false; | 1295 fDone = false; |
| 1296 if (rgn.isRect()) { | 1296 if (rgn.isRect()) { |
| 1297 fRect = rgn.fBounds; | 1297 fRect = rgn.fBounds; |
| 1298 fRuns = NULL; | 1298 fRuns = nullptr; |
| 1299 } else { | 1299 } else { |
| 1300 fRuns = rgn.fRunHead->readonly_runs(); | 1300 fRuns = rgn.fRunHead->readonly_runs(); |
| 1301 fRect.set(fRuns[3], fRuns[0], fRuns[4], fRuns[1]); | 1301 fRect.set(fRuns[3], fRuns[0], fRuns[4], fRuns[1]); |
| 1302 fRuns += 5; | 1302 fRuns += 5; |
| 1303 // Now fRuns points to the 2nd interval (or x-sentinel) | 1303 // Now fRuns points to the 2nd interval (or x-sentinel) |
| 1304 } | 1304 } |
| 1305 } | 1305 } |
| 1306 } | 1306 } |
| 1307 | 1307 |
| 1308 void SkRegion::Iterator::next() { | 1308 void SkRegion::Iterator::next() { |
| 1309 if (fDone) { | 1309 if (fDone) { |
| 1310 return; | 1310 return; |
| 1311 } | 1311 } |
| 1312 | 1312 |
| 1313 if (fRuns == NULL) { // rect case | 1313 if (fRuns == nullptr) { // rect case |
| 1314 fDone = true; | 1314 fDone = true; |
| 1315 return; | 1315 return; |
| 1316 } | 1316 } |
| 1317 | 1317 |
| 1318 const RunType* runs = fRuns; | 1318 const RunType* runs = fRuns; |
| 1319 | 1319 |
| 1320 if (runs[0] < kRunTypeSentinel) { // valid X value | 1320 if (runs[0] < kRunTypeSentinel) { // valid X value |
| 1321 fRect.fLeft = runs[0]; | 1321 fRect.fLeft = runs[0]; |
| 1322 fRect.fRight = runs[1]; | 1322 fRect.fRight = runs[1]; |
| 1323 runs += 2; | 1323 runs += 2; |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1395 right > r.fLeft && left < r.fRight) { | 1395 right > r.fLeft && left < r.fRight) { |
| 1396 if (rgn.isRect()) { | 1396 if (rgn.isRect()) { |
| 1397 if (left < r.fLeft) { | 1397 if (left < r.fLeft) { |
| 1398 left = r.fLeft; | 1398 left = r.fLeft; |
| 1399 } | 1399 } |
| 1400 if (right > r.fRight) { | 1400 if (right > r.fRight) { |
| 1401 right = r.fRight; | 1401 right = r.fRight; |
| 1402 } | 1402 } |
| 1403 fLeft = left; | 1403 fLeft = left; |
| 1404 fRight = right; | 1404 fRight = right; |
| 1405 fRuns = NULL; // means we're a rect, not a rgn | 1405 fRuns = nullptr; // means we're a rect, not a rgn |
| 1406 fDone = false; | 1406 fDone = false; |
| 1407 } else { | 1407 } else { |
| 1408 const SkRegion::RunType* runs = rgn.fRunHead->findScanline(y); | 1408 const SkRegion::RunType* runs = rgn.fRunHead->findScanline(y); |
| 1409 runs += 2; // skip Bottom and IntervalCount | 1409 runs += 2; // skip Bottom and IntervalCount |
| 1410 for (;;) { | 1410 for (;;) { |
| 1411 // runs[0..1] is to the right of the span, so we're done | 1411 // runs[0..1] is to the right of the span, so we're done |
| 1412 if (runs[0] >= right) { | 1412 if (runs[0] >= right) { |
| 1413 break; | 1413 break; |
| 1414 } | 1414 } |
| 1415 // runs[0..1] is to the left of the span, so continue | 1415 // runs[0..1] is to the left of the span, so continue |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1426 } | 1426 } |
| 1427 } | 1427 } |
| 1428 } | 1428 } |
| 1429 } | 1429 } |
| 1430 | 1430 |
| 1431 bool SkRegion::Spanerator::next(int* left, int* right) { | 1431 bool SkRegion::Spanerator::next(int* left, int* right) { |
| 1432 if (fDone) { | 1432 if (fDone) { |
| 1433 return false; | 1433 return false; |
| 1434 } | 1434 } |
| 1435 | 1435 |
| 1436 if (fRuns == NULL) { // we're a rect | 1436 if (fRuns == nullptr) { // we're a rect |
| 1437 fDone = true; // ok, now we're done | 1437 fDone = true; // ok, now we're done |
| 1438 if (left) { | 1438 if (left) { |
| 1439 *left = fLeft; | 1439 *left = fLeft; |
| 1440 } | 1440 } |
| 1441 if (right) { | 1441 if (right) { |
| 1442 *right = fRight; | 1442 *right = fRight; |
| 1443 } | 1443 } |
| 1444 return true; // this interval is legal | 1444 return true; // this interval is legal |
| 1445 } | 1445 } |
| 1446 | 1446 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1470 bool SkRegion::debugSetRuns(const RunType runs[], int count) { | 1470 bool SkRegion::debugSetRuns(const RunType runs[], int count) { |
| 1471 // we need to make a copy, since the real method may modify the array, and | 1471 // we need to make a copy, since the real method may modify the array, and |
| 1472 // so it cannot be const. | 1472 // so it cannot be const. |
| 1473 | 1473 |
| 1474 SkAutoTArray<RunType> storage(count); | 1474 SkAutoTArray<RunType> storage(count); |
| 1475 memcpy(storage.get(), runs, count * sizeof(RunType)); | 1475 memcpy(storage.get(), runs, count * sizeof(RunType)); |
| 1476 return this->setRuns(storage.get(), count); | 1476 return this->setRuns(storage.get(), count); |
| 1477 } | 1477 } |
| 1478 | 1478 |
| 1479 #endif | 1479 #endif |
| OLD | NEW |