aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/SkAlphaRuns.cpp
diff options
context:
space:
mode:
authorGravatar reed@android.com <reed@android.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2008-12-17 15:59:43 +0000
committerGravatar reed@android.com <reed@android.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2008-12-17 15:59:43 +0000
commit8a1c16ff38322f0210116fa7293eb8817c7e477e (patch)
treefe40e07f6c8983318a2f79032b9a706ede1090c1 /src/core/SkAlphaRuns.cpp
parent2559c629078f738ac37095d896d580b681ac6a30 (diff)
grab from latest android
git-svn-id: http://skia.googlecode.com/svn/trunk@27 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/core/SkAlphaRuns.cpp')
-rw-r--r--src/core/SkAlphaRuns.cpp185
1 files changed, 185 insertions, 0 deletions
diff --git a/src/core/SkAlphaRuns.cpp b/src/core/SkAlphaRuns.cpp
new file mode 100644
index 0000000000..46b0206ee8
--- /dev/null
+++ b/src/core/SkAlphaRuns.cpp
@@ -0,0 +1,185 @@
+/* libs/graphics/sgl/SkAlphaRuns.cpp
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#include "SkAntiRun.h"
+
+void SkAlphaRuns::reset(int width)
+{
+ SkASSERT(width > 0);
+
+ fRuns[0] = SkToS16(width);
+ fRuns[width] = 0;
+ fAlpha[0] = 0;
+
+ SkDEBUGCODE(fWidth = width;)
+ SkDEBUGCODE(this->validate();)
+}
+
+void SkAlphaRuns::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;
+ }
+}
+
+void SkAlphaRuns::add(int x, U8CPU startAlpha, int middleCount, U8CPU stopAlpha, U8CPU maxValue)
+{
+ SkASSERT(middleCount >= 0);
+ SkASSERT(x >= 0 && x + (startAlpha != 0) + middleCount + (stopAlpha != 0) <= fWidth);
+
+ int16_t* runs = fRuns;
+ uint8_t* alpha = fAlpha;
+
+ 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;
+ 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();)
+ }
+ if (stopAlpha)
+ {
+ SkAlphaRuns::Break(runs, alpha, x, 1);
+ alpha[x] = SkToU8(alpha[x] + stopAlpha);
+ SkDEBUGCODE(this->validate();)
+ }
+}
+
+#ifdef SK_DEBUG
+ void SkAlphaRuns::assertValid(int y, int maxStep) const
+ {
+ int max = (y + 1) * maxStep - (y == maxStep - 1);
+
+ const int16_t* runs = fRuns;
+ const uint8_t* alpha = fAlpha;
+
+ while (*runs)
+ {
+ SkASSERT(*alpha <= max);
+ alpha += *runs;
+ runs += *runs;
+ }
+ }
+
+ void SkAlphaRuns::dump() const
+ {
+ const int16_t* runs = fRuns;
+ const uint8_t* alpha = fAlpha;
+
+ SkDebugf("Runs");
+ while (*runs)
+ {
+ int n = *runs;
+
+ SkDebugf(" %02x", *alpha);
+ if (n > 1)
+ SkDebugf(",%d", n);
+ alpha += n;
+ runs += n;
+ }
+ SkDebugf("\n");
+ }
+
+ void SkAlphaRuns::validate() const
+ {
+ SkASSERT(fWidth > 0);
+
+ int count = 0;
+ const int16_t* runs = fRuns;
+
+ while (*runs)
+ {
+ SkASSERT(*runs > 0);
+ count += *runs;
+ SkASSERT(count <= fWidth);
+ runs += *runs;
+ }
+ SkASSERT(count == fWidth);
+ }
+#endif
+