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

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

Issue 1299243002: subdivide path when side-clipping fails (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: add init to avoid warning Created 5 years, 4 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 | « gm/cubicpaths.cpp ('k') | no next file » | 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 /* 2 /*
3 * Copyright 2009 The Android Open Source Project 3 * Copyright 2009 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 "SkEdgeClipper.h" 10 #include "SkEdgeClipper.h"
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after
263 } else { 263 } else {
264 // if chopMonoCubicAtY failed, then we may have hit inexact numerics 264 // if chopMonoCubicAtY failed, then we may have hit inexact numerics
265 // so we just clamp against the bottom 265 // so we just clamp against the bottom
266 for (int i = 0; i < 4; i++) { 266 for (int i = 0; i < 4; i++) {
267 clamp_le(pts[i].fY, clip.fBottom); 267 clamp_le(pts[i].fY, clip.fBottom);
268 } 268 }
269 } 269 }
270 } 270 }
271 } 271 }
272 272
273 static void chop_mono_cubic_at_x(SkPoint pts[4], SkScalar x, SkPoint tmp[7]) {
reed1 2015/08/20 14:24:45 perhaps rename pts -> src or orig tmp -> dst or ch
274 if (SkChopMonoCubicAtX(pts, x, tmp)) {
275 return;
276 }
277 SkScalar t = 0.5f;
278 SkScalar lastT;
279 SkScalar bestT SK_INIT_TO_AVOID_WARNING;
280 SkScalar step = 0.25f;
281 SkScalar D = pts[0].fX;
282 SkScalar A = pts[3].fX + 3*(pts[1].fX - pts[2].fX) - D;
283 SkScalar B = 3*(pts[2].fX - pts[1].fX - pts[1].fX + D);
284 SkScalar C = 3*(pts[1].fX - D);
285 x -= D;
286 SkScalar closest = SK_ScalarMax;
287 do {
288 SkScalar loc = ((A * t + B) * t + C) * t;
289 SkScalar dist = SkScalarAbs(loc - x);
290 if (closest > dist) {
291 closest = dist;
292 bestT = t;
293 }
294 lastT = t;
295 t += loc < x ? step : -step;
296 step *= 0.5f;
297 } while (closest > 0.25f && lastT != t);
298 SkChopCubicAt(pts, tmp, bestT);
299 }
300
273 // srcPts[] must be monotonic in X and Y 301 // srcPts[] must be monotonic in X and Y
274 void SkEdgeClipper::clipMonoCubic(const SkPoint src[4], const SkRect& clip) { 302 void SkEdgeClipper::clipMonoCubic(const SkPoint src[4], const SkRect& clip) {
275 SkPoint pts[4]; 303 SkPoint pts[4];
276 bool reverse = sort_increasing_Y(pts, src, 4); 304 bool reverse = sort_increasing_Y(pts, src, 4);
277 305
278 // are we completely above or below 306 // are we completely above or below
279 if (pts[3].fY <= clip.fTop || pts[0].fY >= clip.fBottom) { 307 if (pts[3].fY <= clip.fTop || pts[0].fY >= clip.fBottom) {
280 return; 308 return;
281 } 309 }
282 310
(...skipping 15 matching lines...) Expand all
298 if (pts[0].fX >= clip.fRight) { // wholly to the right 326 if (pts[0].fX >= clip.fRight) { // wholly to the right
299 if (!this->canCullToTheRight()) { 327 if (!this->canCullToTheRight()) {
300 this->appendVLine(clip.fRight, pts[0].fY, pts[3].fY, reverse); 328 this->appendVLine(clip.fRight, pts[0].fY, pts[3].fY, reverse);
301 } 329 }
302 return; 330 return;
303 } 331 }
304 332
305 // are we partially to the left 333 // are we partially to the left
306 if (pts[0].fX < clip.fLeft) { 334 if (pts[0].fX < clip.fLeft) {
307 SkPoint tmp[7]; 335 SkPoint tmp[7];
308 if (SkChopMonoCubicAtX(pts, clip.fLeft, tmp)) { 336 chop_mono_cubic_at_x(pts, clip.fLeft, tmp);
309 this->appendVLine(clip.fLeft, tmp[0].fY, tmp[3].fY, reverse); 337 this->appendVLine(clip.fLeft, tmp[0].fY, tmp[3].fY, reverse);
310 338
311 // tmp[3, 4].fX should all be to the right of clip.fLeft. 339 // tmp[3, 4].fX should all be to the right of clip.fLeft.
312 // Since we can't trust the numerics of 340 // Since we can't trust the numerics of
313 // the chopper, we force those conditions now 341 // the chopper, we force those conditions now
314 tmp[3].fX = clip.fLeft; 342 tmp[3].fX = clip.fLeft;
315 clamp_ge(tmp[4].fX, clip.fLeft); 343 clamp_ge(tmp[4].fX, clip.fLeft);
316 344
317 pts[0] = tmp[3]; 345 pts[0] = tmp[3];
318 pts[1] = tmp[4]; 346 pts[1] = tmp[4];
319 pts[2] = tmp[5]; 347 pts[2] = tmp[5];
320 } else {
321 // if chopMonocubicAtY failed, then we may have hit inexact numerics
322 // so we just clamp against the left
323 this->appendVLine(clip.fLeft, pts[0].fY, pts[3].fY, reverse);
324 return;
325 }
326 } 348 }
327 349
328 // are we partially to the right 350 // are we partially to the right
329 if (pts[3].fX > clip.fRight) { 351 if (pts[3].fX > clip.fRight) {
330 SkPoint tmp[7]; 352 SkPoint tmp[7];
331 if (SkChopMonoCubicAtX(pts, clip.fRight, tmp)) { 353 chop_mono_cubic_at_x(pts, clip.fRight, tmp);
332 tmp[3].fX = clip.fRight; 354 tmp[3].fX = clip.fRight;
333 clamp_le(tmp[2].fX, clip.fRight); 355 clamp_le(tmp[2].fX, clip.fRight);
334 356
335 this->appendCubic(tmp, reverse); 357 this->appendCubic(tmp, reverse);
336 this->appendVLine(clip.fRight, tmp[3].fY, tmp[6].fY, reverse); 358 this->appendVLine(clip.fRight, tmp[3].fY, tmp[6].fY, reverse);
337 } else {
338 // if chopMonoCubicAtX failed, then we may have hit inexact numerics
339 // so we just clamp against the right
340 this->appendVLine(clip.fRight, pts[0].fY, pts[3].fY, reverse);
341 }
342 } else { // wholly inside the clip 359 } else { // wholly inside the clip
343 this->appendCubic(pts, reverse); 360 this->appendCubic(pts, reverse);
344 } 361 }
345 } 362 }
346 363
347 bool SkEdgeClipper::clipCubic(const SkPoint srcPts[4], const SkRect& clip) { 364 bool SkEdgeClipper::clipCubic(const SkPoint srcPts[4], const SkRect& clip) {
348 fCurrPoint = fPoints; 365 fCurrPoint = fPoints;
349 fCurrVerb = fVerbs; 366 fCurrVerb = fVerbs;
350 367
351 SkRect bounds; 368 SkRect bounds;
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
464 assert_monotonic(&pts[0].fY, count); 481 assert_monotonic(&pts[0].fY, count);
465 } 482 }
466 } 483 }
467 484
468 void sk_assert_monotonic_x(const SkPoint pts[], int count) { 485 void sk_assert_monotonic_x(const SkPoint pts[], int count) {
469 if (count > 1) { 486 if (count > 1) {
470 assert_monotonic(&pts[0].fX, count); 487 assert_monotonic(&pts[0].fX, count);
471 } 488 }
472 } 489 }
473 #endif 490 #endif
OLDNEW
« no previous file with comments | « gm/cubicpaths.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698