| OLD | NEW |
| (Empty) |
| 1 /* libs/graphics/sgl/SkAlphaRuns.cpp | |
| 2 ** | |
| 3 ** Copyright 2006, The Android Open Source Project | |
| 4 ** | |
| 5 ** Licensed under the Apache License, Version 2.0 (the "License"); | |
| 6 ** you may not use this file except in compliance with the License. | |
| 7 ** You may obtain a copy of the License at | |
| 8 ** | |
| 9 ** http://www.apache.org/licenses/LICENSE-2.0 | |
| 10 ** | |
| 11 ** Unless required by applicable law or agreed to in writing, software | |
| 12 ** distributed under the License is distributed on an "AS IS" BASIS, | |
| 13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| 14 ** See the License for the specific language governing permissions and | |
| 15 ** limitations under the License. | |
| 16 */ | |
| 17 | |
| 18 #include "SkAntiRun.h" | |
| 19 | |
| 20 void SkAlphaRuns::reset(int width) | |
| 21 { | |
| 22 SkASSERT(width > 0); | |
| 23 | |
| 24 fRuns[0] = SkToS16(width); | |
| 25 fRuns[width] = 0; | |
| 26 fAlpha[0] = 0; | |
| 27 | |
| 28 SkDEBUGCODE(fWidth = width;) | |
| 29 SkDEBUGCODE(this->validate();) | |
| 30 } | |
| 31 | |
| 32 void SkAlphaRuns::Break(int16_t runs[], uint8_t alpha[], int x, int count) | |
| 33 { | |
| 34 SkASSERT(count > 0 && x >= 0); | |
| 35 | |
| 36 // SkAlphaRuns::BreakAt(runs, alpha, x); | |
| 37 // SkAlphaRuns::BreakAt(&runs[x], &alpha[x], count); | |
| 38 | |
| 39 int16_t* next_runs = runs + x; | |
| 40 uint8_t* next_alpha = alpha + x; | |
| 41 | |
| 42 while (x > 0) | |
| 43 { | |
| 44 int n = runs[0]; | |
| 45 SkASSERT(n > 0); | |
| 46 | |
| 47 if (x < n) | |
| 48 { | |
| 49 alpha[x] = alpha[0]; | |
| 50 runs[0] = SkToS16(x); | |
| 51 runs[x] = SkToS16(n - x); | |
| 52 break; | |
| 53 } | |
| 54 runs += n; | |
| 55 alpha += n; | |
| 56 x -= n; | |
| 57 } | |
| 58 | |
| 59 runs = next_runs; | |
| 60 alpha = next_alpha; | |
| 61 x = count; | |
| 62 | |
| 63 for (;;) | |
| 64 { | |
| 65 int n = runs[0]; | |
| 66 SkASSERT(n > 0); | |
| 67 | |
| 68 if (x < n) | |
| 69 { | |
| 70 alpha[x] = alpha[0]; | |
| 71 runs[0] = SkToS16(x); | |
| 72 runs[x] = SkToS16(n - x); | |
| 73 break; | |
| 74 } | |
| 75 x -= n; | |
| 76 if (x <= 0) | |
| 77 break; | |
| 78 | |
| 79 runs += n; | |
| 80 alpha += n; | |
| 81 } | |
| 82 } | |
| 83 | |
| 84 void SkAlphaRuns::add(int x, U8CPU startAlpha, int middleCount, U8CPU stopAlpha,
U8CPU maxValue) | |
| 85 { | |
| 86 SkASSERT(middleCount >= 0); | |
| 87 SkASSERT(x >= 0 && x + (startAlpha != 0) + middleCount + (stopAlpha != 0) <=
fWidth); | |
| 88 | |
| 89 int16_t* runs = fRuns; | |
| 90 uint8_t* alpha = fAlpha; | |
| 91 | |
| 92 if (startAlpha) | |
| 93 { | |
| 94 SkAlphaRuns::Break(runs, alpha, x, 1); | |
| 95 /* I should be able to just add alpha[x] + startAlpha. | |
| 96 However, if the trailing edge of the previous span and the leading | |
| 97 edge of the current span round to the same super-sampled x value, | |
| 98 I might overflow to 256 with this add, hence the funny subtract (cru
d). | |
| 99 */ | |
| 100 unsigned tmp = alpha[x] + startAlpha; | |
| 101 SkASSERT(tmp <= 256); | |
| 102 alpha[x] = SkToU8(tmp - (tmp >> 8)); // was (tmp >> 7), but that seem
s wrong if we're trying to catch 256 | |
| 103 | |
| 104 runs += x + 1; | |
| 105 alpha += x + 1; | |
| 106 x = 0; | |
| 107 SkDEBUGCODE(this->validate();) | |
| 108 } | |
| 109 if (middleCount) | |
| 110 { | |
| 111 SkAlphaRuns::Break(runs, alpha, x, middleCount); | |
| 112 alpha += x; | |
| 113 runs += x; | |
| 114 x = 0; | |
| 115 do { | |
| 116 alpha[0] = SkToU8(alpha[0] + maxValue); | |
| 117 int n = runs[0]; | |
| 118 SkASSERT(n <= middleCount); | |
| 119 alpha += n; | |
| 120 runs += n; | |
| 121 middleCount -= n; | |
| 122 } while (middleCount > 0); | |
| 123 SkDEBUGCODE(this->validate();) | |
| 124 } | |
| 125 if (stopAlpha) | |
| 126 { | |
| 127 SkAlphaRuns::Break(runs, alpha, x, 1); | |
| 128 alpha[x] = SkToU8(alpha[x] + stopAlpha); | |
| 129 SkDEBUGCODE(this->validate();) | |
| 130 } | |
| 131 } | |
| 132 | |
| 133 #ifdef SK_DEBUG | |
| 134 void SkAlphaRuns::assertValid(int y, int maxStep) const | |
| 135 { | |
| 136 int max = (y + 1) * maxStep - (y == maxStep - 1); | |
| 137 | |
| 138 const int16_t* runs = fRuns; | |
| 139 const uint8_t* alpha = fAlpha; | |
| 140 | |
| 141 while (*runs) | |
| 142 { | |
| 143 SkASSERT(*alpha <= max); | |
| 144 alpha += *runs; | |
| 145 runs += *runs; | |
| 146 } | |
| 147 } | |
| 148 | |
| 149 void SkAlphaRuns::dump() const | |
| 150 { | |
| 151 const int16_t* runs = fRuns; | |
| 152 const uint8_t* alpha = fAlpha; | |
| 153 | |
| 154 SkDebugf("Runs"); | |
| 155 while (*runs) | |
| 156 { | |
| 157 int n = *runs; | |
| 158 | |
| 159 SkDebugf(" %02x", *alpha); | |
| 160 if (n > 1) | |
| 161 SkDebugf(",%d", n); | |
| 162 alpha += n; | |
| 163 runs += n; | |
| 164 } | |
| 165 SkDebugf("\n"); | |
| 166 } | |
| 167 | |
| 168 void SkAlphaRuns::validate() const | |
| 169 { | |
| 170 SkASSERT(fWidth > 0); | |
| 171 | |
| 172 int count = 0; | |
| 173 const int16_t* runs = fRuns; | |
| 174 | |
| 175 while (*runs) | |
| 176 { | |
| 177 SkASSERT(*runs > 0); | |
| 178 count += *runs; | |
| 179 SkASSERT(count <= fWidth); | |
| 180 runs += *runs; | |
| 181 } | |
| 182 SkASSERT(count == fWidth); | |
| 183 } | |
| 184 #endif | |
| 185 | |
| OLD | NEW |