Home | History | Annotate | Download | only in core
      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 "SkFilterShader.h"
      9 
     10 #include "SkColorFilter.h"
     11 #include "SkFlattenableBuffers.h"
     12 #include "SkShader.h"
     13 #include "SkString.h"
     14 
     15 SkFilterShader::SkFilterShader(SkShader* shader, SkColorFilter* filter) {
     16     fShader = shader;
     17     shader->ref();
     18 
     19     fFilter = filter;
     20     filter->ref();
     21 }
     22 
     23 SkFilterShader::SkFilterShader(SkFlattenableReadBuffer& buffer)
     24     : INHERITED(buffer) {
     25     fShader = buffer.readFlattenableT<SkShader>();
     26     fFilter = buffer.readFlattenableT<SkColorFilter>();
     27 }
     28 
     29 SkFilterShader::~SkFilterShader() {
     30     fFilter->unref();
     31     fShader->unref();
     32 }
     33 
     34 void SkFilterShader::flatten(SkFlattenableWriteBuffer& buffer) const {
     35     this->INHERITED::flatten(buffer);
     36     buffer.writeFlattenable(fShader);
     37     buffer.writeFlattenable(fFilter);
     38 }
     39 
     40 uint32_t SkFilterShader::getFlags() {
     41     uint32_t shaderF = fShader->getFlags();
     42     uint32_t filterF = fFilter->getFlags();
     43 
     44     // if the filter doesn't support 16bit, clear the matching bit in the shader
     45     if (!(filterF & SkColorFilter::kHasFilter16_Flag)) {
     46         shaderF &= ~SkShader::kHasSpan16_Flag;
     47     }
     48     // if the filter might change alpha, clear the opaque flag in the shader
     49     if (!(filterF & SkColorFilter::kAlphaUnchanged_Flag)) {
     50         shaderF &= ~(SkShader::kOpaqueAlpha_Flag | SkShader::kHasSpan16_Flag);
     51     }
     52     return shaderF;
     53 }
     54 
     55 bool SkFilterShader::setContext(const SkBitmap& device,
     56                                 const SkPaint& paint,
     57                                 const SkMatrix& matrix) {
     58     // we need to keep the setContext/endContext calls balanced. If we return
     59     // false, our endContext() will not be called.
     60 
     61     if (!this->INHERITED::setContext(device, paint, matrix)) {
     62         return false;
     63     }
     64     if (!fShader->setContext(device, paint, matrix)) {
     65         this->INHERITED::endContext();
     66         return false;
     67     }
     68     return true;
     69 }
     70 
     71 void SkFilterShader::endContext() {
     72     fShader->endContext();
     73     this->INHERITED::endContext();
     74 }
     75 
     76 void SkFilterShader::shadeSpan(int x, int y, SkPMColor result[], int count) {
     77     fShader->shadeSpan(x, y, result, count);
     78     fFilter->filterSpan(result, count, result);
     79 }
     80 
     81 void SkFilterShader::shadeSpan16(int x, int y, uint16_t result[], int count) {
     82     SkASSERT(fShader->getFlags() & SkShader::kHasSpan16_Flag);
     83     SkASSERT(fFilter->getFlags() & SkColorFilter::kHasFilter16_Flag);
     84 
     85     fShader->shadeSpan16(x, y, result, count);
     86     fFilter->filterSpan16(result, count, result);
     87 }
     88 
     89 #ifdef SK_DEVELOPER
     90 void SkFilterShader::toString(SkString* str) const {
     91     str->append("SkFilterShader: (");
     92 
     93     str->append("Shader: ");
     94     fShader->toString(str);
     95     str->append(" Filter: ");
     96     // TODO: add "fFilter->toString(str);" once SkColorFilter::toString is added
     97 
     98     this->INHERITED::toString(str);
     99 
    100     str->append(")");
    101 }
    102 #endif
    103