Pull SkMergeImageFilter out into its own file.

Review URL: https://codereview.appspot.com/6873052

git-svn-id: http://skia.googlecode.com/svn/trunk@6662 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
senorblanco@chromium.org 2012-12-04 14:18:50 +00:00
parent 8182fa0cac
commit 4a9a612b52
8 changed files with 217 additions and 190 deletions

View File

@ -13,6 +13,7 @@
#include "SkColorFilter.h"
#include "SkColorMatrixFilter.h"
#include "SkColorFilterImageFilter.h"
#include "SkMergeImageFilter.h"
#include "SkMorphologyImageFilter.h"
#include "SkTestImageFilters.h"

View File

@ -13,6 +13,7 @@
#include "SkBlurImageFilter.h"
#include "SkColorFilterImageFilter.h"
#include "SkMergeImageFilter.h"
#include "SkOffsetImageFilter.h"
#include "SkTestImageFilters.h"

View File

@ -33,9 +33,10 @@
'<(skia_src_path)/effects/SkLayerDrawLooper.cpp',
'<(skia_src_path)/effects/SkLayerRasterizer.cpp',
'<(skia_src_path)/effects/SkLightingImageFilter.cpp',
'<(skia_src_path)/effects/SkOffsetImageFilter.cpp',
'<(skia_src_path)/effects/SkMatrixConvolutionImageFilter.cpp',
'<(skia_src_path)/effects/SkMergeImageFilter.cpp',
'<(skia_src_path)/effects/SkMorphologyImageFilter.cpp',
'<(skia_src_path)/effects/SkOffsetImageFilter.cpp',
'<(skia_src_path)/effects/SkPaintFlagsDrawFilter.cpp',
'<(skia_src_path)/effects/SkPixelXorXfermode.cpp',
'<(skia_src_path)/effects/SkPorterDuff.cpp',

View File

