skia2/samplecode/SamplePicture.cpp
scroggo@google.com b5571b3324 Change SkImageDecoders to take an SkStreamRewindable.
Only affects factories, static functions that will use the factories,
and subset decoding, which all require rewinding. The decoders
themselves continue to take an SkStream. This is merely documentation
stating which functions will possibly rewind the passed in SkStream.

This is part of the general change to coordinate SkStreams with
Android's streams, which don't necessarily support rewinding in all
cases.

Update callers to use SkStreamRewindable.

BUG=skia:1572
R=bungeman@google.com, reed@google.com

Review URL: https://codereview.chromium.org/23477009

git-svn-id: http://skia.googlecode.com/svn/trunk@11460 2bbb7eff-a529-9590-31e7-b0007b416f81
2013-09-25 21:34:24 +00:00

201 lines
5.8 KiB
C++

/*
* Copyright 2011 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "SampleCode.h"
#include "SkDumpCanvas.h"
#include "SkView.h"
#include "SkCanvas.h"
#include "Sk64.h"
#include "SkGradientShader.h"
#include "SkGraphics.h"
#include "SkImageDecoder.h"
#include "SkPath.h"
#include "SkPicture.h"
#include "SkRandom.h"
#include "SkRegion.h"
#include "SkShader.h"
#include "SkUtils.h"
#include "SkColorPriv.h"
#include "SkColorFilter.h"
#include "SkTime.h"
#include "SkTypeface.h"
#include "SkXfermode.h"
#include "SkStream.h"
#include "SkXMLParser.h"
///////////////////////////////////////////////////////////////////////////////
#include "SkImageRef_GlobalPool.h"
static SkBitmap load_bitmap() {
SkBitmap bm;
SkStreamAsset* stream = SkStream::NewFromFile("/skimages/sesame_street_ensemble-hp.jpg");
if (stream) {
SkAutoUnref aur(stream);
if (SkImageDecoder::DecodeStream(stream, &bm, SkBitmap::kNo_Config,
SkImageDecoder::kDecodeBounds_Mode)) {
SkPixelRef* pr = new SkImageRef_GlobalPool(stream, bm.config(), 1);
bm.setPixelRef(pr)->unref();
}
}
return bm;
}
static void drawCircle(SkCanvas* canvas, int r, SkColor color) {
SkPaint paint;
paint.setAntiAlias(true);
paint.setColor(color);
canvas->drawCircle(SkIntToScalar(r), SkIntToScalar(r), SkIntToScalar(r),
paint);
}
class PictureView : public SampleView {
SkBitmap fBitmap;
public:
PictureView() {
SkImageRef_GlobalPool::SetRAMBudget(16 * 1024);
fBitmap = load_bitmap();
fPicture = new SkPicture;
SkCanvas* canvas = fPicture->beginRecording(100, 100);
SkPaint paint;
paint.setAntiAlias(true);
canvas->drawBitmap(fBitmap, 0, 0, NULL);
drawCircle(canvas, 50, SK_ColorBLACK);
fSubPicture = new SkPicture;
canvas->drawPicture(*fSubPicture);
canvas->translate(SkIntToScalar(50), 0);
canvas->drawPicture(*fSubPicture);
canvas->translate(0, SkIntToScalar(50));
canvas->drawPicture(*fSubPicture);
canvas->translate(SkIntToScalar(-50), 0);
canvas->drawPicture(*fSubPicture);
// fPicture now has (4) references to us. We can release ours, and just
// unref fPicture in our destructor, and it will in turn take care of
// the other references to fSubPicture
fSubPicture->unref();
}
virtual ~PictureView() {
fPicture->unref();
}
protected:
// overrides from SkEventSink
virtual bool onQuery(SkEvent* evt) {
if (SampleCode::TitleQ(*evt)) {
SampleCode::TitleR(evt, "Picture");
return true;
}
return this->INHERITED::onQuery(evt);
}
void drawSomething(SkCanvas* canvas) {
SkPaint paint;
canvas->save();
canvas->scale(SkFloatToScalar(0.5f), SkFloatToScalar(0.5f));
canvas->drawBitmap(fBitmap, 0, 0, NULL);
canvas->restore();
const char beforeStr[] = "before circle";
const char afterStr[] = "after circle";
paint.setAntiAlias(true);
paint.setColor(SK_ColorRED);
canvas->drawData(beforeStr, sizeof(beforeStr));
canvas->drawCircle(SkIntToScalar(50), SkIntToScalar(50),
SkIntToScalar(40), paint);
canvas->drawData(afterStr, sizeof(afterStr));
paint.setColor(SK_ColorBLACK);
paint.setTextSize(SkIntToScalar(40));
canvas->drawText("Picture", 7, SkIntToScalar(50), SkIntToScalar(62),
paint);
}
virtual void onDrawContent(SkCanvas* canvas) {
drawSomething(canvas);
SkPicture* pict = new SkPicture;
SkAutoUnref aur(pict);
drawSomething(pict->beginRecording(100, 100));
pict->endRecording();
canvas->save();
canvas->translate(SkIntToScalar(300), SkIntToScalar(50));
canvas->scale(-SK_Scalar1, -SK_Scalar1);
canvas->translate(-SkIntToScalar(100), -SkIntToScalar(50));
canvas->drawPicture(*pict);
canvas->restore();
canvas->save();
canvas->translate(SkIntToScalar(200), SkIntToScalar(150));
canvas->scale(SK_Scalar1, -SK_Scalar1);
canvas->translate(0, -SkIntToScalar(50));
canvas->drawPicture(*pict);
canvas->restore();
canvas->save();
canvas->translate(SkIntToScalar(100), SkIntToScalar(100));
canvas->scale(-SK_Scalar1, SK_Scalar1);
canvas->translate(-SkIntToScalar(100), 0);
canvas->drawPicture(*pict);
canvas->restore();
#ifdef SK_DEVELOPER
if (false) {
SkDebugfDumper dumper;
SkDumpCanvas dumpCanvas(&dumper);
dumpCanvas.drawPicture(*pict);
}
#endif
// test that we can re-record a subpicture, and see the results
SkRandom rand(SampleCode::GetAnimTime());
canvas->translate(SkIntToScalar(10), SkIntToScalar(250));
drawCircle(fSubPicture->beginRecording(50, 50), 25,
rand.nextU() | 0xFF000000);
canvas->drawPicture(*fPicture);
delayInval(500);
}
private:
#define INVAL_ALL_TYPE "inval-all"
void delayInval(SkMSec delay) {
(new SkEvent(INVAL_ALL_TYPE, this->getSinkID()))->postDelay(delay);
}
virtual bool onEvent(const SkEvent& evt) {
if (evt.isType(INVAL_ALL_TYPE)) {
this->inval(NULL);
return true;
}
return this->INHERITED::onEvent(evt);
}
SkPicture* fPicture;
SkPicture* fSubPicture;
typedef SampleView INHERITED;
};
//////////////////////////////////////////////////////////////////////////////
static SkView* MyFactory() { return new PictureView; }
static SkViewRegister reg(MyFactory);