SkCanvas::drawImage is the new way for drawing a SkImage to a Canvas

BUG=skia:2947
R=junov@chromium.org, reed@google.com, bsalomon@google.com

Author: piotaixr@chromium.org

Review URL: https://codereview.chromium.org/583453002
This commit is contained in:
piotaixr 2014-09-23 14:10:50 -07:00 committed by Commit bot
parent 271a030f5d
commit 432789972c
11 changed files with 83 additions and 61 deletions

View File

@ -176,7 +176,7 @@ protected:
// render offscreen buffer
if (surface) {
SkImage* image = surface->newImageSnapshot();
image->draw(inputCanvas, 0, 0, NULL);
inputCanvas->drawImage(image, 0, 0, NULL);
image->unref();
}
#endif

View File

@ -30,7 +30,7 @@ static void drawJpeg(SkCanvas* canvas, const SkISize& size) {
SkAutoCanvasRestore acr(canvas, true);
canvas->scale(size.width() * 1.0f / image->width(),
size.height() * 1.0f / image->height());
image->draw(canvas, 0, 0, NULL);
canvas->drawImage(image, 0, 0, NULL);
image->unref();
}
}
@ -77,8 +77,8 @@ static void test_surface(SkCanvas* canvas, SkSurface* surf, bool usePaint) {
// paint.setFilterBitmap(true);
// paint.setAlpha(0x80);
imgR->draw(canvas, 0, 0, usePaint ? &paint : NULL);
imgG->draw(canvas, 0, 80, usePaint ? &paint : NULL);
canvas->drawImage(imgR, 0, 0, usePaint ? &paint : NULL);
canvas->drawImage(imgG, 0, 80, usePaint ? &paint : NULL);
surf->draw(canvas, 0, 160, usePaint ? &paint : NULL);
SkRect src1, src2, src3;
@ -93,10 +93,10 @@ static void test_surface(SkCanvas* canvas, SkSurface* surf, bool usePaint) {
dst3.set(0, 400, 65, 465);
dst4.set(0, 480, 65, 545);
imgR->draw(canvas, &src1, dst1, usePaint ? &paint : NULL);
imgG->draw(canvas, &src2, dst2, usePaint ? &paint : NULL);
imgR->draw(canvas, &src3, dst3, usePaint ? &paint : NULL);
imgG->draw(canvas, NULL, dst4, usePaint ? &paint : NULL);
canvas->drawImageRect(imgR, &src1, dst1, usePaint ? &paint : NULL);
canvas->drawImageRect(imgG, &src2, dst2, usePaint ? &paint : NULL);
canvas->drawImageRect(imgR, &src3, dst3, usePaint ? &paint : NULL);
canvas->drawImageRect(imgG, NULL, dst4, usePaint ? &paint : NULL);
imgG->unref();
imgR->unref();

View File

@ -56,7 +56,7 @@ static const SkPicture* make_hex_plane_picture(SkColor fillColor) {
SkPictureRecorder recorder;
SkCanvas* canvas = recorder.beginRecording(SkIntToScalar(kPicWidth),
SkCanvas* canvas = recorder.beginRecording(SkIntToScalar(kPicWidth),
SkIntToScalar(kPicHeight));
SkScalar xPos, yPos = 0;
@ -138,7 +138,7 @@ static const SkPicture* make_sub_picture(const SkPicture* tri) {
}
// Create a Sierpinkski-like picture that starts with a top row with a picture
// that just contains a triangle. Subsequent rows take the prior row's picture,
// that just contains a triangle. Subsequent rows take the prior row's picture,
// shrinks it and replicates it 3 times then draws and appropriate number of
// copies of it.
static const SkPicture* make_sierpinski_picture() {
@ -217,7 +217,7 @@ static void rrect_clip(SkCanvas* canvas, const SkPicture* pictures[kNumPictures]
SkRect rect = pictures[0]->cullRect();
rect.inset(kInset, kInset);
SkRRect rrect;
rrect.setRectXY(rect, kInset, kInset);
@ -280,7 +280,7 @@ static void create_content(SkMultiPictureDraw* mpd, PFContentMtd pfGen,
{
SkPictureRecorder recorder;
SkCanvas* pictureCanvas = recorder.beginRecording(SkIntToScalar(kPicWidth),
SkCanvas* pictureCanvas = recorder.beginRecording(SkIntToScalar(kPicWidth),
SkIntToScalar(kPicHeight));
(*pfGen)(pictureCanvas, pictures);
@ -291,13 +291,13 @@ static void create_content(SkMultiPictureDraw* mpd, PFContentMtd pfGen,
mpd->add(dest, composite, &xform);
}
typedef void(*PFLayoutMtd)(SkCanvas* finalCanvas, SkMultiPictureDraw* mpd,
typedef void(*PFLayoutMtd)(SkCanvas* finalCanvas, SkMultiPictureDraw* mpd,
PFContentMtd pfGen, const SkPicture* pictures[kNumPictures],
SkTArray<ComposeStep>* composeSteps);
// Draw the content into a single canvas
static void simple(SkCanvas* finalCanvas, SkMultiPictureDraw* mpd,
PFContentMtd pfGen,
static void simple(SkCanvas* finalCanvas, SkMultiPictureDraw* mpd,
PFContentMtd pfGen,
const SkPicture* pictures[kNumPictures],
SkTArray<ComposeStep> *composeSteps) {
@ -312,7 +312,7 @@ static void simple(SkCanvas* finalCanvas, SkMultiPictureDraw* mpd,
// Draw the content into multiple canvases/tiles
static void tiled(SkCanvas* finalCanvas, SkMultiPictureDraw* mpd,
PFContentMtd pfGen,
PFContentMtd pfGen,
const SkPicture* pictures[kNumPictures],
SkTArray<ComposeStep> *composeSteps) {
static const int kNumTilesX = 2;
@ -324,7 +324,7 @@ static void tiled(SkCanvas* finalCanvas, SkMultiPictureDraw* mpd,
SkASSERT(kPicHeight == kNumTilesY * kTileHeight);
static const SkColor colors[kNumTilesX][kNumTilesY] = {
{ SK_ColorCYAN, SK_ColorMAGENTA },
{ SK_ColorCYAN, SK_ColorMAGENTA },
{ SK_ColorYELLOW, SK_ColorGREEN }
};
@ -415,8 +415,8 @@ namespace skiagm {
SkTArray<ComposeStep> composeSteps;
// Fill up the MultiPictureDraw
(*gLayoutMthds[fLayout])(canvas, &mpd,
gContentMthds[fContent],
(*gLayoutMthds[fLayout])(canvas, &mpd,
gContentMthds[fContent],
fPictures, &composeSteps);
mpd.draw();
@ -427,14 +427,14 @@ namespace skiagm {
SkAutoTUnref<SkImage> image(step.fSurf->newImageSnapshot());
image->draw(canvas, step.fX, step.fY, step.fPaint);
canvas->drawImage(image, step.fX, step.fY, step.fPaint);
}
}
virtual SkISize onISize() SK_OVERRIDE { return SkISize::Make(kPicWidth, kPicHeight); }
virtual SkString onShortName() SK_OVERRIDE {
static const char* gContentNames[] = {
static const char* gContentNames[] = {
"noclip", "rectclip", "rrectclip", "pathclip", "invpathclip", "sierpinski"
};
static const char* gLayoutNames[] = { "simple", "tiled" };
@ -456,28 +456,28 @@ namespace skiagm {
typedef GM INHERITED;
};
DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kNoClipSingle_Content,
DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kNoClipSingle_Content,
MultiPictureDraw::kSimple_Layout));)
DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kRectClipMulti_Content,
DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kRectClipMulti_Content,
MultiPictureDraw::kSimple_Layout));)
DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kRRectClipMulti_Content,
DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kRRectClipMulti_Content,
MultiPictureDraw::kSimple_Layout));)
DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kPathClipMulti_Content,
DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kPathClipMulti_Content,
MultiPictureDraw::kSimple_Layout));)
DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kInvPathClipMulti_Content,
DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kInvPathClipMulti_Content,
MultiPictureDraw::kSimple_Layout));)
DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kSierpinski_Content,
MultiPictureDraw::kSimple_Layout));)
DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kNoClipSingle_Content,
DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kNoClipSingle_Content,
MultiPictureDraw::kTiled_Layout));)
DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kRectClipMulti_Content,
DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kRectClipMulti_Content,
MultiPictureDraw::kTiled_Layout));)
DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kRRectClipMulti_Content,
DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kRRectClipMulti_Content,
MultiPictureDraw::kTiled_Layout));)
DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kPathClipMulti_Content,
DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kPathClipMulti_Content,
MultiPictureDraw::kTiled_Layout));)
DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kInvPathClipMulti_Content,
DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kInvPathClipMulti_Content,
MultiPictureDraw::kTiled_Layout));)
DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kSierpinski_Content,
MultiPictureDraw::kTiled_Layout));)