@ -0,0 +1,46 @@
/*
* Copyright 2012 The Android Open Source Project
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkMergeImageFilter_DEFINED
#define SkMergeImageFilter_DEFINED
#include "SkImageFilter.h"
#include "SkXfermode.h"
class SK_API SkMergeImageFilter : public SkImageFilter {
public:
SkMergeImageFilter(SkImageFilter* first, SkImageFilter* second,
SkXfermode::Mode = SkXfermode::kSrcOver_Mode);
SkMergeImageFilter(SkImageFilter* filters[], int count,
const SkXfermode::Mode modes[] = NULL);
virtual ~SkMergeImageFilter();
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkMergeImageFilter)
protected:
SkMergeImageFilter(SkFlattenableReadBuffer& buffer);
virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
virtual bool onFilterImage(Proxy*, const SkBitmap& src, const SkMatrix&,
SkBitmap* result, SkIPoint* loc) SK_OVERRIDE;
virtual bool onFilterBounds(const SkIRect&, const SkMatrix&, SkIRect*) SK_OVERRIDE;
private:
uint8_t* fModes; // SkXfermode::Mode
// private storage, to avoid dynamically allocating storage for our copy
// of the modes (unless the count is so large we can't fit).
intptr_t fStorage[16];
void initAllocModes();
void initModes(const SkXfermode::Mode []);
typedef SkImageFilter INHERITED;
};
#endif

View File

@ -22,40 +22,6 @@ private:
typedef SkImageFilter INHERITED;
};
#include "SkXfermode.h"
class SK_API SkMergeImageFilter : public SkImageFilter {
public:
SkMergeImageFilter(SkImageFilter* first, SkImageFilter* second,
SkXfermode::Mode = SkXfermode::kSrcOver_Mode);
SkMergeImageFilter(SkImageFilter* filters[], int count,
const SkXfermode::Mode modes[] = NULL);
virtual ~SkMergeImageFilter();
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkMergeImageFilter)
protected:
SkMergeImageFilter(SkFlattenableReadBuffer& buffer);
virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
virtual bool onFilterImage(Proxy*, const SkBitmap& src, const SkMatrix&,
SkBitmap* result, SkIPoint* loc) SK_OVERRIDE;
virtual bool onFilterBounds(const SkIRect&, const SkMatrix&, SkIRect*) SK_OVERRIDE;
private:
uint8_t* fModes; // SkXfermode::Mode
int fCount;
// private storage, to avoid dynamically allocating storage for our copy
// of the filters and modes (unless fCount is so large we can't fit).
intptr_t fStorage[16];
void initAllocModes();
void initModes(const SkXfermode::Mode []);
typedef SkImageFilter INHERITED;
};
///////////////////////////////////////////////////////////////////////////////
// Fun mode that scales down (only) and then scales back up to look pixelated

View File

@ -0,0 +1,165 @@
/*
* Copyright 2012 The Android Open Source Project
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "SkMergeImageFilter.h"
#include "SkCanvas.h"
#include "SkDevice.h"
#include "SkFlattenableBuffers.h"
///////////////////////////////////////////////////////////////////////////////
void SkMergeImageFilter::initAllocModes() {
int inputCount = countInputs();
if (inputCount) {
size_t size = sizeof(uint8_t) * inputCount;
if (size <= sizeof(fStorage)) {
fModes = SkTCast<uint8_t*>(fStorage);
} else {
fModes = SkTCast<uint8_t*>(sk_malloc_throw(size));
}
} else {
fModes = NULL;
}
}
void SkMergeImageFilter::initModes(const SkXfermode::Mode modes[]) {
if (modes) {
this->initAllocModes();
int inputCount = countInputs();
for (int i = 0; i < inputCount; ++i) {
fModes[i] = SkToU8(modes[i]);
}
} else {
fModes = NULL;
}
}
SkMergeImageFilter::SkMergeImageFilter(SkImageFilter* first, SkImageFilter* second,
SkXfermode::Mode mode) : INHERITED(first, second) {
if (SkXfermode::kSrcOver_Mode != mode) {
SkXfermode::Mode modes[] = { mode, mode };
this->initModes(modes);
} else {
fModes = NULL;
}
}
SkMergeImageFilter::SkMergeImageFilter(SkImageFilter* filters[], int count,
const SkXfermode::Mode modes[]) : INHERITED(count, filters) {
this->initModes(modes);
}
SkMergeImageFilter::~SkMergeImageFilter() {
if (fModes != SkTCast<uint8_t*>(fStorage)) {
sk_free(fModes);
}
}
bool SkMergeImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm,
SkIRect* dst) {
if (countInputs() < 1) {
return false;
}
SkIRect totalBounds;
int inputCount = countInputs();
for (int i = 0; i < inputCount; ++i) {
SkImageFilter* filter = getInput(i);
SkIRect r;
if (filter) {
if (!filter->filterBounds(src, ctm, &r)) {
return false;
}
} else {
r = src;
}
if (0 == i) {
totalBounds = r;
} else {
totalBounds.join(r);
}
}
// don't modify dst until now, so we don't accidentally change it in the
// loop, but then return false on the next filter.
*dst = totalBounds;
return true;
}
bool SkMergeImageFilter::onFilterImage(Proxy* proxy, const SkBitmap& src,
const SkMatrix& ctm,
SkBitmap* result, SkIPoint* loc) {
if (countInputs() < 1) {
return false;
}
const SkIRect srcBounds = SkIRect::MakeXYWH(loc->x(), loc->y(),
src.width(), src.height());
SkIRect bounds;
if (!this->filterBounds(srcBounds, ctm, &bounds)) {
return false;
}
const int x0 = bounds.left();
const int y0 = bounds.top();
SkAutoTUnref<SkDevice> dst(proxy->createDevice(bounds.width(), bounds.height()));
if (NULL == dst) {
return false;
}
SkCanvas canvas(dst);
SkPaint paint;
int inputCount = countInputs();
for (int i = 0; i < inputCount; ++i) {
SkBitmap tmp;
const SkBitmap* srcPtr;
SkIPoint pos = *loc;
SkImageFilter* filter = getInput(i);
if (filter) {
if (!filter->filterImage(proxy, src, ctm, &tmp, &pos)) {
return false;
}
srcPtr = &tmp;
} else {
srcPtr = &src;
}
if (fModes) {
paint.setXfermodeMode((SkXfermode::Mode)fModes[i]);
} else {
paint.setXfermode(NULL);
}
canvas.drawSprite(*srcPtr, pos.x() - x0, pos.y() - y0, &paint);
}
loc->set(bounds.left(), bounds.top());
*result = dst->accessBitmap(false);
return true;
}
void SkMergeImageFilter::flatten(SkFlattenableWriteBuffer& buffer) const {
this->INHERITED::flatten(buffer);
buffer.writeBool(fModes != NULL);
if (fModes) {
buffer.writeByteArray(fModes, countInputs() * sizeof(fModes[0]));
}
}
SkMergeImageFilter::SkMergeImageFilter(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {
bool hasModes = buffer.readBool();
if (hasModes) {
this->initAllocModes();
SkASSERT(buffer.getArrayCount() == countInputs() * sizeof(fModes[0]));
buffer.readByteArray(fModes);
} else {
fModes = 0;
}
}

View File

@ -68,160 +68,6 @@ SkComposeImageFilter::SkComposeImageFilter(SkFlattenableReadBuffer& buffer) : IN
///////////////////////////////////////////////////////////////////////////////
void SkMergeImageFilter::initAllocModes() {
int inputCount = countInputs();
if (inputCount) {
size_t size = sizeof(uint8_t) * inputCount;
if (size <= sizeof(fStorage)) {
fModes = SkTCast<uint8_t*>(fStorage);
} else {
fModes = SkTCast<uint8_t*>(sk_malloc_throw(size));
}
} else {
fModes = NULL;
}
}
void SkMergeImageFilter::initModes(const SkXfermode::Mode modes[]) {
if (modes) {
this->initAllocModes();
int inputCount = countInputs();
for (int i = 0; i < inputCount; ++i) {
fModes[i] = SkToU8(modes[i]);
}
} else {
fModes = NULL;
}
}
SkMergeImageFilter::SkMergeImageFilter(SkImageFilter* first, SkImageFilter* second,
SkXfermode::Mode mode) : INHERITED(first, second) {
if (SkXfermode::kSrcOver_Mode != mode) {
SkXfermode::Mode modes[] = { mode, mode };
this->initModes(modes);
} else {
fModes = NULL;
}
}
SkMergeImageFilter::SkMergeImageFilter(SkImageFilter* filters[], int count,
const SkXfermode::Mode modes[]) : INHERITED(count, filters) {
this->initModes(modes);
}
SkMergeImageFilter::~SkMergeImageFilter() {
if (fModes != SkTCast<uint8_t*>(fStorage)) {
sk_free(fModes);
}
}
bool SkMergeImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm,
SkIRect* dst) {
if (countInputs() < 1) {
return false;
}
SkIRect totalBounds;
int inputCount = countInputs();
for (int i = 0; i < inputCount; ++i) {
SkImageFilter* filter = getInput(i);
SkIRect r;
if (filter) {
if (!filter->filterBounds(src, ctm, &r)) {
return false;
}
} else {
r = src;
}
if (0 == i) {
totalBounds = r;
} else {
totalBounds.join(r);
}
}
// don't modify dst until now, so we don't accidentally change it in the
// loop, but then return false on the next filter.
*dst = totalBounds;
return true;
}
bool SkMergeImageFilter::onFilterImage(Proxy* proxy, const SkBitmap& src,
const SkMatrix& ctm,
SkBitmap* result, SkIPoint* loc) {
if (countInputs() < 1) {
return false;
}
const SkIRect srcBounds = SkIRect::MakeXYWH(loc->x(), loc->y(),
src.width(), src.height());
SkIRect bounds;
if (!this->filterBounds(srcBounds, ctm, &bounds)) {
return false;
}
const int x0 = bounds.left();
const int y0 = bounds.top();
SkDevice* dst = proxy->createDevice(bounds.width(), bounds.height());
if (NULL == dst) {
return false;
}
OwnDeviceCanvas canvas(dst);
SkPaint paint;
int inputCount = countInputs();
for (int i = 0; i < inputCount; ++i) {
SkBitmap tmp;
const SkBitmap* srcPtr;
SkIPoint pos = *loc;
SkImageFilter* filter = getInput(i);
if (filter) {
if (!filter->filterImage(proxy, src, ctm, &tmp, &pos)) {
return false;
}
srcPtr = &tmp;
} else {
srcPtr = &src;
}
if (fModes) {
paint.setXfermodeMode((SkXfermode::Mode)fModes[i]);
} else {
paint.setXfermode(NULL);
}
canvas.drawSprite(*srcPtr, pos.x() - x0, pos.y() - y0, &paint);
}
loc->set(bounds.left(), bounds.top());
*result = dst->accessBitmap(false);
return true;
}
void SkMergeImageFilter::flatten(SkFlattenableWriteBuffer& buffer) const {
this->INHERITED::flatten(buffer);
buffer.writeBool(fModes != NULL);
if (fModes) {
buffer.writeByteArray(fModes, countInputs() * sizeof(fModes[0]));
}
}
SkMergeImageFilter::SkMergeImageFilter(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {
bool hasModes = buffer.readBool();
if (hasModes) {
this->initAllocModes();
SkASSERT(buffer.getArrayCount() == countInputs() * sizeof(fModes[0]));
buffer.readByteArray(fModes);
} else {
fModes = 0;
}
}
///////////////////////////////////////////////////////////////////////////////
bool SkDownSampleImageFilter::onFilterImage(Proxy* proxy, const SkBitmap& src,
const SkMatrix& matrix,
SkBitmap* result, SkIPoint*) {

View File

@ -39,10 +39,11 @@
#include "SkLayerDrawLooper.h"
#include "SkLayerRasterizer.h"
#include "SkLightingImageFilter.h"
#include "SkOffsetImageFilter.h"
#include "SkMagnifierImageFilter.h"
#include "SkMatrixConvolutionImageFilter.h"
#include "SkMergeImageFilter.h"
#include "SkMorphologyImageFilter.h"
#include "SkOffsetImageFilter.h"
#include "SkPixelXorXfermode.h"
#include "SkStippleMaskFilter.h"
#include "SkTableColorFilter.h"