| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2006 The Android Open Source Project | 2 * Copyright 2006 The Android Open Source Project |
| 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 "SkRegionPriv.h" | 8 #include "SkRegionPriv.h" |
| 9 #include "SkBlitter.h" | 9 #include "SkBlitter.h" |
| 10 #include "SkScan.h" | 10 #include "SkScan.h" |
| (...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 261 2, // kQuad_VerbB | 261 2, // kQuad_VerbB |
| 262 2, // kConic_VerbB | 262 2, // kConic_VerbB |
| 263 3, // kCubic_Verb | 263 3, // kCubic_Verb |
| 264 0, // kClose_Verb | 264 0, // kClose_Verb |
| 265 0 // kDone_Verb | 265 0 // kDone_Verb |
| 266 }; | 266 }; |
| 267 SkASSERT((unsigned)verb < SK_ARRAY_COUNT(gPathVerbToMaxEdges)); | 267 SkASSERT((unsigned)verb < SK_ARRAY_COUNT(gPathVerbToMaxEdges)); |
| 268 return gPathVerbToMaxEdges[verb]; | 268 return gPathVerbToMaxEdges[verb]; |
| 269 } | 269 } |
| 270 | 270 |
| 271 | 271 // If returns 0, ignore itop and ibot |
| 272 static int count_path_runtype_values(const SkPath& path, int* itop, int* ibot) { | 272 static int count_path_runtype_values(const SkPath& path, int* itop, int* ibot) { |
| 273 SkPath::Iter iter(path, true); | 273 SkPath::Iter iter(path, true); |
| 274 SkPoint pts[4]; | 274 SkPoint pts[4]; |
| 275 SkPath::Verb verb; | 275 SkPath::Verb verb; |
| 276 | 276 |
| 277 int maxEdges = 0; | 277 int maxEdges = 0; |
| 278 SkScalar top = SkIntToScalar(SK_MaxS16); | 278 SkScalar top = SkIntToScalar(SK_MaxS16); |
| 279 SkScalar bot = SkIntToScalar(SK_MinS16); | 279 SkScalar bot = SkIntToScalar(SK_MinS16); |
| 280 | 280 |
| 281 while ((verb = iter.next(pts, false)) != SkPath::kDone_Verb) { | 281 while ((verb = iter.next(pts, false)) != SkPath::kDone_Verb) { |
| 282 maxEdges += verb_to_max_edges(verb); | 282 maxEdges += verb_to_max_edges(verb); |
| 283 | 283 |
| 284 int lastIndex = verb_to_initial_last_index(verb); | 284 int lastIndex = verb_to_initial_last_index(verb); |
| 285 if (lastIndex > 0) { | 285 if (lastIndex > 0) { |
| 286 for (int i = 1; i <= lastIndex; i++) { | 286 for (int i = 1; i <= lastIndex; i++) { |
| 287 if (top > pts[i].fY) { | 287 if (top > pts[i].fY) { |
| 288 top = pts[i].fY; | 288 top = pts[i].fY; |
| 289 } else if (bot < pts[i].fY) { | 289 } else if (bot < pts[i].fY) { |
| 290 bot = pts[i].fY; | 290 bot = pts[i].fY; |
| 291 } | 291 } |
| 292 } | 292 } |
| 293 } else if (SkPath::kMove_Verb == verb) { | 293 } else if (SkPath::kMove_Verb == verb) { |
| 294 if (top > pts[0].fY) { | 294 if (top > pts[0].fY) { |
| 295 top = pts[0].fY; | 295 top = pts[0].fY; |
| 296 } else if (bot < pts[0].fY) { | 296 } else if (bot < pts[0].fY) { |
| 297 bot = pts[0].fY; | 297 bot = pts[0].fY; |
| 298 } | 298 } |
| 299 } | 299 } |
| 300 } | 300 } |
| 301 if (0 == maxEdges) { |
| 302 return 0; // we have only moves+closes |
| 303 } |
| 304 |
| 301 SkASSERT(top <= bot); | 305 SkASSERT(top <= bot); |
| 302 | |
| 303 *itop = SkScalarRoundToInt(top); | 306 *itop = SkScalarRoundToInt(top); |
| 304 *ibot = SkScalarRoundToInt(bot); | 307 *ibot = SkScalarRoundToInt(bot); |
| 305 return maxEdges; | 308 return maxEdges; |
| 306 } | 309 } |
| 307 | 310 |
| 311 static bool check_inverse_on_empty_return(SkRegion* dst, const SkPath& path, con
st SkRegion& clip) { |
| 312 if (path.isInverseFillType()) { |
| 313 return dst->set(clip); |
| 314 } else { |
| 315 return dst->setEmpty(); |
| 316 } |
| 317 } |
| 318 |
| 308 bool SkRegion::setPath(const SkPath& path, const SkRegion& clip) { | 319 bool SkRegion::setPath(const SkPath& path, const SkRegion& clip) { |
| 309 SkDEBUGCODE(this->validate();) | 320 SkDEBUGCODE(this->validate();) |
| 310 | 321 |
| 311 if (clip.isEmpty()) { | 322 if (clip.isEmpty()) { |
| 312 return this->setEmpty(); | 323 return this->setEmpty(); |
| 313 } | 324 } |
| 314 | 325 |
| 315 if (path.isEmpty()) { | 326 if (path.isEmpty()) { |
| 316 if (path.isInverseFillType()) { | 327 return check_inverse_on_empty_return(this, path, clip); |
| 317 return this->set(clip); | |
| 318 } else { | |
| 319 return this->setEmpty(); | |
| 320 } | |
| 321 } | 328 } |
| 322 | 329 |
| 323 // compute worst-case rgn-size for the path | 330 // compute worst-case rgn-size for the path |
| 324 int pathTop, pathBot; | 331 int pathTop, pathBot; |
| 325 int pathTransitions = count_path_runtype_values(path, &pathTop, &pathBot); | 332 int pathTransitions = count_path_runtype_values(path, &pathTop, &pathBot); |
| 333 if (0 == pathTransitions) { |
| 334 return check_inverse_on_empty_return(this, path, clip); |
| 335 } |
| 336 |
| 326 int clipTop, clipBot; | 337 int clipTop, clipBot; |
| 327 int clipTransitions; | 338 int clipTransitions = clip.count_runtype_values(&clipTop, &clipBot); |
| 328 | |
| 329 clipTransitions = clip.count_runtype_values(&clipTop, &clipBot); | |
| 330 | 339 |
| 331 int top = SkMax32(pathTop, clipTop); | 340 int top = SkMax32(pathTop, clipTop); |
| 332 int bot = SkMin32(pathBot, clipBot); | 341 int bot = SkMin32(pathBot, clipBot); |
| 333 | 342 if (top >= bot) { |
| 334 if (top >= bot) | 343 return check_inverse_on_empty_return(this, path, clip); |
| 335 return this->setEmpty(); | 344 } |
| 336 | 345 |
| 337 SkRgnBuilder builder; | 346 SkRgnBuilder builder; |
| 338 | 347 |
| 339 if (!builder.init(bot - top, | 348 if (!builder.init(bot - top, |
| 340 SkMax32(pathTransitions, clipTransitions), | 349 SkMax32(pathTransitions, clipTransitions), |
| 341 path.isInverseFillType())) { | 350 path.isInverseFillType())) { |
| 342 // can't allocate working space, so return false | 351 // can't allocate working space, so return false |
| 343 return this->setEmpty(); | 352 return this->setEmpty(); |
| 344 } | 353 } |
| 345 | 354 |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 518 #endif | 527 #endif |
| 519 | 528 |
| 520 path->incReserve(count << 1); | 529 path->incReserve(count << 1); |
| 521 do { | 530 do { |
| 522 SkASSERT(count > 1); | 531 SkASSERT(count > 1); |
| 523 count -= extract_path(start, stop, path); | 532 count -= extract_path(start, stop, path); |
| 524 } while (count > 0); | 533 } while (count > 0); |
| 525 | 534 |
| 526 return true; | 535 return true; |
| 527 } | 536 } |
| OLD | NEW |