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

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

Issue 1008883002: Handle paths that do not report empty, but have no edges. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: fix uninit warning? Created 5 years, 9 months 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
« no previous file with comments | « no previous file | tests/CanvasTest.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | tests/CanvasTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698