Index: src/core/SkAntiRun.h |
diff --git a/src/core/SkAntiRun.h b/src/core/SkAntiRun.h |
index 123972692eb6cdad8fe762d0fe65e13170f3af4d..9a0003935f71ac0777549cc68ed5f5bae8b82197 100644 |
--- a/src/core/SkAntiRun.h |
+++ b/src/core/SkAntiRun.h |
@@ -45,8 +45,63 @@ public: |
* assuming we're on the same scanline. If the caller is switching |
* scanlines, then offsetX should be 0 when this is called. |
*/ |
- int add(int x, U8CPU startAlpha, int middleCount, U8CPU stopAlpha, |
- U8CPU maxValue, int offsetX); |
+ SK_ALWAYS_INLINE int add(int x, U8CPU startAlpha, int middleCount, U8CPU stopAlpha, |
+ U8CPU maxValue, int offsetX) { |
+ SkASSERT(middleCount >= 0); |
+ SkASSERT(x >= 0 && x + (startAlpha != 0) + middleCount + (stopAlpha != 0) <= fWidth); |
+ |
+ SkASSERT(fRuns[offsetX] >= 0); |
+ |
+ int16_t* runs = fRuns + offsetX; |
+ uint8_t* alpha = fAlpha + offsetX; |
+ uint8_t* lastAlpha = alpha; |
+ x -= offsetX; |
+ |
+ if (startAlpha) { |
+ SkAlphaRuns::Break(runs, alpha, x, 1); |
+ /* I should be able to just add alpha[x] + startAlpha. |
+ However, if the trailing edge of the previous span and the leading |
+ edge of the current span round to the same super-sampled x value, |
+ I might overflow to 256 with this add, hence the funny subtract (crud). |
+ */ |
+ unsigned tmp = alpha[x] + startAlpha; |
+ SkASSERT(tmp <= 256); |
+ alpha[x] = SkToU8(tmp - (tmp >> 8)); // was (tmp >> 7), but that seems wrong if we're trying to catch 256 |
+ |
+ runs += x + 1; |
+ alpha += x + 1; |
+ x = 0; |
+ lastAlpha += x; // we don't want the +1 |
+ SkDEBUGCODE(this->validate();) |
+ } |
+ |
+ if (middleCount) { |
+ SkAlphaRuns::Break(runs, alpha, x, middleCount); |
+ alpha += x; |
+ runs += x; |
+ x = 0; |
+ do { |
+ alpha[0] = SkToU8(alpha[0] + maxValue); |
+ int n = runs[0]; |
+ SkASSERT(n <= middleCount); |
+ alpha += n; |
+ runs += n; |
+ middleCount -= n; |
+ } while (middleCount > 0); |
+ SkDEBUGCODE(this->validate();) |
+ lastAlpha = alpha; |
+ } |
+ |
+ if (stopAlpha) { |
+ SkAlphaRuns::Break(runs, alpha, x, 1); |
+ alpha += x; |
+ alpha[0] = SkToU8(alpha[0] + stopAlpha); |
+ SkDEBUGCODE(this->validate();) |
+ lastAlpha = alpha; |
+ } |
+ |
+ return SkToS32(lastAlpha - fAlpha); // new offsetX |
+ } |
SkDEBUGCODE(void assertValid(int y, int maxStep) const;) |
SkDEBUGCODE(void dump() const;) |
@@ -59,7 +114,52 @@ public: |
* Allows add() to sum another run to some of the new sub-runs. |
* i.e. adding ..CCCCC. would produce AADDEEEB, rle as A2D2E3B1. |
*/ |
- static void Break(int16_t runs[], uint8_t alpha[], int x, int count); |
+ static void Break(int16_t runs[], uint8_t alpha[], int x, int count) { |
+ SkASSERT(count > 0 && x >= 0); |
+ |
+ // SkAlphaRuns::BreakAt(runs, alpha, x); |
+ // SkAlphaRuns::BreakAt(&runs[x], &alpha[x], count); |
+ |
+ int16_t* next_runs = runs + x; |
+ uint8_t* next_alpha = alpha + x; |
+ |
+ while (x > 0) { |
+ int n = runs[0]; |
+ SkASSERT(n > 0); |
+ |
+ if (x < n) { |
+ alpha[x] = alpha[0]; |
+ runs[0] = SkToS16(x); |
+ runs[x] = SkToS16(n - x); |
+ break; |
+ } |
+ runs += n; |
+ alpha += n; |
+ x -= n; |
+ } |
+ |
+ runs = next_runs; |
+ alpha = next_alpha; |
+ x = count; |
+ |
+ for (;;) { |
+ int n = runs[0]; |
+ SkASSERT(n > 0); |
+ |
+ if (x < n) { |
+ alpha[x] = alpha[0]; |
+ runs[0] = SkToS16(x); |
+ runs[x] = SkToS16(n - x); |
+ break; |
+ } |
+ x -= n; |
+ if (x <= 0) { |
+ break; |
+ } |
+ runs += n; |
+ alpha += n; |
+ } |
+ } |
/** |
* Cut (at offset x in the buffer) a run into two shorter runs with |