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