| 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 "SkScan.h" | 10 #include "SkScan.h" |
| (...skipping 22 matching lines...) Expand all Loading... |
| 33 } while (++y < stopy); | 33 } while (++y < stopy); |
| 34 } | 34 } |
| 35 | 35 |
| 36 #ifdef SK_DEBUG | 36 #ifdef SK_DEBUG |
| 37 static bool canConvertFDot6ToFixed(SkFDot6 x) { | 37 static bool canConvertFDot6ToFixed(SkFDot6 x) { |
| 38 const int maxDot6 = SK_MaxS32 >> (16 - 6); | 38 const int maxDot6 = SK_MaxS32 >> (16 - 6); |
| 39 return SkAbs32(x) <= maxDot6; | 39 return SkAbs32(x) <= maxDot6; |
| 40 } | 40 } |
| 41 #endif | 41 #endif |
| 42 | 42 |
| 43 void SkScan::HairLineRgn(const SkPoint& pt0, const SkPoint& pt1, | 43 void SkScan::HairLineRgn(SkPoint pt0, SkPoint pt1, const SkRegion* clip, SkBlitt
er* blitter) { |
| 44 const SkRegion* clip, SkBlitter* blitter) { | |
| 45 SkBlitterClipper clipper; | 44 SkBlitterClipper clipper; |
| 46 SkRect r; | 45 SkRect r; |
| 47 SkIRect clipR, ptsR; | 46 SkIRect clipR, ptsR; |
| 48 SkPoint pts[2] = { pt0, pt1 }; | 47 SkPoint pts[2] = { pt0, pt1 }; |
| 49 | 48 |
| 50 // We have to pre-clip the line to fit in a SkFixed, so we just chop | 49 // We have to pre-clip the line to fit in a SkFixed, so we just chop |
| 51 // the line. TODO find a way to actually draw beyond that range. | 50 // the line. TODO find a way to actually draw beyond that range. |
| 52 { | 51 { |
| 53 SkRect fixedBounds; | 52 SkRect fixedBounds; |
| 54 const SkScalar max = SkIntToScalar(32767); | 53 const SkScalar max = SkIntToScalar(32767); |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 203 int idx = SkScalarCeilToInt(dx); | 202 int idx = SkScalarCeilToInt(dx); |
| 204 int idy = SkScalarCeilToInt(dy); | 203 int idy = SkScalarCeilToInt(dy); |
| 205 // use the cheap approx for distance | 204 // use the cheap approx for distance |
| 206 if (idx > idy) { | 205 if (idx > idy) { |
| 207 return idx + (idy >> 1); | 206 return idx + (idy >> 1); |
| 208 } else { | 207 } else { |
| 209 return idy + (idx >> 1); | 208 return idy + (idx >> 1); |
| 210 } | 209 } |
| 211 } | 210 } |
| 212 | 211 |
| 213 typedef void (*LineProc)(const SkPoint&, const SkPoint&, const SkRegion*, | 212 typedef void (*LineProc)(SkPoint, SkPoint, const SkRegion*, SkBlitter*); |
| 214 SkBlitter*); | |
| 215 | 213 |
| 216 static void hairquad(const SkPoint pts[3], const SkRegion* clip, | 214 static void hairquad(const SkPoint pts[3], const SkRegion* clip, |
| 217 SkBlitter* blitter, int level, LineProc lineproc) { | 215 SkBlitter* blitter, int level, LineProc lineproc) { |
| 218 if (level > 0) { | 216 if (level > 0) { |
| 219 SkPoint tmp[5]; | 217 SkPoint tmp[5]; |
| 220 | 218 |
| 221 SkChopQuadAtHalf(pts, tmp); | 219 SkChopQuadAtHalf(pts, tmp); |
| 222 hairquad(tmp, clip, blitter, level - 1, lineproc); | 220 hairquad(tmp, clip, blitter, level - 1, lineproc); |
| 223 hairquad(&tmp[2], clip, blitter, level - 1, lineproc); | 221 hairquad(&tmp[2], clip, blitter, level - 1, lineproc); |
| 224 } else { | 222 } else { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 250 than a pixel. | 248 than a pixel. |
| 251 */ | 249 */ |
| 252 int level = (33 - SkCLZ(d)) >> 1; | 250 int level = (33 - SkCLZ(d)) >> 1; |
| 253 // sanity check on level (from the previous version) | 251 // sanity check on level (from the previous version) |
| 254 if (level > kMaxQuadSubdivideLevel) { | 252 if (level > kMaxQuadSubdivideLevel) { |
| 255 level = kMaxQuadSubdivideLevel; | 253 level = kMaxQuadSubdivideLevel; |
| 256 } | 254 } |
| 257 return level; | 255 return level; |
| 258 } | 256 } |
| 259 | 257 |
| 260 static void hair_path(const SkPath& path, const SkRasterClip& rclip, | 258 static void hair_path(const SkPath& path, const SkRasterClip& rclip, SkBlitter*
blitter, |
| 261 SkBlitter* blitter, LineProc lineproc) { | 259 LineProc lineproc) { |
| 262 if (path.isEmpty()) { | 260 if (path.isEmpty()) { |
| 263 return; | 261 return; |
| 264 } | 262 } |
| 265 | 263 |
| 266 SkAAClipBlitterWrapper wrap; | 264 SkAAClipBlitterWrapper wrap; |
| 267 const SkRegion* clip = NULL; | 265 const SkRegion* clip = NULL; |
| 268 | 266 |
| 269 { | 267 { |
| 270 const SkIRect ibounds = path.getBounds().roundOut().makeOutset(1, 1); | 268 const SkIRect ibounds = path.getBounds().roundOut().makeOutset(1, 1); |
| 271 | 269 |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 314 haircubic(pts, clip, blitter, kMaxCubicSubdivideLevel, lineproc)
; | 312 haircubic(pts, clip, blitter, kMaxCubicSubdivideLevel, lineproc)
; |
| 315 break; | 313 break; |
| 316 case SkPath::kClose_Verb: | 314 case SkPath::kClose_Verb: |
| 317 break; | 315 break; |
| 318 case SkPath::kDone_Verb: | 316 case SkPath::kDone_Verb: |
| 319 break; | 317 break; |
| 320 } | 318 } |
| 321 } | 319 } |
| 322 } | 320 } |
| 323 | 321 |
| 324 void SkScan::HairPath(const SkPath& path, const SkRasterClip& clip, | 322 void SkScan::HairPath(const SkPath& path, const SkRasterClip& clip, SkBlitter* b
litter) { |
| 325 SkBlitter* blitter) { | |
| 326 hair_path(path, clip, blitter, SkScan::HairLineRgn); | 323 hair_path(path, clip, blitter, SkScan::HairLineRgn); |
| 327 } | 324 } |
| 328 | 325 |
| 329 void SkScan::AntiHairPath(const SkPath& path, const SkRasterClip& clip, | 326 void SkScan::AntiHairPath(const SkPath& path, const SkRasterClip& clip, SkBlitte
r* blitter) { |
| 330 SkBlitter* blitter) { | |
| 331 hair_path(path, clip, blitter, SkScan::AntiHairLineRgn); | 327 hair_path(path, clip, blitter, SkScan::AntiHairLineRgn); |
| 332 } | 328 } |
| 333 | 329 |
| 334 /////////////////////////////////////////////////////////////////////////////// | 330 /////////////////////////////////////////////////////////////////////////////// |
| 335 | 331 |
| 336 void SkScan::FrameRect(const SkRect& r, const SkPoint& strokeSize, | 332 void SkScan::FrameRect(const SkRect& r, const SkPoint& strokeSize, |
| 337 const SkRasterClip& clip, SkBlitter* blitter) { | 333 const SkRasterClip& clip, SkBlitter* blitter) { |
| 338 SkASSERT(strokeSize.fX >= 0 && strokeSize.fY >= 0); | 334 SkASSERT(strokeSize.fX >= 0 && strokeSize.fY >= 0); |
| 339 | 335 |
| 340 if (strokeSize.fX < 0 || strokeSize.fY < 0) { | 336 if (strokeSize.fX < 0 || strokeSize.fY < 0) { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 361 tmp.fBottom = outer.fBottom; | 357 tmp.fBottom = outer.fBottom; |
| 362 SkScan::FillRect(tmp, clip, blitter); | 358 SkScan::FillRect(tmp, clip, blitter); |
| 363 | 359 |
| 364 tmp.set(outer.fLeft, outer.fTop + dy, outer.fLeft + dx, outer.fBottom - dy); | 360 tmp.set(outer.fLeft, outer.fTop + dy, outer.fLeft + dx, outer.fBottom - dy); |
| 365 SkScan::FillRect(tmp, clip, blitter); | 361 SkScan::FillRect(tmp, clip, blitter); |
| 366 tmp.fLeft = outer.fRight - dx; | 362 tmp.fLeft = outer.fRight - dx; |
| 367 tmp.fRight = outer.fRight; | 363 tmp.fRight = outer.fRight; |
| 368 SkScan::FillRect(tmp, clip, blitter); | 364 SkScan::FillRect(tmp, clip, blitter); |
| 369 } | 365 } |
| 370 | 366 |
| 371 void SkScan::HairLine(const SkPoint& p0, const SkPoint& p1, | 367 void SkScan::HairLine(SkPoint p0, SkPoint p1, const SkRasterClip& clip, SkBlitte
r* blitter) { |
| 372 const SkRasterClip& clip, SkBlitter* blitter) { | |
| 373 if (clip.isBW()) { | 368 if (clip.isBW()) { |
| 374 HairLineRgn(p0, p1, &clip.bwRgn(), blitter); | 369 HairLineRgn(p0, p1, &clip.bwRgn(), blitter); |
| 375 } else { | 370 } else { |
| 376 const SkRegion* clipRgn = NULL; | 371 const SkRegion* clipRgn = NULL; |
| 377 SkRect r; | 372 SkRect r; |
| 378 r.set(p0.fX, p0.fY, p1.fX, p1.fY); | 373 r.set(p0.fX, p0.fY, p1.fX, p1.fY); |
| 379 r.sort(); | 374 r.sort(); |
| 380 r.outset(SK_ScalarHalf, SK_ScalarHalf); | 375 r.outset(SK_ScalarHalf, SK_ScalarHalf); |
| 381 | 376 |
| 382 SkAAClipBlitterWrapper wrap; | 377 SkAAClipBlitterWrapper wrap; |
| 383 if (!clip.quickContains(r.roundOut())) { | 378 if (!clip.quickContains(r.roundOut())) { |
| 384 wrap.init(clip, blitter); | 379 wrap.init(clip, blitter); |
| 385 blitter = wrap.getBlitter(); | 380 blitter = wrap.getBlitter(); |
| 386 clipRgn = &wrap.getRgn(); | 381 clipRgn = &wrap.getRgn(); |
| 387 } | 382 } |
| 388 HairLineRgn(p0, p1, clipRgn, blitter); | 383 HairLineRgn(p0, p1, clipRgn, blitter); |
| 389 } | 384 } |
| 390 } | 385 } |
| 391 | 386 |
| 392 void SkScan::AntiHairLine(const SkPoint& p0, const SkPoint& p1, | 387 void SkScan::AntiHairLine(SkPoint p0, SkPoint p1, const SkRasterClip& clip, SkBl
itter* blitter) { |
| 393 const SkRasterClip& clip, SkBlitter* blitter) { | |
| 394 if (clip.isBW()) { | 388 if (clip.isBW()) { |
| 395 AntiHairLineRgn(p0, p1, &clip.bwRgn(), blitter); | 389 AntiHairLineRgn(p0, p1, &clip.bwRgn(), blitter); |
| 396 } else { | 390 } else { |
| 397 const SkRegion* clipRgn = NULL; | 391 const SkRegion* clipRgn = NULL; |
| 398 SkRect r; | 392 SkRect r; |
| 399 r.set(p0.fX, p0.fY, p1.fX, p1.fY); | 393 r.set(p0.fX, p0.fY, p1.fX, p1.fY); |
| 400 r.sort(); | 394 r.sort(); |
| 401 | 395 |
| 402 SkAAClipBlitterWrapper wrap; | 396 SkAAClipBlitterWrapper wrap; |
| 403 if (!clip.quickContains(r.roundOut().makeOutset(1, 1))) { | 397 if (!clip.quickContains(r.roundOut().makeOutset(1, 1))) { |
| 404 wrap.init(clip, blitter); | 398 wrap.init(clip, blitter); |
| 405 blitter = wrap.getBlitter(); | 399 blitter = wrap.getBlitter(); |
| 406 clipRgn = &wrap.getRgn(); | 400 clipRgn = &wrap.getRgn(); |
| 407 } | 401 } |
| 408 AntiHairLineRgn(p0, p1, clipRgn, blitter); | 402 AntiHairLineRgn(p0, p1, clipRgn, blitter); |
| 409 } | 403 } |
| 410 } | 404 } |
| OLD | NEW |