| Index: src/core/SkScalerContext.cpp
|
| diff --git a/src/core/SkScalerContext.cpp b/src/core/SkScalerContext.cpp
|
| index 1d6c2f79a5dcb427cfbf5b94f110596a207df977..f4f23911b0e3aedbae6194e6efa997a0c96cd946 100644
|
| --- a/src/core/SkScalerContext.cpp
|
| +++ b/src/core/SkScalerContext.cpp
|
| @@ -523,10 +523,54 @@ static void pack4xHToLCD32(const SkBitmap& src, const SkMask& dst,
|
| }
|
| }
|
|
|
| +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) {
|
| - SkBitmap::Config config;
|
| - SkPaint paint;
|
| + SkPaint paint;
|
|
|
| int srcW = mask.fBounds.width();
|
| int srcH = mask.fBounds.height();
|
| @@ -538,27 +582,25 @@ static void generateMask(const SkMask& mask, const SkPath& path,
|
| matrix.setTranslate(-SkIntToScalar(mask.fBounds.fLeft),
|
| -SkIntToScalar(mask.fBounds.fTop));
|
|
|
| - 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");
|
| - }
|
| + 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");
|
| }
|
|
|
| SkRasterClip clip;
|
| @@ -587,6 +629,9 @@ static void generateMask(const SkMask& mask, const SkPath& path,
|
| 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);
|
|
|