diff options
-rw-r--r-- | gm/resizeimagefilter.cpp | 96 | ||||
-rw-r--r-- | gyp/effects.gypi | 1 | ||||
-rw-r--r-- | gyp/gmslides.gypi | 1 | ||||
-rw-r--r-- | include/effects/SkResizeImageFilter.h | 51 | ||||
-rw-r--r-- | src/effects/SkResizeImageFilter.cpp | 81 | ||||
-rw-r--r-- | src/ports/SkGlobalInitialization_chromium.cpp | 2 | ||||
-rw-r--r-- | src/ports/SkGlobalInitialization_default.cpp | 2 |
7 files changed, 234 insertions, 0 deletions
diff --git a/gm/resizeimagefilter.cpp b/gm/resizeimagefilter.cpp new file mode 100644 index 0000000000..fa407c4bfa --- /dev/null +++ b/gm/resizeimagefilter.cpp @@ -0,0 +1,96 @@ +/* + * Copyright 2013 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "gm.h" +#include "SkColor.h" +#include "SkResizeImageFilter.h" + +namespace skiagm { + +class ResizeGM : public GM { +public: + ResizeGM() { + this->setBGColor(0x00000000); + } + +protected: + virtual SkString onShortName() { + return SkString("resizeimagefilter"); + } + + void draw(SkCanvas* canvas, + const SkRect& rect, + const SkSize& deviceSize, + SkPaint::FilterLevel filterLevel) { + SkRect dstRect; + canvas->getTotalMatrix().mapRect(&dstRect, rect); + canvas->save(); + SkScalar deviceScaleX = SkScalarDiv(deviceSize.width(), dstRect.width()); + SkScalar deviceScaleY = SkScalarDiv(deviceSize.height(), dstRect.height()); + canvas->translate(rect.x(), rect.y()); + canvas->scale(deviceScaleX, deviceScaleY); + canvas->translate(-rect.x(), -rect.y()); + SkAutoTUnref<SkImageFilter> imageFilter( + new SkResizeImageFilter(SkScalarInvert(deviceScaleX), + SkScalarInvert(deviceScaleY), + filterLevel)); + SkPaint filteredPaint; + filteredPaint.setImageFilter(imageFilter.get()); + canvas->saveLayer(&rect, &filteredPaint); + SkPaint paint; + paint.setColor(0xFF00FF00); + SkRect ovalRect = rect; + ovalRect.inset(SkIntToScalar(4), SkIntToScalar(4)); + canvas->drawOval(ovalRect, paint); + canvas->restore(); // for saveLayer + canvas->restore(); + } + + virtual SkISize onISize() { + return make_isize(420, 100); + } + + virtual void onDraw(SkCanvas* canvas) { + canvas->clear(0x00000000); + + SkRect srcRect = SkRect::MakeWH(96, 96); + + SkSize deviceSize = SkSize::Make(16, 16); + draw(canvas, + srcRect, + deviceSize, + SkPaint::kNone_FilterLevel); + + canvas->translate(srcRect.width() + SkIntToScalar(10), 0); + draw(canvas, + srcRect, + deviceSize, + SkPaint::kLow_FilterLevel); + + canvas->translate(srcRect.width() + SkIntToScalar(10), 0); + draw(canvas, + srcRect, + deviceSize, + SkPaint::kMedium_FilterLevel); + + canvas->translate(srcRect.width() + SkIntToScalar(10), 0); + draw(canvas, + srcRect, + deviceSize, + SkPaint::kHigh_FilterLevel); + } + +private: + typedef GM INHERITED; +}; + +////////////////////////////////////////////////////////////////////////////// + +static GM* MyFactory(void*) { return new ResizeGM; } +static GMRegistry reg(MyFactory); + +} diff --git a/gyp/effects.gypi b/gyp/effects.gypi index 21e02e447b..9315c268aa 100644 --- a/gyp/effects.gypi +++ b/gyp/effects.gypi @@ -52,6 +52,7 @@ '<(skia_src_path)/effects/SkPixelXorXfermode.cpp', '<(skia_src_path)/effects/SkPorterDuff.cpp', '<(skia_src_path)/effects/SkRectShaderImageFilter.cpp', + '<(skia_src_path)/effects/SkResizeImageFilter.cpp', '<(skia_src_path)/effects/SkStippleMaskFilter.cpp', '<(skia_src_path)/effects/SkTableColorFilter.cpp', '<(skia_src_path)/effects/SkTableMaskFilter.cpp', diff --git a/gyp/gmslides.gypi b/gyp/gmslides.gypi index 8e50eb074c..8069419de3 100644 --- a/gyp/gmslides.gypi +++ b/gyp/gmslides.gypi @@ -111,6 +111,7 @@ '../gm/polygons.cpp', '../gm/quadpaths.cpp', '../gm/rects.cpp', + '../gm/resizeimagefilter.cpp', '../gm/rrect.cpp', '../gm/rrects.cpp', '../gm/roundrects.cpp', diff --git a/include/effects/SkResizeImageFilter.h b/include/effects/SkResizeImageFilter.h new file mode 100644 index 0000000000..d63855561e --- /dev/null +++ b/include/effects/SkResizeImageFilter.h @@ -0,0 +1,51 @@ +/* + * Copyright 2013 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 SkResizeImageFilter_DEFINED +#define SkResizeImageFilter_DEFINED + +#include "SkImageFilter.h" +#include "SkScalar.h" +#include "SkRect.h" +#include "SkPoint.h" +#include "SkPaint.h" + +/*! \class SkResizeImageFilter + Resampling image filter. This filter draws its source image resampled using the given scale + values. + */ + +class SK_API SkResizeImageFilter : public SkImageFilter { +public: + /** Construct a (scaling-only) resampling image filter. + * @param sx The x scale parameter to apply when resizing. + * @param sy The y scale parameter to apply when resizing. + * @param filterLevel The quality of filtering to apply when scaling. + * @param input The input image filter. If NULL, the src bitmap + * passed to filterImage() is used instead. + */ + + SkResizeImageFilter(SkScalar sx, SkScalar sy, SkPaint::FilterLevel filterLevel, + SkImageFilter* input = NULL); + virtual ~SkResizeImageFilter(); + + SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkResizeImageFilter) + +protected: + SkResizeImageFilter(SkFlattenableReadBuffer& buffer); + virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE; + + virtual bool onFilterImage(Proxy*, const SkBitmap& src, const SkMatrix&, + SkBitmap* result, SkIPoint* loc) SK_OVERRIDE; + +private: + SkScalar fSx, fSy; + SkPaint::FilterLevel fFilterLevel; + typedef SkImageFilter INHERITED; +}; + +#endif diff --git a/src/effects/SkResizeImageFilter.cpp b/src/effects/SkResizeImageFilter.cpp new file mode 100644 index 0000000000..4d700901ef --- /dev/null +++ b/src/effects/SkResizeImageFilter.cpp @@ -0,0 +1,81 @@ +/* + * Copyright 2013 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 "SkResizeImageFilter.h" +#include "SkBitmap.h" +#include "SkCanvas.h" +#include "SkDevice.h" +#include "SkColorPriv.h" +#include "SkFlattenableBuffers.h" +#include "SkMatrix.h" +#include "SkRect.h" + +SkResizeImageFilter::SkResizeImageFilter(SkScalar sx, SkScalar sy, SkPaint::FilterLevel filterLevel, + SkImageFilter* input) + : INHERITED(input), + fSx(sx), + fSy(sy), + fFilterLevel(filterLevel) { +} + +SkResizeImageFilter::SkResizeImageFilter(SkFlattenableReadBuffer& buffer) + : INHERITED(1, buffer) { + fSx = buffer.readScalar(); + fSy = buffer.readScalar(); + fFilterLevel = static_cast<SkPaint::FilterLevel>(buffer.readInt()); +} + +void SkResizeImageFilter::flatten(SkFlattenableWriteBuffer& buffer) const { + this->INHERITED::flatten(buffer); + buffer.writeScalar(fSx); + buffer.writeScalar(fSy); + buffer.writeInt(fFilterLevel); +} + +SkResizeImageFilter::~SkResizeImageFilter() { +} + +bool SkResizeImageFilter::onFilterImage(Proxy* proxy, + const SkBitmap& source, + const SkMatrix& matrix, + SkBitmap* result, + SkIPoint* offset) { + SkBitmap src = source; + SkIPoint srcOffset = SkIPoint::Make(0, 0); + if (getInput(0) && !getInput(0)->filterImage(proxy, source, matrix, &src, &srcOffset)) { + return false; + } + + SkRect dstRect; + SkIRect srcBounds, dstBounds; + src.getBounds(&srcBounds); + srcBounds.offset(srcOffset); + SkRect srcRect = SkRect::Make(srcBounds); + SkMatrix dstMatrix; + dstMatrix.setScale(fSx, fSy); + dstMatrix.mapRect(&dstRect, srcRect); + dstRect.roundOut(&dstBounds); + + SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(dstBounds.width(), dstBounds.height())); + if (NULL == device.get()) { + return false; + } + + SkCanvas canvas(device.get()); + canvas.translate(-SkIntToScalar(dstBounds.fLeft), -SkIntToScalar(dstBounds.fTop)); + SkPaint paint; + + paint.setXfermodeMode(SkXfermode::kSrc_Mode); + paint.setFilterLevel(fFilterLevel); + canvas.concat(dstMatrix); + canvas.drawBitmap(src, srcRect.left(), srcRect.top(), &paint); + + *result = device.get()->accessBitmap(false); + offset->fX = dstBounds.fLeft; + offset->fY = dstBounds.fTop; + return true; +} diff --git a/src/ports/SkGlobalInitialization_chromium.cpp b/src/ports/SkGlobalInitialization_chromium.cpp index d402c02e21..79ed46c70e 100644 --- a/src/ports/SkGlobalInitialization_chromium.cpp +++ b/src/ports/SkGlobalInitialization_chromium.cpp @@ -52,6 +52,7 @@ #include "SkPerlinNoiseShader.h" #include "SkPixelXorXfermode.h" #include "SkRectShaderImageFilter.h" +#include "SkResizeImageFilter.h" #include "SkStippleMaskFilter.h" #include "SkTableColorFilter.h" #include "SkTestImageFilters.h" @@ -89,6 +90,7 @@ static void InitializeFlattenables(int*) { SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPerlinNoiseShader) SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPixelXorXfermode) SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkRectShaderImageFilter) + SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkResizeImageFilter) SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkStippleMaskFilter) SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSumPathEffect) SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkTileImageFilter) diff --git a/src/ports/SkGlobalInitialization_default.cpp b/src/ports/SkGlobalInitialization_default.cpp index d402c02e21..79ed46c70e 100644 --- a/src/ports/SkGlobalInitialization_default.cpp +++ b/src/ports/SkGlobalInitialization_default.cpp @@ -52,6 +52,7 @@ #include "SkPerlinNoiseShader.h" #include "SkPixelXorXfermode.h" #include "SkRectShaderImageFilter.h" +#include "SkResizeImageFilter.h" #include "SkStippleMaskFilter.h" #include "SkTableColorFilter.h" #include "SkTestImageFilters.h" @@ -89,6 +90,7 @@ static void InitializeFlattenables(int*) { SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPerlinNoiseShader) SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPixelXorXfermode) SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkRectShaderImageFilter) + SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkResizeImageFilter) SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkStippleMaskFilter) SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSumPathEffect) SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkTileImageFilter) |