Revert "remove kA1_Config, as it is no longer supported"
This reverts commit 2d72d8b242eac6e9d30228f5b0a407236491c369.
git-svn-id: http://skia.googlecode.com/svn/trunk@12387 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/core/SkBitmap.cpp b/src/core/SkBitmap.cpp
index 38594f8..2fae75a 100644
--- a/src/core/SkBitmap.cpp
+++ b/src/core/SkBitmap.cpp
@@ -161,6 +161,7 @@
int bpp;
switch (config) {
case kNo_Config:
+ case kA1_Config:
bpp = 0; // not applicable
break;
case kA8_Config:
@@ -193,6 +194,11 @@
switch (c) {
case kNo_Config:
break;
+ case kA1_Config:
+ rowBytes.set(width);
+ rowBytes.add(7);
+ rowBytes.shiftRight(3);
+ break;
case kA8_Config:
case kIndex8_Config:
rowBytes.set(width);
@@ -269,6 +275,7 @@
case SkBitmap::kNo_Config:
alphaType = kIgnore_SkAlphaType;
break;
+ case SkBitmap::kA1_Config:
case SkBitmap::kA8_Config:
if (kUnpremul_SkAlphaType == alphaType) {
alphaType = kPremul_SkAlphaType;
@@ -284,8 +291,6 @@
case SkBitmap::kRGB_565_Config:
alphaType = kOpaque_SkAlphaType;
break;
- default:
- return false;
}
if (canonical) {
*canonical = alphaType;
@@ -601,6 +606,8 @@
case SkBitmap::kIndex8_Config:
base += x;
break;
+ case SkBitmap::kA1_Config:
+ base += x >> 3;
break;
default:
SkDEBUGFAIL("Can't return addr for config");
@@ -616,6 +623,15 @@
SkASSERT((unsigned)y < (unsigned)this->height());
switch (this->config()) {
+ case SkBitmap::kA1_Config: {
+ uint8_t* addr = this->getAddr1(x, y);
+ uint8_t mask = 1 << (7 - (x % 8));
+ if (addr[0] & mask) {
+ return SK_ColorBLACK;
+ } else {
+ return 0;
+ }
+ }
case SkBitmap::kA8_Config: {
uint8_t* addr = this->getAddr8(x, y);
return SkColorSetA(0, addr[0]);
@@ -638,7 +654,6 @@
return SkUnPreMultiply::PMColorToColor(addr[0]);
}
case kNo_Config:
- default:
SkASSERT(false);
return 0;
}
@@ -656,6 +671,9 @@
const int width = bm.width();
switch (bm.config()) {
+ case SkBitmap::kA1_Config: {
+ // TODO
+ } break;
case SkBitmap::kA8_Config: {
unsigned a = 0xFF;
for (int y = 0; y < height; ++y) {
@@ -761,6 +779,38 @@
}
switch (fConfig) {
+ case kA1_Config: {
+ uint8_t* p = this->getAddr1(area.fLeft, area.fTop);
+ const int left = area.fLeft >> 3;
+ const int right = area.fRight >> 3;
+
+ int middle = right - left - 1;
+
+ uint8_t leftMask = 0xFF >> (area.fLeft & 7);
+ uint8_t rightMask = ~(0xFF >> (area.fRight & 7));
+ if (left == right) {
+ leftMask &= rightMask;
+ rightMask = 0;
+ }
+
+ a = (a >> 7) ? 0xFF : 0;
+ while (--height >= 0) {
+ uint8_t* startP = p;
+
+ *p = (*p & ~leftMask) | (a & leftMask);
+ p++;
+ if (middle > 0) {
+ memset(p, a, middle);
+ p += middle;
+ }
+ if (rightMask) {
+ *p = (*p & ~rightMask) | (a & rightMask);
+ }
+
+ p = startP + rowBytes;
+ }
+ break;
+ }
case kA8_Config: {
uint8_t* p = this->getAddr8(area.fLeft, area.fTop);
while (--height >= 0) {
@@ -846,6 +896,7 @@
break;
case SkBitmap::kNo_Config:
+ case SkBitmap::kA1_Config:
default:
return SUB_OFFSET_FAILURE;
}
@@ -888,6 +939,8 @@
case SkBitmap::kNo_Config:
// Fall through.
+ case SkBitmap::kA1_Config:
+ // Fall through.
default:
return false;
}
@@ -968,6 +1021,7 @@
case kRGB_565_Config:
case kARGB_8888_Config:
break;
+ case kA1_Config:
case kIndex8_Config:
if (!sameConfigs) {
return false;
@@ -978,6 +1032,12 @@
default:
return false;
}
+
+ // do not copy src if srcConfig == kA1_Config while dstConfig != kA1_Config
+ if (this->config() == kA1_Config && !sameConfigs) {
+ return false;
+ }
+
return true;
}
@@ -1621,7 +1681,7 @@
void SkBitmap::toString(SkString* str) const {
static const char* gConfigNames[kConfigCount] = {
- "NONE", "A8", "INDEX8", "565", "4444", "8888"
+ "NONE", "A1", "A8", "INDEX8", "565", "4444", "8888"
};
str->appendf("bitmap: ((%d, %d) %s", this->width(), this->height(),
diff --git a/src/core/SkBlitter.cpp b/src/core/SkBlitter.cpp
index 9682d55..dc7946a 100644
--- a/src/core/SkBlitter.cpp
+++ b/src/core/SkBlitter.cpp
@@ -945,6 +945,11 @@
switch (device.config()) {
+ case SkBitmap::kA1_Config:
+ SK_PLACEMENT_NEW_ARGS(blitter, SkA1_Blitter,
+ storage, storageSize, (device, *paint));
+ break;
+
case SkBitmap::kA8_Config:
if (drawCoverage) {
SkASSERT(NULL == shader);
diff --git a/src/core/SkBlitter_A1.cpp b/src/core/SkBlitter_A1.cpp
new file mode 100644
index 0000000..b64afe2
--- /dev/null
+++ b/src/core/SkBlitter_A1.cpp
@@ -0,0 +1,50 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#include "SkCoreBlitters.h"
+
+SkA1_Blitter::SkA1_Blitter(const SkBitmap& device, const SkPaint& paint)
+ : INHERITED(device) {
+ fSrcA = paint.getAlpha();
+}
+
+void SkA1_Blitter::blitH(int x, int y, int width) {
+ SkASSERT(x >= 0 && y >= 0 &&
+ (unsigned)(x + width) <= (unsigned)fDevice.width());
+
+ if (fSrcA <= 0x7F) {
+ return;
+ }
+ uint8_t* dst = fDevice.getAddr1(x, y);
+ int right = x + width;
+
+ int left_mask = 0xFF >> (x & 7);
+ int rite_mask = 0xFF << (8 - (right & 7));
+ int full_runs = (right >> 3) - ((x + 7) >> 3);
+
+ // check for empty right mask, so we don't read off the end
+ // (or go slower than we need to)
+ if (rite_mask == 0) {
+ SkASSERT(full_runs >= 0);
+ full_runs -= 1;
+ rite_mask = 0xFF;
+ }
+ if (left_mask == 0xFF) {
+ full_runs -= 1;
+ }
+ if (full_runs < 0) {
+ SkASSERT((left_mask & rite_mask) != 0);
+ *dst |= (left_mask & rite_mask);
+ } else {
+ *dst++ |= left_mask;
+ memset(dst, 0xFF, full_runs);
+ dst += full_runs;
+ *dst |= rite_mask;
+ }
+}
diff --git a/src/core/SkCoreBlitters.h b/src/core/SkCoreBlitters.h
index 1605a52..673b874 100644
--- a/src/core/SkCoreBlitters.h
+++ b/src/core/SkCoreBlitters.h
@@ -162,6 +162,22 @@
///////////////////////////////////////////////////////////////////////////////
+class SkA1_Blitter : public SkRasterBlitter {
+public:
+ SkA1_Blitter(const SkBitmap& device, const SkPaint& paint);
+ virtual void blitH(int x, int y, int width) SK_OVERRIDE;
+
+private:
+ uint8_t fSrcA;
+
+ // illegal
+ SkA1_Blitter& operator=(const SkA1_Blitter&);
+
+ typedef SkRasterBlitter INHERITED;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
/* These return the correct subclass of blitter for their device config.
Currently, they make the following assumptions about the state of the
diff --git a/src/core/SkScalerContext.cpp b/src/core/SkScalerContext.cpp
index f4f2391..1d6c2f7 100644
--- a/src/core/SkScalerContext.cpp
+++ b/src/core/SkScalerContext.cpp
@@ -523,54 +523,10 @@
}
}
-static inline int convert_8_to_1(unsigned byte) {
- SkASSERT(byte <= 0xFF);
- return byte >> 7;
-}
-
-static uint8_t pack_8_to_1(const uint8_t alpha[8]) {
- unsigned bits = 0;
- for (int i = 0; i < 8; ++i) {
- bits |= convert_8_to_1(alpha[i]);
- bits <<= 1;
- }
- return SkToU8(bits);
-}
-
-static void packA8ToA1(const SkMask& mask, const uint8_t* src, size_t srcRB) {
- const int height = mask.fBounds.height();
- const int width = mask.fBounds.width();
- const int octs = width >> 3;
- const int leftOverBits = width & 7;
-
- uint8_t* dst = mask.fImage;
- const int dstPad = mask.fRowBytes - SkAlign8(width);
- SkASSERT(dstPad >= 0);
-
- const int srcPad = srcRB - width;
- SkASSERT(srcPad >= 0);
-
- for (int y = 0; y < height; ++y) {
- for (int i = 0; i < octs; ++i) {
- *dst++ = pack_8_to_1(src);
- src += 8;
- }
- if (leftOverBits > 0) {
- unsigned bits = 0;
- int shift = 7;
- for (int i = 0; i < leftOverBits; ++i, --shift) {
- bits |= convert_8_to_1(*src++ >> 7) << shift;
- }
- *dst++ = bits;
- }
- src += srcPad;
- dst += dstPad;
- }
-}
-
static void generateMask(const SkMask& mask, const SkPath& path,
const SkMaskGamma::PreBlend& maskPreBlend) {
- SkPaint paint;
+ SkBitmap::Config config;
+ SkPaint paint;
int srcW = mask.fBounds.width();
int srcH = mask.fBounds.height();
@@ -582,25 +538,27 @@
matrix.setTranslate(-SkIntToScalar(mask.fBounds.fLeft),
-SkIntToScalar(mask.fBounds.fTop));
- SkBitmap::Config config = SkBitmap::kA8_Config;
- paint.setAntiAlias(SkMask::kBW_Format != mask.fFormat);
- switch (mask.fFormat) {
- case SkMask::kBW_Format:
- dstRB = 0; // signals we need a copy
- break;
- case SkMask::kA8_Format:
- break;
- case SkMask::kLCD16_Format:
- case SkMask::kLCD32_Format:
- // TODO: trigger off LCD orientation
- dstW = 4*dstW - 8;
- matrix.setTranslate(-SkIntToScalar(mask.fBounds.fLeft + 1),
- -SkIntToScalar(mask.fBounds.fTop));
- matrix.postScale(SkIntToScalar(4), SK_Scalar1);
- dstRB = 0; // signals we need a copy
- break;
- default:
- SkDEBUGFAIL("unexpected mask format");
+ if (SkMask::kBW_Format == mask.fFormat) {
+ config = SkBitmap::kA1_Config;
+ paint.setAntiAlias(false);
+ } else {
+ config = SkBitmap::kA8_Config;
+ paint.setAntiAlias(true);
+ switch (mask.fFormat) {
+ case SkMask::kA8_Format:
+ break;
+ case SkMask::kLCD16_Format:
+ case SkMask::kLCD32_Format:
+ // TODO: trigger off LCD orientation
+ dstW = 4*dstW - 8;
+ matrix.setTranslate(-SkIntToScalar(mask.fBounds.fLeft + 1),
+ -SkIntToScalar(mask.fBounds.fTop));
+ matrix.postScale(SkIntToScalar(4), SK_Scalar1);
+ dstRB = 0; // signals we need a copy
+ break;
+ default:
+ SkDEBUGFAIL("unexpected mask format");
+ }
}
SkRasterClip clip;
@@ -629,9 +587,6 @@
draw.drawPath(path, paint);
switch (mask.fFormat) {
- case SkMask::kBW_Format:
- packA8ToA1(mask, bm.getAddr8(0, 0), bm.rowBytes());
- break;
case SkMask::kA8_Format:
if (maskPreBlend.isApplicable()) {
applyLUTToA8Mask(mask, maskPreBlend.fG);