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 14 SkXfermode* 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 24 SkLerpXfermode::SkLerpXfermode(unsigned scale256) : fScale256(scale256) {} 25 26 #ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING 27 SkLerpXfermode::SkLerpXfermode(SkReadBuffer& buffer) : INHERITED(buffer) { 28 fScale256 = buffer.readUInt(); 29 } 30 #endif 31 32 void SkLerpXfermode::flatten(SkWriteBuffer& buffer) const { 33 buffer.writeUInt(fScale256); 34 } 35 36 SkFlattenable* SkLerpXfermode::CreateProc(SkReadBuffer& buffer) { 37 return SkNEW_ARGS(SkLerpXfermode, (buffer.readUInt())); 38 } 39 40 void 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 63 void 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 88 void 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 112 void SkLerpXfermode::toString(SkString* str) const { 113 str->printf("SkLerpXfermode: scale: %g", fScale256 / 256.0); 114 } 115 #endif 116