View File

@ -29,6 +29,7 @@ class SkCanvasClipVisitor;
class SkBaseDevice;
class SkDraw;
class SkDrawFilter;
class SkImage;
class SkMetaData;
class SkPicture;
class SkRRect;
@ -811,6 +812,13 @@ public:
*/
virtual void drawPath(const SkPath& path, const SkPaint& paint);
virtual void drawImage(const SkImage* image, SkScalar left, SkScalar top,
const SkPaint* paint = NULL);
virtual void drawImageRect(const SkImage* image, const SkRect* src,
const SkRect& dst,
const SkPaint* paint = NULL);
/** Draw the specified bitmap, with its top/left corner at (x,y), using the
specified paint, transformed by the current matrix. Note: if the paint
contains a maskfilter that generates a mask which extends beyond the
@ -1313,7 +1321,7 @@ private:
friend class SkSurface_Raster; // needs getDevice()
friend class SkRecorder; // InitFlags
friend class SkNoSaveLayerCanvas; // InitFlags
enum InitFlags {
kDefault_InitFlags = 0,
kConservativeRasterClip_InitFlag = 1 << 0,
@ -1324,7 +1332,7 @@ private:
// needs gettotalclip()
friend SkCanvasState* SkCanvasStateUtils::CaptureCanvasState(SkCanvas*);
SkBaseDevice* createLayerDevice(const SkImageInfo&);
// call this each time we attach ourselves to a device

View File

@ -71,17 +71,6 @@ public:
SkShader::TileMode,
const SkMatrix* localMatrix = NULL) const;
void draw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*) const;
/**
* Draw the image, cropped to the src rect, to the dst rect of a canvas.
* If src is larger than the bounds of the image, the rest of the image is
* filled with transparent black pixels.
*
* See SkCanvas::drawBitmapRectToRect for similar behavior.
*/
void draw(SkCanvas*, const SkRect* src, const SkRect& dst, const SkPaint*) const;
/**
* If the image has direct access to its pixels (i.e. they are in local
* RAM) return the (const) address of those pixels, and if not null, return
@ -122,6 +111,19 @@ private:
typedef SkRefCnt INHERITED;
friend class SkCanvas;
void draw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*) const;
/**
* Draw the image, cropped to the src rect, to the dst rect of a canvas.
* If src is larger than the bounds of the image, the rest of the image is
* filled with transparent black pixels.
*
* See SkCanvas::drawBitmapRectToRect for similar behavior.
*/
void draw(SkCanvas*, const SkRect* src, const SkRect& dst, const SkPaint*) const;
/**
* Return a copy of the image's pixels, limiting them to the subset
* rectangle's intersection wit the image bounds. If subset is NULL, then

View File

@ -71,7 +71,7 @@ protected:
srcRect.setXYWH(1, 1, 3, 3);
dstRect.setXYWH(405, 5, 305, 305);
image->draw(canvas, &srcRect, dstRect, &paint);
canvas->drawImageRect(image, &srcRect, dstRect, &paint);
// Test that bitmap blurring using a subrect
// renders correctly
@ -83,7 +83,7 @@ protected:
SkBlurMaskFilter::kHighQuality_BlurFlag |
SkBlurMaskFilter::kIgnoreTransform_BlurFlag);
paint.setMaskFilter(mf)->unref();
image->draw(canvas, &srcRect, dstRect, &paint);
canvas->drawImageRect(image, &srcRect, dstRect, &paint);
// Blur and a rotation + NULL src rect
// This should not trigger the texture domain code

View File

@ -12,6 +12,7 @@
#include "SkDraw.h"
#include "SkDrawFilter.h"
#include "SkDrawLooper.h"
#include "SkImage.h"
#include "SkMetaData.h"
#include "SkPathOps.h"
#include "SkPatchUtils.h"
@ -183,7 +184,7 @@ public:
fFilter = NULL;
fLayer = NULL;
fTopLayer = NULL;
// don't bother initializing fNext
inc_rec();
}
@ -192,7 +193,7 @@ public:
fFilter = SkSafeRef(prev.fFilter);
fLayer = NULL;
fTopLayer = prev.fTopLayer;
// don't bother initializing fNext
inc_rec();
}
@ -292,7 +293,7 @@ public:
// can we be marked as simple?
fIsSimple = !fFilter && !fDoClearImageFilter;
}
uint32_t oldFlags = paint.getFlags();
fNewPaintFlags = filter_paint_flags(props, oldFlags);
if (fIsSimple && (fNewPaintFlags != oldFlags)) {
@ -457,7 +458,7 @@ public:
SkNoPixelsBitmapDevice(int width, int height) : INHERITED(make_nopixels(width, height)) {}
private:
typedef SkBitmapDevice INHERITED;
};
@ -466,7 +467,7 @@ SkCanvas::SkCanvas(int width, int height)
, fProps(SkSurfaceProps::kLegacyFontHost_InitType)
{
inc_canvas();
this->init(SkNEW_ARGS(SkNoPixelsBitmapDevice, (width, height)), kDefault_InitFlags)->unref();
}
@ -475,7 +476,7 @@ SkCanvas::SkCanvas(int width, int height, InitFlags flags)
, fProps(SkSurfaceProps::kLegacyFontHost_InitType)
{
inc_canvas();
this->init(SkNEW_ARGS(SkNoPixelsBitmapDevice, (width, height)), flags)->unref();
}
@ -484,7 +485,7 @@ SkCanvas::SkCanvas(SkBaseDevice* device, const SkSurfaceProps* props, InitFlags
, fProps(SkSurfacePropsCopyOrDefault(props))
{
inc_canvas();
this->init(device, flags);
}
@ -493,7 +494,7 @@ SkCanvas::SkCanvas(SkBaseDevice* device)
, fProps(SkSurfaceProps::kLegacyFontHost_InitType)
{
inc_canvas();
this->init(device, kDefault_InitFlags);
}
@ -502,7 +503,7 @@ SkCanvas::SkCanvas(const SkBitmap& bitmap, const SkSurfaceProps& props)
, fProps(props)
{
inc_canvas();
SkAutoTUnref<SkBaseDevice> device(SkNEW_ARGS(SkBitmapDevice, (bitmap)));
this->init(device, kDefault_InitFlags);
}
@ -512,7 +513,7 @@ SkCanvas::SkCanvas(const SkBitmap& bitmap)
, fProps(SkSurfaceProps::kLegacyFontHost_InitType)
{
inc_canvas();
SkAutoTUnref<SkBaseDevice> device(SkNEW_ARGS(SkBitmapDevice, (bitmap)));
this->init(device, kDefault_InitFlags);
}
@ -1885,6 +1886,17 @@ void SkCanvas::drawPath(const SkPath& path, const SkPaint& paint) {
LOOPER_END
}
void SkCanvas::drawImage(const SkImage* image, SkScalar left, SkScalar top,
const SkPaint* paint) {
image->draw(this, left, top, paint);
}
void SkCanvas::drawImageRect(const SkImage* image, const SkRect* src,
const SkRect& dst,
const SkPaint* paint) {
image->draw(this, src, dst, paint);
}
void SkCanvas::drawBitmap(const SkBitmap& bitmap, SkScalar x, SkScalar y,
const SkPaint* paint) {
SkDEBUGCODE(bitmap.validate();)

View File

@ -57,12 +57,12 @@ static inline void draw_replacement_bitmap(const GrReplacements::ReplacementInfo
SkRect src = SkRect::Make(ri->fSrcRect);
SkRect dst = SkRect::MakeXYWH(SkIntToScalar(ri->fPos.fX),
SkIntToScalar(ri->fPos.fY),
SkIntToScalar(ri->fSrcRect.width()),
SkIntToScalar(ri->fSrcRect.width()),
SkIntToScalar(ri->fSrcRect.height()));
canvas->save();
canvas->setMatrix(initialMatrix);
ri->fImage->draw(canvas, &src, dst, ri->fPaint);
canvas->drawImageRect(ri->fImage, &src, dst, ri->fPaint);
canvas->restore();
}

View File

@ -76,7 +76,7 @@ SkSurface_Base::~SkSurface_Base() {
void SkSurface_Base::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint) {
SkImage* image = this->newImageSnapshot();
if (image) {
image->draw(canvas, x, y, paint);
canvas->drawImage(image, x, y, paint);
image->unref();
}
}

View File

@ -456,7 +456,7 @@ static int lcanvas_drawImage(lua_State* L) {
paint.setAlpha(SkScalarRoundToInt(lua2scalar(L, 5) * 255));
paintPtr = &paint;
}
image->draw(canvas, x, y, paintPtr);
canvas->drawImage(image, x, y, paintPtr);
return 0;
}

View File

@ -350,7 +350,7 @@ DEF_TEST(Image_NewFromGenerator, r) {
SkCanvas canvas(bitmap);
const SkColor kDefaultColor = 0xffabcdef;
canvas.clear(kDefaultColor);
image->draw(&canvas, 0, 0, NULL);
canvas.drawImage(image, 0, 0, NULL);
if (TestImageGenerator::kSucceedGetPixels_TestType == test) {
REPORTER_ASSERT(
r, TestImageGenerator::Color() == *bitmap.getAddr32(0, 0));