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 |