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