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