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