Implement an SkPicture image filter source. This is required for the external-SVG reference feature of feImage. It simply plays back an SkPicture to a given destination rect.
R=reed@google.com Review URL: https://codereview.chromium.org/114263002 git-svn-id: http://skia.googlecode.com/svn/trunk@12661 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
6b8dbb668f
commit
533330065a
82
gm/pictureimagefilter.cpp
Normal file
82
gm/pictureimagefilter.cpp
Normal file
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* 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 "SkPictureImageFilter.h"
|
||||
|
||||
// This GM exercises the SkPictureImageFilter ImageFilter class.
|
||||
|
||||
class PictureImageFilterGM : public skiagm::GM {
|
||||
public:
|
||||
PictureImageFilterGM() {
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual SkString onShortName() SK_OVERRIDE {
|
||||
return SkString("pictureimagefilter");
|
||||
}
|
||||
|
||||
void makePicture() {
|
||||
SkCanvas* canvas = fPicture.beginRecording(100, 100);
|
||||
canvas->clear(0x00000000);
|
||||
SkPaint paint;
|
||||
paint.setAntiAlias(true);
|
||||
paint.setColor(0xFFFFFFFF);
|
||||
paint.setTextSize(SkIntToScalar(96));
|
||||
const char* str = "e";
|
||||
canvas->drawText(str, strlen(str), SkIntToScalar(20), SkIntToScalar(70), paint);
|
||||
fPicture.endRecording();
|
||||
}
|
||||
|
||||
virtual SkISize onISize() SK_OVERRIDE { return SkISize::Make(500, 150); }
|
||||
|
||||
virtual void onOnceBeforeDraw() SK_OVERRIDE {
|
||||
this->makePicture();
|
||||
}
|
||||
|
||||
static void fillRectFiltered(SkCanvas* canvas, const SkRect& clipRect, SkImageFilter* filter) {
|
||||
SkPaint paint;
|
||||
paint.setImageFilter(filter);
|
||||
canvas->save();
|
||||
canvas->clipRect(clipRect);
|
||||
canvas->drawPaint(paint);
|
||||
canvas->restore();
|
||||
}
|
||||
|
||||
virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
|
||||
canvas->clear(0x00000000);
|
||||
{
|
||||
SkRect srcRect = SkRect::MakeXYWH(20, 20, 30, 30);
|
||||
SkRect emptyRect = SkRect::MakeXYWH(20, 20, 0, 0);
|
||||
SkRect bounds = SkRect::MakeXYWH(0, 0, 100, 100);
|
||||
SkAutoTUnref<SkImageFilter> pictureSource(new SkPictureImageFilter(&fPicture));
|
||||
SkAutoTUnref<SkImageFilter> pictureSourceSrcRect(new SkPictureImageFilter(&fPicture, srcRect));
|
||||
SkAutoTUnref<SkImageFilter> pictureSourceEmptyRect(new SkPictureImageFilter(&fPicture, emptyRect));
|
||||
|
||||
// Draw the picture unscaled.
|
||||
fillRectFiltered(canvas, bounds, pictureSource);
|
||||
canvas->translate(SkIntToScalar(100), 0);
|
||||
|
||||
// Draw an unscaled subset of the source picture.
|
||||
fillRectFiltered(canvas, bounds, pictureSourceSrcRect);
|
||||
canvas->translate(SkIntToScalar(100), 0);
|
||||
|
||||
// Draw the picture to an empty rect (should draw nothing).
|
||||
fillRectFiltered(canvas, bounds, pictureSourceEmptyRect);
|
||||
canvas->translate(SkIntToScalar(100), 0);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
SkPicture fPicture;
|
||||
typedef GM INHERITED;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DEF_GM( return new PictureImageFilterGM; )
|
@ -48,6 +48,7 @@
|
||||
'<(skia_src_path)/effects/SkOffsetImageFilter.cpp',
|
||||
'<(skia_src_path)/effects/SkPaintFlagsDrawFilter.cpp',
|
||||
'<(skia_src_path)/effects/SkPerlinNoiseShader.cpp',
|
||||
'<(skia_src_path)/effects/SkPictureImageFilter.cpp',
|
||||
'<(skia_src_path)/effects/SkPixelXorXfermode.cpp',
|
||||
'<(skia_src_path)/effects/SkPorterDuff.cpp',
|
||||
'<(skia_src_path)/effects/SkRectShaderImageFilter.cpp',
|
||||
|
@ -105,6 +105,7 @@
|
||||
'../gm/pathopsskpclip.cpp',
|
||||
'../gm/pathreverse.cpp',
|
||||
'../gm/perlinnoise.cpp',
|
||||
'../gm/pictureimagefilter.cpp',
|
||||
'../gm/points.cpp',
|
||||
'../gm/poly2poly.cpp',
|
||||
'../gm/polygons.cpp',
|
||||
|
42
include/effects/SkPictureImageFilter.h
Normal file
42
include/effects/SkPictureImageFilter.h
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* 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 SkPictureImageFilter_DEFINED
|
||||
#define SkPictureImageFilter_DEFINED
|
||||
|
||||
#include "SkImageFilter.h"
|
||||
#include "SkPicture.h"
|
||||
|
||||
class SK_API SkPictureImageFilter : public SkImageFilter {
|
||||
public:
|
||||
/**
|
||||
* Refs the passed-in picture.
|
||||
*/
|
||||
explicit SkPictureImageFilter(SkPicture* picture);
|
||||
|
||||
/**
|
||||
* Refs the passed-in picture. rect can be used to crop or expand the destination rect when
|
||||
* the picture is drawn. (No scaling is implied by the dest rect; only the CTM is applied.)
|
||||
*/
|
||||
SkPictureImageFilter(SkPicture* picture, const SkRect& rect);
|
||||
|
||||
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkPictureImageFilter)
|
||||
|
||||
protected:
|
||||
virtual ~SkPictureImageFilter();
|
||||
explicit SkPictureImageFilter(SkFlattenableReadBuffer& buffer);
|
||||
virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
|
||||
virtual bool onFilterImage(Proxy*, const SkBitmap& src, const SkMatrix&,
|
||||
SkBitmap* result, SkIPoint* offset) SK_OVERRIDE;
|
||||
|
||||
private:
|
||||
SkPicture* fPicture;
|
||||
SkRect fRect;
|
||||
typedef SkImageFilter INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
77
src/effects/SkPictureImageFilter.cpp
Normal file
77
src/effects/SkPictureImageFilter.cpp
Normal file
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* 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 "SkPictureImageFilter.h"
|
||||
#include "SkDevice.h"
|
||||
#include "SkCanvas.h"
|
||||
#include "SkFlattenableBuffers.h"
|
||||
#include "SkValidationUtils.h"
|
||||
|
||||
SkPictureImageFilter::SkPictureImageFilter(SkPicture* picture)
|
||||
: INHERITED(0, 0),
|
||||
fPicture(picture),
|
||||
fRect(SkRect::MakeWH(picture ? SkIntToScalar(picture->width()) : 0,
|
||||
picture ? SkIntToScalar(picture->height()) : 0)) {
|
||||
SkSafeRef(fPicture);
|
||||
}
|
||||
|
||||
SkPictureImageFilter::SkPictureImageFilter(SkPicture* picture, const SkRect& rect)
|
||||
: INHERITED(0, 0),
|
||||
fPicture(picture),
|
||||
fRect(rect) {
|
||||
SkSafeRef(fPicture);
|
||||
}
|
||||
|
||||
SkPictureImageFilter::~SkPictureImageFilter() {
|
||||
SkSafeUnref(fPicture);
|
||||
}
|
||||
|
||||
SkPictureImageFilter::SkPictureImageFilter(SkFlattenableReadBuffer& buffer)
|
||||
: INHERITED(0, buffer),
|
||||
fPicture(NULL) {
|
||||
// FIXME: unflatten picture here.
|
||||
buffer.readRect(&fRect);
|
||||
}
|
||||
|
||||
void SkPictureImageFilter::flatten(SkFlattenableWriteBuffer& buffer) const {
|
||||
this->INHERITED::flatten(buffer);
|
||||
// FIXME: flatten picture here.
|
||||
buffer.writeRect(fRect);
|
||||
}
|
||||
|
||||
bool SkPictureImageFilter::onFilterImage(Proxy* proxy, const SkBitmap&, const SkMatrix& matrix,
|
||||
SkBitmap* result, SkIPoint* offset) {
|
||||
if (!fPicture) {
|
||||
return true;
|
||||
}
|
||||
|
||||
SkRect floatBounds;
|
||||
SkIRect bounds;
|
||||
matrix.mapRect(&floatBounds, fRect);
|
||||
floatBounds.roundOut(&bounds);
|
||||
|
||||
if (bounds.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(bounds.width(), bounds.height()));
|
||||
if (NULL == device.get()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SkCanvas canvas(device.get());
|
||||
SkPaint paint;
|
||||
|
||||
canvas.translate(-SkIntToScalar(bounds.fLeft), -SkIntToScalar(bounds.fTop));
|
||||
canvas.concat(matrix);
|
||||
canvas.drawPicture(*fPicture);
|
||||
|
||||
*result = device.get()->accessBitmap(false);
|
||||
offset->fX += bounds.fLeft;
|
||||
offset->fY += bounds.fTop;
|
||||
return true;
|
||||
}
|
Loading…
Reference in New Issue
Block a user