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 26#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING 27SkLerpXfermode::SkLerpXfermode(SkReadBuffer& buffer) : INHERITED(buffer) { 28 fScale256 = buffer.readUInt(); 29} 30#endif 31 32void SkLerpXfermode::flatten(SkWriteBuffer& buffer) const { 33 buffer.writeUInt(fScale256); 34} 35 36SkFlattenable* SkLerpXfermode::CreateProc(SkReadBuffer& buffer) { 37 return SkNEW_ARGS(SkLerpXfermode, (buffer.readUInt())); 38} 39 40void SkLerpXfermode::xfer32(SkPMColor dst[], const SkPMColor src[], int count, 41 const SkAlpha aa[]) const { 42 const int scale = fScale256; 43 44 if (aa) { 45 for (int i = 0; i < count; ++i) { 46 unsigned a = aa[i]; 47 if (a) { 48 SkPMColor dstC = dst[i]; 49 SkPMColor resC = SkFastFourByteInterp256(src[i], dstC, scale); 50 if (a < 255) { 51 resC = SkFastFourByteInterp256(resC, dstC, a + (a >> 7)); 52 } 53 dst[i] = resC; 54 } 55 } 56 } else { 57 for (int i = 0; i < count; ++i) { 58 dst[i] = SkFastFourByteInterp256(src[i], dst[i], scale); 59 } 60 } 61} 62 63void SkLerpXfermode::xfer16(uint16_t dst[], const SkPMColor src[], int count, 64 const SkAlpha aa[]) const { 65 const int scale = fScale256; 66 67 if (aa) { 68 for (int i = 0; i < count; ++i) { 69 unsigned a = aa[i]; 70 if (a) { 71 SkPMColor dstC = SkPixel16ToPixel32(dst[i]); 72 SkPMColor resC = SkFastFourByteInterp256(src[i], dstC, scale); 73 if (a < 255) { 74 resC = SkFastFourByteInterp256(resC, dstC, a + (a >> 7)); 75 } 76 dst[i] = SkPixel32ToPixel16(resC); 77 } 78 } 79 } else { 80 for (int i = 0; i < count; ++i) { 81 SkPMColor dstC = SkPixel16ToPixel32(dst[i]); 82 SkPMColor resC = SkFastFourByteInterp256(src[i], dstC, scale); 83 dst[i] = SkPixel32ToPixel16(resC); 84 } 85 } 86} 87 88void SkLerpXfermode::xferA8(SkAlpha dst[], const SkPMColor src[], int count, 89 const SkAlpha aa[]) const { 90 const int scale = fScale256; 91 92 if (aa) { 93 for (int i = 0; i < count; ++i) { 94 unsigned a = aa[i]; 95 if (a) { 96 unsigned dstA = dst[i]; 97 unsigned resA = SkAlphaBlend(SkGetPackedA32(src[i]), dstA, scale); 98 if (a < 255) { 99 resA = SkAlphaBlend(resA, dstA, a + (a >> 7)); 100 } 101 dst[i] = resA; 102 } 103 } 104 } else { 105 for (int i = 0; i < count; ++i) { 106 dst[i] = SkAlphaBlend(SkGetPackedA32(src[i]), dst[i], scale); 107 } 108 } 109} 110 111#ifndef SK_IGNORE_TO_STRING 112void SkLerpXfermode::toString(SkString* str) const { 113 str->printf("SkLerpXfermode: scale: %g", fScale256 / 256.0); 114} 115#endif 116