Home | History | Annotate | Download | only in effects
      1 /*
      2  * Copyright 2012 The Android Open Source Project
      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 "SkColorFilterImageFilter.h"
      9 #include "SkBitmap.h"
     10 #include "SkCanvas.h"
     11 #include "SkColorMatrixFilter.h"
     12 #include "SkDevice.h"
     13 #include "SkColorFilter.h"
     14 #include "SkReadBuffer.h"
     15 #include "SkTableColorFilter.h"
     16 #include "SkWriteBuffer.h"
     17 
     18 SkColorFilterImageFilter* SkColorFilterImageFilter::Create(SkColorFilter* cf,
     19         SkImageFilter* input, const CropRect* cropRect) {
     20     if (NULL == cf) {
     21         return NULL;
     22     }
     23 
     24     SkColorFilter* inputCF;
     25     if (input && input->isColorFilterNode(&inputCF)) {
     26         // This is an optimization, as it collapses the hierarchy by just combining the two
     27         // colorfilters into a single one, which the new imagefilter will wrap.
     28         SkAutoUnref autoUnref(inputCF);
     29         SkAutoTUnref<SkColorFilter> newCF(SkColorFilter::CreateComposeFilter(cf, inputCF));
     30         if (newCF) {
     31             return SkNEW_ARGS(SkColorFilterImageFilter, (newCF, input->getInput(0), cropRect));
     32         }
     33     }
     34 
     35     return SkNEW_ARGS(SkColorFilterImageFilter, (cf, input, cropRect));
     36 }
     37 
     38 SkColorFilterImageFilter::SkColorFilterImageFilter(SkColorFilter* cf,
     39         SkImageFilter* input, const CropRect* cropRect)
     40     : INHERITED(1, &input, cropRect), fColorFilter(SkRef(cf)) {
     41 }
     42 
     43 SkFlattenable* SkColorFilterImageFilter::CreateProc(SkReadBuffer& buffer) {
     44     SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1);
     45     SkAutoTUnref<SkColorFilter> cf(buffer.readColorFilter());
     46     return Create(cf, common.getInput(0), &common.cropRect());
     47 }
     48 
     49 void SkColorFilterImageFilter::flatten(SkWriteBuffer& buffer) const {
     50     this->INHERITED::flatten(buffer);
     51     buffer.writeFlattenable(fColorFilter);
     52 }
     53 
     54 SkColorFilterImageFilter::~SkColorFilterImageFilter() {
     55     fColorFilter->unref();
     56 }
     57 
     58 bool SkColorFilterImageFilter::onFilterImage(Proxy* proxy, const SkBitmap& source,
     59                                              const Context& ctx,
     60                                              SkBitmap* result,
     61                                              SkIPoint* offset) const {
     62     SkBitmap src = source;
     63     SkIPoint srcOffset = SkIPoint::Make(0, 0);
     64     if (getInput(0) && !getInput(0)->filterImage(proxy, source, ctx, &src, &srcOffset)) {
     65         return false;
     66     }
     67 
     68     SkIRect bounds;
     69     if (!this->applyCropRect(ctx, src, srcOffset, &bounds)) {
     70         return false;
     71     }
     72 
     73     SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(bounds.width(), bounds.height()));
     74     if (NULL == device.get()) {
     75         return false;
     76     }
     77     SkCanvas canvas(device.get());
     78     SkPaint paint;
     79 
     80     paint.setXfermodeMode(SkXfermode::kSrc_Mode);
     81     paint.setColorFilter(fColorFilter);
     82     canvas.drawSprite(src, srcOffset.fX - bounds.fLeft, srcOffset.fY - bounds.fTop, &paint);
     83 
     84     *result = device.get()->accessBitmap(false);
     85     offset->fX = bounds.fLeft;
     86     offset->fY = bounds.fTop;
     87     return true;
     88 }
     89 
     90 bool SkColorFilterImageFilter::onIsColorFilterNode(SkColorFilter** filter) const {
     91     SkASSERT(1 == this->countInputs());
     92     if (!this->cropRectIsSet()) {
     93         if (filter) {
     94             *filter = SkRef(fColorFilter);
     95         }
     96         return true;
     97     }
     98     return false;
     99 }
    100 
    101 #ifndef SK_IGNORE_TO_STRING
    102 void SkColorFilterImageFilter::toString(SkString* str) const {
    103     str->appendf("SkColorFilterImageFilter: (");
    104 
    105     str->appendf("input: (");
    106 
    107     if (this->getInput(0)) {
    108         this->getInput(0)->toString(str);
    109     }
    110 
    111     str->appendf(") color filter: ");
    112     fColorFilter->toString(str);
    113 
    114     str->append(")");
    115 }
    116 #endif
    117