1b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com/* 2b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com * Copyright 2013 Google Inc. 3b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com * 4b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com * Use of this source code is governed by a BSD-style license that can be 5b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com * found in the LICENSE file. 6b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com */ 7b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com 8b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com#include "SkLerpXfermode.h" 9b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com#include "SkColorPriv.h" 108b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#include "SkReadBuffer.h" 118b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#include "SkWriteBuffer.h" 12b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com#include "SkString.h" 13b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com 14b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.comSkXfermode* SkLerpXfermode::Create(SkScalar scale) { 15b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com int scale256 = SkScalarRoundToInt(scale * 256); 16b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com if (scale256 >= 256) { 17b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com return SkXfermode::Create(SkXfermode::kSrc_Mode); 18b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com } else if (scale256 <= 0) { 19b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com return SkXfermode::Create(SkXfermode::kDst_Mode); 20b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com } 21b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com return SkNEW_ARGS(SkLerpXfermode, (scale256)); 22b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com} 23b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com 24b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.comSkLerpXfermode::SkLerpXfermode(unsigned scale256) : fScale256(scale256) {} 25b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com 269fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING 279fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reedSkLerpXfermode::SkLerpXfermode(SkReadBuffer& buffer) : INHERITED(buffer) { 28b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com fScale256 = buffer.readUInt(); 29b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com} 309fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed#endif 31b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com 328b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgvoid SkLerpXfermode::flatten(SkWriteBuffer& buffer) const { 33b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com buffer.writeUInt(fScale256); 34b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com} 35b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com 369fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reedSkFlattenable* SkLerpXfermode::CreateProc(SkReadBuffer& buffer) { 379fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed return SkNEW_ARGS(SkLerpXfermode, (buffer.readUInt())); 389fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed} 399fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed 40b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.comvoid SkLerpXfermode::xfer32(SkPMColor dst[], const SkPMColor src[], int count, 41b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com const SkAlpha aa[]) const { 42b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com const int scale = fScale256; 43b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com 44b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com if (aa) { 45b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com for (int i = 0; i < count; ++i) { 46b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com unsigned a = aa[i]; 47b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com if (a) { 48b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com SkPMColor dstC = dst[i]; 49b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com SkPMColor resC = SkFastFourByteInterp256(src[i], dstC, scale); 50b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com if (a < 255) { 51b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com resC = SkFastFourByteInterp256(resC, dstC, a + (a >> 7)); 52b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com } 53b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com dst[i] = resC; 54b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com } 55b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com } 56b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com } else { 57b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com for (int i = 0; i < count; ++i) { 58b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com dst[i] = SkFastFourByteInterp256(src[i], dst[i], scale); 59b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com } 60b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com } 61b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com} 62b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com 63b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.comvoid SkLerpXfermode::xfer16(uint16_t dst[], const SkPMColor src[], int count, 64b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com const SkAlpha aa[]) const { 65b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com const int scale = fScale256; 66b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com 67b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com if (aa) { 68b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com for (int i = 0; i < count; ++i) { 69b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com unsigned a = aa[i]; 70b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com if (a) { 71b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com SkPMColor dstC = SkPixel16ToPixel32(dst[i]); 72b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com SkPMColor resC = SkFastFourByteInterp256(src[i], dstC, scale); 73b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com if (a < 255) { 74b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com resC = SkFastFourByteInterp256(resC, dstC, a + (a >> 7)); 75b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com } 76b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com dst[i] = SkPixel32ToPixel16(resC); 77b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com } 78b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com } 79b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com } else { 80b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com for (int i = 0; i < count; ++i) { 81b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com SkPMColor dstC = SkPixel16ToPixel32(dst[i]); 82b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com SkPMColor resC = SkFastFourByteInterp256(src[i], dstC, scale); 83b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com dst[i] = SkPixel32ToPixel16(resC); 84b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com } 85b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com } 86b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com} 87b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com 88b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.comvoid SkLerpXfermode::xferA8(SkAlpha dst[], const SkPMColor src[], int count, 89b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com const SkAlpha aa[]) const { 90b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com const int scale = fScale256; 91b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com 92b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com if (aa) { 93b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com for (int i = 0; i < count; ++i) { 94b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com unsigned a = aa[i]; 95b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com if (a) { 96b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com unsigned dstA = dst[i]; 97b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com unsigned resA = SkAlphaBlend(SkGetPackedA32(src[i]), dstA, scale); 98b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com if (a < 255) { 99b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com resA = SkAlphaBlend(resA, dstA, a + (a >> 7)); 100b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com } 101b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com dst[i] = resA; 102b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com } 103b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com } 104b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com } else { 105b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com for (int i = 0; i < count; ++i) { 106b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com dst[i] = SkAlphaBlend(SkGetPackedA32(src[i]), dst[i], scale); 107b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com } 108b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com } 109b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com} 110b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com 1110f10f7bf1fb43ca6346dc220a076773b1f19a367commit-bot@chromium.org#ifndef SK_IGNORE_TO_STRING 112b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.comvoid SkLerpXfermode::toString(SkString* str) const { 113b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com str->printf("SkLerpXfermode: scale: %g", fScale256 / 256.0); 114b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com} 115b83cb9bf89d26b40e4db83db1b9782437d2adba7reed@google.com#endif 116