11cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
21cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/*
31cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Copyright 2006 The Android Open Source Project
41cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *
51cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be
61cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * found in the LICENSE file.
71cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */
81cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
90910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkBlitter.h"
110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkAntiRun.h"
120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkColor.h"
130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkColorFilter.h"
140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkMask.h"
150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkMaskFilter.h"
160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkTemplatesPriv.h"
170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkUtils.h"
180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkXfermode.h"
190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2059f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike ReedSkBlitter::~SkBlitter() {}
210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerconst SkBitmap* SkBlitter::justAnOpaqueColor(uint32_t* value) {
230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return NULL;
240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkBlitter::blitH(int x, int y, int width) {
271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkDEBUGFAIL("unimplemented");
280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkBlitter::blitAntiH(int x, int y, const SkAlpha antialias[],
3140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                          const int16_t runs[]) {
321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkDEBUGFAIL("unimplemented");
330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkBlitter::blitV(int x, int y, int height, SkAlpha alpha) {
3640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (alpha == 255) {
370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        this->blitRect(x, y, 1, height);
3840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    } else {
390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int16_t runs[2];
400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        runs[0] = 1;
410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        runs[1] = 0;
420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        while (--height >= 0) {
440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            this->blitAntiH(x, y++, &alpha, runs);
4540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        }
460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkBlitter::blitRect(int x, int y, int width, int height) {
501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkASSERT(width > 0);
5140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    while (--height >= 0) {
520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        this->blitH(x, y++, width);
5340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    }
540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/// Default implementation doesn't check for any easy optimizations
571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/// such as alpha == 0 or 255; also uses blitV(), which some subclasses
581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/// may not support.
591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid SkBlitter::blitAntiRect(int x, int y, int width, int height,
601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                             SkAlpha leftAlpha, SkAlpha rightAlpha) {
611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    this->blitV(x++, y, height, leftAlpha);
621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (width > 0) {
631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        this->blitRect(x, y, width, height);
641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        x += width;
651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    this->blitV(x, y, height, rightAlpha);
671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project//////////////////////////////////////////////////////////////////////////////
700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic inline void bits_to_runs(SkBlitter* blitter, int x, int y,
7240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                                const uint8_t bits[],
7340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                                U8CPU left_mask, int rowBytes,
7440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                                U8CPU right_mask) {
750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int inFill = 0;
760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int pos = 0;
770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    while (--rowBytes >= 0) {
790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        unsigned b = *bits++ & left_mask;
8040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        if (rowBytes == 0) {
810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            b &= right_mask;
8240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        }
830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        for (unsigned test = 0x80; test != 0; test >>= 1) {
8540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            if (b & test) {
8640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                if (!inFill) {
870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    pos = x;
880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    inFill = true;
890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
9040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            } else {
9140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                if (inFill) {
920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    blitter->blitH(pos, y, x - pos);
930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    inFill = false;
940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            x += 1;
970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        left_mask = 0xFF;
990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
1000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // final cleanup
10240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (inFill) {
1030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        blitter->blitH(pos, y, x - pos);
10440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    }
1050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkBlitter::blitMask(const SkMask& mask, const SkIRect& clip) {
1080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(mask.fBounds.contains(clip));
1090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (mask.fFormat == SkMask::kBW_Format) {
1110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int cx = clip.fLeft;
1120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int cy = clip.fTop;
1130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int maskLeft = mask.fBounds.fLeft;
1140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int mask_rowBytes = mask.fRowBytes;
1150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int height = clip.height();
1160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        const uint8_t* bits = mask.getAddr1(cx, cy);
1180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        if (cx == maskLeft && clip.fRight == mask.fBounds.fRight) {
12040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            while (--height >= 0) {
1210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                bits_to_runs(this, cx, cy, bits, 0xFF, mask_rowBytes, 0xFF);
1220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                bits += mask_rowBytes;
1230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                cy += 1;
1240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
12540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        } else {
1260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            int left_edge = cx - maskLeft;
1270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkASSERT(left_edge >= 0);
1280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            int rite_edge = clip.fRight - maskLeft;
1290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkASSERT(rite_edge > left_edge);
1300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            int left_mask = 0xFF >> (left_edge & 7);
1320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            int rite_mask = 0xFF << (8 - (rite_edge & 7));
1330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            int full_runs = (rite_edge >> 3) - ((left_edge + 7) >> 3);
1340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            // check for empty right mask, so we don't read off the end (or go slower than we need to)
13640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            if (rite_mask == 0) {
1370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SkASSERT(full_runs >= 0);
1380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                full_runs -= 1;
1390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                rite_mask = 0xFF;
1400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
14140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            if (left_mask == 0xFF) {
1420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                full_runs -= 1;
14340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            }
1440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            // back up manually so we can keep in sync with our byte-aligned src
1460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            // have cx reflect our actual starting x-coord
1470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            cx -= left_edge & 7;
1480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
14940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            if (full_runs < 0) {
1500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SkASSERT((left_mask & rite_mask) != 0);
15140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                while (--height >= 0) {
1520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    bits_to_runs(this, cx, cy, bits, left_mask, 1, rite_mask);
1530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    bits += mask_rowBytes;
1540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    cy += 1;
1550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
15640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            } else {
15740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                while (--height >= 0) {
1580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    bits_to_runs(this, cx, cy, bits, left_mask, full_runs + 2, rite_mask);
1590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    bits += mask_rowBytes;
1600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    cy += 1;
1610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
1620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
1630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
16440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    } else {
1650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int                         width = clip.width();
1660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkAutoSTMalloc<64, int16_t> runStorage(width + 1);
1670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int16_t*                    runs = runStorage.get();
1681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        const uint8_t*              aa = mask.getAddr8(clip.fLeft, clip.fTop);
1690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_memset16((uint16_t*)runs, 1, width);
1710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        runs[width] = 0;
1720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int height = clip.height();
1740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int y = clip.fTop;
17540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        while (--height >= 0) {
1760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            this->blitAntiH(clip.fLeft, y, aa, runs);
1770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            aa += mask.fRowBytes;
1780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            y += 1;
1790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
1800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
1810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/////////////////////// these guys are not virtual, just a helpers
1840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkBlitter::blitMaskRegion(const SkMask& mask, const SkRegion& clip) {
1860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (clip.quickReject(mask.fBounds)) {
1870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return;
1880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
18940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
1900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRegion::Cliperator clipper(clip, mask.fBounds);
19140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
1920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    while (!clipper.done()) {
1930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        const SkIRect& cr = clipper.rect();
1940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        this->blitMask(mask, cr);
1950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        clipper.next();
1960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
1970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkBlitter::blitRectRegion(const SkIRect& rect, const SkRegion& clip) {
2000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRegion::Cliperator clipper(clip, rect);
20140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
2020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    while (!clipper.done()) {
2030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        const SkIRect& cr = clipper.rect();
2040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        this->blitRect(cr.fLeft, cr.fTop, cr.width(), cr.height());
2050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        clipper.next();
2060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
2070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkBlitter::blitRegion(const SkRegion& clip) {
2100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRegion::Iterator iter(clip);
21140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
2120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    while (!iter.done()) {
2130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        const SkIRect& cr = iter.rect();
2140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        this->blitRect(cr.fLeft, cr.fTop, cr.width(), cr.height());
2150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        iter.next();
2160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
2170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
21940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger///////////////////////////////////////////////////////////////////////////////
2200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
22140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkNullBlitter::blitH(int x, int y, int width) {}
2220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
22340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkNullBlitter::blitAntiH(int x, int y, const SkAlpha antialias[],
22440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                              const int16_t runs[]) {}
2250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
22640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkNullBlitter::blitV(int x, int y, int height, SkAlpha alpha) {}
2270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
22840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkNullBlitter::blitRect(int x, int y, int width, int height) {}
2290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
23040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkNullBlitter::blitMask(const SkMask& mask, const SkIRect& clip) {}
2310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
23240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerconst SkBitmap* SkNullBlitter::justAnOpaqueColor(uint32_t* value) {
2330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return NULL;
2340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
23640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger///////////////////////////////////////////////////////////////////////////////
2370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
23840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic int compute_anti_width(const int16_t runs[]) {
2390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int width = 0;
24040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
24140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    for (;;) {
2420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int count = runs[0];
24340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
2440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(count >= 0);
24540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        if (count == 0) {
2460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            break;
24740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        }
2480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        width += count;
2490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        runs += count;
2500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
2510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return width;
2520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
25440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic inline bool y_in_rect(int y, const SkIRect& rect) {
2550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return (unsigned)(y - rect.fTop) < (unsigned)rect.height();
2560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
25840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic inline bool x_in_rect(int x, const SkIRect& rect) {
2590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return (unsigned)(x - rect.fLeft) < (unsigned)rect.width();
2600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
26240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkRectClipBlitter::blitH(int left, int y, int width) {
2630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(width > 0);
2640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
26540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (!y_in_rect(y, fClipRect)) {
2660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return;
26740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    }
2680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int right = left + width;
2700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
27140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (left < fClipRect.fLeft) {
2720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        left = fClipRect.fLeft;
27340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    }
27440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (right > fClipRect.fRight) {
2750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        right = fClipRect.fRight;
27640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    }
2770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    width = right - left;
27940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (width > 0) {
2800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fBlitter->blitH(left, y, width);
28140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    }
2820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
28440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkRectClipBlitter::blitAntiH(int left, int y, const SkAlpha aa[],
28540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                                  const int16_t runs[]) {
28640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (!y_in_rect(y, fClipRect) || left >= fClipRect.fRight) {
2870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return;
28840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    }
2890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int x0 = left;
2910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int x1 = left + compute_anti_width(runs);
2920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
29340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (x1 <= fClipRect.fLeft) {
2940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return;
29540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    }
2960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(x0 < x1);
29840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (x0 < fClipRect.fLeft) {
2990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int dx = fClipRect.fLeft - x0;
3000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkAlphaRuns::BreakAt((int16_t*)runs, (uint8_t*)aa, dx);
3010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        runs += dx;
3020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        aa += dx;
3030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        x0 = fClipRect.fLeft;
3040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
3050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(x0 < x1 && runs[x1 - x0] == 0);
30740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (x1 > fClipRect.fRight) {
3080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        x1 = fClipRect.fRight;
3090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkAlphaRuns::BreakAt((int16_t*)runs, (uint8_t*)aa, x1 - x0);
3100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        ((int16_t*)runs)[x1 - x0] = 0;
3110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
3120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(x0 < x1 && runs[x1 - x0] == 0);
3140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(compute_anti_width(runs) == x1 - x0);
3150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fBlitter->blitAntiH(x0, y, aa, runs);
3170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
3180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
31940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkRectClipBlitter::blitV(int x, int y, int height, SkAlpha alpha) {
3200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(height > 0);
3210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
32240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (!x_in_rect(x, fClipRect)) {
3230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return;
32440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    }
3250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int y0 = y;
3270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int y1 = y + height;
3280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
32940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (y0 < fClipRect.fTop) {
3300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        y0 = fClipRect.fTop;
33140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    }
33240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (y1 > fClipRect.fBottom) {
3330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        y1 = fClipRect.fBottom;
33440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    }
3350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
33640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (y0 < y1) {
3370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fBlitter->blitV(x, y0, y1 - y0, alpha);
33840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    }
3390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
3400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
34140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkRectClipBlitter::blitRect(int left, int y, int width, int height) {
3420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkIRect    r;
3430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    r.set(left, y, left + width, y + height);
34540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (r.intersect(fClipRect)) {
3460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fBlitter->blitRect(r.fLeft, r.fTop, r.width(), r.height());
34740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    }
3480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
3490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid SkRectClipBlitter::blitAntiRect(int left, int y, int width, int height,
3511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                     SkAlpha leftAlpha, SkAlpha rightAlpha) {
3521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkIRect    r;
3531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
3541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // The *true* width of the rectangle blitted is width+2:
3551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    r.set(left, y, left + width + 2, y + height);
3561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (r.intersect(fClipRect)) {
3571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (r.fLeft != left) {
3581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            SkASSERT(r.fLeft > left);
3591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            leftAlpha = 255;
3601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
3611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (r.fRight != left + width + 2) {
3621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            SkASSERT(r.fRight < left + width + 2);
3631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            rightAlpha = 255;
3641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
3651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (255 == leftAlpha && 255 == rightAlpha) {
3661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            fBlitter->blitRect(r.fLeft, r.fTop, r.width(), r.height());
3671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        } else if (1 == r.width()) {
3681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            if (r.fLeft == left) {
3691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                fBlitter->blitV(r.fLeft, r.fTop, r.height(), leftAlpha);
3701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            } else {
3711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                SkASSERT(r.fLeft == left + width + 1);
3721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                fBlitter->blitV(r.fLeft, r.fTop, r.height(), rightAlpha);
3731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            }
3741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        } else {
3751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            fBlitter->blitAntiRect(r.fLeft, r.fTop, r.width() - 2, r.height(),
3761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                   leftAlpha, rightAlpha);
3771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
3781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
3791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
3801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
38140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkRectClipBlitter::blitMask(const SkMask& mask, const SkIRect& clip) {
3820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(mask.fBounds.contains(clip));
3830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkIRect    r = clip;
3850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
38640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (r.intersect(fClipRect)) {
3870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fBlitter->blitMask(mask, r);
38840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    }
3890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
3900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
39140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerconst SkBitmap* SkRectClipBlitter::justAnOpaqueColor(uint32_t* value) {
3920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return fBlitter->justAnOpaqueColor(value);
3930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
3940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
39540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger///////////////////////////////////////////////////////////////////////////////
3960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
39740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkRgnClipBlitter::blitH(int x, int y, int width) {
3980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRegion::Spanerator span(*fRgn, y, x, x + width);
3990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int left, right;
4000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
40140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    while (span.next(&left, &right)) {
4020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(left < right);
4030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fBlitter->blitH(left, y, right - left);
4040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
4050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
4060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
40740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkRgnClipBlitter::blitAntiH(int x, int y, const SkAlpha aa[],
40840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                                 const int16_t runs[]) {
4090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int width = compute_anti_width(runs);
4100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRegion::Spanerator span(*fRgn, y, x, x + width);
4110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int left, right;
4120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkDEBUGCODE(const SkIRect& bounds = fRgn->getBounds();)
41340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
4140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int prevRite = x;
41540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    while (span.next(&left, &right)) {
4160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(x <= left);
4170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(left < right);
4180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(left >= bounds.fLeft && right <= bounds.fRight);
41940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
4200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkAlphaRuns::Break((int16_t*)runs, (uint8_t*)aa, left - x, right - left);
4210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // now zero before left
42340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        if (left > prevRite) {
4240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            int index = prevRite - x;
4250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            ((uint8_t*)aa)[index] = 0;   // skip runs after right
4260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            ((int16_t*)runs)[index] = SkToS16(left - prevRite);
4270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
42840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
4290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        prevRite = right;
4300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
43140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
43240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (prevRite > x) {
4330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        ((int16_t*)runs)[prevRite - x] = 0;
43440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
4350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (x < 0) {
4360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            int skip = runs[0];
4370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkASSERT(skip >= -x);
4380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            aa += skip;
4390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            runs += skip;
4400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            x += skip;
4410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
4420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fBlitter->blitAntiH(x, y, aa, runs);
4430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
4440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
4450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
44640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkRgnClipBlitter::blitV(int x, int y, int height, SkAlpha alpha) {
4470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkIRect    bounds;
4480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bounds.set(x, y, x + 1, y + height);
4490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRegion::Cliperator    iter(*fRgn, bounds);
4510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
45240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    while (!iter.done()) {
4530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        const SkIRect& r = iter.rect();
4540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(bounds.contains(r));
4550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fBlitter->blitV(x, r.fTop, r.height(), alpha);
4570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        iter.next();
4580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
4590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
4600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
46140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkRgnClipBlitter::blitRect(int x, int y, int width, int height) {
4620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkIRect    bounds;
4630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bounds.set(x, y, x + width, y + height);
4640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRegion::Cliperator    iter(*fRgn, bounds);
4660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
46740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    while (!iter.done()) {
4680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        const SkIRect& r = iter.rect();
4690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(bounds.contains(r));
4700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fBlitter->blitRect(r.fLeft, r.fTop, r.width(), r.height());
4720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        iter.next();
4730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
4740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
4750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid SkRgnClipBlitter::blitAntiRect(int x, int y, int width, int height,
4771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                    SkAlpha leftAlpha, SkAlpha rightAlpha) {
4781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // The *true* width of the rectangle to blit is width + 2
4791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkIRect    bounds;
4801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    bounds.set(x, y, x + width + 2, y + height);
4811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
4821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkRegion::Cliperator    iter(*fRgn, bounds);
4831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
4841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    while (!iter.done()) {
4851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        const SkIRect& r = iter.rect();
4861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkASSERT(bounds.contains(r));
4871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkASSERT(r.fLeft >= x);
4881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkASSERT(r.fRight <= x + width + 2);
4891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
4901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkAlpha effectiveLeftAlpha = (r.fLeft == x) ? leftAlpha : 255;
4911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkAlpha effectiveRightAlpha = (r.fRight == x + width + 2) ?
4921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                      rightAlpha : 255;
4931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
4941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (255 == effectiveLeftAlpha && 255 == effectiveRightAlpha) {
4951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            fBlitter->blitRect(r.fLeft, r.fTop, r.width(), r.height());
4961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        } else if (1 == r.width()) {
4971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            if (r.fLeft == x) {
4981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                fBlitter->blitV(r.fLeft, r.fTop, r.height(),
4991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                effectiveLeftAlpha);
5001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            } else {
5011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                SkASSERT(r.fLeft == x + width + 1);
5021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                fBlitter->blitV(r.fLeft, r.fTop, r.height(),
5031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                effectiveRightAlpha);
5041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            }
5051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        } else {
5061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            fBlitter->blitAntiRect(r.fLeft, r.fTop, r.width() - 2, r.height(),
5071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                   effectiveLeftAlpha, effectiveRightAlpha);
5081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
5091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        iter.next();
5101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
5111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
5121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
5131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
51440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkRgnClipBlitter::blitMask(const SkMask& mask, const SkIRect& clip) {
5150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(mask.fBounds.contains(clip));
5160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRegion::Cliperator iter(*fRgn, clip);
5180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const SkIRect&       r = iter.rect();
5190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkBlitter*           blitter = fBlitter;
5200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
52140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    while (!iter.done()) {
5220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        blitter->blitMask(mask, r);
5230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        iter.next();
5240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
5250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
5260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
52740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerconst SkBitmap* SkRgnClipBlitter::justAnOpaqueColor(uint32_t* value) {
5280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return fBlitter->justAnOpaqueColor(value);
5290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
5300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
53140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger///////////////////////////////////////////////////////////////////////////////
5320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
53340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek SollenbergerSkBlitter* SkBlitterClipper::apply(SkBlitter* blitter, const SkRegion* clip,
53440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                                   const SkIRect* ir) {
53540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (clip) {
5360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        const SkIRect& clipR = clip->getBounds();
5370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
53840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        if (clip->isEmpty() || (ir && !SkIRect::Intersects(clipR, *ir))) {
5390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            blitter = &fNullBlitter;
54040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        } else if (clip->isRect()) {
54140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            if (ir == NULL || !clipR.contains(*ir)) {
5420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                fRectBlitter.init(blitter, clipR);
5430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                blitter = &fRectBlitter;
5440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
54540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        } else {
5460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            fRgnBlitter.init(blitter, clip);
5470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            blitter = &fRgnBlitter;
5480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
5490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
5500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return blitter;
5510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
5520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
55340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger///////////////////////////////////////////////////////////////////////////////
5540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkColorShader.h"
5560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkColorPriv.h"
5570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectclass Sk3DShader : public SkShader {
5590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic:
56040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    Sk3DShader(SkShader* proxy) : fProxy(proxy) {
56140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        SkSafeRef(proxy);
5620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fMask = NULL;
5630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
56440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
56540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    virtual ~Sk3DShader() {
56640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        SkSafeUnref(fProxy);
5670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
56840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
5690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    void setMask(const SkMask* mask) { fMask = mask; }
5700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
57140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    virtual bool setContext(const SkBitmap& device, const SkPaint& paint,
57240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                            const SkMatrix& matrix) {
57340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        if (fProxy) {
5740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            return fProxy->setContext(device, paint, matrix);
57540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        } else {
5760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            fPMColor = SkPreMultiplyColor(paint.getColor());
5770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            return this->INHERITED::setContext(device, paint, matrix);
5780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
5790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
58040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
58140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    virtual void shadeSpan(int x, int y, SkPMColor span[], int count) {
58240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        if (fProxy) {
5830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            fProxy->shadeSpan(x, y, span, count);
58440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        }
5850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
58640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        if (fMask == NULL) {
58740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            if (fProxy == NULL) {
5880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                sk_memset32(span, fPMColor, count);
58940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            }
5900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            return;
5910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
5920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(fMask->fBounds.contains(x, y));
5940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(fMask->fBounds.contains(x + count - 1, y));
5950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        size_t          size = fMask->computeImageSize();
5971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        const uint8_t*  alpha = fMask->getAddr8(x, y);
5980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        const uint8_t*  mulp = alpha + size;
5990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        const uint8_t*  addp = mulp + size;
6000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
60140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        if (fProxy) {
60240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            for (int i = 0; i < count; i++) {
60340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                if (alpha[i]) {
6040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    SkPMColor c = span[i];
60540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                    if (c) {
6060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        unsigned a = SkGetPackedA32(c);
6070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        unsigned r = SkGetPackedR32(c);
6080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        unsigned g = SkGetPackedG32(c);
6090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        unsigned b = SkGetPackedB32(c);
6100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        unsigned mul = SkAlpha255To256(mulp[i]);
6120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        unsigned add = addp[i];
6130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        r = SkFastMin32(SkAlphaMul(r, mul) + add, a);
6150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        g = SkFastMin32(SkAlphaMul(g, mul) + add, a);
6160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        b = SkFastMin32(SkAlphaMul(b, mul) + add, a);
6170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        span[i] = SkPackARGB32(a, r, g, b);
6190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    }
62040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                } else {
6210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    span[i] = 0;
62240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                }
6230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
62440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        } else {    // color
6250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            unsigned a = SkGetPackedA32(fPMColor);
6260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            unsigned r = SkGetPackedR32(fPMColor);
6270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            unsigned g = SkGetPackedG32(fPMColor);
6280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            unsigned b = SkGetPackedB32(fPMColor);
62940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            for (int i = 0; i < count; i++) {
63040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                if (alpha[i]) {
6310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    unsigned mul = SkAlpha255To256(mulp[i]);
6320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    unsigned add = addp[i];
6330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    span[i] = SkPackARGB32( a,
63540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                                    SkFastMin32(SkAlphaMul(r, mul) + add, a),
63640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                                    SkFastMin32(SkAlphaMul(g, mul) + add, a),
63740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                                    SkFastMin32(SkAlphaMul(b, mul) + add, a));
63840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                } else {
6390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    span[i] = 0;
64040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                }
6410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
6420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
6430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
64440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
64540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    virtual void beginSession() {
6460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        this->INHERITED::beginSession();
64740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        if (fProxy) {
6480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            fProxy->beginSession();
64940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        }
6500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
65140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
65240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    virtual void endSession() {
65340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        if (fProxy) {
6540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            fProxy->endSession();
65540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        }
6560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        this->INHERITED::endSession();
6570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
6580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprotected:
6600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    Sk3DShader(SkFlattenableReadBuffer& buffer) :
66140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            INHERITED(buffer) {
6620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fProxy = static_cast<SkShader*>(buffer.readFlattenable());
6630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fPMColor = buffer.readU32();
6640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fMask = NULL;
6650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
66640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
66740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    virtual void flatten(SkFlattenableWriteBuffer& buffer) {
6680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        this->INHERITED::flatten(buffer);
6690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        buffer.writeFlattenable(fProxy);
6700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        buffer.write32(fPMColor);
6710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
67240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
67340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    virtual Factory getFactory() {
6740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return CreateProc;
6750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
6760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprivate:
67840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
6790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return SkNEW_ARGS(Sk3DShader, (buffer));
6800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
6810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkShader*       fProxy;
6830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkPMColor       fPMColor;
6840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const SkMask*   fMask;
6850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    typedef SkShader INHERITED;
6870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project};
6880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectclass Sk3DBlitter : public SkBlitter {
6900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic:
6910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    Sk3DBlitter(SkBlitter* proxy, Sk3DShader* shader, void (*killProc)(void*))
69240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            : fProxy(proxy), f3DShader(shader), fKillProc(killProc) {
6930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        shader->ref();
6940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
69540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
69640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    virtual ~Sk3DBlitter() {
6970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        f3DShader->unref();
6980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fKillProc(fProxy);
6990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
7000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
70140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    virtual void blitH(int x, int y, int width) {
7020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fProxy->blitH(x, y, width);
7030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
70440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
70540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    virtual void blitAntiH(int x, int y, const SkAlpha antialias[],
70640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                           const int16_t runs[]) {
7070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fProxy->blitAntiH(x, y, antialias, runs);
7080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
70940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
71040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    virtual void blitV(int x, int y, int height, SkAlpha alpha) {
7110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fProxy->blitV(x, y, height, alpha);
7120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
71340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
71440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    virtual void blitRect(int x, int y, int width, int height) {
7150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fProxy->blitRect(x, y, width, height);
7160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
71740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
71840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    virtual void blitMask(const SkMask& mask, const SkIRect& clip) {
71940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        if (mask.fFormat == SkMask::k3D_Format) {
7200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            f3DShader->setMask(&mask);
7210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            ((SkMask*)&mask)->fFormat = SkMask::kA8_Format;
7230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            fProxy->blitMask(mask, clip);
7240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            ((SkMask*)&mask)->fFormat = SkMask::k3D_Format;
7250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            f3DShader->setMask(NULL);
72740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        } else {
7280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            fProxy->blitMask(mask, clip);
72940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        }
7300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
73140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
7320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprivate:
7330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkBlitter*  fProxy;
7340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    Sk3DShader* f3DShader;
7350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    void        (*fKillProc)(void*);
7360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project};
7370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
73840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger///////////////////////////////////////////////////////////////////////////////
7390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkCoreBlitters.h"
7410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectclass SkAutoCallProc {
7430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic:
7440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    typedef void (*Proc)(void*);
74540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
7460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoCallProc(void* obj, Proc proc)
74740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    : fObj(obj), fProc(proc) {}
74840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
74940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    ~SkAutoCallProc() {
75040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        if (fObj && fProc) {
7510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            fProc(fObj);
75240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        }
7530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
75440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
7550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    void* get() const { return fObj; }
75640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
75740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    void* detach() {
7580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        void* obj = fObj;
7590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fObj = NULL;
7600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return obj;
7610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
76240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
7630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprivate:
7640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    void*   fObj;
7650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    Proc    fProc;
7660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project};
7670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
76840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic void destroy_blitter(void* blitter) {
7690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    ((SkBlitter*)blitter)->~SkBlitter();
7700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
7710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
77240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic void delete_blitter(void* blitter) {
7730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkDELETE((SkBlitter*)blitter);
7740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
7750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
776ab1af391811c7721e755a3893539d51565422eccMike Reedstatic bool just_solid_color(const SkPaint& paint) {
777ab1af391811c7721e755a3893539d51565422eccMike Reed    if (paint.getAlpha() == 0xFF && paint.getColorFilter() == NULL) {
778ab1af391811c7721e755a3893539d51565422eccMike Reed        SkShader* shader = paint.getShader();
779ab1af391811c7721e755a3893539d51565422eccMike Reed        if (NULL == shader ||
780ab1af391811c7721e755a3893539d51565422eccMike Reed            (shader->getFlags() & SkShader::kOpaqueAlpha_Flag)) {
781ab1af391811c7721e755a3893539d51565422eccMike Reed            return true;
782ab1af391811c7721e755a3893539d51565422eccMike Reed        }
783ab1af391811c7721e755a3893539d51565422eccMike Reed    }
784ab1af391811c7721e755a3893539d51565422eccMike Reed    return false;
785ab1af391811c7721e755a3893539d51565422eccMike Reed}
78640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
787ab1af391811c7721e755a3893539d51565422eccMike Reed/** By analyzing the paint (with an xfermode), we may decide we can take
788ab1af391811c7721e755a3893539d51565422eccMike Reed    special action. This enum lists our possible actions
789ab1af391811c7721e755a3893539d51565422eccMike Reed */
790ab1af391811c7721e755a3893539d51565422eccMike Reedenum XferInterp {
791ab1af391811c7721e755a3893539d51565422eccMike Reed    kNormal_XferInterp,         // no special interpretation, draw normally
792ab1af391811c7721e755a3893539d51565422eccMike Reed    kSrcOver_XferInterp,        // draw as if in srcover mode
793ab1af391811c7721e755a3893539d51565422eccMike Reed    kSkipDrawing_XferInterp     // draw nothing
794ab1af391811c7721e755a3893539d51565422eccMike Reed};
795ab1af391811c7721e755a3893539d51565422eccMike Reed
796ab1af391811c7721e755a3893539d51565422eccMike Reedstatic XferInterp interpret_xfermode(const SkPaint& paint, SkXfermode* xfer,
797ab1af391811c7721e755a3893539d51565422eccMike Reed                                     SkBitmap::Config deviceConfig) {
79859f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed    SkXfermode::Mode  mode;
79940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
8001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (SkXfermode::AsMode(xfer, &mode)) {
801ab1af391811c7721e755a3893539d51565422eccMike Reed        switch (mode) {
80259f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed            case SkXfermode::kSrc_Mode:
803ab1af391811c7721e755a3893539d51565422eccMike Reed                if (just_solid_color(paint)) {
804ab1af391811c7721e755a3893539d51565422eccMike Reed                    return kSrcOver_XferInterp;
805ab1af391811c7721e755a3893539d51565422eccMike Reed                }
806ab1af391811c7721e755a3893539d51565422eccMike Reed                break;
80759f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed            case SkXfermode::kDst_Mode:
808ab1af391811c7721e755a3893539d51565422eccMike Reed                return kSkipDrawing_XferInterp;
80959f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed            case SkXfermode::kSrcOver_Mode:
810ab1af391811c7721e755a3893539d51565422eccMike Reed                return kSrcOver_XferInterp;
81159f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed            case SkXfermode::kDstOver_Mode:
812ab1af391811c7721e755a3893539d51565422eccMike Reed                if (SkBitmap::kRGB_565_Config == deviceConfig) {
813ab1af391811c7721e755a3893539d51565422eccMike Reed                    return kSkipDrawing_XferInterp;
814ab1af391811c7721e755a3893539d51565422eccMike Reed                }
815ab1af391811c7721e755a3893539d51565422eccMike Reed                break;
81659f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed            case SkXfermode::kSrcIn_Mode:
817ab1af391811c7721e755a3893539d51565422eccMike Reed                if (SkBitmap::kRGB_565_Config == deviceConfig &&
818ab1af391811c7721e755a3893539d51565422eccMike Reed                    just_solid_color(paint)) {
819ab1af391811c7721e755a3893539d51565422eccMike Reed                    return kSrcOver_XferInterp;
820ab1af391811c7721e755a3893539d51565422eccMike Reed                }
821ab1af391811c7721e755a3893539d51565422eccMike Reed                break;
82259f59bde0b05a6ac5ff28fdebc1942dbf0d43aabMike Reed            case SkXfermode::kDstIn_Mode:
823ab1af391811c7721e755a3893539d51565422eccMike Reed                if (just_solid_color(paint)) {
824ab1af391811c7721e755a3893539d51565422eccMike Reed                    return kSkipDrawing_XferInterp;
825ab1af391811c7721e755a3893539d51565422eccMike Reed                }
826ab1af391811c7721e755a3893539d51565422eccMike Reed                break;
827ab1af391811c7721e755a3893539d51565422eccMike Reed            default:
828ab1af391811c7721e755a3893539d51565422eccMike Reed                break;
829ab1af391811c7721e755a3893539d51565422eccMike Reed        }
830ab1af391811c7721e755a3893539d51565422eccMike Reed    }
831ab1af391811c7721e755a3893539d51565422eccMike Reed    return kNormal_XferInterp;
832ab1af391811c7721e755a3893539d51565422eccMike Reed}
833ab1af391811c7721e755a3893539d51565422eccMike Reed
8340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkBlitter* SkBlitter::Choose(const SkBitmap& device,
8350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                             const SkMatrix& matrix,
83635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger                             const SkPaint& origPaint,
83740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                             void* storage, size_t storageSize) {
8380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(storageSize == 0 || storage != NULL);
8390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkBlitter*  blitter = NULL;
8410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // which check, in case we're being called by a client with a dummy device
8430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // (e.g. they have a bounder that always aborts the draw)
84440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (SkBitmap::kNo_Config == device.getConfig()) {
8450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SK_PLACEMENT_NEW(blitter, SkNullBlitter, storage, storageSize);
8460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return blitter;
8470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
8480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
84935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    SkPaint paint(origPaint);
8500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkShader* shader = paint.getShader();
85135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    SkColorFilter* cf = paint.getColorFilter();
85235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    SkXfermode* mode = paint.getXfermode();
8530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    Sk3DShader* shader3D = NULL;
85540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (paint.getMaskFilter() != NULL &&
85640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            paint.getMaskFilter()->getFormat() == SkMask::k3D_Format) {
8570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        shader3D = SkNEW_ARGS(Sk3DShader, (shader));
85835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        paint.setShader(shader3D)->unref();
8590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        shader = shader3D;
8600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
8610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
862ab1af391811c7721e755a3893539d51565422eccMike Reed    if (NULL != mode) {
863ab1af391811c7721e755a3893539d51565422eccMike Reed        switch (interpret_xfermode(paint, mode, device.config())) {
864ab1af391811c7721e755a3893539d51565422eccMike Reed            case kSrcOver_XferInterp:
865ab1af391811c7721e755a3893539d51565422eccMike Reed                mode = NULL;
86635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger                paint.setXfermode(NULL);
867ab1af391811c7721e755a3893539d51565422eccMike Reed                break;
868ab1af391811c7721e755a3893539d51565422eccMike Reed            case kSkipDrawing_XferInterp:
869ab1af391811c7721e755a3893539d51565422eccMike Reed                SK_PLACEMENT_NEW(blitter, SkNullBlitter, storage, storageSize);
870ab1af391811c7721e755a3893539d51565422eccMike Reed                return blitter;
871ab1af391811c7721e755a3893539d51565422eccMike Reed            default:
872ab1af391811c7721e755a3893539d51565422eccMike Reed                break;
873ab1af391811c7721e755a3893539d51565422eccMike Reed        }
874ab1af391811c7721e755a3893539d51565422eccMike Reed    }
875ab1af391811c7721e755a3893539d51565422eccMike Reed
87635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    if (NULL == shader) {
87735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger#ifdef SK_IGNORE_CF_OPTIMIZATION
87835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        if (mode || cf) {
87935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger#else
88035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        if (mode) {
88135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger#endif
88235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger            // xfermodes (and filters) require shaders for our current blitters
88335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger            shader = SkNEW(SkColorShader);
88435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger            paint.setShader(shader)->unref();
88535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        } else if (cf) {
88635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger            // if no shader && no xfermode, we just apply the colorfilter to
88735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger            // our color and move on.
88835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger            paint.setColor(cf->filterColor(paint.getColor()));
88935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger            paint.setColorFilter(NULL);
89035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger            cf = NULL;
89135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        }
8920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
89340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
89435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    if (cf) {
8950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(shader);
89635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        shader = SkNEW_ARGS(SkFilterShader, (shader, cf));
89735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        paint.setShader(shader)->unref();
8984663d79a396bd4d45a9140626921c9fbad77fbf8Mike Reed        // blitters should ignore the presence/absence of a filter, since
8994663d79a396bd4d45a9140626921c9fbad77fbf8Mike Reed        // if there is one, the shader will take care of it.
9000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
90140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
9023026a9ec59b285412941d278a570e382088f8adaMike Reed    if (shader && !shader->setContext(device, paint, matrix)) {
9033026a9ec59b285412941d278a570e382088f8adaMike Reed        return SkNEW(SkNullBlitter);
9040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
9050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    switch (device.getConfig()) {
90740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        case SkBitmap::kA1_Config:
90840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            SK_PLACEMENT_NEW_ARGS(blitter, SkA1_Blitter,
90940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                                  storage, storageSize, (device, paint));
91040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            break;
91140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
91240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        case SkBitmap::kA8_Config:
91340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            if (shader) {
91440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                SK_PLACEMENT_NEW_ARGS(blitter, SkA8_Shader_Blitter,
91540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                                      storage, storageSize, (device, paint));
91640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            } else {
91740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                SK_PLACEMENT_NEW_ARGS(blitter, SkA8_Blitter,
91840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                                      storage, storageSize, (device, paint));
91940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            }
92040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            break;
92140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
92240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        case SkBitmap::kARGB_4444_Config:
92340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            blitter = SkBlitter_ChooseD4444(device, paint, storage, storageSize);
92440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            break;
92540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
92640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        case SkBitmap::kRGB_565_Config:
92740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            blitter = SkBlitter_ChooseD565(device, paint, storage, storageSize);
92840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            break;
92940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
93040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        case SkBitmap::kARGB_8888_Config:
93140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            if (shader) {
93240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                SK_PLACEMENT_NEW_ARGS(blitter, SkARGB32_Shader_Blitter,
93340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                                      storage, storageSize, (device, paint));
93440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            } else if (paint.getColor() == SK_ColorBLACK) {
93540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                SK_PLACEMENT_NEW_ARGS(blitter, SkARGB32_Black_Blitter,
93640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                                      storage, storageSize, (device, paint));
93740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            } else if (paint.getAlpha() == 0xFF) {
93840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                SK_PLACEMENT_NEW_ARGS(blitter, SkARGB32_Opaque_Blitter,
93940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                                      storage, storageSize, (device, paint));
94040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            } else {
94140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                SK_PLACEMENT_NEW_ARGS(blitter, SkARGB32_Blitter,
94240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                                      storage, storageSize, (device, paint));
94340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            }
94440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            break;
94540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
94640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        default:
9471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            SkDEBUGFAIL("unsupported device config");
94840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            SK_PLACEMENT_NEW(blitter, SkNullBlitter, storage, storageSize);
94940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            break;
9500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
9510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
95240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (shader3D) {
9530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        void (*proc)(void*) = ((void*)storage == (void*)blitter) ? destroy_blitter : delete_blitter;
9540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkAutoCallProc  tmp(blitter, proc);
9550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        blitter = SkNEW_ARGS(Sk3DBlitter, (blitter, shader3D, proc));
9570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        (void)tmp.detach();
9580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
9590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return blitter;
9600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
9610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
96240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger///////////////////////////////////////////////////////////////////////////////
9630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectconst uint16_t gMask_0F0F = 0xF0F;
9650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectconst uint32_t gMask_00FF00FF = 0xFF00FF;
9660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
96740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger///////////////////////////////////////////////////////////////////////////////
9680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkShaderBlitter::SkShaderBlitter(const SkBitmap& device, const SkPaint& paint)
970f294d10d594ac335ea3bd09caec89004d41edc5cMike Reed        : INHERITED(device) {
9710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fShader = paint.getShader();
9720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(fShader);
9730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fShader->ref();
9750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fShader->beginSession();
976f294d10d594ac335ea3bd09caec89004d41edc5cMike Reed    fShaderFlags = fShader->getFlags();
9770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
9780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
979f294d10d594ac335ea3bd09caec89004d41edc5cMike ReedSkShaderBlitter::~SkShaderBlitter() {
9800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fShader->endSession();
9810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fShader->unref();
9820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
9830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
984