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 |