Home | History | Annotate | Download | only in effects
      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