Home | History | Annotate | Download | only in effects
      1 /* libs/graphics/effects/SkTransparentShader.cpp
      2 **
      3 ** Copyright 2006, The Android Open Source Project
      4 **
      5 ** Licensed under the Apache License, Version 2.0 (the "License");
      6 ** you may not use this file except in compliance with the License.
      7 ** You may obtain a copy of the License at
      8 **
      9 **     http://www.apache.org/licenses/LICENSE-2.0
     10 **
     11 ** Unless required by applicable law or agreed to in writing, software
     12 ** distributed under the License is distributed on an "AS IS" BASIS,
     13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14 ** See the License for the specific language governing permissions and
     15 ** limitations under the License.
     16 */
     17 
     18 #include "SkTransparentShader.h"
     19 #include "SkColorPriv.h"
     20 
     21 bool SkTransparentShader::setContext(const SkBitmap& device,
     22                                      const SkPaint& paint,
     23                                      const SkMatrix& matrix)
     24 {
     25     fDevice = &device;
     26     fAlpha = paint.getAlpha();
     27 
     28     return this->INHERITED::setContext(device, paint, matrix);
     29 }
     30 
     31 uint32_t SkTransparentShader::getFlags()
     32 {
     33     uint32_t flags = this->INHERITED::getFlags();
     34 
     35     switch (fDevice->getConfig()) {
     36     case SkBitmap::kRGB_565_Config:
     37         flags |= kHasSpan16_Flag;
     38         if (fAlpha == 255)
     39             flags |= kOpaqueAlpha_Flag;
     40         break;
     41     case SkBitmap::kARGB_8888_Config:
     42     case SkBitmap::kARGB_4444_Config:
     43         if (fAlpha == 255 && fDevice->isOpaque())
     44             flags |= kOpaqueAlpha_Flag;
     45         break;
     46     default:
     47         break;
     48     }
     49     return flags;
     50 }
     51 
     52 void SkTransparentShader::shadeSpan(int x, int y, SkPMColor span[], int count)
     53 {
     54     unsigned scale = SkAlpha255To256(fAlpha);
     55 
     56     switch (fDevice->getConfig()) {
     57     case SkBitmap::kARGB_8888_Config:
     58         if (scale == 256)
     59             memcpy(span, fDevice->getAddr32(x, y), count * sizeof(SkPMColor));
     60         else
     61         {
     62             const SkPMColor* src = fDevice->getAddr32(x, y);
     63             for (int i = count - 1; i >= 0; --i)
     64                 span[i] = SkAlphaMulQ(src[i], scale);
     65         }
     66         break;
     67     case SkBitmap::kRGB_565_Config:
     68         {
     69             const uint16_t* src = fDevice->getAddr16(x, y);
     70             if (scale == 256)
     71             {
     72                 for (int i = count - 1; i >= 0; --i)
     73                     span[i] = SkPixel16ToPixel32(src[i]);
     74             }
     75             else
     76             {
     77                 unsigned alpha = fAlpha;
     78                 for (int i = count - 1; i >= 0; --i)
     79                 {
     80                     uint16_t c = src[i];
     81                     unsigned r = SkPacked16ToR32(c);
     82                     unsigned g = SkPacked16ToG32(c);
     83                     unsigned b = SkPacked16ToB32(c);
     84 
     85                     span[i] = SkPackARGB32( alpha,
     86                                             SkAlphaMul(r, scale),
     87                                             SkAlphaMul(g, scale),
     88                                             SkAlphaMul(b, scale));
     89                 }
     90             }
     91         }
     92         break;
     93     case SkBitmap::kARGB_4444_Config:
     94         {
     95             const uint16_t* src = fDevice->getAddr16(x, y);
     96             if (scale == 256)
     97             {
     98                 for (int i = count - 1; i >= 0; --i)
     99                     span[i] = SkPixel4444ToPixel32(src[i]);
    100             }
    101             else
    102             {
    103                 unsigned scale16 = scale >> 4;
    104                 for (int i = count - 1; i >= 0; --i)
    105                 {
    106                     uint32_t c = SkExpand_4444(src[i]) * scale16;
    107                     span[i] = SkCompact_8888(c);
    108                 }
    109             }
    110         }
    111             break;
    112             case SkBitmap::kIndex8_Config:
    113         SkASSERT(!"index8 not supported as a destination device");
    114         break;
    115     case SkBitmap::kA8_Config:
    116         {
    117             const uint8_t* src = fDevice->getAddr8(x, y);
    118             if (scale == 256)
    119             {
    120                 for (int i = count - 1; i >= 0; --i)
    121                     span[i] = SkPackARGB32(src[i], 0, 0, 0);
    122             }
    123             else
    124             {
    125                 for (int i = count - 1; i >= 0; --i)
    126                     span[i] = SkPackARGB32(SkAlphaMul(src[i], scale), 0, 0, 0);
    127             }
    128         }
    129         break;
    130     case SkBitmap::kA1_Config:
    131         SkASSERT(!"kA1_Config umimplemented at this time");
    132         break;
    133     default:    // to avoid warnings
    134         break;
    135     }
    136 }
    137 
    138 void SkTransparentShader::shadeSpan16(int x, int y, uint16_t span[], int count)
    139 {
    140     SkASSERT(fDevice->getConfig() == SkBitmap::kRGB_565_Config);
    141 
    142     memcpy(span, fDevice->getAddr16(x, y), count << 1);
    143 }
    144 
    145