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