/*
* 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 "SkView.h"
#include "SkCanvas.h"
#include "SkDevice.h"
#include "SkPaint.h"
#include "SkShader.h"
static SkBitmap createBitmap(int n) {
SkBitmap bitmap;
bitmap.setConfig(SkBitmap::kARGB_8888_Config, n, n);
bitmap.allocPixels();
bitmap.eraseColor(0);
SkCanvas canvas(bitmap);
SkRect r;
r.set(0, 0, SkIntToScalar(n), SkIntToScalar(n));
SkPaint paint;
paint.setAntiAlias(true);
paint.setColor(SK_ColorRED);
canvas.drawOval(r, paint);
paint.setColor(SK_ColorBLUE);
paint.setStrokeWidth(SkIntToScalar(n)/15);
paint.setStyle(SkPaint::kStroke_Style);
canvas.drawLine(0, 0, r.fRight, r.fBottom, paint);
canvas.drawLine(0, r.fBottom, r.fRight, 0, paint);
return bitmap;
}
class MipMapView : public SampleView {
SkBitmap fBitmap;
enum {
N = 64
};
public:
MipMapView() {
fBitmap = createBitmap(N);
fWidth = N;
}
protected:
// overrides from SkEventSink
virtual bool onQuery(SkEvent* evt) {
if (SampleCode::TitleQ(*evt)) {
SampleCode::TitleR(evt, "MipMaps");
return true;
}
return this->INHERITED::onQuery(evt);
}
void drawN(SkCanvas* canvas, const SkBitmap& bitmap) {
SkAutoCanvasRestore acr(canvas, true);
for (int i = N; i > 1; i >>= 1) {
canvas->drawBitmap(bitmap, 0, 0, NULL);
canvas->translate(SkIntToScalar(N + 8), 0);
canvas->scale(SK_ScalarHalf, SK_ScalarHalf);
}
}
void drawN2(SkCanvas* canvas, const SkBitmap& bitmap) {
SkBitmap bg;
bg.setConfig(SkBitmap::kARGB_8888_Config, N, N);
bg.allocPixels();
SkAutoCanvasRestore acr(canvas, true);
for (int i = 0; i < 6; i++) {
bg.eraseColor(0);
SkCanvas c(bg);
c.scale(SK_Scalar1 / (1 << i), SK_Scalar1 / (1 << i));
c.drawBitmap(bitmap, 0, 0, NULL);
canvas->save();
canvas->scale(SkIntToScalar(1 << i), SkIntToScalar(1 << i));
canvas->drawBitmap(bg, 0, 0, NULL);
canvas->restore();
canvas->translate(SkIntToScalar(N + 8), 0);
}
}
virtual void onDrawContent(SkCanvas* canvas) {
canvas->translate(SkIntToScalar(10), SkIntToScalar(10));
canvas->scale(1.00000001f, 0.9999999f);
drawN2(canvas, fBitmap);
canvas->translate(0, SkIntToScalar(N + 8));
SkBitmap bitmap(fBitmap);
bitmap.buildMipMap();
drawN2(canvas, bitmap);
SkScalar time = SampleCode::GetAnimScalar(SkIntToScalar(1)/4,
SkIntToScalar(2));
if (time >= SK_Scalar1) {
time = SkIntToScalar(2) - time;
}
fWidth = 8 + SkScalarRound(N * time);
SkRect dst;
dst.set(0, 0, SkIntToScalar(fWidth), SkIntToScalar(fWidth));
SkPaint paint;
paint.setFilterBitmap(true);
paint.setAntiAlias(true);
canvas->translate(0, SkIntToScalar(N + 8));
canvas->drawBitmapRect(fBitmap, NULL, dst, NULL);
canvas->translate(SkIntToScalar(N + 8), 0);
canvas->drawBitmapRect(fBitmap, NULL, dst, &paint);
canvas->translate(-SkIntToScalar(N + 8), SkIntToScalar(N + 8));
canvas->drawBitmapRect(bitmap, NULL, dst, NULL);
canvas->translate(SkIntToScalar(N + 8), 0);
canvas->drawBitmapRect(bitmap, NULL, dst, &paint);
SkShader* s = SkShader::CreateBitmapShader(bitmap,
SkShader::kRepeat_TileMode,
SkShader::kRepeat_TileMode);
paint.setShader(s)->unref();
SkMatrix m;
m.setScale(SkIntToScalar(fWidth) / N,
SkIntToScalar(fWidth) / N);
s->setLocalMatrix(m);
SkRect r;
r.set(0, 0, SkIntToScalar(4*N), SkIntToScalar(5*N/2));
r.offset(SkIntToScalar(N + 12), -SkIntToScalar(N + 4));
canvas->drawRect(r, paint);
this->inval(NULL);
}
private:
int fWidth;
typedef SampleView INHERITED;
};
//////////////////////////////////////////////////////////////////////////////
static SkView* MyFactory() { return new MipMapView; }
static SkViewRegister reg(MyFactory);