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:
parent
8182fa0cac
commit
4a9a612b52
@ -13,6 +13,7 @@
|
||||
#include "SkColorFilter.h"
|
||||
#include "SkColorMatrixFilter.h"
|
||||
#include "SkColorFilterImageFilter.h"
|
||||
#include "SkMergeImageFilter.h"
|
||||
#include "SkMorphologyImageFilter.h"
|
||||
|
||||
#include "SkTestImageFilters.h"
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
#include "SkBlurImageFilter.h"
|
||||
#include "SkColorFilterImageFilter.h"
|
||||
#include "SkMergeImageFilter.h"
|
||||
#include "SkOffsetImageFilter.h"
|
||||
#include "SkTestImageFilters.h"
|
||||
|
||||
|
@ -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',
|
||||
|
46
include/effects/SkMergeImageFilter.h
Executable file
46
include/effects/SkMergeImageFilter.h
Executable 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
|
@ -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
|
||||
|
165
src/effects/SkMergeImageFilter.cpp
Executable file
165
src/effects/SkMergeImageFilter.cpp
Executable 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;
|
||||
}
|
||||
}
|
@ -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*) {
|
||||
|
@ -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"
|
||||
|
Loading…
Reference in New Issue
Block a user