Home | History | Annotate | Download | only in effects
      1 
      2 /*
      3  * Copyright 2006 The Android Open Source Project
      4  *
      5  * Use of this source code is governed by a BSD-style license that can be
      6  * found in the LICENSE file.
      7  */
      8 
      9 
     10 #include "SkTransparentShader.h"
     11 #include "SkColorPriv.h"
     12 #include "SkString.h"
     13 
     14 SkShader::Context* SkTransparentShader::onCreateContext(const ContextRec& rec,
     15                                                         void* storage) const {
     16     return SkNEW_PLACEMENT_ARGS(storage, TransparentShaderContext, (*this, rec));
     17 }
     18 
     19 size_t SkTransparentShader::contextSize() const {
     20     return sizeof(TransparentShaderContext);
     21 }
     22 
     23 SkTransparentShader::TransparentShaderContext::TransparentShaderContext(
     24         const SkTransparentShader& shader, const ContextRec& rec)
     25     : INHERITED(shader, rec)
     26     , fDevice(rec.fDevice) {}
     27 
     28 SkTransparentShader::TransparentShaderContext::~TransparentShaderContext() {}
     29 
     30 uint32_t SkTransparentShader::TransparentShaderContext::getFlags() const {
     31     uint32_t flags = this->INHERITED::getFlags();
     32 
     33     switch (fDevice->colorType()) {
     34         case kRGB_565_SkColorType:
     35             flags |= kHasSpan16_Flag;
     36             if (this->getPaintAlpha() == 255)
     37                 flags |= kOpaqueAlpha_Flag;
     38             break;
     39         case kN32_SkColorType:
     40             if (this->getPaintAlpha() == 255 && fDevice->isOpaque())
     41                 flags |= kOpaqueAlpha_Flag;
     42             break;
     43         default:
     44             break;
     45     }
     46     return flags;
     47 }
     48 
     49 void SkTransparentShader::TransparentShaderContext::shadeSpan(int x, int y, SkPMColor span[],
     50                                                               int count) {
     51     unsigned scale = SkAlpha255To256(this->getPaintAlpha());
     52 
     53     switch (fDevice->colorType()) {
     54         case kN32_SkColorType:
     55             if (scale == 256) {
     56                 SkPMColor* src = fDevice->getAddr32(x, y);
     57                 if (src != span) {
     58                     memcpy(span, src, count * sizeof(SkPMColor));
     59                 }
     60             } else {
     61                 const SkPMColor* src = fDevice->getAddr32(x, y);
     62                 for (int i = count - 1; i >= 0; --i) {
     63                     span[i] = SkAlphaMulQ(src[i], scale);
     64                 }
     65             }
     66             break;
     67         case kRGB_565_SkColorType: {
     68             const uint16_t* src = fDevice->getAddr16(x, y);
     69             if (scale == 256) {
     70                 for (int i = count - 1; i >= 0; --i) {
     71                     span[i] = SkPixel16ToPixel32(src[i]);
     72                 }
     73             } else {
     74                 unsigned alpha = this->getPaintAlpha();
     75                 for (int i = count - 1; i >= 0; --i) {
     76                     uint16_t c = src[i];
     77                     unsigned r = SkPacked16ToR32(c);
     78                     unsigned g = SkPacked16ToG32(c);
     79                     unsigned b = SkPacked16ToB32(c);
     80 
     81                     span[i] = SkPackARGB32( alpha,
     82                                             SkAlphaMul(r, scale),
     83                                             SkAlphaMul(g, scale),
     84                                             SkAlphaMul(b, scale));
     85                 }
     86             }
     87             break;
     88         }
     89         case kAlpha_8_SkColorType: {
     90             const uint8_t* src = fDevice->getAddr8(x, y);
     91             if (scale == 256) {
     92                 for (int i = count - 1; i >= 0; --i) {
     93                     span[i] = SkPackARGB32(src[i], 0, 0, 0);
     94                 }
     95             } else {
     96                 for (int i = count - 1; i >= 0; --i) {
     97                     span[i] = SkPackARGB32(SkAlphaMul(src[i], scale), 0, 0, 0);
     98                 }
     99             }
    100             break;
    101         }
    102         default:
    103             SkDEBUGFAIL("colorType not supported as a destination device");
    104             break;
    105     }
    106 }
    107 
    108 void SkTransparentShader::TransparentShaderContext::shadeSpan16(int x, int y, uint16_t span[],
    109                                                                 int count) {
    110     SkASSERT(fDevice->colorType() == kRGB_565_SkColorType);
    111 
    112     uint16_t* src = fDevice->getAddr16(x, y);
    113     if (src != span) {
    114         memcpy(span, src, count << 1);
    115     }
    116 }
    117 
    118 #ifndef SK_IGNORE_TO_STRING
    119 void SkTransparentShader::toString(SkString* str) const {
    120     str->append("SkTransparentShader: (");
    121 
    122     this->INHERITED::toString(str);
    123 
    124     str->append(")");
    125 }
    126 #endif
    127