SkBlitter_A8.cpp revision ab7442c8d733e0642d1cd80af23cdab43d77039e
1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2006 The Android Open Source Project
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */
8ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkCoreBlitters.h"
118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkColorPriv.h"
128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkShader.h"
138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkXfermode.h"
148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkA8_Blitter::SkA8_Blitter(const SkBitmap& device, const SkPaint& paint)
16eadc8072aaa8f6fc71f47cd41fab1ed3b4bc1c68mike@reedtribe.org        : INHERITED(device) {
17eadc8072aaa8f6fc71f47cd41fab1ed3b4bc1c68mike@reedtribe.org    fSrcA = paint.getAlpha();
188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2082065d667f64e232bcde2ad849756a6096fcbe6freed@google.comconst SkBitmap* SkA8_Blitter::justAnOpaqueColor(uint32_t* value) {
2182065d667f64e232bcde2ad849756a6096fcbe6freed@google.com    if (255 == fSrcA) {
228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        *value = 255;
238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return &fDevice;
248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return NULL;
268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2882065d667f64e232bcde2ad849756a6096fcbe6freed@google.comvoid SkA8_Blitter::blitH(int x, int y, int width) {
2982065d667f64e232bcde2ad849756a6096fcbe6freed@google.com    SkASSERT(x >= 0 && y >= 0 &&
3082065d667f64e232bcde2ad849756a6096fcbe6freed@google.com             (unsigned)(x + width) <= (unsigned)fDevice.width());
318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3282065d667f64e232bcde2ad849756a6096fcbe6freed@google.com    if (fSrcA == 0) {
338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return;
3482065d667f64e232bcde2ad849756a6096fcbe6freed@google.com    }
358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    uint8_t* device = fDevice.getAddr8(x, y);
378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3882065d667f64e232bcde2ad849756a6096fcbe6freed@google.com    if (fSrcA == 255) {
398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        memset(device, 0xFF, width);
4082065d667f64e232bcde2ad849756a6096fcbe6freed@google.com    } else {
418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        unsigned scale = 256 - SkAlpha255To256(fSrcA);
428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        unsigned srcA = fSrcA;
438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4482065d667f64e232bcde2ad849756a6096fcbe6freed@google.com        for (int i = 0; i < width; i++) {
458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            device[i] = SkToU8(srcA + SkAlphaMul(device[i], scale));
468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
5082065d667f64e232bcde2ad849756a6096fcbe6freed@google.comvoid SkA8_Blitter::blitAntiH(int x, int y, const SkAlpha antialias[],
5182065d667f64e232bcde2ad849756a6096fcbe6freed@google.com                             const int16_t runs[]) {
5282065d667f64e232bcde2ad849756a6096fcbe6freed@google.com    if (fSrcA == 0) {
538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return;
5482065d667f64e232bcde2ad849756a6096fcbe6freed@google.com    }
558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    uint8_t*    device = fDevice.getAddr8(x, y);
578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    unsigned    srcA = fSrcA;
588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
5982065d667f64e232bcde2ad849756a6096fcbe6freed@google.com    for (;;) {
608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        int count = runs[0];
618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkASSERT(count >= 0);
6282065d667f64e232bcde2ad849756a6096fcbe6freed@google.com        if (count == 0) {
638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            return;
6482065d667f64e232bcde2ad849756a6096fcbe6freed@google.com        }
658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        unsigned aa = antialias[0];
668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
6782065d667f64e232bcde2ad849756a6096fcbe6freed@google.com        if (aa == 255 && srcA == 255) {
688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            memset(device, 0xFF, count);
6982065d667f64e232bcde2ad849756a6096fcbe6freed@google.com        } else {
708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            unsigned sa = SkAlphaMul(srcA, SkAlpha255To256(aa));
718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            unsigned scale = 256 - sa;
728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
7382065d667f64e232bcde2ad849756a6096fcbe6freed@google.com            for (int i = 0; i < count; i++) {
748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                device[i] = SkToU8(sa + SkAlphaMul(device[i], scale));
758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            }
768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        runs += count;
788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        antialias += count;
798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        device += count;
808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////////////
848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define solid_8_pixels(mask, dst)           \
868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    do {                                    \
878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (mask & 0x80) dst[0] = 0xFF;     \
888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (mask & 0x40) dst[1] = 0xFF;     \
898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (mask & 0x20) dst[2] = 0xFF;     \
908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (mask & 0x10) dst[3] = 0xFF;     \
918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (mask & 0x08) dst[4] = 0xFF;     \
928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (mask & 0x04) dst[5] = 0xFF;     \
938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (mask & 0x02) dst[6] = 0xFF;     \
948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (mask & 0x01) dst[7] = 0xFF;     \
958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    } while (0)
968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_BLITBWMASK_NAME                  SkA8_BlitBW
9882065d667f64e232bcde2ad849756a6096fcbe6freed@google.com#define SK_BLITBWMASK_ARGS
998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_BLITBWMASK_BLIT8(mask, dst)      solid_8_pixels(mask, dst)
1008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_BLITBWMASK_GETADDR               getAddr8
1018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_BLITBWMASK_DEVTYPE               uint8_t
1028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkBlitBWMaskTemplate.h"
1038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
10482065d667f64e232bcde2ad849756a6096fcbe6freed@google.comstatic inline void blend_8_pixels(U8CPU bw, uint8_t dst[], U8CPU sa,
10582065d667f64e232bcde2ad849756a6096fcbe6freed@google.com                                  unsigned dst_scale) {
1068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (bw & 0x80) dst[0] = SkToU8(sa + SkAlphaMul(dst[0], dst_scale));
1078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (bw & 0x40) dst[1] = SkToU8(sa + SkAlphaMul(dst[1], dst_scale));
1088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (bw & 0x20) dst[2] = SkToU8(sa + SkAlphaMul(dst[2], dst_scale));
1098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (bw & 0x10) dst[3] = SkToU8(sa + SkAlphaMul(dst[3], dst_scale));
1108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (bw & 0x08) dst[4] = SkToU8(sa + SkAlphaMul(dst[4], dst_scale));
1118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (bw & 0x04) dst[5] = SkToU8(sa + SkAlphaMul(dst[5], dst_scale));
1128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (bw & 0x02) dst[6] = SkToU8(sa + SkAlphaMul(dst[6], dst_scale));
1138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (bw & 0x01) dst[7] = SkToU8(sa + SkAlphaMul(dst[7], dst_scale));
1148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_BLITBWMASK_NAME                  SkA8_BlendBW
1178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_BLITBWMASK_ARGS                  , U8CPU sa, unsigned dst_scale
1188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_BLITBWMASK_BLIT8(mask, dst)      blend_8_pixels(mask, dst, sa, dst_scale)
1198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_BLITBWMASK_GETADDR               getAddr8
1208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_BLITBWMASK_DEVTYPE               uint8_t
1218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkBlitBWMaskTemplate.h"
1228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
12382065d667f64e232bcde2ad849756a6096fcbe6freed@google.comvoid SkA8_Blitter::blitMask(const SkMask& mask, const SkIRect& clip) {
12482065d667f64e232bcde2ad849756a6096fcbe6freed@google.com    if (fSrcA == 0) {
1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return;
12682065d667f64e232bcde2ad849756a6096fcbe6freed@google.com    }
1278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
12882065d667f64e232bcde2ad849756a6096fcbe6freed@google.com    if (mask.fFormat == SkMask::kBW_Format) {
12982065d667f64e232bcde2ad849756a6096fcbe6freed@google.com        if (fSrcA == 0xFF) {
1308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            SkA8_BlitBW(fDevice, mask, clip);
13182065d667f64e232bcde2ad849756a6096fcbe6freed@google.com        } else {
13282065d667f64e232bcde2ad849756a6096fcbe6freed@google.com            SkA8_BlendBW(fDevice, mask, clip, fSrcA,
13382065d667f64e232bcde2ad849756a6096fcbe6freed@google.com                         SkAlpha255To256(255 - fSrcA));
13482065d667f64e232bcde2ad849756a6096fcbe6freed@google.com        }
1358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return;
1368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int x = clip.fLeft;
1398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int y = clip.fTop;
1408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int width = clip.width();
1418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int height = clip.height();
1428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    uint8_t* device = fDevice.getAddr8(x, y);
1437989186dab6bc2f1c1927daf91bddd32b7fd8d0creed@google.com    const uint8_t* alpha = mask.getAddr8(x, y);
1448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    unsigned    srcA = fSrcA;
1458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
14682065d667f64e232bcde2ad849756a6096fcbe6freed@google.com    while (--height >= 0) {
14782065d667f64e232bcde2ad849756a6096fcbe6freed@google.com        for (int i = width - 1; i >= 0; --i) {
1488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            unsigned sa;
1498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            // scale our src by the alpha value
1508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            {
1518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                int aa = alpha[i];
15282065d667f64e232bcde2ad849756a6096fcbe6freed@google.com                if (aa == 0) {
1538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                    continue;
15482065d667f64e232bcde2ad849756a6096fcbe6freed@google.com                }
15582065d667f64e232bcde2ad849756a6096fcbe6freed@google.com                if (aa == 255) {
15682065d667f64e232bcde2ad849756a6096fcbe6freed@google.com                    if (srcA == 255) {
1578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                        device[i] = 0xFF;
1588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                        continue;
1598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                    }
1608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                    sa = srcA;
16182065d667f64e232bcde2ad849756a6096fcbe6freed@google.com                } else {
1628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                    sa = SkAlphaMul(srcA, SkAlpha255To256(aa));
16382065d667f64e232bcde2ad849756a6096fcbe6freed@google.com                }
1648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            }
1658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            int scale = 256 - SkAlpha255To256(sa);
1678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            device[i] = SkToU8(sa + SkAlphaMul(device[i], scale));
1688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
1698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        device += fDevice.rowBytes();
1708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        alpha += mask.fRowBytes;
1718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
17482065d667f64e232bcde2ad849756a6096fcbe6freed@google.com///////////////////////////////////////////////////////////////////////////////
1758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
17682065d667f64e232bcde2ad849756a6096fcbe6freed@google.comvoid SkA8_Blitter::blitV(int x, int y, int height, SkAlpha alpha) {
17782065d667f64e232bcde2ad849756a6096fcbe6freed@google.com    if (fSrcA == 0) {
1788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return;
17982065d667f64e232bcde2ad849756a6096fcbe6freed@google.com    }
1808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    unsigned sa = SkAlphaMul(fSrcA, SkAlpha255To256(alpha));
1828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    uint8_t* device = fDevice.getAddr8(x, y);
183e5f48243bdbed2662be7a31be0888abc273b09e8scroggo@google.com    size_t   rowBytes = fDevice.rowBytes();
1848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
18582065d667f64e232bcde2ad849756a6096fcbe6freed@google.com    if (sa == 0xFF) {
18682065d667f64e232bcde2ad849756a6096fcbe6freed@google.com        for (int i = 0; i < height; i++) {
1878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            *device = SkToU8(sa);
1888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            device += rowBytes;
1898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
19082065d667f64e232bcde2ad849756a6096fcbe6freed@google.com    } else {
1918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        unsigned scale = 256 - SkAlpha255To256(sa);
1928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
19382065d667f64e232bcde2ad849756a6096fcbe6freed@google.com        for (int i = 0; i < height; i++) {
1948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            *device = SkToU8(sa + SkAlphaMul(*device, scale));
1958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            device += rowBytes;
1968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
1978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
20082065d667f64e232bcde2ad849756a6096fcbe6freed@google.comvoid SkA8_Blitter::blitRect(int x, int y, int width, int height) {
20182065d667f64e232bcde2ad849756a6096fcbe6freed@google.com    SkASSERT(x >= 0 && y >= 0 &&
20282065d667f64e232bcde2ad849756a6096fcbe6freed@google.com             (unsigned)(x + width) <= (unsigned)fDevice.width() &&
20382065d667f64e232bcde2ad849756a6096fcbe6freed@google.com             (unsigned)(y + height) <= (unsigned)fDevice.height());
2048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
20582065d667f64e232bcde2ad849756a6096fcbe6freed@google.com    if (fSrcA == 0) {
2068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return;
20782065d667f64e232bcde2ad849756a6096fcbe6freed@google.com    }
2088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    uint8_t*    device = fDevice.getAddr8(x, y);
2108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    unsigned    srcA = fSrcA;
2118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
21282065d667f64e232bcde2ad849756a6096fcbe6freed@google.com    if (srcA == 255) {
21382065d667f64e232bcde2ad849756a6096fcbe6freed@google.com        while (--height >= 0) {
2148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            memset(device, 0xFF, width);
2158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            device += fDevice.rowBytes();
2168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
21782065d667f64e232bcde2ad849756a6096fcbe6freed@google.com    } else {
2188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        unsigned scale = 256 - SkAlpha255To256(srcA);
2198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
22082065d667f64e232bcde2ad849756a6096fcbe6freed@google.com        while (--height >= 0) {
22182065d667f64e232bcde2ad849756a6096fcbe6freed@google.com            for (int i = 0; i < width; i++) {
2228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                device[i] = SkToU8(srcA + SkAlphaMul(device[i], scale));
2238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            }
2248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            device += fDevice.rowBytes();
2258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
2268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
2278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////
2308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkA8_Shader_Blitter::SkA8_Shader_Blitter(const SkBitmap& device, const SkPaint& paint)
23282065d667f64e232bcde2ad849756a6096fcbe6freed@google.com    : INHERITED(device, paint) {
23382065d667f64e232bcde2ad849756a6096fcbe6freed@google.com    if ((fXfermode = paint.getXfermode()) != NULL) {
2348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fXfermode->ref();
2358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkASSERT(fShader);
2368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
2378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int width = device.width();
2398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fBuffer = (SkPMColor*)sk_malloc_throw(sizeof(SkPMColor) * (width + (SkAlign4(width) >> 2)));
2408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fAAExpand = (uint8_t*)(fBuffer + width);
2418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
24382065d667f64e232bcde2ad849756a6096fcbe6freed@google.comSkA8_Shader_Blitter::~SkA8_Shader_Blitter() {
24457f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com    if (fXfermode) SkSafeUnref(fXfermode);
2458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    sk_free(fBuffer);
2468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
24882065d667f64e232bcde2ad849756a6096fcbe6freed@google.comvoid SkA8_Shader_Blitter::blitH(int x, int y, int width) {
24982065d667f64e232bcde2ad849756a6096fcbe6freed@google.com    SkASSERT(x >= 0 && y >= 0 &&
25082065d667f64e232bcde2ad849756a6096fcbe6freed@google.com             (unsigned)(x + width) <= (unsigned)fDevice.width());
2518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    uint8_t* device = fDevice.getAddr8(x, y);
2538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
25482065d667f64e232bcde2ad849756a6096fcbe6freed@google.com    if ((fShader->getFlags() & SkShader::kOpaqueAlpha_Flag) && !fXfermode) {
2558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        memset(device, 0xFF, width);
25682065d667f64e232bcde2ad849756a6096fcbe6freed@google.com    } else {
2578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkPMColor*  span = fBuffer;
2588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fShader->shadeSpan(x, y, span, width);
26082065d667f64e232bcde2ad849756a6096fcbe6freed@google.com        if (fXfermode) {
2618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            fXfermode->xferA8(device, span, width, NULL);
26282065d667f64e232bcde2ad849756a6096fcbe6freed@google.com        } else {
26382065d667f64e232bcde2ad849756a6096fcbe6freed@google.com            for (int i = width - 1; i >= 0; --i) {
2648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                unsigned    srcA = SkGetPackedA32(span[i]);
2658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                unsigned    scale = 256 - SkAlpha255To256(srcA);
2668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                device[i] = SkToU8(srcA + SkAlphaMul(device[i], scale));
2688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            }
2698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
2708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
2718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
27382065d667f64e232bcde2ad849756a6096fcbe6freed@google.comstatic inline uint8_t aa_blend8(SkPMColor src, U8CPU da, int aa) {
2748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkASSERT((unsigned)aa <= 255);
2758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int src_scale = SkAlpha255To256(aa);
2778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int sa = SkGetPackedA32(src);
2788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int dst_scale = 256 - SkAlphaMul(sa, src_scale);
2798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return SkToU8((sa * src_scale + da * dst_scale) >> 8);
2818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
28382065d667f64e232bcde2ad849756a6096fcbe6freed@google.comvoid SkA8_Shader_Blitter::blitAntiH(int x, int y, const SkAlpha antialias[],
28482065d667f64e232bcde2ad849756a6096fcbe6freed@google.com                                    const int16_t runs[]) {
2858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkShader*   shader = fShader;
2868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkXfermode* mode = fXfermode;
2878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    uint8_t*    aaExpand = fAAExpand;
2888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkPMColor*  span = fBuffer;
2898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    uint8_t*    device = fDevice.getAddr8(x, y);
2908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int         opaque = fShader->getFlags() & SkShader::kOpaqueAlpha_Flag;
2918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
29282065d667f64e232bcde2ad849756a6096fcbe6freed@google.com    for (;;) {
2938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        int count = *runs;
29482065d667f64e232bcde2ad849756a6096fcbe6freed@google.com        if (count == 0) {
2958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            break;
29682065d667f64e232bcde2ad849756a6096fcbe6freed@google.com        }
2978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        int aa = *antialias;
29882065d667f64e232bcde2ad849756a6096fcbe6freed@google.com        if (aa) {
29982065d667f64e232bcde2ad849756a6096fcbe6freed@google.com            if (opaque && aa == 255 && mode == NULL) {
3008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                memset(device, 0xFF, count);
30182065d667f64e232bcde2ad849756a6096fcbe6freed@google.com            } else {
3028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                shader->shadeSpan(x, y, span, count);
30382065d667f64e232bcde2ad849756a6096fcbe6freed@google.com                if (mode) {
3048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                    memset(aaExpand, aa, count);
3058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                    mode->xferA8(device, span, count, aaExpand);
30682065d667f64e232bcde2ad849756a6096fcbe6freed@google.com                } else {
30782065d667f64e232bcde2ad849756a6096fcbe6freed@google.com                    for (int i = count - 1; i >= 0; --i) {
3088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                        device[i] = aa_blend8(span[i], device[i], aa);
30982065d667f64e232bcde2ad849756a6096fcbe6freed@google.com                    }
3108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                }
3118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            }
3128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
3138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        device += count;
3148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        runs += count;
3158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        antialias += count;
3168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        x += count;
31782065d667f64e232bcde2ad849756a6096fcbe6freed@google.com    }
3188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
3198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
32082065d667f64e232bcde2ad849756a6096fcbe6freed@google.comvoid SkA8_Shader_Blitter::blitMask(const SkMask& mask, const SkIRect& clip) {
32182065d667f64e232bcde2ad849756a6096fcbe6freed@google.com    if (mask.fFormat == SkMask::kBW_Format) {
3228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        this->INHERITED::blitMask(mask, clip);
3238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return;
3248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
32582065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
3268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int x = clip.fLeft;
3278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int y = clip.fTop;
3288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int width = clip.width();
3298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int height = clip.height();
3308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    uint8_t* device = fDevice.getAddr8(x, y);
3317989186dab6bc2f1c1927daf91bddd32b7fd8d0creed@google.com    const uint8_t* alpha = mask.getAddr8(x, y);
3328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkPMColor*  span = fBuffer;
3348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
33582065d667f64e232bcde2ad849756a6096fcbe6freed@google.com    while (--height >= 0) {
3368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fShader->shadeSpan(x, y, span, width);
33757f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com        if (fXfermode) {
33857f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com            fXfermode->xferA8(device, span, width, alpha);
33996583db7990ec524b6410c539518ebbc9844c5eccommit-bot@chromium.org        } else {
34096583db7990ec524b6410c539518ebbc9844c5eccommit-bot@chromium.org            for (int i = width - 1; i >= 0; --i) {
34196583db7990ec524b6410c539518ebbc9844c5eccommit-bot@chromium.org                device[i] = aa_blend8(span[i], device[i], alpha[i]);
34296583db7990ec524b6410c539518ebbc9844c5eccommit-bot@chromium.org            }
34357f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com        }
34482065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
3458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        y += 1;
3468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        device += fDevice.rowBytes();
3478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        alpha += mask.fRowBytes;
3488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
3498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
350126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com
351126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com///////////////////////////////////////////////////////////////////////////////
352126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com
353126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com#define SK_A8_COVERAGE_BLIT_SKIP_ZEROS
354126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com
355126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.comSkA8_Coverage_Blitter::SkA8_Coverage_Blitter(const SkBitmap& device,
356126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com                             const SkPaint& paint) : SkRasterBlitter(device) {
357126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com    SkASSERT(NULL == paint.getShader());
358126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com    SkASSERT(NULL == paint.getXfermode());
359126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com    SkASSERT(NULL == paint.getColorFilter());
360126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com}
361126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com
362126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.comvoid SkA8_Coverage_Blitter::blitAntiH(int x, int y, const SkAlpha antialias[],
363126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com                                      const int16_t runs[]) {
364126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com    SkASSERT(0 == x);
365126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com
366126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com    uint8_t* device = fDevice.getAddr8(x, y);
367126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com    SkDEBUGCODE(int totalCount = 0;)
368ab7442c8d733e0642d1cd80af23cdab43d77039eskia.committer@gmail.com
369126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com    for (;;) {
370126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com        int count = runs[0];
371126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com        SkASSERT(count >= 0);
372126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com        if (count == 0) {
373126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com            return;
374126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com        }
375126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com#ifdef SK_A8_COVERAGE_BLIT_SKIP_ZEROS
376126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com        if (antialias[0])
377126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com#endif
378126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com        {
379126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com            memset(device, antialias[0], count);
380126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com        }
381126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com        runs += count;
382126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com        antialias += count;
383126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com        device += count;
384126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com
385126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com        SkDEBUGCODE(totalCount += count;)
386126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com    }
387126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com    SkASSERT(fDevice.width() == totalCount);
388126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com}
389126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com
390126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.comvoid SkA8_Coverage_Blitter::blitH(int x, int y, int width) {
391126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com    memset(fDevice.getAddr8(x, y), 0xFF, width);
392126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com}
393126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com
394126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.comvoid SkA8_Coverage_Blitter::blitV(int x, int y, int height, SkAlpha alpha) {
395126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com#ifdef SK_A8_COVERAGE_BLIT_SKIP_ZEROS
396126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com    if (0 == alpha) {
397126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com        return;
398126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com    }
399126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com#endif
400126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com    uint8_t* dst = fDevice.getAddr8(x, y);
401126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com    const size_t dstRB = fDevice.rowBytes();
402126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com    while (--height >= 0) {
403126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com        *dst = alpha;
404126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com        dst += dstRB;
405126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com    }
406126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com}
407126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com
408126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.comvoid SkA8_Coverage_Blitter::blitRect(int x, int y, int width, int height) {
409126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com    uint8_t* dst = fDevice.getAddr8(x, y);
410126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com    const size_t dstRB = fDevice.rowBytes();
411126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com    while (--height >= 0) {
412126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com        memset(dst, 0xFF, width);
413126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com        dst += dstRB;
414126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com    }
415126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com}
416126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com
417126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.comvoid SkA8_Coverage_Blitter::blitMask(const SkMask& mask, const SkIRect& clip) {
418126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com    SkASSERT(SkMask::kA8_Format == mask.fFormat);
419126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com
420126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com    int x = clip.fLeft;
421126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com    int y = clip.fTop;
422126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com    int width = clip.width();
423126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com    int height = clip.height();
424126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com
425126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com    uint8_t* dst = fDevice.getAddr8(x, y);
426126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com    const uint8_t* src = mask.getAddr8(x, y);
427126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com    const size_t srcRB = mask.fRowBytes;
428126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com    const size_t dstRB = fDevice.rowBytes();
429ab7442c8d733e0642d1cd80af23cdab43d77039eskia.committer@gmail.com
430126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com    while (--height >= 0) {
431126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com        memcpy(dst, src, width);
432126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com        dst += dstRB;
433126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com        src += srcRB;
434126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com    }
435126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com}
436126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com
437126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.comconst SkBitmap* SkA8_Coverage_Blitter::justAnOpaqueColor(uint32_t*) {
438126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com    return NULL;
439126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com}
440