1
2 /*
3 * Copyright 2006 The Android Open Source Project
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9
10 #include "SkScanPriv.h"
11 #include "SkPath.h"
12 #include "SkMatrix.h"
13 #include "SkBlitter.h"
14 #include "SkRegion.h"
15 #include "SkAntiRun.h"
16
17 #define SHIFT 2
18 #define SCALE (1 << SHIFT)
19 #define MASK (SCALE - 1)
20
21 /** @file
22 We have two techniques for capturing the output of the supersampler:
23 - SUPERMASK, which records a large mask-bitmap
24 this is often faster for small, complex objects
25 - RLE, which records a rle-encoded scanline
26 this is often faster for large objects with big spans
27
28 These blitters use two coordinate systems:
29 - destination coordinates, scale equal to the output - often
30 abbreviated with 'i' or 'I' in variable names
31 - supersampled coordinates, scale equal to the output * SCALE
32
33 NEW_AA is a set of code-changes to try to make both paths produce identical
34 results. Its not quite there yet, though the remaining differences may be
35 in the subsequent blits, and not in the different masks/runs...
36
37 SK_USE_EXACT_COVERAGE makes coverage_to_partial_alpha() behave similarly to
38 coverage_to_exact_alpha(). Enabling it will requrie rebaselining about 1/3
39 of GMs for changes in the 3 least significant bits along the edges of
40 antialiased spans.
41 */
42 //#define FORCE_SUPERMASK
43 //#define FORCE_RLE
44 //#define SK_SUPPORT_NEW_AA
45 //#define SK_USE_EXACT_COVERAGE
46
47 ///////////////////////////////////////////////////////////////////////////////
48
49 /// Base class for a single-pass supersampled blitter.
50 class BaseSuperBlitter : public SkBlitter {
51 public:
52 BaseSuperBlitter(SkBlitter* realBlitter, const SkIRect& ir,
53 const SkRegion& clip);
54
55 /// Must be explicitly defined on subclasses.
blitAntiH(int x,int y,const SkAlpha antialias[],const int16_t runs[])56 virtual void blitAntiH(int x, int y, const SkAlpha antialias[],
57 const int16_t runs[]) SK_OVERRIDE {
58 SkDEBUGFAIL("How did I get here?");
59 }
60 /// May not be called on BaseSuperBlitter because it blits out of order.
blitV(int x,int y,int height,SkAlpha alpha)61 virtual void blitV(int x, int y, int height, SkAlpha alpha) SK_OVERRIDE {
62 SkDEBUGFAIL("How did I get here?");
63 }
64
65 protected:
66 SkBlitter* fRealBlitter;
67 /// Current y coordinate, in destination coordinates.
68 int fCurrIY;
69 /// Widest row of region to be blitted, in destination coordinates.
70 int fWidth;
71 /// Leftmost x coordinate in any row, in destination coordinates.
72 int fLeft;
73 /// Leftmost x coordinate in any row, in supersampled coordinates.
74 int fSuperLeft;
75
76 SkDEBUGCODE(int fCurrX;)
77 /// Current y coordinate in supersampled coordinates.
78 int fCurrY;
79 /// Initial y coordinate (top of bounds).
80 int fTop;
81 };
82
BaseSuperBlitter(SkBlitter * realBlitter,const SkIRect & ir,const SkRegion & clip)83 BaseSuperBlitter::BaseSuperBlitter(SkBlitter* realBlitter, const SkIRect& ir,
84 const SkRegion& clip) {
85 fRealBlitter = realBlitter;
86
87 /*
88 * We use the clip bounds instead of the ir, since we may be asked to
89 * draw outside of the rect if we're a inverse filltype
90 */
91 const int left = clip.getBounds().fLeft;
92 const int right = clip.getBounds().fRight;
93
94 fLeft = left;
95 fSuperLeft = left << SHIFT;
96 fWidth = right - left;
97 #if 0
98 fCurrIY = -1;
99 fCurrY = -1;
100 #else
101 fTop = ir.fTop;
102 fCurrIY = ir.fTop - 1;
103 fCurrY = (ir.fTop << SHIFT) - 1;
104 #endif
105 SkDEBUGCODE(fCurrX = -1;)
106 }
107
108 /// Run-length-encoded supersampling antialiased blitter.
109 class SuperBlitter : public BaseSuperBlitter {
110 public:
111 SuperBlitter(SkBlitter* realBlitter, const SkIRect& ir,
112 const SkRegion& clip);
113
~SuperBlitter()114 virtual ~SuperBlitter() {
115 this->flush();
116 sk_free(fRuns.fRuns);
117 }
118
119 /// Once fRuns contains a complete supersampled row, flush() blits
120 /// it out through the wrapped blitter.
121 void flush();
122
123 /// Blits a row of pixels, with location and width specified
124 /// in supersampled coordinates.
125 virtual void blitH(int x, int y, int width) SK_OVERRIDE;
126 /// Blits a rectangle of pixels, with location and size specified
127 /// in supersampled coordinates.
128 virtual void blitRect(int x, int y, int width, int height) SK_OVERRIDE;
129
130 private:
131 SkAlphaRuns fRuns;
132 int fOffsetX;
133 };
134
SuperBlitter(SkBlitter * realBlitter,const SkIRect & ir,const SkRegion & clip)135 SuperBlitter::SuperBlitter(SkBlitter* realBlitter, const SkIRect& ir,
136 const SkRegion& clip)
137 : BaseSuperBlitter(realBlitter, ir, clip) {
138 const int width = fWidth;
139
140 // extra one to store the zero at the end
141 fRuns.fRuns = (int16_t*)sk_malloc_throw((width + 1 + (width + 2)/2) * sizeof(int16_t));
142 fRuns.fAlpha = (uint8_t*)(fRuns.fRuns + width + 1);
143 fRuns.reset(width);
144
145 fOffsetX = 0;
146 }
147
flush()148 void SuperBlitter::flush() {
149 if (fCurrIY >= fTop) {
150 if (!fRuns.empty()) {
151 // SkDEBUGCODE(fRuns.dump();)
152 fRealBlitter->blitAntiH(fLeft, fCurrIY, fRuns.fAlpha, fRuns.fRuns);
153 fRuns.reset(fWidth);
154 fOffsetX = 0;
155 }
156 fCurrIY = fTop - 1;
157 SkDEBUGCODE(fCurrX = -1;)
158 }
159 }
160
161 /** coverage_to_partial_alpha() is being used by SkAlphaRuns, which
162 *accumulates* SCALE pixels worth of "alpha" in [0,(256/SCALE)]
163 to produce a final value in [0, 255] and handles clamping 256->255
164 itself, with the same (alpha - (alpha >> 8)) correction as
165 coverage_to_exact_alpha().
166 */
coverage_to_partial_alpha(int aa)167 static inline int coverage_to_partial_alpha(int aa) {
168 #ifdef SK_USE_EXACT_COVERAGE
169 return aa << (8 - 2 * SHIFT);
170 #else
171 aa <<= 8 - 2*SHIFT;
172 aa -= aa >> (8 - SHIFT - 1);
173 return aa;
174 #endif
175 }
176
177 /** coverage_to_exact_alpha() is being used by our blitter, which wants
178 a final value in [0, 255].
179 */
coverage_to_exact_alpha(int aa)180 static inline int coverage_to_exact_alpha(int aa) {
181 int alpha = (256 >> SHIFT) * aa;
182 // clamp 256->255
183 return alpha - (alpha >> 8);
184 }
185
blitH(int x,int y,int width)186 void SuperBlitter::blitH(int x, int y, int width) {
187 SkASSERT(width > 0);
188
189 int iy = y >> SHIFT;
190 SkASSERT(iy >= fCurrIY);
191
192 x -= fSuperLeft;
193 // hack, until I figure out why my cubics (I think) go beyond the bounds
194 if (x < 0) {
195 width += x;
196 x = 0;
197 }
198
199 #ifdef SK_DEBUG
200 SkASSERT(y != fCurrY || x >= fCurrX);
201 #endif
202 SkASSERT(y >= fCurrY);
203 if (fCurrY != y) {
204 fOffsetX = 0;
205 fCurrY = y;
206 }
207
208 if (iy != fCurrIY) { // new scanline
209 this->flush();
210 fCurrIY = iy;
211 }
212
213 int start = x;
214 int stop = x + width;
215
216 SkASSERT(start >= 0 && stop > start);
217 // integer-pixel-aligned ends of blit, rounded out
218 int fb = start & MASK;
219 int fe = stop & MASK;
220 int n = (stop >> SHIFT) - (start >> SHIFT) - 1;
221
222 if (n < 0) {
223 fb = fe - fb;
224 n = 0;
225 fe = 0;
226 } else {
227 if (fb == 0) {
228 n += 1;
229 } else {
230 fb = SCALE - fb;
231 }
232 }
233
234 fOffsetX = fRuns.add(x >> SHIFT, coverage_to_partial_alpha(fb),
235 n, coverage_to_partial_alpha(fe),
236 (1 << (8 - SHIFT)) - (((y & MASK) + 1) >> SHIFT),
237 fOffsetX);
238
239 #ifdef SK_DEBUG
240 fRuns.assertValid(y & MASK, (1 << (8 - SHIFT)));
241 fCurrX = x + width;
242 #endif
243 }
244
set_left_rite_runs(SkAlphaRuns & runs,int ileft,U8CPU leftA,int n,U8CPU riteA)245 static void set_left_rite_runs(SkAlphaRuns& runs, int ileft, U8CPU leftA,
246 int n, U8CPU riteA) {
247 SkASSERT(leftA <= 0xFF);
248 SkASSERT(riteA <= 0xFF);
249
250 int16_t* run = runs.fRuns;
251 uint8_t* aa = runs.fAlpha;
252
253 if (ileft > 0) {
254 run[0] = ileft;
255 aa[0] = 0;
256 run += ileft;
257 aa += ileft;
258 }
259
260 SkASSERT(leftA < 0xFF);
261 if (leftA > 0) {
262 *run++ = 1;
263 *aa++ = leftA;
264 }
265
266 if (n > 0) {
267 run[0] = n;
268 aa[0] = 0xFF;
269 run += n;
270 aa += n;
271 }
272
273 SkASSERT(riteA < 0xFF);
274 if (riteA > 0) {
275 *run++ = 1;
276 *aa++ = riteA;
277 }
278 run[0] = 0;
279 }
280
blitRect(int x,int y,int width,int height)281 void SuperBlitter::blitRect(int x, int y, int width, int height) {
282 SkASSERT(width > 0);
283 SkASSERT(height > 0);
284
285 // blit leading rows
286 while ((y & MASK)) {
287 this->blitH(x, y++, width);
288 if (--height <= 0) {
289 return;
290 }
291 }
292 SkASSERT(height > 0);
293
294 // Since this is a rect, instead of blitting supersampled rows one at a
295 // time and then resolving to the destination canvas, we can blit
296 // directly to the destintion canvas one row per SCALE supersampled rows.
297 int start_y = y >> SHIFT;
298 int stop_y = (y + height) >> SHIFT;
299 int count = stop_y - start_y;
300 if (count > 0) {
301 y += count << SHIFT;
302 height -= count << SHIFT;
303
304 // save original X for our tail blitH() loop at the bottom
305 int origX = x;
306
307 x -= fSuperLeft;
308 // hack, until I figure out why my cubics (I think) go beyond the bounds
309 if (x < 0) {
310 width += x;
311 x = 0;
312 }
313
314 // There is always a left column, a middle, and a right column.
315 // ileft is the destination x of the first pixel of the entire rect.
316 // xleft is (SCALE - # of covered supersampled pixels) in that
317 // destination pixel.
318 int ileft = x >> SHIFT;
319 int xleft = x & MASK;
320 // irite is the destination x of the last pixel of the OPAQUE section.
321 // xrite is the number of supersampled pixels extending beyond irite;
322 // xrite/SCALE should give us alpha.
323 int irite = (x + width) >> SHIFT;
324 int xrite = (x + width) & MASK;
325 if (!xrite) {
326 xrite = SCALE;
327 irite--;
328 }
329
330 // Need to call flush() to clean up pending draws before we
331 // even consider blitV(), since otherwise it can look nonmonotonic.
332 SkASSERT(start_y > fCurrIY);
333 this->flush();
334
335 int n = irite - ileft - 1;
336 if (n < 0) {
337 // If n < 0, we'll only have a single partially-transparent column
338 // of pixels to render.
339 xleft = xrite - xleft;
340 SkASSERT(xleft <= SCALE);
341 SkASSERT(xleft > 0);
342 xrite = 0;
343 fRealBlitter->blitV(ileft + fLeft, start_y, count,
344 coverage_to_exact_alpha(xleft));
345 } else {
346 // With n = 0, we have two possibly-transparent columns of pixels
347 // to render; with n > 0, we have opaque columns between them.
348
349 xleft = SCALE - xleft;
350
351 // Using coverage_to_exact_alpha is not consistent with blitH()
352 const int coverageL = coverage_to_exact_alpha(xleft);
353 const int coverageR = coverage_to_exact_alpha(xrite);
354
355 SkASSERT(coverageL > 0 || n > 0 || coverageR > 0);
356 SkASSERT((coverageL != 0) + n + (coverageR != 0) <= fWidth);
357
358 fRealBlitter->blitAntiRect(ileft + fLeft, start_y, n, count,
359 coverageL, coverageR);
360 }
361
362 // preamble for our next call to blitH()
363 fCurrIY = stop_y - 1;
364 fOffsetX = 0;
365 fCurrY = y - 1;
366 fRuns.reset(fWidth);
367 x = origX;
368 }
369
370 // catch any remaining few rows
371 SkASSERT(height <= MASK);
372 while (--height >= 0) {
373 this->blitH(x, y++, width);
374 }
375 }
376
377 ///////////////////////////////////////////////////////////////////////////////
378
379 /// Masked supersampling antialiased blitter.
380 class MaskSuperBlitter : public BaseSuperBlitter {
381 public:
382 MaskSuperBlitter(SkBlitter* realBlitter, const SkIRect& ir,
383 const SkRegion& clip);
~MaskSuperBlitter()384 virtual ~MaskSuperBlitter() {
385 fRealBlitter->blitMask(fMask, fClipRect);
386 }
387
388 virtual void blitH(int x, int y, int width) SK_OVERRIDE;
389
CanHandleRect(const SkIRect & bounds)390 static bool CanHandleRect(const SkIRect& bounds) {
391 #ifdef FORCE_RLE
392 return false;
393 #endif
394 int width = bounds.width();
395 int64_t rb = SkAlign4(width);
396 // use 64bits to detect overflow
397 int64_t storage = rb * bounds.height();
398
399 return (width <= MaskSuperBlitter::kMAX_WIDTH) &&
400 (storage <= MaskSuperBlitter::kMAX_STORAGE);
401 }
402
403 private:
404 enum {
405 #ifdef FORCE_SUPERMASK
406 kMAX_WIDTH = 2048,
407 kMAX_STORAGE = 1024 * 1024 * 2
408 #else
409 kMAX_WIDTH = 32, // so we don't try to do very wide things, where the RLE blitter would be faster
410 kMAX_STORAGE = 1024
411 #endif
412 };
413
414 SkMask fMask;
415 SkIRect fClipRect;
416 // we add 1 because add_aa_span can write (unchanged) 1 extra byte at the end, rather than
417 // perform a test to see if stopAlpha != 0
418 uint32_t fStorage[(kMAX_STORAGE >> 2) + 1];
419 };
420
MaskSuperBlitter(SkBlitter * realBlitter,const SkIRect & ir,const SkRegion & clip)421 MaskSuperBlitter::MaskSuperBlitter(SkBlitter* realBlitter, const SkIRect& ir,
422 const SkRegion& clip)
423 : BaseSuperBlitter(realBlitter, ir, clip) {
424 SkASSERT(CanHandleRect(ir));
425
426 fMask.fImage = (uint8_t*)fStorage;
427 fMask.fBounds = ir;
428 fMask.fRowBytes = ir.width();
429 fMask.fFormat = SkMask::kA8_Format;
430
431 fClipRect = ir;
432 fClipRect.intersect(clip.getBounds());
433
434 // For valgrind, write 1 extra byte at the end so we don't read
435 // uninitialized memory. See comment in add_aa_span and fStorage[].
436 memset(fStorage, 0, fMask.fBounds.height() * fMask.fRowBytes + 1);
437 }
438
add_aa_span(uint8_t * alpha,U8CPU startAlpha)439 static void add_aa_span(uint8_t* alpha, U8CPU startAlpha) {
440 /* I should be able to just add alpha[x] + startAlpha.
441 However, if the trailing edge of the previous span and the leading
442 edge of the current span round to the same super-sampled x value,
443 I might overflow to 256 with this add, hence the funny subtract.
444 */
445 unsigned tmp = *alpha + startAlpha;
446 SkASSERT(tmp <= 256);
447 *alpha = SkToU8(tmp - (tmp >> 8));
448 }
449
quadplicate_byte(U8CPU value)450 static inline uint32_t quadplicate_byte(U8CPU value) {
451 uint32_t pair = (value << 8) | value;
452 return (pair << 16) | pair;
453 }
454
455 // minimum count before we want to setup an inner loop, adding 4-at-a-time
456 #define MIN_COUNT_FOR_QUAD_LOOP 16
457
add_aa_span(uint8_t * alpha,U8CPU startAlpha,int middleCount,U8CPU stopAlpha,U8CPU maxValue)458 static void add_aa_span(uint8_t* alpha, U8CPU startAlpha, int middleCount,
459 U8CPU stopAlpha, U8CPU maxValue) {
460 SkASSERT(middleCount >= 0);
461
462 /* I should be able to just add alpha[x] + startAlpha.
463 However, if the trailing edge of the previous span and the leading
464 edge of the current span round to the same super-sampled x value,
465 I might overflow to 256 with this add, hence the funny subtract.
466 */
467 #ifdef SK_SUPPORT_NEW_AA
468 if (startAlpha) {
469 unsigned tmp = *alpha + startAlpha;
470 SkASSERT(tmp <= 256);
471 *alpha++ = SkToU8(tmp - (tmp >> 8));
472 }
473 #else
474 unsigned tmp = *alpha + startAlpha;
475 SkASSERT(tmp <= 256);
476 *alpha++ = SkToU8(tmp - (tmp >> 8));
477 #endif
478
479 if (middleCount >= MIN_COUNT_FOR_QUAD_LOOP) {
480 // loop until we're quad-byte aligned
481 while (SkTCast<intptr_t>(alpha) & 0x3) {
482 alpha[0] = SkToU8(alpha[0] + maxValue);
483 alpha += 1;
484 middleCount -= 1;
485 }
486
487 int bigCount = middleCount >> 2;
488 uint32_t* qptr = reinterpret_cast<uint32_t*>(alpha);
489 uint32_t qval = quadplicate_byte(maxValue);
490 do {
491 *qptr++ += qval;
492 } while (--bigCount > 0);
493
494 middleCount &= 3;
495 alpha = reinterpret_cast<uint8_t*> (qptr);
496 // fall through to the following while-loop
497 }
498
499 while (--middleCount >= 0) {
500 alpha[0] = SkToU8(alpha[0] + maxValue);
501 alpha += 1;
502 }
503
504 // potentially this can be off the end of our "legal" alpha values, but that
505 // only happens if stopAlpha is also 0. Rather than test for stopAlpha != 0
506 // every time (slow), we just do it, and ensure that we've allocated extra space
507 // (see the + 1 comment in fStorage[]
508 *alpha = SkToU8(*alpha + stopAlpha);
509 }
510
blitH(int x,int y,int width)511 void MaskSuperBlitter::blitH(int x, int y, int width) {
512 int iy = (y >> SHIFT);
513
514 SkASSERT(iy >= fMask.fBounds.fTop && iy < fMask.fBounds.fBottom);
515 iy -= fMask.fBounds.fTop; // make it relative to 0
516
517 // This should never happen, but it does. Until the true cause is
518 // discovered, let's skip this span instead of crashing.
519 // See http://crbug.com/17569.
520 if (iy < 0) {
521 return;
522 }
523
524 #ifdef SK_DEBUG
525 {
526 int ix = x >> SHIFT;
527 SkASSERT(ix >= fMask.fBounds.fLeft && ix < fMask.fBounds.fRight);
528 }
529 #endif
530
531 x -= (fMask.fBounds.fLeft << SHIFT);
532
533 // hack, until I figure out why my cubics (I think) go beyond the bounds
534 if (x < 0) {
535 width += x;
536 x = 0;
537 }
538
539 uint8_t* row = fMask.fImage + iy * fMask.fRowBytes + (x >> SHIFT);
540
541 int start = x;
542 int stop = x + width;
543
544 SkASSERT(start >= 0 && stop > start);
545 int fb = start & MASK;
546 int fe = stop & MASK;
547 int n = (stop >> SHIFT) - (start >> SHIFT) - 1;
548
549
550 if (n < 0) {
551 SkASSERT(row >= fMask.fImage);
552 SkASSERT(row < fMask.fImage + kMAX_STORAGE + 1);
553 add_aa_span(row, coverage_to_partial_alpha(fe - fb));
554 } else {
555 #ifdef SK_SUPPORT_NEW_AA
556 if (0 == fb) {
557 n += 1;
558 } else {
559 fb = SCALE - fb;
560 }
561 #else
562 fb = SCALE - fb;
563 #endif
564 SkASSERT(row >= fMask.fImage);
565 SkASSERT(row + n + 1 < fMask.fImage + kMAX_STORAGE + 1);
566 add_aa_span(row, coverage_to_partial_alpha(fb),
567 n, coverage_to_partial_alpha(fe),
568 (1 << (8 - SHIFT)) - (((y & MASK) + 1) >> SHIFT));
569 }
570
571 #ifdef SK_DEBUG
572 fCurrX = x + width;
573 #endif
574 }
575
576 ///////////////////////////////////////////////////////////////////////////////
577
fitsInsideLimit(const SkRect & r,SkScalar max)578 static bool fitsInsideLimit(const SkRect& r, SkScalar max) {
579 const SkScalar min = -max;
580 return r.fLeft > min && r.fTop > min &&
581 r.fRight < max && r.fBottom < max;
582 }
583
overflows_short_shift(int value,int shift)584 static int overflows_short_shift(int value, int shift) {
585 const int s = 16 + shift;
586 return (value << s >> s) - value;
587 }
588
589 /**
590 Would any of the coordinates of this rectangle not fit in a short,
591 when left-shifted by shift?
592 */
rect_overflows_short_shift(SkIRect rect,int shift)593 static int rect_overflows_short_shift(SkIRect rect, int shift) {
594 SkASSERT(!overflows_short_shift(8191, SHIFT));
595 SkASSERT(overflows_short_shift(8192, SHIFT));
596 SkASSERT(!overflows_short_shift(32767, 0));
597 SkASSERT(overflows_short_shift(32768, 0));
598
599 // Since we expect these to succeed, we bit-or together
600 // for a tiny extra bit of speed.
601 return overflows_short_shift(rect.fLeft, SHIFT) |
602 overflows_short_shift(rect.fRight, SHIFT) |
603 overflows_short_shift(rect.fTop, SHIFT) |
604 overflows_short_shift(rect.fBottom, SHIFT);
605 }
606
safeRoundOut(const SkRect & src,SkIRect * dst,int32_t maxInt)607 static bool safeRoundOut(const SkRect& src, SkIRect* dst, int32_t maxInt) {
608 #ifdef SK_SCALAR_IS_FIXED
609 // the max-int (shifted) is exactly what we want to compare against, to know
610 // if we can survive shifting our fixed-point coordinates
611 const SkFixed maxScalar = maxInt;
612 #else
613 const SkScalar maxScalar = SkIntToScalar(maxInt);
614 #endif
615 if (fitsInsideLimit(src, maxScalar)) {
616 src.roundOut(dst);
617 return true;
618 }
619 return false;
620 }
621
AntiFillPath(const SkPath & path,const SkRegion & origClip,SkBlitter * blitter,bool forceRLE)622 void SkScan::AntiFillPath(const SkPath& path, const SkRegion& origClip,
623 SkBlitter* blitter, bool forceRLE) {
624 if (origClip.isEmpty()) {
625 return;
626 }
627
628 SkIRect ir;
629
630 if (!safeRoundOut(path.getBounds(), &ir, SK_MaxS32 >> SHIFT)) {
631 #if 0
632 const SkRect& r = path.getBounds();
633 SkDebugf("--- bounds can't fit in SkIRect\n", r.fLeft, r.fTop, r.fRight, r.fBottom);
634 #endif
635 return;
636 }
637 if (ir.isEmpty()) {
638 if (path.isInverseFillType()) {
639 blitter->blitRegion(origClip);
640 }
641 return;
642 }
643
644 // If the intersection of the path bounds and the clip bounds
645 // will overflow 32767 when << by SHIFT, we can't supersample,
646 // so draw without antialiasing.
647 SkIRect clippedIR;
648 if (path.isInverseFillType()) {
649 // If the path is an inverse fill, it's going to fill the entire
650 // clip, and we care whether the entire clip exceeds our limits.
651 clippedIR = origClip.getBounds();
652 } else {
653 if (!clippedIR.intersect(ir, origClip.getBounds())) {
654 return;
655 }
656 }
657 if (rect_overflows_short_shift(clippedIR, SHIFT)) {
658 SkScan::FillPath(path, origClip, blitter);
659 return;
660 }
661
662 // Our antialiasing can't handle a clip larger than 32767, so we restrict
663 // the clip to that limit here. (the runs[] uses int16_t for its index).
664 //
665 // A more general solution (one that could also eliminate the need to
666 // disable aa based on ir bounds (see overflows_short_shift) would be
667 // to tile the clip/target...
668 SkRegion tmpClipStorage;
669 const SkRegion* clipRgn = &origClip;
670 {
671 static const int32_t kMaxClipCoord = 32767;
672 const SkIRect& bounds = origClip.getBounds();
673 if (bounds.fRight > kMaxClipCoord || bounds.fBottom > kMaxClipCoord) {
674 SkIRect limit = { 0, 0, kMaxClipCoord, kMaxClipCoord };
675 tmpClipStorage.op(origClip, limit, SkRegion::kIntersect_Op);
676 clipRgn = &tmpClipStorage;
677 }
678 }
679 // for here down, use clipRgn, not origClip
680
681 SkScanClipper clipper(blitter, clipRgn, ir);
682 const SkIRect* clipRect = clipper.getClipRect();
683
684 if (clipper.getBlitter() == NULL) { // clipped out
685 if (path.isInverseFillType()) {
686 blitter->blitRegion(*clipRgn);
687 }
688 return;
689 }
690
691 // now use the (possibly wrapped) blitter
692 blitter = clipper.getBlitter();
693
694 if (path.isInverseFillType()) {
695 sk_blit_above(blitter, ir, *clipRgn);
696 }
697
698 SkIRect superRect, *superClipRect = NULL;
699
700 if (clipRect) {
701 superRect.set( clipRect->fLeft << SHIFT, clipRect->fTop << SHIFT,
702 clipRect->fRight << SHIFT, clipRect->fBottom << SHIFT);
703 superClipRect = &superRect;
704 }
705
706 SkASSERT(SkIntToScalar(ir.fTop) <= path.getBounds().fTop);
707
708 // MaskSuperBlitter can't handle drawing outside of ir, so we can't use it
709 // if we're an inverse filltype
710 if (!path.isInverseFillType() && MaskSuperBlitter::CanHandleRect(ir) && !forceRLE) {
711 MaskSuperBlitter superBlit(blitter, ir, *clipRgn);
712 SkASSERT(SkIntToScalar(ir.fTop) <= path.getBounds().fTop);
713 sk_fill_path(path, superClipRect, &superBlit, ir.fTop, ir.fBottom, SHIFT, *clipRgn);
714 } else {
715 SuperBlitter superBlit(blitter, ir, *clipRgn);
716 sk_fill_path(path, superClipRect, &superBlit, ir.fTop, ir.fBottom, SHIFT, *clipRgn);
717 }
718
719 if (path.isInverseFillType()) {
720 sk_blit_below(blitter, ir, *clipRgn);
721 }
722 }
723
724 ///////////////////////////////////////////////////////////////////////////////
725
726 #include "SkRasterClip.h"
727
FillPath(const SkPath & path,const SkRasterClip & clip,SkBlitter * blitter)728 void SkScan::FillPath(const SkPath& path, const SkRasterClip& clip,
729 SkBlitter* blitter) {
730 if (clip.isEmpty()) {
731 return;
732 }
733
734 if (clip.isBW()) {
735 FillPath(path, clip.bwRgn(), blitter);
736 } else {
737 SkRegion tmp;
738 SkAAClipBlitter aaBlitter;
739
740 tmp.setRect(clip.getBounds());
741 aaBlitter.init(blitter, &clip.aaRgn());
742 SkScan::FillPath(path, tmp, &aaBlitter);
743 }
744 }
745
AntiFillPath(const SkPath & path,const SkRasterClip & clip,SkBlitter * blitter)746 void SkScan::AntiFillPath(const SkPath& path, const SkRasterClip& clip,
747 SkBlitter* blitter) {
748 if (clip.isEmpty()) {
749 return;
750 }
751
752 if (clip.isBW()) {
753 AntiFillPath(path, clip.bwRgn(), blitter);
754 } else {
755 SkRegion tmp;
756 SkAAClipBlitter aaBlitter;
757
758 tmp.setRect(clip.getBounds());
759 aaBlitter.init(blitter, &clip.aaRgn());
760 SkScan::AntiFillPath(path, tmp, &aaBlitter, true);
761 }
762 }
763
764