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 : //#define FORCE_SUPERMASK
38 : //#define FORCE_RLE
39 : #define SK_SUPPORT_NEW_AA
40 :
41 : ///////////////////////////////////////////////////////////////////////////////
42 :
43 : /// Base class for a single-pass supersampled blitter.
44 0 : class BaseSuperBlitter : public SkBlitter {
45 : public:
46 : BaseSuperBlitter(SkBlitter* realBlitter, const SkIRect& ir,
47 : const SkRegion& clip);
48 :
49 : /// Must be explicitly defined on subclasses.
50 0 : virtual void blitAntiH(int x, int y, const SkAlpha antialias[],
51 : const int16_t runs[]) SK_OVERRIDE {
52 0 : SkDEBUGFAIL("How did I get here?");
53 0 : }
54 : /// May not be called on BaseSuperBlitter because it blits out of order.
55 0 : virtual void blitV(int x, int y, int height, SkAlpha alpha) SK_OVERRIDE {
56 0 : SkDEBUGFAIL("How did I get here?");
57 0 : }
58 :
59 : protected:
60 : SkBlitter* fRealBlitter;
61 : /// Current y coordinate, in destination coordinates.
62 : int fCurrIY;
63 : /// Widest row of region to be blitted, in destination coordinates.
64 : int fWidth;
65 : /// Leftmost x coordinate in any row, in destination coordinates.
66 : int fLeft;
67 : /// Leftmost x coordinate in any row, in supersampled coordinates.
68 : int fSuperLeft;
69 :
70 : SkDEBUGCODE(int fCurrX;)
71 : /// Current y coordinate in supersampled coordinates.
72 : int fCurrY;
73 : /// Initial y coordinate (top of bounds).
74 : int fTop;
75 : };
76 :
77 0 : BaseSuperBlitter::BaseSuperBlitter(SkBlitter* realBlitter, const SkIRect& ir,
78 0 : const SkRegion& clip) {
79 0 : fRealBlitter = realBlitter;
80 :
81 : // take the union of the ir bounds and clip, since we may be called with an
82 : // inverse filltype
83 0 : const int left = SkMin32(ir.fLeft, clip.getBounds().fLeft);
84 0 : const int right = SkMax32(ir.fRight, clip.getBounds().fRight);
85 :
86 0 : fLeft = left;
87 0 : fSuperLeft = left << SHIFT;
88 0 : fWidth = right - left;
89 : #if 0
90 : fCurrIY = -1;
91 : fCurrY = -1;
92 : #else
93 0 : fTop = ir.fTop;
94 0 : fCurrIY = ir.fTop - 1;
95 0 : fCurrY = (ir.fTop << SHIFT) - 1;
96 : #endif
97 0 : SkDEBUGCODE(fCurrX = -1;)
98 0 : }
99 :
100 : /// Run-length-encoded supersampling antialiased blitter.
101 : class SuperBlitter : public BaseSuperBlitter {
102 : public:
103 : SuperBlitter(SkBlitter* realBlitter, const SkIRect& ir,
104 : const SkRegion& clip);
105 :
106 0 : virtual ~SuperBlitter() {
107 0 : this->flush();
108 0 : sk_free(fRuns.fRuns);
109 0 : }
110 :
111 : /// Once fRuns contains a complete supersampled row, flush() blits
112 : /// it out through the wrapped blitter.
113 : void flush();
114 :
115 : /// Blits a row of pixels, with location and width specified
116 : /// in supersampled coordinates.
117 : virtual void blitH(int x, int y, int width) SK_OVERRIDE;
118 : /// Blits a rectangle of pixels, with location and size specified
119 : /// in supersampled coordinates.
120 : virtual void blitRect(int x, int y, int width, int height) SK_OVERRIDE;
121 :
122 : private:
123 : SkAlphaRuns fRuns;
124 : int fOffsetX;
125 : };
126 :
127 0 : SuperBlitter::SuperBlitter(SkBlitter* realBlitter, const SkIRect& ir,
128 : const SkRegion& clip)
129 0 : : BaseSuperBlitter(realBlitter, ir, clip) {
130 0 : const int width = fWidth;
131 :
132 : // extra one to store the zero at the end
133 0 : fRuns.fRuns = (int16_t*)sk_malloc_throw((width + 1 + (width + 2)/2) * sizeof(int16_t));
134 0 : fRuns.fAlpha = (uint8_t*)(fRuns.fRuns + width + 1);
135 0 : fRuns.reset(width);
136 :
137 0 : fOffsetX = 0;
138 0 : }
139 :
140 0 : void SuperBlitter::flush() {
141 0 : if (fCurrIY >= fTop) {
142 0 : if (!fRuns.empty()) {
143 : // SkDEBUGCODE(fRuns.dump();)
144 0 : fRealBlitter->blitAntiH(fLeft, fCurrIY, fRuns.fAlpha, fRuns.fRuns);
145 0 : fRuns.reset(fWidth);
146 0 : fOffsetX = 0;
147 : }
148 0 : fCurrIY = fTop - 1;
149 0 : SkDEBUGCODE(fCurrX = -1;)
150 : }
151 0 : }
152 :
153 0 : static inline int coverage_to_alpha(int aa) {
154 0 : aa <<= 8 - 2*SHIFT;
155 0 : aa -= aa >> (8 - SHIFT - 1);
156 0 : return aa;
157 : }
158 :
159 0 : static inline int coverage_to_exact_alpha(int aa) {
160 0 : int alpha = (256 >> SHIFT) * aa;
161 : // clamp 256->255
162 0 : return alpha - (alpha >> 8);
163 : }
164 :
165 0 : void SuperBlitter::blitH(int x, int y, int width) {
166 0 : SkASSERT(width > 0);
167 :
168 0 : int iy = y >> SHIFT;
169 0 : SkASSERT(iy >= fCurrIY);
170 :
171 0 : x -= fSuperLeft;
172 : // hack, until I figure out why my cubics (I think) go beyond the bounds
173 0 : if (x < 0) {
174 0 : width += x;
175 0 : x = 0;
176 : }
177 :
178 : #ifdef SK_DEBUG
179 0 : SkASSERT(y != fCurrY || x >= fCurrX);
180 : #endif
181 0 : SkASSERT(y >= fCurrY);
182 0 : if (fCurrY != y) {
183 0 : fOffsetX = 0;
184 0 : fCurrY = y;
185 : }
186 :
187 0 : if (iy != fCurrIY) { // new scanline
188 0 : this->flush();
189 0 : fCurrIY = iy;
190 : }
191 :
192 0 : int start = x;
193 0 : int stop = x + width;
194 :
195 0 : SkASSERT(start >= 0 && stop > start);
196 : // integer-pixel-aligned ends of blit, rounded out
197 0 : int fb = start & MASK;
198 0 : int fe = stop & MASK;
199 0 : int n = (stop >> SHIFT) - (start >> SHIFT) - 1;
200 :
201 0 : if (n < 0) {
202 0 : fb = fe - fb;
203 0 : n = 0;
204 0 : fe = 0;
205 : } else {
206 0 : if (fb == 0) {
207 0 : n += 1;
208 : } else {
209 0 : fb = SCALE - fb;
210 : }
211 : }
212 :
213 : // TODO - should this be using coverage_to_exact_alpha?
214 0 : fOffsetX = fRuns.add(x >> SHIFT, coverage_to_alpha(fb),
215 0 : n, coverage_to_alpha(fe),
216 : (1 << (8 - SHIFT)) - (((y & MASK) + 1) >> SHIFT),
217 0 : fOffsetX);
218 :
219 : #ifdef SK_DEBUG
220 0 : fRuns.assertValid(y & MASK, (1 << (8 - SHIFT)));
221 0 : fCurrX = x + width;
222 : #endif
223 0 : }
224 :
225 0 : static void set_left_rite_runs(SkAlphaRuns& runs, int ileft, U8CPU leftA,
226 : int n, U8CPU riteA) {
227 0 : SkASSERT(leftA <= 0xFF);
228 0 : SkASSERT(riteA <= 0xFF);
229 :
230 0 : int16_t* run = runs.fRuns;
231 0 : uint8_t* aa = runs.fAlpha;
232 :
233 0 : if (ileft > 0) {
234 0 : run[0] = ileft;
235 0 : aa[0] = 0;
236 0 : run += ileft;
237 0 : aa += ileft;
238 : }
239 :
240 0 : SkASSERT(leftA < 0xFF);
241 0 : if (leftA > 0) {
242 0 : *run++ = 1;
243 0 : *aa++ = leftA;
244 : }
245 :
246 0 : if (n > 0) {
247 0 : run[0] = n;
248 0 : aa[0] = 0xFF;
249 0 : run += n;
250 0 : aa += n;
251 : }
252 :
253 0 : SkASSERT(riteA < 0xFF);
254 0 : if (riteA > 0) {
255 0 : *run++ = 1;
256 0 : *aa++ = riteA;
257 : }
258 0 : run[0] = 0;
259 0 : }
260 :
261 0 : void SuperBlitter::blitRect(int x, int y, int width, int height) {
262 0 : SkASSERT(width > 0);
263 0 : SkASSERT(height > 0);
264 :
265 : // blit leading rows
266 0 : while ((y & MASK)) {
267 0 : this->blitH(x, y++, width);
268 0 : if (--height <= 0) {
269 0 : return;
270 : }
271 : }
272 0 : SkASSERT(height > 0);
273 :
274 : // Since this is a rect, instead of blitting supersampled rows one at a
275 : // time and then resolving to the destination canvas, we can blit
276 : // directly to the destintion canvas one row per SCALE supersampled rows.
277 0 : int start_y = y >> SHIFT;
278 0 : int stop_y = (y + height) >> SHIFT;
279 0 : int count = stop_y - start_y;
280 0 : if (count > 0) {
281 0 : y += count << SHIFT;
282 0 : height -= count << SHIFT;
283 :
284 : // save original X for our tail blitH() loop at the bottom
285 0 : int origX = x;
286 :
287 0 : x -= fSuperLeft;
288 : // hack, until I figure out why my cubics (I think) go beyond the bounds
289 0 : if (x < 0) {
290 0 : width += x;
291 0 : x = 0;
292 : }
293 :
294 : // There is always a left column, a middle, and a right column.
295 : // ileft is the destination x of the first pixel of the entire rect.
296 : // xleft is (SCALE - # of covered supersampled pixels) in that
297 : // destination pixel.
298 0 : int ileft = x >> SHIFT;
299 0 : int xleft = x & MASK;
300 : // irite is the destination x of the last pixel of the OPAQUE section.
301 : // xrite is the number of supersampled pixels extending beyond irite;
302 : // xrite/SCALE should give us alpha.
303 0 : int irite = (x + width) >> SHIFT;
304 0 : int xrite = (x + width) & MASK;
305 0 : if (!xrite) {
306 0 : xrite = SCALE;
307 0 : irite--;
308 : }
309 :
310 : // Need to call flush() to clean up pending draws before we
311 : // even consider blitV(), since otherwise it can look nonmonotonic.
312 0 : SkASSERT(start_y > fCurrIY);
313 0 : this->flush();
314 :
315 0 : int n = irite - ileft - 1;
316 0 : if (n < 0) {
317 : // If n < 0, we'll only have a single partially-transparent column
318 : // of pixels to render.
319 0 : xleft = xrite - xleft;
320 0 : SkASSERT(xleft <= SCALE);
321 0 : SkASSERT(xleft > 0);
322 0 : xrite = 0;
323 : fRealBlitter->blitV(ileft + fLeft, start_y, count,
324 0 : coverage_to_exact_alpha(xleft));
325 : } else {
326 : // With n = 0, we have two possibly-transparent columns of pixels
327 : // to render; with n > 0, we have opaque columns between them.
328 :
329 0 : xleft = SCALE - xleft;
330 :
331 : // Using coverage_to_exact_alpha is not consistent with blitH()
332 0 : const int coverageL = coverage_to_exact_alpha(xleft);
333 0 : const int coverageR = coverage_to_exact_alpha(xrite);
334 :
335 0 : SkASSERT(coverageL > 0 || n > 0 || coverageR > 0);
336 0 : SkASSERT((coverageL != 0) + n + (coverageR != 0) <= fWidth);
337 :
338 : fRealBlitter->blitAntiRect(ileft + fLeft, start_y, n, count,
339 0 : coverageL, coverageR);
340 : }
341 :
342 : // preamble for our next call to blitH()
343 0 : fCurrIY = stop_y - 1;
344 0 : fOffsetX = 0;
345 0 : fCurrY = y - 1;
346 0 : fRuns.reset(fWidth);
347 0 : x = origX;
348 : }
349 :
350 : // catch any remaining few rows
351 0 : SkASSERT(height <= MASK);
352 0 : while (--height >= 0) {
353 0 : this->blitH(x, y++, width);
354 : }
355 : }
356 :
357 : ///////////////////////////////////////////////////////////////////////////////
358 :
359 : /// Masked supersampling antialiased blitter.
360 : class MaskSuperBlitter : public BaseSuperBlitter {
361 : public:
362 : MaskSuperBlitter(SkBlitter* realBlitter, const SkIRect& ir,
363 : const SkRegion& clip);
364 0 : virtual ~MaskSuperBlitter() {
365 0 : fRealBlitter->blitMask(fMask, fClipRect);
366 0 : }
367 :
368 : virtual void blitH(int x, int y, int width) SK_OVERRIDE;
369 :
370 0 : static bool CanHandleRect(const SkIRect& bounds) {
371 : #ifdef FORCE_RLE
372 : return false;
373 : #endif
374 0 : int width = bounds.width();
375 0 : int rb = SkAlign4(width);
376 :
377 : return (width <= MaskSuperBlitter::kMAX_WIDTH) &&
378 0 : (rb * bounds.height() <= MaskSuperBlitter::kMAX_STORAGE);
379 : }
380 :
381 : private:
382 : enum {
383 : #ifdef FORCE_SUPERMASK
384 : kMAX_WIDTH = 2048,
385 : kMAX_STORAGE = 1024 * 1024 * 2
386 : #else
387 : kMAX_WIDTH = 32, // so we don't try to do very wide things, where the RLE blitter would be faster
388 : kMAX_STORAGE = 1024
389 : #endif
390 : };
391 :
392 : SkMask fMask;
393 : SkIRect fClipRect;
394 : // we add 1 because add_aa_span can write (unchanged) 1 extra byte at the end, rather than
395 : // perform a test to see if stopAlpha != 0
396 : uint32_t fStorage[(kMAX_STORAGE >> 2) + 1];
397 : };
398 :
399 0 : MaskSuperBlitter::MaskSuperBlitter(SkBlitter* realBlitter, const SkIRect& ir,
400 : const SkRegion& clip)
401 0 : : BaseSuperBlitter(realBlitter, ir, clip) {
402 0 : SkASSERT(CanHandleRect(ir));
403 :
404 0 : fMask.fImage = (uint8_t*)fStorage;
405 0 : fMask.fBounds = ir;
406 0 : fMask.fRowBytes = ir.width();
407 0 : fMask.fFormat = SkMask::kA8_Format;
408 :
409 0 : fClipRect = ir;
410 0 : fClipRect.intersect(clip.getBounds());
411 :
412 : // For valgrind, write 1 extra byte at the end so we don't read
413 : // uninitialized memory. See comment in add_aa_span and fStorage[].
414 0 : memset(fStorage, 0, fMask.fBounds.height() * fMask.fRowBytes + 1);
415 0 : }
416 :
417 0 : static void add_aa_span(uint8_t* alpha, U8CPU startAlpha) {
418 : /* I should be able to just add alpha[x] + startAlpha.
419 : However, if the trailing edge of the previous span and the leading
420 : edge of the current span round to the same super-sampled x value,
421 : I might overflow to 256 with this add, hence the funny subtract.
422 : */
423 0 : unsigned tmp = *alpha + startAlpha;
424 0 : SkASSERT(tmp <= 256);
425 0 : *alpha = SkToU8(tmp - (tmp >> 8));
426 0 : }
427 :
428 0 : static inline uint32_t quadplicate_byte(U8CPU value) {
429 0 : uint32_t pair = (value << 8) | value;
430 0 : return (pair << 16) | pair;
431 : }
432 :
433 : // minimum count before we want to setup an inner loop, adding 4-at-a-time
434 : #define MIN_COUNT_FOR_QUAD_LOOP 16
435 :
436 0 : static void add_aa_span(uint8_t* alpha, U8CPU startAlpha, int middleCount,
437 : U8CPU stopAlpha, U8CPU maxValue) {
438 0 : SkASSERT(middleCount >= 0);
439 :
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 : #ifdef SK_SUPPORT_NEW_AA
446 0 : if (startAlpha) {
447 0 : unsigned tmp = *alpha + startAlpha;
448 0 : SkASSERT(tmp <= 256);
449 0 : *alpha++ = SkToU8(tmp - (tmp >> 8));
450 : }
451 : #else
452 : unsigned tmp = *alpha + startAlpha;
453 : SkASSERT(tmp <= 256);
454 : *alpha++ = SkToU8(tmp - (tmp >> 8));
455 : #endif
456 :
457 0 : if (middleCount >= MIN_COUNT_FOR_QUAD_LOOP) {
458 : // loop until we're quad-byte aligned
459 0 : while (SkTCast<intptr_t>(alpha) & 0x3) {
460 0 : alpha[0] = SkToU8(alpha[0] + maxValue);
461 0 : alpha += 1;
462 0 : middleCount -= 1;
463 : }
464 :
465 0 : int bigCount = middleCount >> 2;
466 0 : uint32_t* qptr = reinterpret_cast<uint32_t*>(alpha);
467 0 : uint32_t qval = quadplicate_byte(maxValue);
468 0 : do {
469 0 : *qptr++ += qval;
470 : } while (--bigCount > 0);
471 :
472 0 : middleCount &= 3;
473 0 : alpha = reinterpret_cast<uint8_t*> (qptr);
474 : // fall through to the following while-loop
475 : }
476 :
477 0 : while (--middleCount >= 0) {
478 0 : alpha[0] = SkToU8(alpha[0] + maxValue);
479 0 : alpha += 1;
480 : }
481 :
482 : // potentially this can be off the end of our "legal" alpha values, but that
483 : // only happens if stopAlpha is also 0. Rather than test for stopAlpha != 0
484 : // every time (slow), we just do it, and ensure that we've allocated extra space
485 : // (see the + 1 comment in fStorage[]
486 0 : *alpha = SkToU8(*alpha + stopAlpha);
487 0 : }
488 :
489 0 : void MaskSuperBlitter::blitH(int x, int y, int width) {
490 0 : int iy = (y >> SHIFT);
491 :
492 0 : SkASSERT(iy >= fMask.fBounds.fTop && iy < fMask.fBounds.fBottom);
493 0 : iy -= fMask.fBounds.fTop; // make it relative to 0
494 :
495 : // This should never happen, but it does. Until the true cause is
496 : // discovered, let's skip this span instead of crashing.
497 : // See http://crbug.com/17569.
498 0 : if (iy < 0) {
499 0 : return;
500 : }
501 :
502 : #ifdef SK_DEBUG
503 : {
504 0 : int ix = x >> SHIFT;
505 0 : SkASSERT(ix >= fMask.fBounds.fLeft && ix < fMask.fBounds.fRight);
506 : }
507 : #endif
508 :
509 0 : x -= (fMask.fBounds.fLeft << SHIFT);
510 :
511 : // hack, until I figure out why my cubics (I think) go beyond the bounds
512 0 : if (x < 0) {
513 0 : width += x;
514 0 : x = 0;
515 : }
516 :
517 0 : uint8_t* row = fMask.fImage + iy * fMask.fRowBytes + (x >> SHIFT);
518 :
519 0 : int start = x;
520 0 : int stop = x + width;
521 :
522 0 : SkASSERT(start >= 0 && stop > start);
523 0 : int fb = start & MASK;
524 0 : int fe = stop & MASK;
525 0 : int n = (stop >> SHIFT) - (start >> SHIFT) - 1;
526 :
527 :
528 0 : if (n < 0) {
529 0 : SkASSERT(row >= fMask.fImage);
530 0 : SkASSERT(row < fMask.fImage + kMAX_STORAGE + 1);
531 0 : add_aa_span(row, coverage_to_alpha(fe - fb));
532 : } else {
533 : #ifdef SK_SUPPORT_NEW_AA
534 0 : if (0 == fb) {
535 0 : n += 1;
536 : } else {
537 0 : fb = SCALE - fb;
538 : }
539 : #else
540 : fb = SCALE - fb;
541 : #endif
542 0 : SkASSERT(row >= fMask.fImage);
543 0 : SkASSERT(row + n + 1 < fMask.fImage + kMAX_STORAGE + 1);
544 0 : add_aa_span(row, coverage_to_alpha(fb), n, coverage_to_alpha(fe),
545 0 : (1 << (8 - SHIFT)) - (((y & MASK) + 1) >> SHIFT));
546 : }
547 :
548 : #ifdef SK_DEBUG
549 0 : fCurrX = x + width;
550 : #endif
551 : }
552 :
553 : ///////////////////////////////////////////////////////////////////////////////
554 :
555 : /* Returns non-zero if (value << shift) overflows a short, which would mean
556 : we could not shift it up and then convert to SkFixed.
557 : i.e. is x expressible as signed (16-shift) bits?
558 : */
559 0 : static int overflows_short_shift(int value, int shift) {
560 0 : const int s = 16 + shift;
561 0 : return (value << s >> s) - value;
562 : }
563 :
564 0 : void SkScan::AntiFillPath(const SkPath& path, const SkRegion& clip,
565 : SkBlitter* blitter, bool forceRLE) {
566 0 : if (clip.isEmpty()) {
567 0 : return;
568 : }
569 :
570 : SkIRect ir;
571 0 : path.getBounds().roundOut(&ir);
572 0 : if (ir.isEmpty()) {
573 0 : if (path.isInverseFillType()) {
574 0 : blitter->blitRegion(clip);
575 : }
576 0 : return;
577 : }
578 :
579 : // use bit-or since we expect all to pass, so no need to go slower with
580 : // a short-circuiting logical-or
581 0 : if (overflows_short_shift(ir.fLeft, SHIFT) |
582 0 : overflows_short_shift(ir.fRight, SHIFT) |
583 0 : overflows_short_shift(ir.fTop, SHIFT) |
584 0 : overflows_short_shift(ir.fBottom, SHIFT)) {
585 : // can't supersample, so draw w/o antialiasing
586 0 : SkScan::FillPath(path, clip, blitter);
587 0 : return;
588 : }
589 :
590 0 : SkScanClipper clipper(blitter, &clip, ir);
591 0 : const SkIRect* clipRect = clipper.getClipRect();
592 :
593 0 : if (clipper.getBlitter() == NULL) { // clipped out
594 0 : if (path.isInverseFillType()) {
595 0 : blitter->blitRegion(clip);
596 : }
597 : return;
598 : }
599 :
600 : // now use the (possibly wrapped) blitter
601 0 : blitter = clipper.getBlitter();
602 :
603 0 : if (path.isInverseFillType()) {
604 0 : sk_blit_above(blitter, ir, clip);
605 : }
606 :
607 0 : SkIRect superRect, *superClipRect = NULL;
608 :
609 0 : if (clipRect) {
610 : superRect.set( clipRect->fLeft << SHIFT, clipRect->fTop << SHIFT,
611 0 : clipRect->fRight << SHIFT, clipRect->fBottom << SHIFT);
612 0 : superClipRect = &superRect;
613 : }
614 :
615 0 : SkASSERT(SkIntToScalar(ir.fTop) <= path.getBounds().fTop);
616 :
617 : // MaskSuperBlitter can't handle drawing outside of ir, so we can't use it
618 : // if we're an inverse filltype
619 0 : if (!path.isInverseFillType() && MaskSuperBlitter::CanHandleRect(ir) && !forceRLE) {
620 0 : MaskSuperBlitter superBlit(blitter, ir, clip);
621 0 : SkASSERT(SkIntToScalar(ir.fTop) <= path.getBounds().fTop);
622 0 : sk_fill_path(path, superClipRect, &superBlit, ir.fTop, ir.fBottom, SHIFT, clip);
623 : } else {
624 0 : SuperBlitter superBlit(blitter, ir, clip);
625 0 : sk_fill_path(path, superClipRect, &superBlit, ir.fTop, ir.fBottom, SHIFT, clip);
626 : }
627 :
628 0 : if (path.isInverseFillType()) {
629 0 : sk_blit_below(blitter, ir, clip);
630 : }
631 : }
632 :
633 : ///////////////////////////////////////////////////////////////////////////////
634 :
635 : #include "SkRasterClip.h"
636 :
637 0 : void SkScan::FillPath(const SkPath& path, const SkRasterClip& clip,
638 : SkBlitter* blitter) {
639 0 : if (clip.isEmpty()) {
640 0 : return;
641 : }
642 :
643 0 : if (clip.isBW()) {
644 0 : FillPath(path, clip.bwRgn(), blitter);
645 : } else {
646 0 : SkRegion tmp;
647 0 : SkAAClipBlitter aaBlitter;
648 :
649 0 : tmp.setRect(clip.getBounds());
650 0 : aaBlitter.init(blitter, &clip.aaRgn());
651 0 : SkScan::FillPath(path, tmp, &aaBlitter);
652 : }
653 : }
654 :
655 0 : void SkScan::AntiFillPath(const SkPath& path, const SkRasterClip& clip,
656 : SkBlitter* blitter) {
657 0 : if (clip.isEmpty()) {
658 0 : return;
659 : }
660 :
661 0 : if (clip.isBW()) {
662 0 : AntiFillPath(path, clip.bwRgn(), blitter);
663 : } else {
664 0 : SkRegion tmp;
665 0 : SkAAClipBlitter aaBlitter;
666 :
667 0 : tmp.setRect(clip.getBounds());
668 0 : aaBlitter.init(blitter, &clip.aaRgn());
669 0 : SkScan::AntiFillPath(path, tmp, &aaBlitter, true);
670 : }
671 : }
672 :
|