Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(181)

Side by Side Diff: src/core/SkPathRef.cpp

Issue 105083003: Move segment mask from SkPath to SkPathRef (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: Moved growForLines to growForRepeatedVerb Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright 2013 Google Inc. 2 * Copyright 2013 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkBuffer.h" 8 #include "SkBuffer.h"
9 #include "SkOnce.h" 9 #include "SkOnce.h"
10 #include "SkPath.h" 10 #include "SkPath.h"
(...skipping 17 matching lines...) Expand all
28 SkDEBUGCODE(sk_atomic_inc(&fPathRef->fEditorsAttached);) 28 SkDEBUGCODE(sk_atomic_inc(&fPathRef->fEditorsAttached);)
29 } 29 }
30 30
31 SkPoint* SkPathRef::Editor::growForConic(SkScalar w) { 31 SkPoint* SkPathRef::Editor::growForConic(SkScalar w) {
32 SkDEBUGCODE(fPathRef->validate();) 32 SkDEBUGCODE(fPathRef->validate();)
33 SkPoint* pts = fPathRef->growForVerb(SkPath::kConic_Verb); 33 SkPoint* pts = fPathRef->growForVerb(SkPath::kConic_Verb);
34 *fPathRef->fConicWeights.append() = w; 34 *fPathRef->fConicWeights.append() = w;
35 return pts; 35 return pts;
36 } 36 }
37 37
38 SkPoint* SkPathRef::Editor::growForConics(int numConics, SkScalar* weights) {
39 SkDEBUGCODE(fPathRef->validate();)
40 SkPoint* pts = fPathRef->growForRepeatedVerb(SkPath::kConic_Verb, numConics) ;
41 *fPathRef->fConicWeights.append(numConics, weights);
42 return pts;
43 }
44
38 ////////////////////////////////////////////////////////////////////////////// 45 //////////////////////////////////////////////////////////////////////////////
39 void SkPathRef::CreateEmptyImpl(SkPathRef** empty) { 46 void SkPathRef::CreateEmptyImpl(SkPathRef** empty) {
40 *empty = SkNEW(SkPathRef); 47 *empty = SkNEW(SkPathRef);
41 (*empty)->computeBounds(); // Preemptively avoid a race to clear fBoundsIsD irty. 48 (*empty)->computeBounds(); // Preemptively avoid a race to clear fBoundsIsD irty.
42 } 49 }
43 50
44 SkPathRef* SkPathRef::CreateEmpty() { 51 SkPathRef* SkPathRef::CreateEmpty() {
45 static SkPathRef* gEmptyPathRef; 52 static SkPathRef* gEmptyPathRef;
46 SK_DECLARE_STATIC_ONCE(once); 53 SK_DECLARE_STATIC_ONCE(once);
47 SkOnce(&once, SkPathRef::CreateEmptyImpl, &gEmptyPathRef); 54 SkOnce(&once, SkPathRef::CreateEmptyImpl, &gEmptyPathRef);
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 (*dst)->fBounds.setEmpty(); 105 (*dst)->fBounds.setEmpty();
99 } 106 }
100 } else { 107 } else {
101 (*dst)->fIsFinite = false; 108 (*dst)->fIsFinite = false;
102 (*dst)->fBounds.setEmpty(); 109 (*dst)->fBounds.setEmpty();
103 } 110 }
104 } else { 111 } else {
105 (*dst)->fBoundsIsDirty = true; 112 (*dst)->fBoundsIsDirty = true;
106 } 113 }
107 114
115 (*dst)->fSegmentMask = src.fSegmentMask;
116
108 // It's an oval only if it stays a rect. 117 // It's an oval only if it stays a rect.
109 (*dst)->fIsOval = src.fIsOval && matrix.rectStaysRect(); 118 (*dst)->fIsOval = src.fIsOval && matrix.rectStaysRect();
110 119
111 SkDEBUGCODE((*dst)->validate();) 120 SkDEBUGCODE((*dst)->validate();)
112 } 121 }
113 122
114 SkPathRef* SkPathRef::CreateFromBuffer(SkRBuffer* buffer 123 SkPathRef* SkPathRef::CreateFromBuffer(SkRBuffer* buffer
115 #ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V16_AND_ALL_OTHER_INSTANCES_TO O 124 #ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V16_AND_ALL_OTHER_INSTANCES_TO O
116 , bool newFormat, int32_t oldPacked 125 , bool newFormat, int32_t oldPacked
117 #endif 126 #endif
118 ) { 127 ) {
119 SkPathRef* ref = SkNEW(SkPathRef); 128 SkPathRef* ref = SkNEW(SkPathRef);
120 bool isOval; 129 bool isOval;
130 uint8_t segmentMask;
121 131
122 int32_t packed; 132 int32_t packed;
123 if (!buffer->readS32(&packed)) { 133 if (!buffer->readS32(&packed)) {
124 SkDELETE(ref); 134 SkDELETE(ref);
125 return NULL; 135 return NULL;
126 } 136 }
127 137
128 ref->fIsFinite = (packed >> kIsFinite_SerializationShift) & 1; 138 ref->fIsFinite = (packed >> kIsFinite_SerializationShift) & 1;
129 139
130 #ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V16_AND_ALL_OTHER_INSTANCES_TO O 140 #ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V16_AND_ALL_OTHER_INSTANCES_TO O
131 if (newFormat) { 141 if (newFormat) {
132 #endif 142 #endif
143 segmentMask = (packed >> kSegmentMask_SerializationShift) & 0xF;
133 isOval = (packed >> kIsOval_SerializationShift) & 1; 144 isOval = (packed >> kIsOval_SerializationShift) & 1;
134 #ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V16_AND_ALL_OTHER_INSTANCES_TO O 145 #ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V16_AND_ALL_OTHER_INSTANCES_TO O
135 } else { 146 } else {
147 segmentMask = (oldPacked >> SkPath::kOldSegmentMask_SerializationShift) & 0xF;
136 isOval = (oldPacked >> SkPath::kOldIsOval_SerializationShift) & 1; 148 isOval = (oldPacked >> SkPath::kOldIsOval_SerializationShift) & 1;
137 } 149 }
138 #endif 150 #endif
139 151
140 int32_t verbCount, pointCount, conicCount; 152 int32_t verbCount, pointCount, conicCount;
141 if (!buffer->readU32(&(ref->fGenerationID)) || 153 if (!buffer->readU32(&(ref->fGenerationID)) ||
142 !buffer->readS32(&verbCount) || 154 !buffer->readS32(&verbCount) ||
143 !buffer->readS32(&pointCount) || 155 !buffer->readS32(&pointCount) ||
144 !buffer->readS32(&conicCount)) { 156 !buffer->readS32(&conicCount)) {
145 SkDELETE(ref); 157 SkDELETE(ref);
146 return NULL; 158 return NULL;
147 } 159 }
148 160
149 ref->resetToSize(verbCount, pointCount, conicCount); 161 ref->resetToSize(verbCount, pointCount, conicCount);
150 SkASSERT(verbCount == ref->countVerbs()); 162 SkASSERT(verbCount == ref->countVerbs());
151 SkASSERT(pointCount == ref->countPoints()); 163 SkASSERT(pointCount == ref->countPoints());
152 SkASSERT(conicCount == ref->fConicWeights.count()); 164 SkASSERT(conicCount == ref->fConicWeights.count());
153 165
154 if (!buffer->read(ref->verbsMemWritable(), verbCount * sizeof(uint8_t)) || 166 if (!buffer->read(ref->verbsMemWritable(), verbCount * sizeof(uint8_t)) ||
155 !buffer->read(ref->fPoints, pointCount * sizeof(SkPoint)) || 167 !buffer->read(ref->fPoints, pointCount * sizeof(SkPoint)) ||
156 !buffer->read(ref->fConicWeights.begin(), conicCount * sizeof(SkScalar)) || 168 !buffer->read(ref->fConicWeights.begin(), conicCount * sizeof(SkScalar)) ||
157 !buffer->read(&ref->fBounds, sizeof(SkRect))) { 169 !buffer->read(&ref->fBounds, sizeof(SkRect))) {
158 SkDELETE(ref); 170 SkDELETE(ref);
159 return NULL; 171 return NULL;
160 } 172 }
161 ref->fBoundsIsDirty = false; 173 ref->fBoundsIsDirty = false;
174
175 // resetToSize clears fSegmentMask and fIsOval
176 ref->fSegmentMask = segmentMask;
162 ref->fIsOval = isOval; 177 ref->fIsOval = isOval;
163 return ref; 178 return ref;
164 } 179 }
165 180
166 void SkPathRef::Rewind(SkAutoTUnref<SkPathRef>* pathRef) { 181 void SkPathRef::Rewind(SkAutoTUnref<SkPathRef>* pathRef) {
167 if ((*pathRef)->unique()) { 182 if ((*pathRef)->unique()) {
168 SkDEBUGCODE((*pathRef)->validate();) 183 SkDEBUGCODE((*pathRef)->validate();)
169 (*pathRef)->fBoundsIsDirty = true; // this also invalidates fIsFinite 184 (*pathRef)->fBoundsIsDirty = true; // this also invalidates fIsFinite
170 (*pathRef)->fVerbCnt = 0; 185 (*pathRef)->fVerbCnt = 0;
171 (*pathRef)->fPointCnt = 0; 186 (*pathRef)->fPointCnt = 0;
172 (*pathRef)->fFreeSpace = (*pathRef)->currSize(); 187 (*pathRef)->fFreeSpace = (*pathRef)->currSize();
173 (*pathRef)->fGenerationID = 0; 188 (*pathRef)->fGenerationID = 0;
174 (*pathRef)->fConicWeights.rewind(); 189 (*pathRef)->fConicWeights.rewind();
190 (*pathRef)->fSegmentMask = 0;
175 (*pathRef)->fIsOval = false; 191 (*pathRef)->fIsOval = false;
176 SkDEBUGCODE((*pathRef)->validate();) 192 SkDEBUGCODE((*pathRef)->validate();)
177 } else { 193 } else {
178 int oldVCnt = (*pathRef)->countVerbs(); 194 int oldVCnt = (*pathRef)->countVerbs();
179 int oldPCnt = (*pathRef)->countPoints(); 195 int oldPCnt = (*pathRef)->countPoints();
180 pathRef->reset(SkNEW(SkPathRef)); 196 pathRef->reset(SkNEW(SkPathRef));
181 (*pathRef)->resetToSize(0, 0, 0, oldVCnt, oldPCnt); 197 (*pathRef)->resetToSize(0, 0, 0, oldVCnt, oldPCnt);
182 } 198 }
183 } 199 }
184 200
185 bool SkPathRef::operator== (const SkPathRef& ref) const { 201 bool SkPathRef::operator== (const SkPathRef& ref) const {
186 SkDEBUGCODE(this->validate();) 202 SkDEBUGCODE(this->validate();)
187 SkDEBUGCODE(ref.validate();) 203 SkDEBUGCODE(ref.validate();)
204
205 // We explicitly check fSegmentMask as a quick-reject. We could skip it,
206 // since it is only a cache of info in the fVerbs, but its a fast way to
207 // notice a difference
208 if (fSegmentMask != ref.fSegmentMask) {
209 return false;
210 }
211
188 bool genIDMatch = fGenerationID && fGenerationID == ref.fGenerationID; 212 bool genIDMatch = fGenerationID && fGenerationID == ref.fGenerationID;
189 #ifdef SK_RELEASE 213 #ifdef SK_RELEASE
190 if (genIDMatch) { 214 if (genIDMatch) {
191 return true; 215 return true;
192 } 216 }
193 #endif 217 #endif
194 if (fPointCnt != ref.fPointCnt || 218 if (fPointCnt != ref.fPointCnt ||
195 fVerbCnt != ref.fVerbCnt) { 219 fVerbCnt != ref.fVerbCnt) {
196 SkASSERT(!genIDMatch); 220 SkASSERT(!genIDMatch);
197 return false; 221 return false;
(...skipping 17 matching lines...) Expand all
215 // We've done the work to determine that these are equal. If either has a ze ro genID, copy 239 // We've done the work to determine that these are equal. If either has a ze ro genID, copy
216 // the other's. If both are 0 then genID() will compute the next ID. 240 // the other's. If both are 0 then genID() will compute the next ID.
217 if (0 == fGenerationID) { 241 if (0 == fGenerationID) {
218 fGenerationID = ref.genID(); 242 fGenerationID = ref.genID();
219 } else if (0 == ref.fGenerationID) { 243 } else if (0 == ref.fGenerationID) {
220 ref.fGenerationID = this->genID(); 244 ref.fGenerationID = this->genID();
221 } 245 }
222 return true; 246 return true;
223 } 247 }
224 248
225 void SkPathRef::writeToBuffer(SkWBuffer* buffer) { 249 void SkPathRef::writeToBuffer(SkWBuffer* buffer) const {
226 SkDEBUGCODE(this->validate();) 250 SkDEBUGCODE(this->validate();)
227 SkDEBUGCODE(size_t beforePos = buffer->pos();) 251 SkDEBUGCODE(size_t beforePos = buffer->pos();)
228 252
229 // Call getBounds() to ensure (as a side-effect) that fBounds 253 // Call getBounds() to ensure (as a side-effect) that fBounds
230 // and fIsFinite are computed. 254 // and fIsFinite are computed.
231 const SkRect& bounds = this->getBounds(); 255 const SkRect& bounds = this->getBounds();
232 256
233 int32_t packed = ((fIsFinite & 1) << kIsFinite_SerializationShift) | 257 int32_t packed = ((fIsFinite & 1) << kIsFinite_SerializationShift) |
234 ((fIsOval & 1) << kIsOval_SerializationShift); 258 ((fIsOval & 1) << kIsOval_SerializationShift) |
259 (fSegmentMask << kSegmentMask_SerializationShift);
235 buffer->write32(packed); 260 buffer->write32(packed);
236 261
237 // TODO: write gen ID here. Problem: We don't know if we're cross process or not from 262 // TODO: write gen ID here. Problem: We don't know if we're cross process or not from
238 // SkWBuffer. Until this is fixed we write 0. 263 // SkWBuffer. Until this is fixed we write 0.
239 buffer->write32(0); 264 buffer->write32(0);
240 buffer->write32(fVerbCnt); 265 buffer->write32(fVerbCnt);
241 buffer->write32(fPointCnt); 266 buffer->write32(fPointCnt);
242 buffer->write32(fConicWeights.count()); 267 buffer->write32(fConicWeights.count());
243 buffer->write(verbsMemBegin(), fVerbCnt * sizeof(uint8_t)); 268 buffer->write(verbsMemBegin(), fVerbCnt * sizeof(uint8_t));
244 buffer->write(fPoints, fPointCnt * sizeof(SkPoint)); 269 buffer->write(fPoints, fPointCnt * sizeof(SkPoint));
245 buffer->write(fConicWeights.begin(), fConicWeights.bytes()); 270 buffer->write(fConicWeights.begin(), fConicWeights.bytes());
246 buffer->write(&bounds, sizeof(bounds)); 271 buffer->write(&bounds, sizeof(bounds));
247 272
248 SkASSERT(buffer->pos() - beforePos == (size_t) this->writeSize()); 273 SkASSERT(buffer->pos() - beforePos == (size_t) this->writeSize());
249 } 274 }
250 275
251 uint32_t SkPathRef::writeSize() { 276 uint32_t SkPathRef::writeSize() const {
252 return uint32_t(5 * sizeof(uint32_t) + 277 return uint32_t(5 * sizeof(uint32_t) +
253 fVerbCnt * sizeof(uint8_t) + 278 fVerbCnt * sizeof(uint8_t) +
254 fPointCnt * sizeof(SkPoint) + 279 fPointCnt * sizeof(SkPoint) +
255 fConicWeights.bytes() + 280 fConicWeights.bytes() +
256 sizeof(SkRect)); 281 sizeof(SkRect));
257 } 282 }
258 283
259 void SkPathRef::copy(const SkPathRef& ref, 284 void SkPathRef::copy(const SkPathRef& ref,
260 int additionalReserveVerbs, 285 int additionalReserveVerbs,
261 int additionalReservePoints) { 286 int additionalReservePoints) {
262 SkDEBUGCODE(this->validate();) 287 SkDEBUGCODE(this->validate();)
263 this->resetToSize(ref.fVerbCnt, ref.fPointCnt, ref.fConicWeights.count(), 288 this->resetToSize(ref.fVerbCnt, ref.fPointCnt, ref.fConicWeights.count(),
264 additionalReserveVerbs, additionalReservePoints); 289 additionalReserveVerbs, additionalReservePoints);
265 memcpy(this->verbsMemWritable(), ref.verbsMemBegin(), ref.fVerbCnt * sizeof( uint8_t)); 290 memcpy(this->verbsMemWritable(), ref.verbsMemBegin(), ref.fVerbCnt * sizeof( uint8_t));
266 memcpy(this->fPoints, ref.fPoints, ref.fPointCnt * sizeof(SkPoint)); 291 memcpy(this->fPoints, ref.fPoints, ref.fPointCnt * sizeof(SkPoint));
267 fConicWeights = ref.fConicWeights; 292 fConicWeights = ref.fConicWeights;
268 // We could call genID() here to force a real ID (instead of 0). However, if we're making 293 // We could call genID() here to force a real ID (instead of 0). However, if we're making
269 // a copy then presumably we intend to make a modification immediately after wards. 294 // a copy then presumably we intend to make a modification immediately after wards.
270 fGenerationID = ref.fGenerationID; 295 fGenerationID = ref.fGenerationID;
271 fBoundsIsDirty = ref.fBoundsIsDirty; 296 fBoundsIsDirty = ref.fBoundsIsDirty;
272 if (!fBoundsIsDirty) { 297 if (!fBoundsIsDirty) {
273 fBounds = ref.fBounds; 298 fBounds = ref.fBounds;
274 fIsFinite = ref.fIsFinite; 299 fIsFinite = ref.fIsFinite;
275 } 300 }
301 fSegmentMask = ref.fSegmentMask;
276 fIsOval = ref.fIsOval; 302 fIsOval = ref.fIsOval;
277 SkDEBUGCODE(this->validate();) 303 SkDEBUGCODE(this->validate();)
278 } 304 }
279 305
306 SkPoint* SkPathRef::growForRepeatedVerb(int /*SkPath::Verb*/ verb, int numVbs) {
307 // This value is just made-up for now. When count is 4, calling memset was m uch
308 // slower than just writing the loop. This seems odd, and hopefully in the
309 // future this will appear to have been a fluke...
310 static const unsigned int kMIN_COUNT_FOR_MEMSET_TO_BE_FAST = 16;
311
312 SkDEBUGCODE(this->validate();)
313 int pCnt;
314 bool dirtyAfterEdit = true;
315 switch (verb) {
316 case SkPath::kMove_Verb:
317 pCnt = numVbs;
318 dirtyAfterEdit = false;
319 break;
320 case SkPath::kLine_Verb:
321 fSegmentMask |= SkPath::kLine_SegmentMask;
322 pCnt = numVbs;
323 break;
324 case SkPath::kQuad_Verb:
325 fSegmentMask |= SkPath::kQuad_SegmentMask;
326 pCnt = 2 * numVbs;
327 break;
328 case SkPath::kConic_Verb:
329 fSegmentMask |= SkPath::kConic_SegmentMask;
330 pCnt = 2 * numVbs;
331 break;
332 case SkPath::kCubic_Verb:
333 fSegmentMask |= SkPath::kCubic_SegmentMask;
334 pCnt = 3 * numVbs;
335 break;
336 case SkPath::kClose_Verb:
337 SkDEBUGFAIL("growForRepeatedVerb called for kClose_Verb");
338 pCnt = 0;
339 dirtyAfterEdit = false;
340 break;
341 case SkPath::kDone_Verb:
342 SkDEBUGFAIL("growForRepeatedVerb called for kDone");
343 // fall through
344 default:
345 SkDEBUGFAIL("default should not be reached");
346 pCnt = 0;
347 dirtyAfterEdit = false;
348 }
349
350 size_t space = numVbs * sizeof(uint8_t) + pCnt * sizeof (SkPoint);
351 this->makeSpace(space);
352
353 SkPoint* ret = fPoints + fPointCnt;
354 uint8_t* vb = fVerbs - fVerbCnt;
355
356 // cast to unsigned, so if kMIN_COUNT_FOR_MEMSET_TO_BE_FAST is defined to
357 // be 0, the compiler will remove the test/branch entirely.
358 if ((unsigned)numVbs >= kMIN_COUNT_FOR_MEMSET_TO_BE_FAST) {
359 memset(vb - numVbs, verb, numVbs);
360 } else {
361 for (int i = 0; i < numVbs; ++i) {
362 vb[~i] = verb;
363 }
364 }
365
366 fVerbCnt += numVbs;
367 fPointCnt += pCnt;
368 fFreeSpace -= space;
369 fBoundsIsDirty = true; // this also invalidates fIsFinite
370 if (dirtyAfterEdit) {
371 fIsOval = false;
372 }
373 SkDEBUGCODE(this->validate();)
374 return ret;
375 }
376
280 SkPoint* SkPathRef::growForVerb(int /* SkPath::Verb*/ verb) { 377 SkPoint* SkPathRef::growForVerb(int /* SkPath::Verb*/ verb) {
281 SkDEBUGCODE(this->validate();) 378 SkDEBUGCODE(this->validate();)
282 int pCnt; 379 int pCnt;
283 bool dirtyAfterEdit = true; 380 bool dirtyAfterEdit = true;
284 switch (verb) { 381 switch (verb) {
285 case SkPath::kMove_Verb: 382 case SkPath::kMove_Verb:
286 pCnt = 1; 383 pCnt = 1;
287 dirtyAfterEdit = false; 384 dirtyAfterEdit = false;
288 break; 385 break;
289 case SkPath::kLine_Verb: 386 case SkPath::kLine_Verb:
387 fSegmentMask |= SkPath::kLine_SegmentMask;
290 pCnt = 1; 388 pCnt = 1;
291 break; 389 break;
292 case SkPath::kQuad_Verb: 390 case SkPath::kQuad_Verb:
293 // fall through 391 fSegmentMask |= SkPath::kQuad_SegmentMask;
392 pCnt = 2;
393 break;
294 case SkPath::kConic_Verb: 394 case SkPath::kConic_Verb:
395 fSegmentMask |= SkPath::kConic_SegmentMask;
295 pCnt = 2; 396 pCnt = 2;
296 break; 397 break;
297 case SkPath::kCubic_Verb: 398 case SkPath::kCubic_Verb:
399 fSegmentMask |= SkPath::kCubic_SegmentMask;
298 pCnt = 3; 400 pCnt = 3;
299 break; 401 break;
300 case SkPath::kClose_Verb: 402 case SkPath::kClose_Verb:
301 pCnt = 0; 403 pCnt = 0;
302 dirtyAfterEdit = false; 404 dirtyAfterEdit = false;
303 break; 405 break;
304 case SkPath::kDone_Verb: 406 case SkPath::kDone_Verb:
305 SkDEBUGFAIL("growForVerb called for kDone"); 407 SkDEBUGFAIL("growForVerb called for kDone");
306 // fall through 408 // fall through
307 default: 409 default:
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
362 fBounds.fLeft - fPoints[i].fX < SK_ScalarNearlyZero && 464 fBounds.fLeft - fPoints[i].fX < SK_ScalarNearlyZero &&
363 fPoints[i].fX - fBounds.fRight < SK_ScalarNearlyZero && 465 fPoints[i].fX - fBounds.fRight < SK_ScalarNearlyZero &&
364 fBounds.fTop - fPoints[i].fY < SK_ScalarNearlyZero && 466 fBounds.fTop - fPoints[i].fY < SK_ScalarNearlyZero &&
365 fPoints[i].fY - fBounds.fBottom < SK_ScalarNearlyZero)); 467 fPoints[i].fY - fBounds.fBottom < SK_ScalarNearlyZero));
366 if (!fPoints[i].isFinite()) { 468 if (!fPoints[i].isFinite()) {
367 isFinite = false; 469 isFinite = false;
368 } 470 }
369 } 471 }
370 SkASSERT(SkToBool(fIsFinite) == isFinite); 472 SkASSERT(SkToBool(fIsFinite) == isFinite);
371 } 473 }
474
475 #ifdef SK_DEBUG_PATH
476 uint32_t mask = 0;
477 for (int i = 0; i < fVerbCnt; ++i) {
478 switch (fVerbs[~i]) {
479 case SkPath::kMove_Verb:
480 break;
481 case SkPath::kLine_Verb:
482 mask |= SkPath::kLine_SegmentMask;
483 break;
484 case SkPath::kQuad_Verb:
485 mask |= SkPath::kQuad_SegmentMask;
486 break;
487 case SkPath::kConic_Verb:
488 mask |= SkPath::kConic_SegmentMask;
489 break;
490 case SkPath::kCubic_Verb:
491 mask |= SkPath::kCubic_SegmentMask;
492 break;
493 case SkPath::kClose_Verb:
494 break;
495 case SkPath::kDone_Verb:
496 SkDEBUGFAIL("Done verb shouldn't be recorded.");
497 break;
498 default:
499 SkDEBUGFAIL("Unknown Verb");
500 break;
501 }
502 }
503 SkASSERT(mask == fSegmentMask);
504 #endif // SK_DEBUG_PATH
372 } 505 }
373 #endif 506 #endif
OLDNEW
« include/core/SkPathRef.h ('K') | « src/core/SkPath.cpp ('k') | tests/PathTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698