diff options
Diffstat (limited to 'samplecode')
106 files changed, 3985 insertions, 1044 deletions
diff --git a/samplecode/ClockFaceView.cpp b/samplecode/ClockFaceView.cpp index c829b69..a479d9c 100644 --- a/samplecode/ClockFaceView.cpp +++ b/samplecode/ClockFaceView.cpp @@ -1,3 +1,10 @@ + +/* + * 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" diff --git a/samplecode/GMSampleView.h b/samplecode/GMSampleView.h new file mode 100644 index 0000000..7decfcb --- /dev/null +++ b/samplecode/GMSampleView.h @@ -0,0 +1,52 @@ + +/* + * Copyright 2011 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + + +#ifndef GMSampleView_DEFINED +#define GMSampleView_DEFINED + +#include "SampleCode.h" +#include "gm.h" + +class GMSampleView : public SampleView { +private: + typedef skiagm::GM GM; + +public: + GMSampleView(GM* gm) + : fGM(gm) {} + + virtual ~GMSampleView() { + delete fGM; + } + +protected: + virtual bool onQuery(SkEvent* evt) { + if (SampleCode::TitleQ(*evt)) { + SkString name("GM:"); + name.append(fGM->shortName()); + SampleCode::TitleR(evt, name.c_str()); + return true; + } + return this->INHERITED::onQuery(evt); + } + + virtual void onDrawContent(SkCanvas* canvas) { + fGM->drawContent(canvas); + } + + virtual void onDrawBackground(SkCanvas* canvas) { + fGM->drawBackground(canvas); + } + +private: + GM* fGM; + typedef SampleView INHERITED; +}; + +#endif diff --git a/samplecode/OverView.cpp b/samplecode/OverView.cpp index 2ae2119..fc4a9ef 100644 --- a/samplecode/OverView.cpp +++ b/samplecode/OverView.cpp @@ -1,3 +1,10 @@ + +/* + * 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 "SkCanvas.h" #include "SkView.h" @@ -6,9 +13,14 @@ static const int N = 8; const SkScalar W = SkIntToScalar(640); const SkScalar H = SkIntToScalar(480); +static const char gIsOverview[] = "is-overview"; +bool is_overview(SkView* view) { + SkEvent isOverview(gIsOverview); + return view->doQuery(&isOverview); +} class OverView : public SkView { public: - OverView(int count, const SkViewFactory factories[]); + OverView(int count, const SkViewFactory* factories[]); virtual ~OverView(); protected: @@ -26,6 +38,9 @@ protected: SampleCode::TitleR(evt, "Overview"); return true; } + if (evt->isType(gIsOverview)) { + return true; + } return this->INHERITED::onQuery(evt); } @@ -46,17 +61,16 @@ protected: private: int fCount; - const SkViewFactory* fFactories; + const SkViewFactory** fFactories; typedef SkView INHERITED; }; -SkView* create_overview(int count, const SkViewFactory factories[]); -SkView* create_overview(int count, const SkViewFactory factories[]) { +SkView* create_overview(int count, const SkViewFactory* factories[]) { return SkNEW_ARGS(OverView, (count, factories)); }; -OverView::OverView(int count, const SkViewFactory factories[]) { +OverView::OverView(int count, const SkViewFactory* factories[]) { fCount = count; fFactories = factories; } @@ -74,7 +88,7 @@ void OverView::onSizeChange() { SkScalar locX = 0; SkScalar locY = 0; for (int i = 0; i < fCount; i++) { - SkView* view = fFactories[i](); + SkView* view = (*fFactories[i])(); view->setVisibleP(true); this->attachChildToBack(view)->unref(); view->setLoc(locX, locY); diff --git a/samplecode/Sample2PtRadial.cpp b/samplecode/Sample2PtRadial.cpp new file mode 100644 index 0000000..0c44fd6 --- /dev/null +++ b/samplecode/Sample2PtRadial.cpp @@ -0,0 +1,52 @@ + +/* + * 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 "SkGradientShader.h" + + +class TwoPtRadialView : public SampleView { +public: + TwoPtRadialView() {} + +protected: + // overrides from SkEventSink + virtual bool onQuery(SkEvent* evt) { + if (SampleCode::TitleQ(*evt)) { + SampleCode::TitleR(evt, "2PtRadial"); + return true; + } + return this->INHERITED::onQuery(evt); + } + + virtual void onDrawContent(SkCanvas* canvas) { + canvas->translate(SkIntToScalar(10), SkIntToScalar(20)); + + SkColor colors[] = { SK_ColorRED, SK_ColorBLUE }; + SkPoint c0 = { 0, 0 }; + SkScalar r0 = 100; + SkPoint c1 = { 100, 100 }; + SkScalar r1 = 100; + SkShader* s = SkGradientShader::CreateTwoPointRadial(c0, r0, c1, r1, colors, + NULL, 2, + SkShader::kClamp_TileMode); + + SkPaint paint; + paint.setShader(s)->unref(); + canvas->drawPaint(paint); + } + +private: + typedef SampleView INHERITED; +}; + +////////////////////////////////////////////////////////////////////////////// + +static SkView* MyFactory() { return new TwoPtRadialView; } +static SkViewRegister reg(MyFactory); diff --git a/samplecode/SampleAAClip.cpp b/samplecode/SampleAAClip.cpp new file mode 100644 index 0000000..d2931fa --- /dev/null +++ b/samplecode/SampleAAClip.cpp @@ -0,0 +1,128 @@ + +/* + * 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 "SkAAClip.h" + +static void testop(const SkIRect& r0, const SkIRect& r1, SkRegion::Op op, + const SkIRect& expectedR) { + SkAAClip c0, c1, c2; + c0.setRect(r0); + c1.setRect(r1); + c2.op(c0, c1, op); + + SkIRect r2 = c2.getBounds(); + SkASSERT(r2 == expectedR); +} + +static const struct { + SkIRect r0; + SkIRect r1; + SkRegion::Op op; + SkIRect expectedR; +} gRec[] = { + {{ 1, 2, 9, 3 }, { -3, 2, 5, 11 }, SkRegion::kDifference_Op, { 5, 2, 9, 3 }}, + {{ 1, 10, 5, 13 }, { 1, 2, 5, 11 }, SkRegion::kDifference_Op, { 1, 11, 5, 13 }}, + {{ 1, 10, 5, 13 }, { 1, 2, 5, 11 }, SkRegion::kReverseDifference_Op, { 1, 2, 5, 10 }}, +}; + +static void testop() { + for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); ++i) { + testop(gRec[i].r0, gRec[i].r1, gRec[i].op, gRec[i].expectedR); + } +} + +static void drawClip(SkCanvas* canvas, const SkAAClip& clip) { + SkMask mask; + SkBitmap bm; + + clip.copyToMask(&mask); + SkAutoMaskFreeImage amfi(mask.fImage); + + bm.setConfig(SkBitmap::kA8_Config, mask.fBounds.width(), + mask.fBounds.height(), mask.fRowBytes); + bm.setPixels(mask.fImage); + + SkPaint paint; + canvas->drawBitmap(bm, + SK_Scalar1 * mask.fBounds.fLeft, + SK_Scalar1 * mask.fBounds.fTop, + &paint); +} + +class AAClipView : public SampleView { +public: + AAClipView() { + testop(); + } + +protected: + // overrides from SkEventSink + virtual bool onQuery(SkEvent* evt) { + if (SampleCode::TitleQ(*evt)) { + SampleCode::TitleR(evt, "AAClip"); + return true; + } + return this->INHERITED::onQuery(evt); + } + + virtual void onDrawContent(SkCanvas* canvas) { +#if 1 + SkAAClip aaclip; + SkPath path; + SkRect bounds; + + bounds.set(0, 0, 20, 20); + bounds.inset(SK_ScalarHalf, SK_ScalarHalf); + +// path.addRect(bounds); +// path.addOval(bounds); + path.addRoundRect(bounds, 4, 4); + aaclip.setPath(path); + canvas->translate(30, 30); + drawClip(canvas, aaclip); + + SkAAClip aaclip2; + path.offset(10, 10); + aaclip2.setPath(path); + canvas->translate(30, 0); + drawClip(canvas, aaclip2); + + SkAAClip aaclip3; + aaclip3.op(aaclip, aaclip2, SkRegion::kIntersect_Op); + canvas->translate(30, 0); + drawClip(canvas, aaclip3); + +#endif + +#if 0 + SkRect r; + r.set(0, 0, this->width(), this->height()); + r.inset(20, 20); + canvas->clipRect(r); + + SkPath path; + path.addRect(r); + SkPaint paint; + paint.setAntiAlias(true); + paint.setColor(SK_ColorRED); + canvas->drawPath(path, paint); +#endif + } + +private: + typedef SkView INHERITED; +}; + +////////////////////////////////////////////////////////////////////////////// + +static SkView* MyFactory() { return new AAClipView; } +static SkViewRegister reg(MyFactory); + diff --git a/samplecode/SampleAAClip2.cpp b/samplecode/SampleAAClip2.cpp new file mode 100644 index 0000000..d12e13c --- /dev/null +++ b/samplecode/SampleAAClip2.cpp @@ -0,0 +1,194 @@ + +/* + * 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 "SkAAClip.h" +#include "SampleCode.h" +#include "SkView.h" +#include "SkCanvas.h" +#include "SkGradientShader.h" +#include "SkPath.h" +#include "SkRegion.h" +#include "SkShader.h" +#include "SkUtils.h" +#include "SkImageDecoder.h" + +#ifdef SK_BUILD_FOR_WIN +// windows doesn't have roundf +inline float roundf(float x) { return (x-floor(x))>0.5 ? ceil(x) : floor(x); } +#endif + +static void drawClip(SkCanvas* canvas, const SkAAClip& clip) { + SkMask mask; + SkBitmap bm; + + clip.copyToMask(&mask); + SkAutoMaskFreeImage amfi(mask.fImage); + + bm.setConfig(SkBitmap::kA8_Config, mask.fBounds.width(), + mask.fBounds.height(), mask.fRowBytes); + bm.setPixels(mask.fImage); + + SkPaint paint; + canvas->drawBitmap(bm, + SK_Scalar1 * mask.fBounds.fLeft, + SK_Scalar1 * mask.fBounds.fTop, + &paint); +} + +static void paint_rgn(SkCanvas* canvas, const SkAAClip& clip, + const SkPaint& paint) { + SkMask mask; + SkBitmap bm; + + clip.copyToMask(&mask); + SkAutoMaskFreeImage amfi(mask.fImage); + + bm.setConfig(SkBitmap::kA8_Config, mask.fBounds.width(), + mask.fBounds.height(), mask.fRowBytes); + bm.setPixels(mask.fImage); + + canvas->drawBitmap(bm, + SK_Scalar1 * mask.fBounds.fLeft, + SK_Scalar1 * mask.fBounds.fTop, + &paint); +} + +class AAClipView2 : public SampleView { +public: + AAClipView2() { + fBase.set(100, 100, 150, 150); + fRect = fBase; + fRect.inset(5, 5); + fRect.offset(25, 25); + this->setBGColor(0xFFDDDDDD); + } + + static void setAAClip(SkAAClip* clip, const SkIRect& rect) { + SkRect r; + r.set(rect); + SkPath path; + path.addRoundRect(r, SkIntToScalar(5), SkIntToScalar(5)); + clip->setPath(path); + } + + void build_rgn(SkAAClip* clip, SkRegion::Op op) { + setAAClip(clip, fBase); + + SkAAClip clip2; + setAAClip(&clip2, fRect); + clip->op(clip2, op); + } + + +protected: + // overrides from SkEventSink + virtual bool onQuery(SkEvent* evt) { + if (SampleCode::TitleQ(*evt)) { + SampleCode::TitleR(evt, "AAClips"); + return true; + } + return this->INHERITED::onQuery(evt); + } + + void drawOrig(SkCanvas* canvas, bool bg) { + SkRect r; + SkPaint paint; + + paint.setStyle(SkPaint::kStroke_Style); + if (bg) + paint.setColor(0xFFBBBBBB); + + r.set(fBase); + canvas->drawRect(r, paint); + r.set(fRect); + canvas->drawRect(r, paint); + } + + static void outer_frame(SkCanvas* canvas, const SkIRect& rect) { + SkRect r; + r.set(rect); + r.inset(-SK_ScalarHalf, -SK_ScalarHalf); + + SkPaint paint; + paint.setColor(SK_ColorGRAY); + paint.setStyle(SkPaint::kStroke_Style); + canvas->drawRect(r, paint); + } + + void drawRgnOped(SkCanvas* canvas, SkRegion::Op op, SkColor color) { + SkAAClip clip; + + this->build_rgn(&clip, op); + + this->drawOrig(canvas, true); + + SkPaint paint; + paint.setColor((color & ~(0xFF << 24)) | (0x44 << 24)); + paint_rgn(canvas, clip, paint); + + paint.setStyle(SkPaint::kStroke_Style); + paint.setColor(color); + paint_rgn(canvas, clip, paint); + + SkAAClip clip2(clip); + clip2.translate(0, 80); + outer_frame(canvas, clip2.getBounds()); + paint_rgn(canvas, clip2, paint); + } + + virtual void onDrawContent(SkCanvas* canvas) { + + static const struct { + SkColor fColor; + const char* fName; + SkRegion::Op fOp; + } gOps[] = { + { SK_ColorBLACK, "Difference", SkRegion::kDifference_Op }, + { SK_ColorRED, "Intersect", SkRegion::kIntersect_Op }, + { 0xFF008800, "Union", SkRegion::kUnion_Op }, + { SK_ColorBLUE, "XOR", SkRegion::kXOR_Op } + }; + + SkPaint textPaint; + textPaint.setAntiAlias(true); + textPaint.setTextSize(SK_Scalar1*24); + + this->drawOrig(canvas, false); + + canvas->translate(0, SkIntToScalar(200)); + + for (size_t op = 0; op < SK_ARRAY_COUNT(gOps); op++) { + canvas->drawText(gOps[op].fName, strlen(gOps[op].fName), SkIntToScalar(75), SkIntToScalar(50), textPaint); + + this->drawRgnOped(canvas, gOps[op].fOp, gOps[op].fColor); + + canvas->translate(SkIntToScalar(200), 0); + } + } + + virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y) { + return fRect.contains(SkScalarRound(x), SkScalarRound(y)) ? new Click(this) : NULL; + } + + virtual bool onClick(Click* click) { + fRect.offset(click->fICurr.fX - click->fIPrev.fX, + click->fICurr.fY - click->fIPrev.fY); + this->inval(NULL); + return true; + } + +private: + SkIRect fBase, fRect; + + typedef SampleView INHERITED; +}; + +////////////////////////////////////////////////////////////////////////////// + +static SkView* MyFactory() { return new AAClipView2; } +static SkViewRegister reg(MyFactory); + diff --git a/samplecode/SampleAARectModes.cpp b/samplecode/SampleAARectModes.cpp new file mode 100644 index 0000000..7b9e7d5 --- /dev/null +++ b/samplecode/SampleAARectModes.cpp @@ -0,0 +1,152 @@ +/* + * 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 "SkColorPriv.h" +#include "SkShader.h" + +static SkCanvas* create_canvas(int w, int h) { + SkBitmap bm; + bm.setConfig(SkBitmap::kARGB_8888_Config, w, h); + bm.allocPixels(); + bm.eraseColor(0); + return new SkCanvas(bm); +} + +static const SkBitmap& extract_bitmap(SkCanvas* canvas) { + return canvas->getDevice()->accessBitmap(false); +} + +static const struct { + SkXfermode::Mode fMode; + const char* fLabel; +} gModes[] = { + { SkXfermode::kClear_Mode, "Clear" }, + { SkXfermode::kSrc_Mode, "Src" }, + { SkXfermode::kDst_Mode, "Dst" }, + { SkXfermode::kSrcOver_Mode, "SrcOver" }, + { SkXfermode::kDstOver_Mode, "DstOver" }, + { SkXfermode::kSrcIn_Mode, "SrcIn" }, + { SkXfermode::kDstIn_Mode, "DstIn" }, + { SkXfermode::kSrcOut_Mode, "SrcOut" }, + { SkXfermode::kDstOut_Mode, "DstOut" }, + { SkXfermode::kSrcATop_Mode, "SrcATop" }, + { SkXfermode::kDstATop_Mode, "DstATop" }, + { SkXfermode::kXor_Mode, "Xor" }, +}; + +const int gWidth = 64; +const int gHeight = 64; +const SkScalar W = SkIntToScalar(gWidth); +const SkScalar H = SkIntToScalar(gHeight); + +static SkScalar drawCell(SkCanvas* canvas, SkXfermode* mode, + SkAlpha a0, SkAlpha a1) { + + SkPaint paint; + paint.setAntiAlias(true); + + SkRect r = SkRect::MakeWH(W, H); + r.inset(W/10, H/10); + + paint.setColor(SK_ColorBLUE); + paint.setAlpha(a0); + canvas->drawOval(r, paint); + + paint.setColor(SK_ColorRED); + paint.setAlpha(a1); + paint.setXfermode(mode); + + SkScalar offset = SK_Scalar1 / 3; + SkRect rect = SkRect::MakeXYWH(W / 4 + offset, + H / 4 + offset, + W / 2, H / 2); + canvas->drawRect(rect, paint); + + return H; +} + +static SkShader* make_bg_shader() { + SkBitmap bm; + bm.setConfig(SkBitmap::kARGB_8888_Config, 2, 2); + bm.allocPixels(); + *bm.getAddr32(0, 0) = *bm.getAddr32(1, 1) = 0xFFFFFFFF; + *bm.getAddr32(1, 0) = *bm.getAddr32(0, 1) = SkPackARGB32(0xFF, 0xCC, + 0xCC, 0xCC); + + SkShader* s = SkShader::CreateBitmapShader(bm, + SkShader::kRepeat_TileMode, + SkShader::kRepeat_TileMode); + + SkMatrix m; + m.setScale(SkIntToScalar(6), SkIntToScalar(6)); + s->setLocalMatrix(m); + return s; +} + +class AARectsModesView : public SampleView { + SkPaint fBGPaint; +public: + AARectsModesView () { + fBGPaint.setShader(make_bg_shader())->unref(); + } + +protected: + // overrides from SkEventSink + virtual bool onQuery(SkEvent* evt) { + if (SampleCode::TitleQ(*evt)) { + SampleCode::TitleR(evt, "AARectsModes"); + return true; + } + return this->INHERITED::onQuery(evt); + } + + virtual void onDrawContent(SkCanvas* canvas) { + const SkRect bounds = SkRect::MakeWH(W, H); + static const SkAlpha gAlphaValue[] = { 0xFF, 0x88, 0x88 }; + + canvas->translate(SkIntToScalar(4), SkIntToScalar(4)); + + for (int alpha = 0; alpha < 4; ++alpha) { + canvas->save(); + canvas->save(); + for (size_t i = 0; i < SK_ARRAY_COUNT(gModes); ++i) { + if (6 == i) { + canvas->restore(); + canvas->translate(W * 5, 0); + canvas->save(); + } + SkXfermode* mode = SkXfermode::Create(gModes[i].fMode); + + canvas->drawRect(bounds, fBGPaint); + canvas->saveLayer(&bounds, NULL); + SkScalar dy = drawCell(canvas, mode, + gAlphaValue[alpha & 1], + gAlphaValue[alpha & 2]); + canvas->restore(); + + canvas->translate(0, dy * 5 / 4); + SkSafeUnref(mode); + } + canvas->restore(); + canvas->restore(); + canvas->translate(W * 5 / 4, 0); + } + } + +private: + typedef SampleView INHERITED; +}; + +/////////////////////////////////////////////////////////////////////////////// + +static SkView* MyFactory() { return new AARectsModesView; } +static SkViewRegister reg(MyFactory); + diff --git a/samplecode/SampleAARects.cpp b/samplecode/SampleAARects.cpp index 34a33b0..0490552 100644 --- a/samplecode/SampleAARects.cpp +++ b/samplecode/SampleAARects.cpp @@ -1,3 +1,10 @@ + +/* + * 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" diff --git a/samplecode/SampleAll.cpp b/samplecode/SampleAll.cpp index abbf8f9..4321532 100644 --- a/samplecode/SampleAll.cpp +++ b/samplecode/SampleAll.cpp @@ -1,3 +1,10 @@ + +/* + * 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 "SkCanvas.h" #include "SkView.h" diff --git a/samplecode/SampleAnimatedGradient.cpp b/samplecode/SampleAnimatedGradient.cpp index a7b2a46..3caff1c 100644 --- a/samplecode/SampleAnimatedGradient.cpp +++ b/samplecode/SampleAnimatedGradient.cpp @@ -1,3 +1,10 @@ + +/* + * 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 "SkCanvas.h" #include "SkGradientShader.h" diff --git a/samplecode/SampleAnimator.cpp b/samplecode/SampleAnimator.cpp index 99173fc..09742a0 100644 --- a/samplecode/SampleAnimator.cpp +++ b/samplecode/SampleAnimator.cpp @@ -1,3 +1,10 @@ + +/* + * 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" @@ -24,6 +31,7 @@ public: protected: // overrides virtual void onDraw(SkCanvas*); + virtual bool onQuery(SkEvent* evt); private: SkString fBaseURI; @@ -119,8 +127,8 @@ bool SkAnimatorView::decodeStream(SkStream* stream) { #include "SkTime.h" void SkAnimatorView::onDraw(SkCanvas* canvas) { + canvas->drawColor(SK_ColorWHITE); if (fAnimator) { - canvas->drawColor(SK_ColorWHITE); fAnimator->draw(canvas, 0); #if 0 canvas->save(); @@ -140,6 +148,14 @@ void SkAnimatorView::onDraw(SkCanvas* canvas) { } } +bool SkAnimatorView::onQuery(SkEvent* evt) { + if (SampleCode::TitleQ(*evt)) { + SampleCode::TitleR(evt, "Animator"); + return true; + } + return this->INHERITED::onQuery(evt); +} + ////////////////////////////////////////////////////////////////////////////// static SkView* MyFactory() { diff --git a/samplecode/SampleApp.cpp b/samplecode/SampleApp.cpp index f05fe6e..95923c8 100644 --- a/samplecode/SampleApp.cpp +++ b/samplecode/SampleApp.cpp @@ -1,6 +1,15 @@ +/* + * 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 "SampleApp.h" + +#include "SkData.h" #include "SkCanvas.h" #include "SkDevice.h" -#include "SkGpuCanvas.h" +#include "SkGpuDevice.h" #include "SkGraphics.h" #include "SkImageEncoder.h" #include "SkPaint.h" @@ -11,22 +20,46 @@ #include "SampleCode.h" #include "GrContext.h" -#include "SkTouchGesture.h" #include "SkTypeface.h" -#define TEST_GPIPEx +#include "GrGLInterface.h" +#include "GrRenderTarget.h" + +#include "SkPDFDevice.h" +#include "SkPDFDocument.h" +#include "SkStream.h" + +#define TEST_GPIPE #ifdef TEST_GPIPE -#define PIPE_FILE +#define PIPE_FILEx +#ifdef PIPE_FILE #define FILE_PATH "/path/to/drawing.data" #endif +#define PIPE_NETx +#ifdef PIPE_NET +#include "SkSockets.h" +SkTCPServer gServer; +#endif + +#define DEBUGGERx +#ifdef DEBUGGER +extern SkView* create_debugger(const char* data, size_t size); +extern bool is_debugger(SkView* view); +SkTDArray<char> gTempDataStore; +#endif + +#endif + #define USE_ARROWS_FOR_ZOOM true //#define DEFAULT_TO_GPU -extern SkView* create_overview(int, const SkViewFactory[]); +extern SkView* create_overview(int, const SkViewFactory*[]); +extern bool is_overview(SkView* view); +//extern SkView* create_transition(SkView*, SkView*, int); +//extern bool is_transition(SkView* view); -#define SK_SUPPORT_GL #define ANIMATING_EVENTTYPE "nextSample" #define ANIMATING_DELAY 750 @@ -38,16 +71,218 @@ extern SkView* create_overview(int, const SkViewFactory[]); #endif #define FPS_REPEAT_COUNT (10 * FPS_REPEAT_MULTIPLIER) -#ifdef SK_SUPPORT_GL - #include "GrGLConfig.h" -#endif +static SampleWindow* gSampleWindow; + +static void postEventToSink(SkEvent* evt, SkEventSink* sink) { + evt->setTargetID(sink->getSinkID())->post(); +} + +/////////////////////////////////////////////////////////////////////////////// + +static const char* skip_until(const char* str, const char* skip) { + if (!str) { + return NULL; + } + return strstr(str, skip); +} + +static const char* skip_past(const char* str, const char* skip) { + const char* found = skip_until(str, skip); + if (!found) { + return NULL; + } + return found + strlen(skip); +} + +static const char* gPrefFileName = "sampleapp_prefs.txt"; + +static bool readTitleFromPrefs(SkString* title) { + SkFILEStream stream(gPrefFileName); + if (!stream.isValid()) { + return false; + } + + int len = stream.getLength(); + SkString data(len); + stream.read(data.writable_str(), len); + const char* s = data.c_str(); + + s = skip_past(s, "curr-slide-title"); + s = skip_past(s, "="); + s = skip_past(s, "\""); + const char* stop = skip_until(s, "\""); + if (stop > s) { + title->set(s, stop - s); + return true; + } + return false; +} + +static void writeTitleToPrefs(const char* title) { + SkFILEWStream stream(gPrefFileName); + SkString data; + data.printf("curr-slide-title = \"%s\"\n", title); + stream.write(data.c_str(), data.size()); +} + +/////////////////////////////////////////////////////////////////////////////// + +class SampleWindow::DefaultDeviceManager : public SampleWindow::DeviceManager { +public: + + DefaultDeviceManager() { + fGrRenderTarget = NULL; + fGrContext = NULL; + fGL = NULL; + fNullGrContext = NULL; + fNullGrRenderTarget = NULL; + } + + virtual ~DefaultDeviceManager() { + SkSafeUnref(fGrRenderTarget); + SkSafeUnref(fGrContext); + SkSafeUnref(fGL); + SkSafeUnref(fNullGrContext); + SkSafeUnref(fNullGrRenderTarget); + } + + virtual void init(SampleWindow* win) { + if (!win->attachGL()) { + SkDebugf("Failed to initialize GL"); + } + if (NULL == fGL) { + fGL = GrGLCreateNativeInterface(); + GrAssert(NULL == fGrContext); + fGrContext = GrContext::Create(kOpenGL_Shaders_GrEngine, + (GrPlatform3DContext) fGL); + } + if (NULL == fGrContext || NULL == fGL) { + SkSafeUnref(fGrContext); + SkSafeUnref(fGL); + SkDebugf("Failed to setup 3D"); + win->detachGL(); + } + if (NULL == fNullGrContext) { + const GrGLInterface* nullGL = GrGLCreateNullInterface(); + fNullGrContext = GrContext::Create(kOpenGL_Shaders_GrEngine, + (GrPlatform3DContext) nullGL); + nullGL->unref(); + } + } + + virtual bool supportsDeviceType(SampleWindow::DeviceType dType) { + switch (dType) { + case kRaster_DeviceType: + case kPicture_DeviceType: // fallthru + return true; + case kGPU_DeviceType: + return NULL != fGrContext && NULL != fGrRenderTarget; + case kNullGPU_DeviceType: + return NULL != fNullGrContext && NULL != fNullGrRenderTarget; + default: + return false; + } + } + + virtual bool prepareCanvas(SampleWindow::DeviceType dType, + SkCanvas* canvas, + SampleWindow* win) { + switch (dType) { + case kGPU_DeviceType: + if (fGrContext) { + canvas->setDevice(new SkGpuDevice(fGrContext, + fGrRenderTarget))->unref(); + } else { + return false; + } + break; + case kNullGPU_DeviceType: + if (fNullGrContext) { + canvas->setDevice(new SkGpuDevice(fNullGrContext, + fNullGrRenderTarget))->unref(); + } else { + return false; + } + break; + case kRaster_DeviceType: + case kPicture_DeviceType: + break; + } + return true; + } + + virtual void publishCanvas(SampleWindow::DeviceType dType, + SkCanvas* canvas, + SampleWindow* win) { + if (fGrContext) { + // in case we have queued drawing calls + fGrContext->flush(); + if (NULL != fNullGrContext) { + fNullGrContext->flush(); + } + if (dType != kGPU_DeviceType && + dType != kNullGPU_DeviceType) { + // need to send the raster bits to the (gpu) window + fGrContext->setRenderTarget(fGrRenderTarget); + const SkBitmap& bm = win->getBitmap(); + fGrRenderTarget->writePixels(0, 0, bm.width(), bm.height(), + kSkia8888_PM_GrPixelConfig, + bm.getPixels(), + bm.rowBytes()); + } + } + win->presentGL(); + } + + virtual void windowSizeChanged(SampleWindow* win) { + if (fGrContext) { + win->attachGL(); + + GrPlatformRenderTargetDesc desc; + desc.fWidth = SkScalarRound(win->width()); + desc.fHeight = SkScalarRound(win->height()); + desc.fConfig = kSkia8888_PM_GrPixelConfig; + GR_GL_GetIntegerv(fGL, GR_GL_SAMPLES, &desc.fSampleCnt); + GR_GL_GetIntegerv(fGL, GR_GL_STENCIL_BITS, &desc.fStencilBits); + GrGLint buffer; + GR_GL_GetIntegerv(fGL, GR_GL_FRAMEBUFFER_BINDING, &buffer); + desc.fRenderTargetHandle = buffer; + + SkSafeUnref(fGrRenderTarget); + fGrRenderTarget = fGrContext->createPlatformRenderTarget(desc); + } + if (NULL != fNullGrContext) { + GrPlatformRenderTargetDesc desc; + desc.fWidth = SkScalarRound(win->width()); + desc.fHeight = SkScalarRound(win->height()); + desc.fConfig = kSkia8888_PM_GrPixelConfig; + desc.fStencilBits = 8; + desc.fSampleCnt = 0; + desc.fRenderTargetHandle = 0; + fNullGrRenderTarget = fNullGrContext->createPlatformRenderTarget(desc); + } + } + + virtual GrContext* getGrContext(SampleWindow::DeviceType dType) { + if (kNullGPU_DeviceType == dType) { + return fNullGrContext; + } else { + return fGrContext; + } + } +private: + GrContext* fGrContext; + const GrGLInterface* fGL; + GrRenderTarget* fGrRenderTarget; + GrContext* fNullGrContext; + GrRenderTarget* fNullGrRenderTarget; +}; /////////////// static const char view_inval_msg[] = "view-inval-msg"; -static void postInvalDelay(SkEventSinkID sinkID) { - SkEvent* evt = new SkEvent(view_inval_msg); - evt->post(sinkID, 1); +void SampleWindow::postInvalDelay() { + (new SkEvent(view_inval_msg, this->getSinkID()))->postDelay(1); } static bool isInvalEvent(const SkEvent& evt) { @@ -55,23 +290,76 @@ static bool isInvalEvent(const SkEvent& evt) { } ////////////////// +SkFuncViewFactory::SkFuncViewFactory(SkViewCreateFunc func) + : fCreateFunc(func) { +} + +SkView* SkFuncViewFactory::operator() () const { + return (*fCreateFunc)(); +} + +#include "GMSampleView.h" + +SkGMSampleViewFactory::SkGMSampleViewFactory(GMFactoryFunc func) + : fFunc(func) { +} + +SkView* SkGMSampleViewFactory::operator() () const { + return new GMSampleView(fFunc(NULL)); +} + SkViewRegister* SkViewRegister::gHead; -SkViewRegister::SkViewRegister(SkViewFactory fact) : fFact(fact) { - static bool gOnce; - if (!gOnce) { - gHead = NULL; - gOnce = true; - } +SkViewRegister::SkViewRegister(SkViewFactory* fact) : fFact(fact) { + fFact->ref(); + fChain = gHead; + gHead = this; +} +SkViewRegister::SkViewRegister(SkViewCreateFunc func) { + fFact = new SkFuncViewFactory(func); fChain = gHead; gHead = this; } -#if defined(SK_SUPPORT_GL) - #define SK_USE_SHADERS -#endif +SkViewRegister::SkViewRegister(GMFactoryFunc func) { + fFact = new SkGMSampleViewFactory(func); + fChain = gHead; + gHead = this; +} -#ifdef SK_BUILD_FOR_MAC +class AutoUnrefArray { +public: + AutoUnrefArray() {} + ~AutoUnrefArray() { + int count = fObjs.count(); + for (int i = 0; i < count; ++i) { + fObjs[i]->unref(); + } + } + SkRefCnt*& push_back() { return *fObjs.append(); } + +private: + SkTDArray<SkRefCnt*> fObjs; +}; + +// registers GMs as Samples +// This can't be performed during static initialization because it could be +// run before GMRegistry has been fully built. +void SkGMRegistyToSampleRegistry() { + static bool gOnce; + static AutoUnrefArray fRegisters; + + if (!gOnce) { + const skiagm::GMRegistry* gmreg = skiagm::GMRegistry::Head(); + while (gmreg) { + fRegisters.push_back() = new SkViewRegister(gmreg->factory()); + gmreg = gmreg->next(); + } + gOnce = true; + } +} + +#if 0 #include <CoreFoundation/CoreFoundation.h> #include <CoreFoundation/CFURLAccess.h> @@ -111,51 +399,36 @@ enum FlipAxisEnum { kFlipAxis_Y = (1 << 1) }; -enum SkTriState { - kFalse_SkTriState, - kTrue_SkTriState, - kUnknown_SkTriState, -}; - -static SkTriState cycle_tristate(SkTriState state) { - static const SkTriState gCycle[] = { - /* kFalse_SkTriState -> */ kUnknown_SkTriState, - /* kTrue_SkTriState -> */ kFalse_SkTriState, - /* kUnknown_SkTriState -> */ kTrue_SkTriState, - }; - return gCycle[state]; -} - #include "SkDrawFilter.h" class FlagsDrawFilter : public SkDrawFilter { public: - FlagsDrawFilter(SkTriState lcd, SkTriState aa, SkTriState filter, - SkTriState hinting) : + FlagsDrawFilter(SkOSMenu::TriState lcd, SkOSMenu::TriState aa, SkOSMenu::TriState filter, + SkOSMenu::TriState hinting) : fLCDState(lcd), fAAState(aa), fFilterState(filter), fHintingState(hinting) {} virtual void filter(SkPaint* paint, Type t) { - if (kText_Type == t && kUnknown_SkTriState != fLCDState) { - paint->setLCDRenderText(kTrue_SkTriState == fLCDState); + if (kText_Type == t && SkOSMenu::kMixedState != fLCDState) { + paint->setLCDRenderText(SkOSMenu::kOnState == fLCDState); } - if (kUnknown_SkTriState != fAAState) { - paint->setAntiAlias(kTrue_SkTriState == fAAState); + if (SkOSMenu::kMixedState != fAAState) { + paint->setAntiAlias(SkOSMenu::kOnState == fAAState); } - if (kUnknown_SkTriState != fFilterState) { - paint->setFilterBitmap(kTrue_SkTriState == fFilterState); + if (SkOSMenu::kMixedState != fFilterState) { + paint->setFilterBitmap(SkOSMenu::kOnState == fFilterState); } - if (kUnknown_SkTriState != fHintingState) { - paint->setHinting(kTrue_SkTriState == fHintingState ? + if (SkOSMenu::kMixedState != fHintingState) { + paint->setHinting(SkOSMenu::kOnState == fHintingState ? SkPaint::kNormal_Hinting : SkPaint::kSlight_Hinting); } } private: - SkTriState fLCDState; - SkTriState fAAState; - SkTriState fFilterState; - SkTriState fHintingState; + SkOSMenu::TriState fLCDState; + SkOSMenu::TriState fAAState; + SkOSMenu::TriState fFilterState; + SkOSMenu::TriState fHintingState; }; ////////////////////////////////////////////////////////////////////////////// @@ -168,6 +441,7 @@ static const char gKeyEvtName[] = "SampleCode_Key_Event"; static const char gTitleEvtName[] = "SampleCode_Title_Event"; static const char gPrefSizeEvtName[] = "SampleCode_PrefSize_Event"; static const char gFastTextEvtName[] = "SampleCode_FastText_Event"; +static const char gUpdateWindowTitleEvtName[] = "SampleCode_UpdateWindowTitle"; bool SampleCode::CharQ(const SkEvent& evt, SkUnichar* outUni) { if (evt.isType(gCharEvtName, sizeof(gCharEvtName) - 1)) { @@ -198,6 +472,15 @@ void SampleCode::TitleR(SkEvent* evt, const char title[]) { evt->setString(gTitleEvtName, title); } +bool SampleCode::RequestTitle(SkView* view, SkString* title) { + SkEvent evt(gTitleEvtName); + if (view->doQuery(&evt)) { + title->set(evt.findString(gTitleEvtName)); + return true; + } + return false; +} + bool SampleCode::PrefSizeQ(const SkEvent& evt) { return evt.isType(gPrefSizeEvtName, sizeof(gPrefSizeEvtName) - 1); } @@ -237,6 +520,15 @@ SkScalar SampleCode::GetAnimScalar(SkScalar speed, SkScalar period) { return SkDoubleToScalar(value); } +GrContext* SampleCode::GetGr() { + return gSampleWindow ? gSampleWindow->getGrContext() : NULL; +} + +// some GMs rely on having a skiagm::GetGr function defined +namespace skiagm { + GrContext* GetGr() { return SampleCode::GetGr(); } +} + ////////////////////////////////////////////////////////////////////////////// static SkView* curr_view(SkWindow* wind) { @@ -244,111 +536,23 @@ static SkView* curr_view(SkWindow* wind) { return iter.next(); } -class SampleWindow : public SkOSWindow { - SkTDArray<SkViewFactory> fSamples; -public: - SampleWindow(void* hwnd); - virtual ~SampleWindow(); - - virtual void draw(SkCanvas* canvas); - -protected: - virtual void onDraw(SkCanvas* canvas); - virtual bool onHandleKey(SkKey key); - virtual bool onHandleChar(SkUnichar); - virtual void onSizeChange(); - - virtual SkCanvas* beforeChildren(SkCanvas*); - virtual void afterChildren(SkCanvas*); - virtual void beforeChild(SkView* child, SkCanvas* canvas); - virtual void afterChild(SkView* child, SkCanvas* canvas); - - virtual bool onEvent(const SkEvent& evt); - virtual bool onQuery(SkEvent* evt); - - virtual bool onDispatchClick(int x, int y, Click::State); - virtual bool onClick(Click* click); - virtual Click* onFindClickHandler(SkScalar x, SkScalar y); - -#if 0 - virtual bool handleChar(SkUnichar uni); - virtual bool handleEvent(const SkEvent& evt); - virtual bool handleKey(SkKey key); - virtual bool handleKeyUp(SkKey key); - virtual bool onHandleKeyUp(SkKey key); -#endif - -private: - int fCurrIndex; - - SkPicture* fPicture; - SkGpuCanvas* fGpuCanvas; - GrContext* fGrContext; - SkPath fClipPath; - - SkTouchGesture fGesture; - int fZoomLevel; - SkScalar fZoomScale; - - enum CanvasType { - kRaster_CanvasType, - kPicture_CanvasType, - kGPU_CanvasType - }; - CanvasType fCanvasType; - - bool fUseClip; - bool fNClip; - bool fRepeatDrawing; - bool fAnimating; - bool fRotate; - bool fScale; - bool fRequestGrabImage; - bool fUsePipe; - bool fMeasureFPS; - SkMSec fMeasureFPS_Time; - - // The following are for the 'fatbits' drawing - // Latest position of the mouse. - int fMouseX, fMouseY; - int fFatBitsScale; - // Used by the text showing position and color values. - SkTypeface* fTypeface; - bool fShowZoomer; - - SkTriState fLCDState; - SkTriState fAAState; - SkTriState fFilterState; - SkTriState fHintingState; - unsigned fFlipAxis; - - int fScrollTestX, fScrollTestY; - - bool make3DReady(); - void changeZoomLevel(int delta); - - void loadView(SkView*); - void updateTitle(); - bool nextSample(); - - void toggleZoomer(); - bool zoomIn(); - bool zoomOut(); - void updatePointer(int x, int y); - void showZoomer(SkCanvas* canvas); - - void postAnimatingEvent() { - if (fAnimating) { - SkEvent* evt = new SkEvent(ANIMATING_EVENTTYPE); - evt->post(this->getSinkID(), ANIMATING_DELAY); +static bool curr_title(SkWindow* wind, SkString* title) { + SkView* view = curr_view(wind); + if (view) { + SkEvent evt(gTitleEvtName); + if (view->doQuery(&evt)) { + title->set(evt.findString(gTitleEvtName)); + return true; } } + return false; +} - - static CanvasType cycle_canvastype(CanvasType); - - typedef SkOSWindow INHERITED; -}; +void SampleWindow::setZoomCenter(float x, float y) +{ + fZoomCenterX = SkFloatToScalar(x); + fZoomCenterY = SkFloatToScalar(y); +} bool SampleWindow::zoomIn() { @@ -367,12 +571,6 @@ bool SampleWindow::zoomOut() return true; } -void SampleWindow::toggleZoomer() -{ - fShowZoomer = !fShowZoomer; - this->inval(NULL); -} - void SampleWindow::updatePointer(int x, int y) { fMouseX = x; @@ -382,54 +580,19 @@ void SampleWindow::updatePointer(int x, int y) } } -bool SampleWindow::make3DReady() { - -#if defined(SK_SUPPORT_GL) - if (attachGL()) { - if (NULL != fGrContext) { - // various gr lifecycle tests - #if 0 - fGrContext->freeGpuResources(); - #elif 0 - // this will leak resources. - fGrContext->contextLost(); - #elif 0 - GrAssert(1 == fGrContext->refcnt()); - fGrContext->unref(); - fGrContext = NULL; - #endif - } - - if (NULL == fGrContext) { - #if defined(SK_USE_SHADERS) - fGrContext = GrContext::Create(kOpenGL_Shaders_GrEngine, NULL); - #else - fGrContext = GrContext::Create(kOpenGL_Fixed_GrEngine, NULL); - #endif - SkDebugf("---- constructor\n"); - } - - if (NULL != fGrContext) { - return true; - } else { - detachGL(); - } - } -#endif - SkDebugf("Failed to setup 3D"); - return false; -} - -SampleWindow::CanvasType SampleWindow::cycle_canvastype(CanvasType ct) { - static const CanvasType gCT[] = { - kPicture_CanvasType, - kGPU_CanvasType, - kRaster_CanvasType +static inline SampleWindow::DeviceType cycle_devicetype(SampleWindow::DeviceType ct) { + static const SampleWindow::DeviceType gCT[] = { + SampleWindow::kPicture_DeviceType, + SampleWindow::kGPU_DeviceType, + SampleWindow::kRaster_DeviceType, // skip the null gpu device in normal cycling + SampleWindow::kRaster_DeviceType }; return gCT[ct]; } -SampleWindow::SampleWindow(void* hwnd) : INHERITED(hwnd) { +SampleWindow::SampleWindow(void* hwnd, int argc, char** argv, DeviceManager* devManager) : INHERITED(hwnd) { + gSampleWindow = this; + #ifdef PIPE_FILE //Clear existing file or create file if it doesn't exist FILE* f = fopen(FILE_PATH, "wb"); @@ -437,28 +600,26 @@ SampleWindow::SampleWindow(void* hwnd) : INHERITED(hwnd) { #endif fPicture = NULL; - fGpuCanvas = NULL; - - fGrContext = NULL; - + #ifdef DEFAULT_TO_GPU - fCanvasType = kGPU_CanvasType; + fDeviceType = kGPU_DeviceType; #else - fCanvasType = kRaster_CanvasType; + fDeviceType = kRaster_DeviceType; #endif fUseClip = false; fNClip = false; - fRepeatDrawing = false; fAnimating = false; fRotate = false; + fPerspAnim = false; + fPerspAnimTime = 0; fScale = false; fRequestGrabImage = false; fUsePipe = false; fMeasureFPS = false; - fLCDState = kUnknown_SkTriState; - fAAState = kUnknown_SkTriState; - fFilterState = kUnknown_SkTriState; - fHintingState = kUnknown_SkTriState; + fLCDState = SkOSMenu::kMixedState; + fAAState = SkOSMenu::kMixedState; + fFilterState = SkOSMenu::kMixedState; + fHintingState = SkOSMenu::kMixedState; fFlipAxis = 0; fScrollTestX = fScrollTestY = 0; @@ -466,15 +627,74 @@ SampleWindow::SampleWindow(void* hwnd) : INHERITED(hwnd) { fFatBitsScale = 8; fTypeface = SkTypeface::CreateFromTypeface(NULL, SkTypeface::kBold); fShowZoomer = false; - + fZoomLevel = 0; fZoomScale = SK_Scalar1; + + fMagnify = false; + fDebugger = false; + + fSaveToPdf = false; + fPdfCanvas = NULL; + fTransitionNext = 6; + fTransitionPrev = 2; + + int sinkID = this->getSinkID(); + fAppMenu.setTitle("Global Settings"); + int itemID; + + itemID =fAppMenu.appendList("Device Type", "Device Type", sinkID, 0, + "Raster", "Picture", "OpenGL", NULL); + fAppMenu.assignKeyEquivalentToItem(itemID, 'd'); + itemID = fAppMenu.appendTriState("AA", "AA", sinkID, fAAState); + fAppMenu.assignKeyEquivalentToItem(itemID, 'b'); + itemID = fAppMenu.appendTriState("LCD", "LCD", sinkID, fLCDState); + fAppMenu.assignKeyEquivalentToItem(itemID, 'l'); + itemID = fAppMenu.appendTriState("Filter", "Filter", sinkID, fFilterState); + fAppMenu.assignKeyEquivalentToItem(itemID, 'n'); + itemID = fAppMenu.appendTriState("Hinting", "Hinting", sinkID, fHintingState); + fAppMenu.assignKeyEquivalentToItem(itemID, 'h'); + fUsePipeMenuItemID = fAppMenu.appendSwitch("Pipe", "Pipe" , sinkID, fUsePipe); + fAppMenu.assignKeyEquivalentToItem(fUsePipeMenuItemID, 'p'); +#ifdef DEBUGGER + itemID = fAppMenu.appendSwitch("Debugger", "Debugger", sinkID, fDebugger); + fAppMenu.assignKeyEquivalentToItem(itemID, 'q'); +#endif + itemID = fAppMenu.appendSwitch("Slide Show", "Slide Show" , sinkID, false); + fAppMenu.assignKeyEquivalentToItem(itemID, 'a'); + itemID = fAppMenu.appendSwitch("Clip", "Clip" , sinkID, fUseClip); + fAppMenu.assignKeyEquivalentToItem(itemID, 'c'); + itemID = fAppMenu.appendSwitch("Flip X", "Flip X" , sinkID, false); + fAppMenu.assignKeyEquivalentToItem(itemID, 'x'); + itemID = fAppMenu.appendSwitch("Flip Y", "Flip Y" , sinkID, false); + fAppMenu.assignKeyEquivalentToItem(itemID, 'y'); + itemID = fAppMenu.appendSwitch("Zoomer", "Zoomer" , sinkID, fShowZoomer); + fAppMenu.assignKeyEquivalentToItem(itemID, 'z'); + itemID = fAppMenu.appendSwitch("Magnify", "Magnify" , sinkID, fMagnify); + fAppMenu.assignKeyEquivalentToItem(itemID, 'm'); + itemID =fAppMenu.appendList("Transition-Next", "Transition-Next", sinkID, + fTransitionNext, "Up", "Up and Right", "Right", + "Down and Right", "Down", "Down and Left", + "Left", "Up and Left", NULL); + fAppMenu.assignKeyEquivalentToItem(itemID, 'j'); + itemID =fAppMenu.appendList("Transition-Prev", "Transition-Prev", sinkID, + fTransitionPrev, "Up", "Up and Right", "Right", + "Down and Right", "Down", "Down and Left", + "Left", "Up and Left", NULL); + fAppMenu.assignKeyEquivalentToItem(itemID, 'k'); + itemID = fAppMenu.appendAction("Save to PDF", sinkID); + fAppMenu.assignKeyEquivalentToItem(itemID, 'e'); + + this->addMenu(&fAppMenu); + this->addMenu(&fSlideMenu); + // this->setConfig(SkBitmap::kRGB_565_Config); this->setConfig(SkBitmap::kARGB_8888_Config); this->setVisibleP(true); this->setClipToBounds(false); + SkGMRegistyToSampleRegistry(); { const SkViewRegister* reg = SkViewRegister::Head(); while (reg) { @@ -483,20 +703,62 @@ SampleWindow::SampleWindow(void* hwnd) : INHERITED(hwnd) { } } fCurrIndex = 0; - this->loadView(fSamples[fCurrIndex]()); + if (argc > 1) { + fCurrIndex = findByTitle(argv[1]); + if (fCurrIndex < 0) { + fprintf(stderr, "Unknown sample \"%s\"\n", argv[1]); + } + } else { + SkString title; + if (readTitleFromPrefs(&title)) { + fCurrIndex = findByTitle(title.c_str()); + } + } -#ifdef SK_BUILD_FOR_MAC - testpdf(); -#endif + if (fCurrIndex < 0) { + fCurrIndex = 0; + } + this->loadView((*fSamples[fCurrIndex])()); + + fPDFData = NULL; + + if (NULL == devManager) { + fDevManager = new DefaultDeviceManager(); + } else { + devManager->ref(); + fDevManager = devManager; + } + fDevManager->init(this); + + // If another constructor set our dimensions, ensure that our + // onSizeChange gets called. + if (this->height() && this->width()) { + this->onSizeChange(); + } + + // can't call this synchronously, since it may require a subclass to + // to implement, or the caller may need us to have returned from the + // constructor first. Hence we post an event to ourselves. +// this->updateTitle(); + postEventToSink(new SkEvent(gUpdateWindowTitleEvtName), this); } SampleWindow::~SampleWindow() { delete fPicture; - delete fGpuCanvas; - if (NULL != fGrContext) { - fGrContext->unref(); - } + delete fPdfCanvas; fTypeface->unref(); + + SkSafeUnref(fDevManager); +} + +int SampleWindow::findByTitle(const char title[]) { + int i, count = fSamples.count(); + for (i = 0; i < count; i++) { + if (getSampleTitle(i).equals(title)) { + return i; + } + } + return -1; } static SkBitmap capture_bitmap(SkCanvas* canvas) { @@ -548,55 +810,27 @@ static void drawText(SkCanvas* canvas, SkString string, SkScalar left, SkScalar #define YCLIP_N 8 void SampleWindow::draw(SkCanvas* canvas) { + if (!fDevManager->prepareCanvas(fDeviceType, canvas, this)) { + return; + } // update the animation time - gAnimTimePrev = gAnimTime; - gAnimTime = SkTime::GetMSecs(); - - SkScalar cx = SkScalarHalf(this->width()); - SkScalar cy = SkScalarHalf(this->height()); - - if (fZoomLevel) { - SkMatrix m; - SkPoint center; - m = canvas->getTotalMatrix();//.invert(&m); - m.mapXY(cx, cy, ¢er); - cx = center.fX; - cy = center.fY; - - m.setTranslate(-cx, -cy); - m.postScale(fZoomScale, fZoomScale); - m.postTranslate(cx, cy); - - canvas->concat(m); + if (!gAnimTimePrev && !gAnimTime) { + // first time make delta be 0 + gAnimTime = SkTime::GetMSecs(); + gAnimTimePrev = gAnimTime; + } else { + gAnimTimePrev = gAnimTime; + gAnimTime = SkTime::GetMSecs(); } - - if (fFlipAxis) { - SkMatrix m; - m.setTranslate(cx, cy); - if (fFlipAxis & kFlipAxis_X) { - m.preScale(-SK_Scalar1, SK_Scalar1); - } - if (fFlipAxis & kFlipAxis_Y) { - m.preScale(SK_Scalar1, -SK_Scalar1); - } - m.preTranslate(-cx, -cy); - canvas->concat(m); + + const SkMatrix& localM = fGesture.localM(); + if (localM.getType() & SkMatrix::kScale_Mask) { + canvas->setExternalMatrix(&localM); } - - // Apply any gesture matrix - if (true) { - const SkMatrix& localM = fGesture.localM(); - if (localM.getType() & SkMatrix::kScale_Mask) { - canvas->setExternalMatrix(&localM); - } - canvas->concat(localM); - canvas->concat(fGesture.globalM()); - - if (fGesture.isActive()) { - this->inval(NULL); - } + if (fGesture.isActive()) { + this->updateMatrix(); } - + if (fNClip) { this->INHERITED::draw(canvas); SkBitmap orig = capture_bitmap(canvas); @@ -630,14 +864,52 @@ void SampleWindow::draw(SkCanvas* canvas) { } else { this->INHERITED::draw(canvas); } - if (fShowZoomer && fCanvasType != kGPU_CanvasType) { - // In the GPU case, INHERITED::draw calls beforeChildren, which - // creates an SkGpuCanvas. All further draw calls are directed - // at that canvas, which is deleted in afterChildren (which is - // also called by draw), so we cannot show the zoomer here. - // Instead, we call it inside afterChildren. + if (fShowZoomer && !fSaveToPdf) { showZoomer(canvas); } + if (fMagnify && !fSaveToPdf) { + magnify(canvas); + } + + // do this last + fDevManager->publishCanvas(fDeviceType, canvas, this); +} + +static float clipW = 200; +static float clipH = 200; +void SampleWindow::magnify(SkCanvas* canvas) { + SkRect r; + int count = canvas->save(); + + SkMatrix m = canvas->getTotalMatrix(); + m.invert(&m); + SkPoint offset, center; + SkScalar mouseX = fMouseX * SK_Scalar1; + SkScalar mouseY = fMouseY * SK_Scalar1; + m.mapXY(mouseX - clipW/2, mouseY - clipH/2, &offset); + m.mapXY(mouseX, mouseY, ¢er); + + r.set(0, 0, clipW * m.getScaleX(), clipH * m.getScaleX()); + r.offset(offset.fX, offset.fY); + + SkPaint paint; + paint.setColor(0xFF66AAEE); + paint.setStyle(SkPaint::kStroke_Style); + paint.setStrokeWidth(10.f * m.getScaleX()); + //lense offset + //canvas->translate(0, -250); + canvas->drawRect(r, paint); + canvas->clipRect(r); + + m = canvas->getTotalMatrix(); + m.setTranslate(-center.fX, -center.fY); + m.postScale(0.5f * fFatBitsScale, 0.5f * fFatBitsScale); + m.postTranslate(center.fX, center.fY); + canvas->concat(m); + + this->INHERITED::draw(canvas); + + canvas->restoreToCount(count); } void SampleWindow::showZoomer(SkCanvas* canvas) { @@ -726,9 +998,6 @@ void SampleWindow::showZoomer(SkCanvas* canvas) { } void SampleWindow::onDraw(SkCanvas* canvas) { - if (fRepeatDrawing) { - this->inval(NULL); - } } #include "SkColorPriv.h" @@ -749,49 +1018,39 @@ static void reverseRedAndBlue(const SkBitmap& bm) { } } -SkCanvas* SampleWindow::beforeChildren(SkCanvas* canvas) { - if (kGPU_CanvasType != fCanvasType) { -#ifdef SK_SUPPORT_GL - detachGL(); -#endif - } - - switch (fCanvasType) { - case kRaster_CanvasType: - canvas = this->INHERITED::beforeChildren(canvas); - break; - case kPicture_CanvasType: - fPicture = new SkPicture; - canvas = fPicture->beginRecording(9999, 9999); - break; - case kGPU_CanvasType: { - if (make3DReady()) { - SkDevice* device = canvas->getDevice(); - const SkBitmap& bitmap = device->accessBitmap(true); - - GrRenderTarget* renderTarget; - renderTarget = fGrContext->createRenderTargetFrom3DApiState(); - fGpuCanvas = new SkGpuCanvas(fGrContext, renderTarget); - renderTarget->unref(); - - device = fGpuCanvas->createDevice(SkBitmap::kARGB_8888_Config, - bitmap.width(), bitmap.height(), - false, false); - fGpuCanvas->setDevice(device)->unref(); - - fGpuCanvas->concat(canvas->getTotalMatrix()); - canvas = fGpuCanvas; +void SampleWindow::saveToPdf() +{ + fSaveToPdf = true; + this->inval(NULL); +} - } else { +SkCanvas* SampleWindow::beforeChildren(SkCanvas* canvas) { + if (fSaveToPdf) { + const SkBitmap& bmp = canvas->getDevice()->accessBitmap(false); + SkISize size = SkISize::Make(bmp.width(), bmp.height()); + SkPDFDevice* pdfDevice = new SkPDFDevice(size, size, + canvas->getTotalMatrix()); + fPdfCanvas = new SkCanvas(pdfDevice); + pdfDevice->unref(); + canvas = fPdfCanvas; + } else { + switch (fDeviceType) { + case kRaster_DeviceType: + case kGPU_DeviceType: canvas = this->INHERITED::beforeChildren(canvas); - } - break; + break; + case kPicture_DeviceType: + fPicture = new SkPicture; + canvas = fPicture->beginRecording(9999, 9999); + break; + case kNullGPU_DeviceType: + break; } } if (fUseClip) { canvas->drawColor(0xFFFF88FF); - canvas->clipPath(fClipPath); + canvas->clipPath(fClipPath, SkRegion::kIntersect_Op, true); } return canvas; @@ -806,13 +1065,47 @@ static void paint_rgn(const SkBitmap& bm, const SkIRect& r, canvas.clipRegion(inval); canvas.drawColor(0xFFFF8080); } - +#include "SkData.h" void SampleWindow::afterChildren(SkCanvas* orig) { + if (fSaveToPdf) { + fSaveToPdf = false; + if (fShowZoomer) { + showZoomer(fPdfCanvas); + } + SkString name; + name.printf("%s.pdf", this->getTitle()); + SkPDFDocument doc; + SkPDFDevice* device = static_cast<SkPDFDevice*>(fPdfCanvas->getDevice()); + doc.appendPage(device); +#ifdef SK_BUILD_FOR_ANDROID + name.prepend("/sdcard/"); +#endif + +#ifdef SK_BUILD_FOR_IOS + SkDynamicMemoryWStream mstream; + doc.emitPDF(&mstream); + fPDFData = mstream.copyToData(); +#endif + SkFILEWStream stream(name.c_str()); + if (stream.isValid()) { + doc.emitPDF(&stream); + const char* desc = "File saved from Skia SampleApp"; + this->onPDFSaved(this->getTitle(), desc, name.c_str()); + } + + delete fPdfCanvas; + fPdfCanvas = NULL; + + // We took over the draw calls in order to create the PDF, so we need + // to redraw. + this->inval(NULL); + return; + } + if (fRequestGrabImage) { fRequestGrabImage = false; - SkCanvas* canvas = fGpuCanvas ? fGpuCanvas : orig; - SkDevice* device = canvas->getDevice(); + SkDevice* device = orig->getDevice(); SkBitmap bmp; if (device->accessBitmap(false).copyTo(&bmp, SkBitmap::kARGB_8888_Config)) { static int gSampleGrabCounter; @@ -823,46 +1116,34 @@ void SampleWindow::afterChildren(SkCanvas* orig) { } } - switch (fCanvasType) { - case kRaster_CanvasType: - break; - case kPicture_CanvasType: - if (true) { - SkPicture* pict = new SkPicture(*fPicture); - fPicture->unref(); - orig->drawPicture(*pict); - pict->unref(); - } else if (true) { - SkDynamicMemoryWStream ostream; - fPicture->serialize(&ostream); - fPicture->unref(); - - SkMemoryStream istream(ostream.getStream(), ostream.getOffset()); - SkPicture pict(&istream); - orig->drawPicture(pict); - } else { - fPicture->draw(orig); - fPicture->unref(); - } - fPicture = NULL; - break; -#ifdef SK_SUPPORT_GL - case kGPU_CanvasType: - if (fShowZoomer && fGpuCanvas) { - this->showZoomer(fGpuCanvas); - } - delete fGpuCanvas; - fGpuCanvas = NULL; - presentGL(); - break; -#endif + if (kPicture_DeviceType == fDeviceType) { + if (true) { + SkPicture* pict = new SkPicture(*fPicture); + fPicture->unref(); + this->installDrawFilter(orig); + orig->drawPicture(*pict); + pict->unref(); + } else if (true) { + SkDynamicMemoryWStream ostream; + fPicture->serialize(&ostream); + fPicture->unref(); + + SkAutoDataUnref data(ostream.copyToData()); + SkMemoryStream istream(data.data(), data.size()); + SkPicture pict(&istream); + orig->drawPicture(pict); + } else { + fPicture->draw(orig); + fPicture->unref(); + } + fPicture = NULL; } // Do this after presentGL and other finishing, rather than in afterChild if (fMeasureFPS && fMeasureFPS_Time) { fMeasureFPS_Time = SkTime::GetMSecs() - fMeasureFPS_Time; this->updateTitle(); - postInvalDelay(this->getSinkID()); + this->postInvalDelay(); } // if ((fScrollTestX | fScrollTestY) != 0) @@ -876,7 +1157,24 @@ void SampleWindow::afterChildren(SkCanvas* orig) { r.set(50, 50, 50+100, 50+100); bm.scrollRect(&r, dx, dy, &inval); paint_rgn(bm, r, inval); - } + } +#ifdef DEBUGGER + SkView* curr = curr_view(this); + if (fDebugger && !is_debugger(curr) && !is_transition(curr) && !is_overview(curr)) { + //Stop Pipe when fDebugger is active + fUsePipe = false; + (void)SampleView::SetUsePipe(curr, false); + fAppMenu.getItemByID(fUsePipeMenuItemID)->setBool(fUsePipe); + this->onUpdateMenu(&fAppMenu); + + //Reset any transformations + fGesture.stop(); + fGesture.reset(); + + this->loadView(create_debugger(gTempDataStore.begin(), + gTempDataStore.count())); + } +#endif } void SampleWindow::beforeChild(SkView* child, SkCanvas* canvas) { @@ -895,9 +1193,24 @@ void SampleWindow::beforeChild(SkView* child, SkCanvas* canvas) { canvas->rotate(SkIntToScalar(30)); canvas->translate(-cx, -cy); } + if (fPerspAnim) { + fPerspAnimTime += SampleCode::GetAnimSecondsDelta(); - canvas->setDrawFilter(new FlagsDrawFilter(fLCDState, fAAState, - fFilterState, fHintingState))->unref(); + static const SkScalar gAnimPeriod = 10 * SK_Scalar1; + static const SkScalar gAnimMag = SK_Scalar1 / 1000; + SkScalar t = SkScalarMod(fPerspAnimTime, gAnimPeriod); + if (SkScalarFloorToInt(SkScalarDiv(fPerspAnimTime, gAnimPeriod)) & 0x1) { + t = gAnimPeriod - t; + } + t = 2 * t - gAnimPeriod; + t = SkScalarMul(SkScalarDiv(t, gAnimPeriod), gAnimMag); + SkMatrix m; + m.reset(); + m.setPerspY(t); + canvas->concat(m); + } + + this->installDrawFilter(canvas); if (fMeasureFPS) { fMeasureFPS_Time = 0; // 0 means the child is not aware of repeat-draw @@ -907,7 +1220,10 @@ void SampleWindow::beforeChild(SkView* child, SkCanvas* canvas) { } else { (void)SampleView::SetRepeatDraw(child, 1); } - (void)SampleView::SetUsePipe(child, fUsePipe); + if (fPerspAnim) { + this->inval(NULL); + } + //(void)SampleView::SetUsePipe(child, fUsePipe); } void SampleWindow::afterChild(SkView* child, SkCanvas* canvas) { @@ -928,28 +1244,116 @@ static SkBitmap::Config cycle_configs(SkBitmap::Config c) { return gConfigCycle[c]; } -void SampleWindow::changeZoomLevel(int delta) { - fZoomLevel += delta; +void SampleWindow::changeZoomLevel(float delta) { + fZoomLevel += SkFloatToScalar(delta); if (fZoomLevel > 0) { - fZoomLevel = SkMin32(fZoomLevel, MAX_ZOOM_LEVEL); - fZoomScale = SkIntToScalar(fZoomLevel + 1); + fZoomLevel = SkMinScalar(fZoomLevel, MAX_ZOOM_LEVEL); + fZoomScale = fZoomLevel + SK_Scalar1; } else if (fZoomLevel < 0) { - fZoomLevel = SkMax32(fZoomLevel, MIN_ZOOM_LEVEL); - fZoomScale = SK_Scalar1 / (1 - fZoomLevel); + fZoomLevel = SkMaxScalar(fZoomLevel, MIN_ZOOM_LEVEL); + fZoomScale = SK_Scalar1 / (SK_Scalar1 - fZoomLevel); } else { fZoomScale = SK_Scalar1; } + this->updateMatrix(); +} +void SampleWindow::updateMatrix(){ + SkMatrix m; + m.reset(); + if (fZoomLevel) { + SkPoint center; + //m = this->getLocalMatrix();//.invert(&m); + m.mapXY(fZoomCenterX, fZoomCenterY, ¢er); + SkScalar cx = center.fX; + SkScalar cy = center.fY; + + m.setTranslate(-cx, -cy); + m.postScale(fZoomScale, fZoomScale); + m.postTranslate(cx, cy); + } + + if (fFlipAxis) { + m.preTranslate(fZoomCenterX, fZoomCenterY); + if (fFlipAxis & kFlipAxis_X) { + m.preScale(-SK_Scalar1, SK_Scalar1); + } + if (fFlipAxis & kFlipAxis_Y) { + m.preScale(SK_Scalar1, -SK_Scalar1); + } + m.preTranslate(-fZoomCenterX, -fZoomCenterY); + //canvas->concat(m); + } + // Apply any gesture matrix + m.preConcat(fGesture.localM()); + m.preConcat(fGesture.globalM()); + + this->setLocalMatrix(m); + + this->updateTitle(); this->inval(NULL); } +bool SampleWindow::previousSample() { + fCurrIndex = (fCurrIndex - 1 + fSamples.count()) % fSamples.count(); + SkView* view = (*fSamples[fCurrIndex])(); + this->loadView(view); +// this->loadView(create_transition(curr_view(this), (*fSamples[fCurrIndex])(), +// fTransitionPrev)); + return true; +} bool SampleWindow::nextSample() { fCurrIndex = (fCurrIndex + 1) % fSamples.count(); - this->loadView(fSamples[fCurrIndex]()); + SkView* view = (*fSamples[fCurrIndex])(); + this->loadView(view); +// this->loadView(create_transition(curr_view(this), (*fSamples[fCurrIndex])(), +// fTransitionNext)); + return true; +} + +bool SampleWindow::goToSample(int i) { + fCurrIndex = (i) % fSamples.count(); + SkView* view = (*fSamples[fCurrIndex])(); + this->loadView(view); +// this->loadView(create_transition(curr_view(this),(*fSamples[fCurrIndex])(), 6)); return true; } +SkString SampleWindow::getSampleTitle(int i) { + SkView* view = (*fSamples[i])(); + SkString title; + SampleCode::RequestTitle(view, &title); + view->unref(); + return title; +} + +int SampleWindow::sampleCount() { + return fSamples.count(); +} + +void SampleWindow::showOverview() { + this->loadView(create_overview(fSamples.count(), fSamples.begin())); +// this->loadView(create_transition(curr_view(this), +// create_overview(fSamples.count(), fSamples.begin()), +// 4)); +} + +void SampleWindow::installDrawFilter(SkCanvas* canvas) { + canvas->setDrawFilter(new FlagsDrawFilter(fLCDState, fAAState, + fFilterState, fHintingState))->unref(); +} + +void SampleWindow::postAnimatingEvent() { + if (fAnimating) { + (new SkEvent(ANIMATING_EVENTTYPE, this->getSinkID()))->postDelay(ANIMATING_DELAY); + } +} + bool SampleWindow::onEvent(const SkEvent& evt) { + if (evt.isType(gUpdateWindowTitleEvtName)) { + this->updateTitle(); + return true; + } if (evt.isType(ANIMATING_EVENTTYPE)) { if (fAnimating) { this->nextSample(); @@ -957,15 +1361,76 @@ bool SampleWindow::onEvent(const SkEvent& evt) { } return true; } + if (evt.isType("replace-transition-view")) { + this->loadView((SkView*)SkEventSink::FindSink(evt.getFast32())); + return true; + } if (evt.isType("set-curr-index")) { - fCurrIndex = evt.getFast32() % fSamples.count(); - this->loadView(fSamples[fCurrIndex]()); + this->goToSample(evt.getFast32()); return true; } if (isInvalEvent(evt)) { this->inval(NULL); return true; } + int selected = -1; + if (SkOSMenu::FindListIndex(evt, "Device Type", &selected)) { + this->setDeviceType((DeviceType)selected); + return true; + } + if (SkOSMenu::FindSwitchState(evt, "Pipe", &fUsePipe)) { +#ifdef PIPE_NET + if (!fUsePipe) + gServer.disconnectAll(); +#endif + (void)SampleView::SetUsePipe(curr_view(this), fUsePipe); + this->updateTitle(); + this->inval(NULL); + return true; + } + if (SkOSMenu::FindSwitchState(evt, "Slide Show", NULL)) { + this->toggleSlideshow(); + return true; + } + if (SkOSMenu::FindTriState(evt, "AA", &fAAState) || + SkOSMenu::FindTriState(evt, "LCD", &fLCDState) || + SkOSMenu::FindTriState(evt, "Filter", &fFilterState) || + SkOSMenu::FindTriState(evt, "Hinting", &fHintingState) || + SkOSMenu::FindSwitchState(evt, "Clip", &fUseClip) || + SkOSMenu::FindSwitchState(evt, "Zoomer", &fShowZoomer) || + SkOSMenu::FindSwitchState(evt, "Magnify", &fMagnify) || + SkOSMenu::FindListIndex(evt, "Transition-Next", &fTransitionNext) || + SkOSMenu::FindListIndex(evt, "Transition-Prev", &fTransitionPrev)) { + this->inval(NULL); + this->updateTitle(); + return true; + } + if (SkOSMenu::FindSwitchState(evt, "Flip X", NULL)) { + fFlipAxis ^= kFlipAxis_X; + this->updateMatrix(); + return true; + } + if (SkOSMenu::FindSwitchState(evt, "Flip Y", NULL)) { + fFlipAxis ^= kFlipAxis_Y; + this->updateMatrix(); + return true; + } + if (SkOSMenu::FindAction(evt,"Save to PDF")) { + this->saveToPdf(); + return true; + } +#ifdef DEBUGGER + if (SkOSMenu::FindSwitchState(evt, "Debugger", &fDebugger)) { + if (fDebugger) { + fUsePipe = true; + (void)SampleView::SetUsePipe(curr_view(this), true); + } else { + this->loadView(fSamples[fCurrIndex]()); + } + this->inval(NULL); + return true; + } +#endif return this->INHERITED::onEvent(evt); } @@ -975,7 +1440,7 @@ bool SampleWindow::onQuery(SkEvent* query) { return true; } if (query->isType("get-slide-title")) { - SkView* view = fSamples[query->getFast32()](); + SkView* view = (*fSamples[query->getFast32()])(); SkEvent evt(gTitleEvtName); if (view->doQuery(&evt)) { query->setString("title", evt.findString(gTitleEvtName)); @@ -987,6 +1452,10 @@ bool SampleWindow::onQuery(SkEvent* query) { SkEvent evt(gFastTextEvtName); return curr_view(this)->doQuery(&evt); } + if (query->isType("ignore-window-bitmap")) { + query->setFast32(this->getGrContext() != NULL); + return true; + } return this->INHERITED::onQuery(query); } @@ -1013,7 +1482,7 @@ bool SampleWindow::onHandleChar(SkUnichar uni) { } } } - + int dx = 0xFF; int dy = 0xFF; @@ -1044,88 +1513,83 @@ bool SampleWindow::onHandleChar(SkUnichar uni) { } switch (uni) { - case 'a': - fAnimating = !fAnimating; - this->postAnimatingEvent(); - this->updateTitle(); - return true; - case 'b': - fAAState = cycle_tristate(fAAState); - this->updateTitle(); - this->inval(NULL); - break; - case 'c': - fUseClip = !fUseClip; - this->inval(NULL); - this->updateTitle(); - return true; - case 'd': - SkGraphics::SetFontCacheUsed(0); - return true; case 'f': - fMeasureFPS = !fMeasureFPS; - this->inval(NULL); + // only + toggleFPS(); break; case 'g': fRequestGrabImage = true; this->inval(NULL); break; - case 'h': - fHintingState = cycle_tristate(fHintingState); - this->updateTitle(); - this->inval(NULL); - break; case 'i': this->zoomIn(); break; - case 'l': - fLCDState = cycle_tristate(fLCDState); - this->updateTitle(); - this->inval(NULL); - break; - case 'n': - fFilterState = cycle_tristate(fFilterState); - this->updateTitle(); - this->inval(NULL); - break; case 'o': this->zoomOut(); break; - case 'p': - fUsePipe = !fUsePipe; - this->updateTitle(); - this->inval(NULL); - break; case 'r': fRotate = !fRotate; this->inval(NULL); this->updateTitle(); return true; - case 's': - fScale = !fScale; + case 'k': + fPerspAnim = !fPerspAnim; this->inval(NULL); this->updateTitle(); return true; - case 'x': - fFlipAxis ^= kFlipAxis_X; - this->updateTitle(); + case '\\': + if (fDevManager->supportsDeviceType(kNullGPU_DeviceType)) { + fDeviceType= kNullGPU_DeviceType; + this->inval(NULL); + this->updateTitle(); + } + return true; + case 's': + fScale = !fScale; this->inval(NULL); - break; - case 'y': - fFlipAxis ^= kFlipAxis_Y; this->updateTitle(); - this->inval(NULL); - break; - case 'z': - this->toggleZoomer(); - break; + return true; default: break; } - + + if (fAppMenu.handleKeyEquivalent(uni)|| fSlideMenu.handleKeyEquivalent(uni)) { + this->onUpdateMenu(&fAppMenu); + this->onUpdateMenu(&fSlideMenu); + return true; + } return this->INHERITED::onHandleChar(uni); } +void SampleWindow::setDeviceType(DeviceType type) { + if (type != fDeviceType && fDevManager->supportsDeviceType(fDeviceType)) + fDeviceType = type; + this->updateTitle(); + this->inval(NULL); +} + +void SampleWindow::toggleSlideshow() { + fAnimating = !fAnimating; + this->postAnimatingEvent(); + this->updateTitle(); +} + +void SampleWindow::toggleRendering() { + DeviceType origDevType = fDeviceType; + do { + fDeviceType = cycle_devicetype(fDeviceType); + } while (origDevType != fDeviceType && + !fDevManager->supportsDeviceType(fDeviceType)); + this->updateTitle(); + this->inval(NULL); +} + +void SampleWindow::toggleFPS() { + fMeasureFPS = !fMeasureFPS; + this->updateTitle(); + this->inval(NULL); +} + #include "SkDumpCanvas.h" bool SampleWindow::onHandleKey(SkKey key) { @@ -1139,7 +1603,6 @@ bool SampleWindow::onHandleKey(SkKey key) { } } } - switch (key) { case kRight_SkKey: if (this->nextSample()) { @@ -1147,41 +1610,34 @@ bool SampleWindow::onHandleKey(SkKey key) { } break; case kLeft_SkKey: - fCanvasType = cycle_canvastype(fCanvasType); - this->updateTitle(); - this->inval(NULL); + toggleRendering(); return true; case kUp_SkKey: if (USE_ARROWS_FOR_ZOOM) { - this->changeZoomLevel(1); + this->changeZoomLevel(1.f); } else { fNClip = !fNClip; this->inval(NULL); + this->updateTitle(); } - this->updateTitle(); return true; case kDown_SkKey: if (USE_ARROWS_FOR_ZOOM) { - this->changeZoomLevel(-1); + this->changeZoomLevel(-1.f); } else { this->setConfig(cycle_configs(this->getBitmap().config())); + this->updateTitle(); } - this->updateTitle(); return true; - case kOK_SkKey: - if (false) { - SkDebugfDumper dumper; - SkDumpCanvas dc(&dumper); - this->draw(&dc); - } else { - fRepeatDrawing = !fRepeatDrawing; - if (fRepeatDrawing) { - this->inval(NULL); - } + case kOK_SkKey: { + SkString title; + if (curr_title(this, &title)) { + writeTitleToPrefs(title.c_str()); } return true; + } case kBack_SkKey: - this->loadView(NULL); + this->showOverview(); return true; default: break; @@ -1193,7 +1649,8 @@ bool SampleWindow::onHandleKey(SkKey key) { static const char gGestureClickType[] = "GestureClickType"; -bool SampleWindow::onDispatchClick(int x, int y, Click::State state) { +bool SampleWindow::onDispatchClick(int x, int y, Click::State state, + void* owner) { if (Click::kMoved_State == state) { updatePointer(x, y); } @@ -1203,8 +1660,14 @@ bool SampleWindow::onDispatchClick(int x, int y, Click::State state) { // check for the resize-box if (w - x < 16 && h - y < 16) { return false; // let the OS handle the click - } else { - return this->INHERITED::onDispatchClick(x, y, state); + } + else if (fMagnify) { + //it's only necessary to update the drawing if there's a click + this->inval(NULL); + return false; //prevent dragging while magnify is enabled + } + else { + return this->INHERITED::onDispatchClick(x, y, state, owner); } } @@ -1225,19 +1688,20 @@ SkView::Click* SampleWindow::onFindClickHandler(SkScalar x, SkScalar y) { bool SampleWindow::onClick(Click* click) { if (GestureClick::IsGesture(click)) { - float x = SkScalarToFloat(click->fCurr.fX); - float y = SkScalarToFloat(click->fCurr.fY); + float x = static_cast<float>(click->fICurr.fX); + float y = static_cast<float>(click->fICurr.fY); + switch (click->fState) { case SkView::Click::kDown_State: - fGesture.touchBegin(click, x, y); + fGesture.touchBegin(click->fOwner, x, y); break; case SkView::Click::kMoved_State: - fGesture.touchMoved(click, x, y); - this->inval(NULL); + fGesture.touchMoved(click->fOwner, x, y); + this->updateMatrix(); break; case SkView::Click::kUp_State: - fGesture.touchEnd(click); - this->inval(NULL); + fGesture.touchEnd(click->fOwner); + this->updateMatrix(); break; } return true; @@ -1253,15 +1717,24 @@ void SampleWindow::loadView(SkView* view) { if (prev) { prev->detachFromParent(); } - - if (NULL == view) { - view = create_overview(fSamples.count(), fSamples.begin()); - } + view->setVisibleP(true); view->setClipToBounds(false); this->attachChildToFront(view)->unref(); view->setSize(this->width(), this->height()); + //repopulate the slide menu when a view is loaded + fSlideMenu.reset(); +#ifdef DEBUGGER + if (!is_debugger(view) && !is_overview(view) && !is_transition(view) && fDebugger) { + //Force Pipe to be on if using debugger + fUsePipe = true; + } +#endif + (void)SampleView::SetUsePipe(view, fUsePipe); + if (SampleView::IsSampleView(view)) + ((SampleView*)view)->requestMenu(&fSlideMenu); + this->onUpdateMenu(&fSlideMenu); this->updateTitle(); } @@ -1279,36 +1752,32 @@ static const char* configToString(SkBitmap::Config c) { return gConfigNames[c]; } -static const char* gCanvasTypePrefix[] = { +static const char* gDeviceTypePrefix[] = { "raster: ", "picture: ", - "opengl: " + "opengl: ", + "null-gl: " }; -static const char* trystate_str(SkTriState state, +static const char* trystate_str(SkOSMenu::TriState state, const char trueStr[], const char falseStr[]) { - if (kTrue_SkTriState == state) { + if (SkOSMenu::kOnState == state) { return trueStr; - } else if (kFalse_SkTriState == state) { + } else if (SkOSMenu::kOffState == state) { return falseStr; } return NULL; } void SampleWindow::updateTitle() { - SkString title; + SkView* view = curr_view(this); - SkView::F2BIter iter(this); - SkView* view = iter.next(); - SkEvent evt(gTitleEvtName); - if (view->doQuery(&evt)) { - title.set(evt.findString(gTitleEvtName)); - } - if (title.size() == 0) { + SkString title; + if (!curr_title(this, &title)) { title.set("<unknown>"); } - title.prepend(gCanvasTypePrefix[fCanvasType]); + title.prepend(gDeviceTypePrefix[fDeviceType]); title.prepend(" "); title.prepend(configToString(this->getBitmap().config())); @@ -1325,6 +1794,9 @@ void SampleWindow::updateTitle() { if (fNClip) { title.prepend("<C> "); } + if (fPerspAnim) { + title.prepend("<K> "); + } title.prepend(trystate_str(fLCDState, "LCD ", "lcd ")); title.prepend(trystate_str(fAAState, "AA ", "aa ")); @@ -1333,7 +1805,7 @@ void SampleWindow::updateTitle() { title.prepend(fFlipAxis & kFlipAxis_Y ? "Y " : NULL); if (fZoomLevel) { - title.prependf("{%d} ", fZoomLevel); + title.prependf("{%.2f} ", SkScalarToFloat(fZoomLevel)); } if (fMeasureFPS) { @@ -1351,7 +1823,7 @@ void SampleWindow::updateTitle() { void SampleWindow::onSizeChange() { this->INHERITED::onSizeChange(); - + SkView::F2BIter iter(this); SkView* view = iter.next(); view->setSize(this->width(), this->height()); @@ -1378,7 +1850,16 @@ void SampleWindow::onSizeChange() { #endif } + fZoomCenterX = SkScalarHalf(this->width()); + fZoomCenterY = SkScalarHalf(this->height()); + +#ifdef SK_BUILD_FOR_ANDROID + // FIXME: The first draw after a size change does not work on Android, so + // we post an invalidate. + this->postInvalDelay(); +#endif this->updateTitle(); // to refresh our config + fDevManager->windowSizeChanged(this); } /////////////////////////////////////////////////////////////////////////////// @@ -1430,7 +1911,11 @@ class SimplePC : public SkGPipeController { public: SimplePC(SkCanvas* target); ~SimplePC(); - + + /** + * User this method to halt/restart pipe + */ + void setWriteToPipe(bool writeToPipe) { fWriteToPipe = writeToPipe; } virtual void* requestBlock(size_t minRequest, size_t* actual); virtual void notifyWritten(size_t bytes); @@ -1441,6 +1926,7 @@ private: size_t fBytesWritten; int fAtomsWritten; SkGPipeReader::Status fStatus; + bool fWriteToPipe; size_t fTotalWritten; }; @@ -1451,16 +1937,35 @@ SimplePC::SimplePC(SkCanvas* target) : fReader(target) { fStatus = SkGPipeReader::kDone_Status; fTotalWritten = 0; fAtomsWritten = 0; + fWriteToPipe = true; } SimplePC::~SimplePC() { // SkASSERT(SkGPipeReader::kDone_Status == fStatus); - sk_free(fBlock); - if (fTotalWritten) { - SkDebugf("--- %d bytes %d atoms, status %d\n", fTotalWritten, - fAtomsWritten, fStatus); + if (fWriteToPipe) { + SkDebugf("--- %d bytes %d atoms, status %d\n", fTotalWritten, + fAtomsWritten, fStatus); +#ifdef PIPE_FILE + //File is open in append mode + FILE* f = fopen(FILE_PATH, "ab"); + SkASSERT(f != NULL); + fwrite((const char*)fBlock + fBytesWritten, 1, bytes, f); + fclose(f); +#endif +#ifdef PIPE_NET + if (fAtomsWritten > 1 && fTotalWritten > 4) { //ignore done + gServer.acceptConnections(); + gServer.writePacket(fBlock, fTotalWritten); + } +#endif +#ifdef DEBUGGER + gTempDataStore.reset(); + gTempDataStore.append(fTotalWritten, (const char*)fBlock); +#endif + } } + sk_free(fBlock); } void* SimplePC::requestBlock(size_t minRequest, size_t* actual) { @@ -1475,37 +1980,37 @@ void* SimplePC::requestBlock(size_t minRequest, size_t* actual) { void SimplePC::notifyWritten(size_t bytes) { SkASSERT(fBytesWritten + bytes <= fBlockSize); - -#ifdef PIPE_FILE - //File is open in append mode - FILE* f = fopen(FILE_PATH, "ab"); - SkASSERT(f != NULL); - fwrite((const char*)fBlock + fBytesWritten, 1, bytes, f); - fclose(f); -#endif - fStatus = fReader.playback((const char*)fBlock + fBytesWritten, bytes); SkASSERT(SkGPipeReader::kError_Status != fStatus); fBytesWritten += bytes; fTotalWritten += bytes; - + fAtomsWritten += 1; } #endif - -void SampleView::onDraw(SkCanvas* canvas) { +void SampleView::draw(SkCanvas* canvas) { #ifdef TEST_GPIPE - SimplePC controller(canvas); - SkGPipeWriter writer; if (fUsePipe) { + SkGPipeWriter writer; + SimplePC controller(canvas); uint32_t flags = SkGPipeWriter::kCrossProcess_Flag; -// flags = 0; canvas = writer.startRecording(&controller, flags); + //Must draw before controller goes out of scope and sends data + this->INHERITED::draw(canvas); + //explicitly end recording to ensure writer is flushed before the memory + //is freed in the deconstructor of the controller + writer.endRecording(); + controller.setWriteToPipe(fUsePipe); } + else + this->INHERITED::draw(canvas); +#else + this->INHERITED::draw(canvas); #endif - +} +void SampleView::onDraw(SkCanvas* canvas) { this->onDrawBackground(canvas); for (int i = 0; i < fRepeatCount; i++) { @@ -1620,9 +2125,9 @@ static void test() { } } -SkOSWindow* create_sk_window(void* hwnd) { +SkOSWindow* create_sk_window(void* hwnd, int argc, char** argv) { // test(); - return new SampleWindow(hwnd); + return new SampleWindow(hwnd, argc, argv, NULL); } void get_preferred_size(int* x, int* y, int* width, int* height) { diff --git a/samplecode/SampleApp.h b/samplecode/SampleApp.h new file mode 100644 index 0000000..871d47e --- /dev/null +++ b/samplecode/SampleApp.h @@ -0,0 +1,197 @@ + +/* + * Copyright 2011 Skia + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + + +#ifndef SampleWindow_DEFINED +#define SampleWindow_DEFINED + +#include "SkWindow.h" + +#include "SampleCode.h" +#include "SkPath.h" +#include "SkScalar.h" +#include "SkTDArray.h" +#include "SkTouchGesture.h" +#include "SkWindow.h" +#include "SkOSMenu.h" + +class GrContext; +class GrRenderTarget; + +class SkEvent; +class SkCanvas; +class SkPicture; +class SkTypeface; +class SkData; + +class SampleWindow : public SkOSWindow { + SkTDArray<const SkViewFactory*> fSamples; +public: + enum DeviceType { + kRaster_DeviceType, + kPicture_DeviceType, + kGPU_DeviceType, + kNullGPU_DeviceType + }; + /** + * SampleApp ports can subclass this manager class if they want to: + * * filter the types of devices supported + * * customize plugging of SkDevice objects into an SkCanvas + * * customize publishing the results of draw to the OS window + * * manage GrContext / GrRenderTarget lifetimes + */ + class DeviceManager : public SkRefCnt { + public: + // called at end of SampleWindow cons + virtual void init(SampleWindow* win) = 0; + + // called when selecting a new device type + // can disallow a device type by returning false. + virtual bool supportsDeviceType(DeviceType dType) = 0; + + // called before drawing. should install correct device + // type on the canvas. Will skip drawing if returns false. + virtual bool prepareCanvas(DeviceType dType, + SkCanvas* canvas, + SampleWindow* win) = 0; + + // called after drawing, should get the results onto the + // screen. + virtual void publishCanvas(DeviceType dType, + SkCanvas* canvas, + SampleWindow* win) = 0; + + // called when window changes size, guaranteed to be called + // at least once before first draw (after init) + virtual void windowSizeChanged(SampleWindow* win) = 0; + + // return the GrContext backing gpu devices + virtual GrContext* getGrContext(DeviceType dType) = 0; + }; + + SampleWindow(void* hwnd, int argc, char** argv, DeviceManager*); + virtual ~SampleWindow(); + + virtual void draw(SkCanvas* canvas); + + void setDeviceType(DeviceType type); + void toggleRendering(); + void toggleSlideshow(); + void toggleFPS(); + void showOverview(); + + GrContext* getGrContext() const { return fDevManager->getGrContext(fDeviceType); } + + void setZoomCenter(float x, float y); + void changeZoomLevel(float delta); + bool nextSample(); + bool previousSample(); + bool goToSample(int i); + SkString getSampleTitle(int i); + int sampleCount(); + bool handleTouch(int ownerId, float x, float y, + SkView::Click::State state); + void saveToPdf(); + SkData* getPDFData() { return fPDFData; } + void postInvalDelay(); + +protected: + virtual void onDraw(SkCanvas* canvas); + virtual bool onHandleKey(SkKey key); + virtual bool onHandleChar(SkUnichar); + virtual void onSizeChange(); + + virtual SkCanvas* beforeChildren(SkCanvas*); + virtual void afterChildren(SkCanvas*); + virtual void beforeChild(SkView* child, SkCanvas* canvas); + virtual void afterChild(SkView* child, SkCanvas* canvas); + + virtual bool onEvent(const SkEvent& evt); + virtual bool onQuery(SkEvent* evt); + + virtual bool onDispatchClick(int x, int y, Click::State, void* owner); + virtual bool onClick(Click* click); + virtual Click* onFindClickHandler(SkScalar x, SkScalar y); + +private: + class DefaultDeviceManager; + + int fCurrIndex; + + SkPicture* fPicture; + SkPath fClipPath; + + SkTouchGesture fGesture; + SkScalar fZoomLevel; + SkScalar fZoomScale; + + DeviceType fDeviceType; + DeviceManager* fDevManager; + + bool fSaveToPdf; + SkCanvas* fPdfCanvas; + SkData* fPDFData; + + bool fUseClip; + bool fNClip; + bool fAnimating; + bool fRotate; + bool fPerspAnim; + SkScalar fPerspAnimTime; + bool fScale; + bool fRequestGrabImage; + bool fMeasureFPS; + SkMSec fMeasureFPS_Time; + bool fMagnify; + + + bool fUsePipe; + int fUsePipeMenuItemID; + bool fDebugger; + + // The following are for the 'fatbits' drawing + // Latest position of the mouse. + int fMouseX, fMouseY; + int fFatBitsScale; + // Used by the text showing position and color values. + SkTypeface* fTypeface; + bool fShowZoomer; + + SkOSMenu::TriState fLCDState; + SkOSMenu::TriState fAAState; + SkOSMenu::TriState fFilterState; + SkOSMenu::TriState fHintingState; + unsigned fFlipAxis; + + int fScrollTestX, fScrollTestY; + SkScalar fZoomCenterX, fZoomCenterY; + + //Stores global settings + SkOSMenu fAppMenu; + //Stores slide specific settings + SkOSMenu fSlideMenu; + int fTransitionNext; + int fTransitionPrev; + + void loadView(SkView*); + void updateTitle(); + + bool zoomIn(); + bool zoomOut(); + void updatePointer(int x, int y); + void magnify(SkCanvas* canvas); + void showZoomer(SkCanvas* canvas); + void updateMatrix(); + void postAnimatingEvent(); + void installDrawFilter(SkCanvas*); + int findByTitle(const char*); + + typedef SkOSWindow INHERITED; +}; + +#endif diff --git a/samplecode/SampleArc.cpp b/samplecode/SampleArc.cpp index 8e3ad88..d418a4b 100644 --- a/samplecode/SampleArc.cpp +++ b/samplecode/SampleArc.cpp @@ -1,3 +1,10 @@ + +/* + * 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" diff --git a/samplecode/SampleAvoid.cpp b/samplecode/SampleAvoid.cpp index 868a67c..81050a3 100644 --- a/samplecode/SampleAvoid.cpp +++ b/samplecode/SampleAvoid.cpp @@ -1,3 +1,10 @@ + +/* + * 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" diff --git a/samplecode/SampleBigBlur.cpp b/samplecode/SampleBigBlur.cpp new file mode 100644 index 0000000..f5e632c --- /dev/null +++ b/samplecode/SampleBigBlur.cpp @@ -0,0 +1,50 @@ + +/* + * 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 "SkBlurMaskFilter.h" +#include "SkView.h" +#include "SkCanvas.h" + +class BigBlurView : public SampleView { +public: + BigBlurView() { + } + +protected: + // overrides from SkEventSink + virtual bool onQuery(SkEvent* evt) { + if (SampleCode::TitleQ(*evt)) { + SampleCode::TitleR(evt, "BigBlur"); + return true; + } + return this->INHERITED::onQuery(evt); + } + + virtual void onDrawContent(SkCanvas* canvas) { + SkPaint paint; + canvas->save(); + paint.setColor(SK_ColorBLUE); + SkMaskFilter* mf = SkBlurMaskFilter::Create( + 128, + SkBlurMaskFilter::kNormal_BlurStyle, + SkBlurMaskFilter::kHighQuality_BlurFlag); + paint.setMaskFilter(mf)->unref(); + canvas->translate(200, 200); + canvas->drawCircle(100, 100, 200, paint); + canvas->restore(); + } + +private: + typedef SkView INHERITED; +}; + +////////////////////////////////////////////////////////////////////////////// + +static SkView* MyFactory() { return new BigBlurView; } +static SkViewRegister reg(MyFactory); + diff --git a/samplecode/SampleBigGradient.cpp b/samplecode/SampleBigGradient.cpp index 5ebb516..8e08e15 100644 --- a/samplecode/SampleBigGradient.cpp +++ b/samplecode/SampleBigGradient.cpp @@ -1,3 +1,10 @@ + +/* + * 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" diff --git a/samplecode/SampleBitmapRect.cpp b/samplecode/SampleBitmapRect.cpp index 002b2b9..95ea1a7 100644 --- a/samplecode/SampleBitmapRect.cpp +++ b/samplecode/SampleBitmapRect.cpp @@ -1,3 +1,10 @@ + +/* + * 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" @@ -17,28 +24,34 @@ #include "SkOSFile.h" #include "SkStream.h" -static SkBitmap make_bitmap() { - SkBitmap bm; - bm.setConfig(SkBitmap::kARGB_8888_Config, 64, 64); - bm.allocPixels(); - SkCanvas canvas(bm); +#include "SkGpuDevice.h" + +static void make_bitmap(SkBitmap* bitmap, GrContext* ctx) { + SkCanvas canvas; + + if (ctx) { + SkDevice* dev = new SkGpuDevice(ctx, SkBitmap::kARGB_8888_Config, 64, 64); + canvas.setDevice(dev)->unref(); + *bitmap = dev->accessBitmap(false); + } else { + bitmap->setConfig(SkBitmap::kARGB_8888_Config, 64, 64); + bitmap->allocPixels(); + canvas.setBitmapDevice(*bitmap); + } + canvas.drawColor(SK_ColorRED); SkPaint paint; paint.setAntiAlias(true); const SkPoint pts[] = { { 0, 0 }, { 64, 64 } }; const SkColor colors[] = { SK_ColorWHITE, SK_ColorBLUE }; paint.setShader(SkGradientShader::CreateLinear(pts, colors, NULL, 2, - SkShader::kClamp_TileMode))->unref(); + SkShader::kClamp_TileMode))->unref(); canvas.drawCircle(32, 32, 32, paint); - return bm; } class BitmapRectView : public SampleView { public: - SkBitmap fBitmap; - BitmapRectView() { - fBitmap = make_bitmap(); this->setBGColor(SK_ColorGRAY); } @@ -53,6 +66,8 @@ protected: } virtual void onDrawContent(SkCanvas* canvas) { + GrContext* ctx = SampleCode::GetGr(); + const SkIRect src[] = { { 0, 0, 32, 32 }, { 0, 0, 80, 80 }, @@ -62,7 +77,10 @@ protected: SkPaint paint; paint.setStyle(SkPaint::kStroke_Style); - paint.setColor(SK_ColorGREEN); + paint.setColor(ctx ? SK_ColorGREEN : SK_ColorYELLOW); + + SkBitmap bitmap; + make_bitmap(&bitmap, ctx); SkRect dstR = { 0, 200, 128, 380 }; @@ -71,8 +89,8 @@ protected: SkRect srcR; srcR.set(src[i]); - canvas->drawBitmap(fBitmap, 0, 0, &paint); - canvas->drawBitmapRect(fBitmap, &src[i], dstR, &paint); + canvas->drawBitmap(bitmap, 0, 0, &paint); + canvas->drawBitmapRect(bitmap, &src[i], dstR, &paint); canvas->drawRect(dstR, paint); canvas->drawRect(srcR, paint); diff --git a/samplecode/SampleBlur.cpp b/samplecode/SampleBlur.cpp index d2ea2b0..aa92343 100644 --- a/samplecode/SampleBlur.cpp +++ b/samplecode/SampleBlur.cpp @@ -1,3 +1,10 @@ + +/* + * 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 "SkBlurMaskFilter.h" #include "SkColorPriv.h" @@ -41,7 +48,7 @@ static SkBitmap make_bitmap() { return bm; } -class BlurView : public SkView { +class BlurView : public SampleView { SkBitmap fBM; public: BlurView() { @@ -61,7 +68,7 @@ protected: canvas->drawColor(0xFFDDDDDD); } - virtual void onDraw(SkCanvas* canvas) { + virtual void onDrawContent(SkCanvas* canvas) { drawBG(canvas); SkBlurMaskFilter::BlurStyle NONE = SkBlurMaskFilter::BlurStyle(-999); diff --git a/samplecode/SampleBox.cpp b/samplecode/SampleBox.cpp index d445df7..0b1da07 100644 --- a/samplecode/SampleBox.cpp +++ b/samplecode/SampleBox.cpp @@ -1,3 +1,10 @@ + +/* + * 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" diff --git a/samplecode/SampleCamera.cpp b/samplecode/SampleCamera.cpp index 2db3968..a4af2de 100644 --- a/samplecode/SampleCamera.cpp +++ b/samplecode/SampleCamera.cpp @@ -1,3 +1,10 @@ + +/* + * 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" diff --git a/samplecode/SampleCircle.cpp b/samplecode/SampleCircle.cpp index 2abc28d..c3f986d 100644 --- a/samplecode/SampleCircle.cpp +++ b/samplecode/SampleCircle.cpp @@ -1,3 +1,10 @@ + +/* + * 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" diff --git a/samplecode/SampleClamp.cpp b/samplecode/SampleClamp.cpp index 88c1b91..c521f81 100644 --- a/samplecode/SampleClamp.cpp +++ b/samplecode/SampleClamp.cpp @@ -1,3 +1,10 @@ + +/* + * 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" diff --git a/samplecode/SampleClip.cpp b/samplecode/SampleClip.cpp new file mode 100644 index 0000000..570f0b9 --- /dev/null +++ b/samplecode/SampleClip.cpp @@ -0,0 +1,169 @@ +/* + * 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 "SkColorPriv.h" +#include "SkDevice.h" +#include "SkPaint.h" +#include "SkRandom.h" + +#define W 150 +#define H 200 + +static void show_text(SkCanvas* canvas, bool doAA) { + SkRandom rand; + SkPaint paint; + paint.setAntiAlias(doAA); + paint.setLCDRenderText(true); + paint.setTextSize(SkIntToScalar(20)); + + for (int i = 0; i < 200; ++i) { + paint.setColor((SK_A32_MASK << SK_A32_SHIFT) | rand.nextU()); + canvas->drawText("Hamburgefons", 12, + rand.nextSScalar1() * W, rand.nextSScalar1() * H + 20, + paint); + } +} + +static bool valid(int i) { + return i < 15 && i > 7; +} + +static void show_fill(SkCanvas* canvas, bool doAA) { + SkRandom rand; + SkPaint paint; + paint.setAntiAlias(doAA); + + for (int i = 0; i < 50; ++i) { + SkRect r; + SkPath p; + + r.setXYWH(rand.nextSScalar1() * W, rand.nextSScalar1() * H, + rand.nextUScalar1() * W, rand.nextUScalar1() * H); + paint.setColor(rand.nextU()); + canvas->drawRect(r, paint); + + r.setXYWH(rand.nextSScalar1() * W, rand.nextSScalar1() * H, + rand.nextUScalar1() * W, rand.nextUScalar1() * H); + paint.setColor(rand.nextU()); + p.addOval(r); + canvas->drawPath(p, paint); + } +} + +static SkScalar randRange(SkRandom& rand, SkScalar min, SkScalar max) { + SkASSERT(min <= max); + return min + SkScalarMul(rand.nextUScalar1(), max - min); +} + +static void show_stroke(SkCanvas* canvas, bool doAA, SkScalar strokeWidth, int n) { + SkRandom rand; + SkPaint paint; + paint.setAntiAlias(doAA); + paint.setStyle(SkPaint::kStroke_Style); + paint.setStrokeWidth(strokeWidth); + + for (int i = 0; i < n; ++i) { + SkRect r; + SkPath p; + + r.setXYWH(rand.nextSScalar1() * W, rand.nextSScalar1() * H, + rand.nextUScalar1() * W, rand.nextUScalar1() * H); + paint.setColor(rand.nextU()); + canvas->drawRect(r, paint); + + r.setXYWH(rand.nextSScalar1() * W, rand.nextSScalar1() * H, + rand.nextUScalar1() * W, rand.nextUScalar1() * H); + paint.setColor(rand.nextU()); + p.addOval(r); + canvas->drawPath(p, paint); + + const SkScalar minx = -SkIntToScalar(W)/4; + const SkScalar maxx = 5*SkIntToScalar(W)/4; + const SkScalar miny = -SkIntToScalar(H)/4; + const SkScalar maxy = 5*SkIntToScalar(H)/4; + paint.setColor(rand.nextU()); + canvas->drawLine(randRange(rand, minx, maxx), randRange(rand, miny, maxy), + randRange(rand, minx, maxx), randRange(rand, miny, maxy), + paint); + } +} + +static void show_hair(SkCanvas* canvas, bool doAA) { + show_stroke(canvas, doAA, 0, 150); +} + +static void show_thick(SkCanvas* canvas, bool doAA) { + show_stroke(canvas, doAA, SkIntToScalar(5), 50); +} + +typedef void (*CanvasProc)(SkCanvas*, bool); + +#include "SkAAClip.h" + +class ClipView : public SampleView { +public: + ClipView() { + SkAAClip clip; + SkIRect r = { -2, -3, 842, 18 }; + clip.setRect(r); + } + + virtual ~ClipView() { + } + +protected: + // overrides from SkEventSink + virtual bool onQuery(SkEvent* evt) { + if (SampleCode::TitleQ(*evt)) { + SampleCode::TitleR(evt, "Clip"); + return true; + } + return this->INHERITED::onQuery(evt); + } + + virtual void onDrawContent(SkCanvas* canvas) { + canvas->drawColor(SK_ColorWHITE); + canvas->translate(SkIntToScalar(20), SkIntToScalar(20)); + + static const CanvasProc gProc[] = { + show_text, show_thick, show_hair, show_fill + }; + + SkRect r = { 0, 0, SkIntToScalar(W), SkIntToScalar(H) }; + SkPath clipPath; + r.inset(SK_Scalar1 / 4, SK_Scalar1 / 4); + clipPath.addRoundRect(r, SkIntToScalar(20), SkIntToScalar(20)); + +// clipPath.toggleInverseFillType(); + + for (int aa = 0; aa <= 1; ++aa) { + canvas->save(); + for (size_t i = 0; i < SK_ARRAY_COUNT(gProc); ++i) { + canvas->save(); + canvas->clipPath(clipPath, SkRegion::kIntersect_Op, true); +// canvas->drawColor(SK_ColorWHITE); + gProc[i](canvas, SkToBool(aa)); + canvas->restore(); + canvas->translate(W * SK_Scalar1 * 8 / 7, 0); + } + canvas->restore(); + canvas->translate(0, H * SK_Scalar1 * 8 / 7); + } + } + +private: + typedef SampleView INHERITED; +}; + +////////////////////////////////////////////////////////////////////////////// + +static SkView* MyFactory() { return new ClipView; } +static SkViewRegister reg(MyFactory); + diff --git a/samplecode/SampleCode.h b/samplecode/SampleCode.h index c42ee25..197e0f1 100644 --- a/samplecode/SampleCode.h +++ b/samplecode/SampleCode.h @@ -1,3 +1,12 @@ + +/* + * Copyright 2011 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + + #ifndef SampleCode_DEFINED #define SampleCode_DEFINED @@ -5,6 +14,8 @@ #include "SkEvent.h" #include "SkKey.h" #include "SkView.h" +class SkOSMenu; +class GrContext; class SampleCode { public: @@ -13,6 +24,7 @@ public: static bool TitleQ(const SkEvent&); static void TitleR(SkEvent*, const char title[]); + static bool RequestTitle(SkView* view, SkString* title); static bool PrefSizeQ(const SkEvent&); static void PrefSizeR(SkEvent*, SkScalar width, SkScalar height); @@ -23,23 +35,65 @@ public: static SkMSec GetAnimTimeDelta(); static SkScalar GetAnimSecondsDelta(); static SkScalar GetAnimScalar(SkScalar speedPerSec, SkScalar period = 0); + + static GrContext* GetGr(); }; ////////////////////////////////////////////////////////////////////////////// -typedef SkView* (*SkViewFactory)(); +// interface that constructs SkViews +class SkViewFactory : public SkRefCnt { +public: + virtual SkView* operator() () const = 0; +}; -class SkViewRegister : SkNoncopyable { +typedef SkView* (*SkViewCreateFunc)(); + +// wraps SkViewCreateFunc in SkViewFactory interface +class SkFuncViewFactory : public SkViewFactory { public: - explicit SkViewRegister(SkViewFactory); + SkFuncViewFactory(SkViewCreateFunc func); + virtual SkView* operator() () const SK_OVERRIDE; + +private: + SkViewCreateFunc fCreateFunc; +}; + +namespace skiagm { +class GM; +} + +// factory function that creates a skiagm::GM +typedef skiagm::GM* (*GMFactoryFunc)(void*); + +// Takes a GM factory function and implements the SkViewFactory interface +// by making the GM and wrapping it in a GMSampleView. GMSampleView bridges +// the SampleView interface to skiagm::GM. +class SkGMSampleViewFactory : public SkViewFactory { +public: + SkGMSampleViewFactory(GMFactoryFunc func); + virtual SkView* operator() () const SK_OVERRIDE; +private: + GMFactoryFunc fFunc; +}; + +class SkViewRegister : public SkRefCnt { +public: + explicit SkViewRegister(SkViewFactory*); + explicit SkViewRegister(SkViewCreateFunc); + explicit SkViewRegister(GMFactoryFunc); + + ~SkViewRegister() { + fFact->unref(); + } static const SkViewRegister* Head() { return gHead; } SkViewRegister* next() const { return fChain; } - SkViewFactory factory() const { return fFact; } + const SkViewFactory* factory() const { return fFact; } private: - SkViewFactory fFact; + SkViewFactory* fFact; SkViewRegister* fChain; static SkViewRegister* gHead; @@ -49,7 +103,7 @@ private: class SampleView : public SkView { public: - SampleView() : fRepeatCount(1), fBGColor(SK_ColorWHITE) { + SampleView() : fBGColor(SK_ColorWHITE), fRepeatCount(1) { fUsePipe = false; } @@ -58,21 +112,31 @@ public: static bool IsSampleView(SkView*); static bool SetRepeatDraw(SkView*, int count); static bool SetUsePipe(SkView*, bool); + + /** + * Call this to request menu items from a SampleView. + * Subclassing notes: A subclass of SampleView can overwrite this method + * to add new items of various types to the menu and change its title. + * The events attached to any new menu items must be handled in its onEvent + * method. See SkOSMenu.h for helper functions. + */ + virtual void requestMenu(SkOSMenu* menu) {} protected: virtual void onDrawBackground(SkCanvas*); virtual void onDrawContent(SkCanvas*) = 0; - + // overrides virtual bool onEvent(const SkEvent& evt); virtual bool onQuery(SkEvent* evt); + virtual void draw(SkCanvas*); virtual void onDraw(SkCanvas*); + bool fUsePipe; + SkColor fBGColor; + private: int fRepeatCount; - SkColor fBGColor; - - bool fUsePipe; typedef SkView INHERITED; }; diff --git a/samplecode/SampleColorFilter.cpp b/samplecode/SampleColorFilter.cpp index 0e1fb11..52bf950 100644 --- a/samplecode/SampleColorFilter.cpp +++ b/samplecode/SampleColorFilter.cpp @@ -1,3 +1,10 @@ + +/* + * 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" diff --git a/samplecode/SampleComplexClip.cpp b/samplecode/SampleComplexClip.cpp index 672d055..e7f9a01 100644 --- a/samplecode/SampleComplexClip.cpp +++ b/samplecode/SampleComplexClip.cpp @@ -1,3 +1,10 @@ + +/* + * 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 "SkCanvas.h" #include "SkPath.h" diff --git a/samplecode/SampleConcavePaths.cpp b/samplecode/SampleConcavePaths.cpp new file mode 100644 index 0000000..1659ec0 --- /dev/null +++ b/samplecode/SampleConcavePaths.cpp @@ -0,0 +1,153 @@ + +/* + * 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 "SkGradientShader.h" +#include "SkGraphics.h" +#include "SkImageDecoder.h" +#include "SkPath.h" +#include "SkRegion.h" +#include "SkShader.h" +#include "SkUtils.h" +#include "SkXfermode.h" +#include "SkColorPriv.h" +#include "SkColorFilter.h" +#include "SkParsePath.h" +#include "SkTime.h" +#include "SkTypeface.h" + +#include "SkGeometry.h" + +class ConcavePathView : public SampleView { +public: + ConcavePathView() {} + +protected: + // overrides from SkEventSink + virtual bool onQuery(SkEvent* evt) { + if (SampleCode::TitleQ(*evt)) { + SampleCode::TitleR(evt, "ConcavePaths"); + return true; + } + return this->INHERITED::onQuery(evt); + } + + virtual void onDrawContent(SkCanvas* canvas) { + SkPaint paint; + + paint.setAntiAlias(true); + paint.setStyle(SkPaint::kFill_Style); + + // Concave test + if (1) { + SkPath path; + canvas->translate(0, 0); + path.moveTo(SkIntToScalar(20), SkIntToScalar(20)); + path.lineTo(SkIntToScalar(80), SkIntToScalar(20)); + path.lineTo(SkIntToScalar(30), SkIntToScalar(30)); + path.lineTo(SkIntToScalar(20), SkIntToScalar(80)); + canvas->drawPath(path, paint); + } + // Reverse concave test + if (1) { + SkPath path; + canvas->save(); + canvas->translate(100, 0); + path.moveTo(SkIntToScalar(20), SkIntToScalar(20)); + path.lineTo(SkIntToScalar(20), SkIntToScalar(80)); + path.lineTo(SkIntToScalar(30), SkIntToScalar(30)); + path.lineTo(SkIntToScalar(80), SkIntToScalar(20)); + canvas->drawPath(path, paint); + canvas->restore(); + } + // Bowtie (intersection) + if (1) { + SkPath path; + canvas->save(); + canvas->translate(200, 0); + path.moveTo(SkIntToScalar(20), SkIntToScalar(20)); + path.lineTo(SkIntToScalar(80), SkIntToScalar(80)); + path.lineTo(SkIntToScalar(80), SkIntToScalar(20)); + path.lineTo(SkIntToScalar(20), SkIntToScalar(80)); + canvas->drawPath(path, paint); + canvas->restore(); + } + // "fake" bowtie (concave, but no intersection) + if (1) { + SkPath path; + canvas->save(); + canvas->translate(300, 0); + path.moveTo(SkIntToScalar(20), SkIntToScalar(20)); + path.lineTo(SkIntToScalar(50), SkIntToScalar(40)); + path.lineTo(SkIntToScalar(80), SkIntToScalar(20)); + path.lineTo(SkIntToScalar(80), SkIntToScalar(80)); + path.lineTo(SkIntToScalar(50), SkIntToScalar(60)); + path.lineTo(SkIntToScalar(20), SkIntToScalar(80)); + canvas->drawPath(path, paint); + canvas->restore(); + } + // Fish test (intersection/concave) + if (1) { + SkPath path; + canvas->save(); + canvas->translate(0, 100); + path.moveTo(SkIntToScalar(20), SkIntToScalar(20)); + path.lineTo(SkIntToScalar(80), SkIntToScalar(80)); + path.lineTo(SkIntToScalar(70), SkIntToScalar(50)); + path.lineTo(SkIntToScalar(80), SkIntToScalar(20)); + path.lineTo(SkIntToScalar(20), SkIntToScalar(80)); + path.lineTo(SkIntToScalar(0), SkIntToScalar(50)); + canvas->drawPath(path, paint); + canvas->restore(); + } + // Collinear test + if (1) { + SkPath path; + canvas->save(); + canvas->translate(100, 100); + path.moveTo(SkIntToScalar(20), SkIntToScalar(20)); + path.lineTo(SkIntToScalar(50), SkIntToScalar(20)); + path.lineTo(SkIntToScalar(80), SkIntToScalar(20)); + path.lineTo(SkIntToScalar(50), SkIntToScalar(80)); + canvas->drawPath(path, paint); + canvas->restore(); + } + // Hole test + if (1) { + SkPath path; + canvas->save(); + canvas->translate(200, 100); + path.moveTo(SkIntToScalar(20), SkIntToScalar(20)); + path.lineTo(SkIntToScalar(80), SkIntToScalar(20)); + path.lineTo(SkIntToScalar(80), SkIntToScalar(80)); + path.lineTo(SkIntToScalar(20), SkIntToScalar(80)); + path.moveTo(SkIntToScalar(30), SkIntToScalar(30)); + path.lineTo(SkIntToScalar(30), SkIntToScalar(70)); + path.lineTo(SkIntToScalar(70), SkIntToScalar(70)); + path.lineTo(SkIntToScalar(70), SkIntToScalar(30)); + canvas->drawPath(path, paint); + canvas->restore(); + } + } + + virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y) { + this->inval(NULL); + return this->INHERITED::onFindClickHandler(x, y); + } + +private: + typedef SampleView INHERITED; +}; + +////////////////////////////////////////////////////////////////////////////// + +static SkView* MyFactory() { return new ConcavePathView; } +static SkViewRegister reg(MyFactory); + diff --git a/samplecode/SampleCull.cpp b/samplecode/SampleCull.cpp index 7b4eab6..778d0fc 100644 --- a/samplecode/SampleCull.cpp +++ b/samplecode/SampleCull.cpp @@ -1,3 +1,10 @@ + +/* + * 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" diff --git a/samplecode/SampleDash.cpp b/samplecode/SampleDash.cpp index 4cef07f..fc0d678 100644 --- a/samplecode/SampleDash.cpp +++ b/samplecode/SampleDash.cpp @@ -1,3 +1,10 @@ + +/* + * 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" diff --git a/samplecode/SampleDecode.cpp b/samplecode/SampleDecode.cpp index b192c5d..9188257 100644 --- a/samplecode/SampleDecode.cpp +++ b/samplecode/SampleDecode.cpp @@ -1,3 +1,10 @@ + +/* + * 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" diff --git a/samplecode/SampleDegenerateTwoPtRadials.cpp b/samplecode/SampleDegenerateTwoPtRadials.cpp new file mode 100644 index 0000000..5b8f46d --- /dev/null +++ b/samplecode/SampleDegenerateTwoPtRadials.cpp @@ -0,0 +1,92 @@ + +/* + * 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 "Sk64.h" +#include "SkGradientShader.h" + +static void draw_gradient2(SkCanvas* canvas, const SkRect& rect, SkScalar delta) { + SkColor colors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorMAGENTA }; + SkScalar pos[] = { 0, SkFloatToScalar(0.25f), SkFloatToScalar(0.75f), SK_Scalar1 }; + + SkScalar l = rect.fLeft; + SkScalar t = rect.fTop; + SkScalar w = rect.width(); + SkScalar h = rect.height(); + + SkASSERT(0 == SkScalarMod(w, SK_Scalar1 * 5)); + + SkPoint c0 = { l + 2 * w / 5 + delta, t + h / 2 }; + SkPoint c1 = { l + 3 * w / 5, t + h / 2 }; + SkScalar r0 = w / 5; + SkScalar r1 = 2 * w / 5; + SkShader* s = SkGradientShader::CreateTwoPointRadial(c0, r0, c1, r1, colors, + pos, SK_ARRAY_COUNT(pos), + SkShader::kClamp_TileMode); + SkPaint paint; + paint.setShader(s)->unref(); + + canvas->drawRect(rect, paint); +} + + +class DegenerateTwoPtRadialsView : public SampleView { + +public: + DegenerateTwoPtRadialsView() { + fTime = 0; + this->setBGColor(0xFFDDDDDD); + } + +protected: + // overrides from SkEventSink + virtual bool onQuery(SkEvent* evt) { + if (SampleCode::TitleQ(*evt)) { + SampleCode::TitleR(evt, "DegenerateTwoPtRadials"); + return true; + } + return this->INHERITED::onQuery(evt); + } + + virtual void onDrawContent(SkCanvas* canvas) { + fTime += SampleCode::GetAnimSecondsDelta(); + SkScalar delta = fTime / 15.f; + int intPart = SkScalarFloor(delta); + delta = delta - SK_Scalar1 * intPart; + if (intPart % 2) { + delta = SK_Scalar1 - delta; + } + delta -= SK_ScalarHalf; + static const int DELTA_SCALE = 500; + delta /= DELTA_SCALE; + + SkRect rect; + SkScalar w = SK_Scalar1 * 500; + SkScalar h = SK_Scalar1 * 500; + SkScalar l = SK_Scalar1 * 100; + SkScalar t = SK_Scalar1 * 100; + draw_gradient2(canvas, SkRect::MakeXYWH(l, t, w, h), delta); + char txt[512]; + sprintf(txt, "gap at \"tangent\" pt = %f", SkScalarToFloat(delta)); + SkPaint paint; + paint.setAntiAlias(true); + paint.setColor(SK_ColorBLACK); + canvas->drawText(txt, strlen(txt), l + w/2 + w*DELTA_SCALE*delta, t + h + SK_Scalar1 * 10, paint); + this->inval(NULL); + } + +private: + SkScalar fTime; + typedef SampleView INHERITED; +}; + +////////////////////////////////////////////////////////////////////////////// + +static SkView* MyFactory() { return new DegenerateTwoPtRadialsView; } +static SkViewRegister reg(MyFactory); diff --git a/samplecode/SampleDither.cpp b/samplecode/SampleDither.cpp index 3e77a5d..85ac2b1 100644 --- a/samplecode/SampleDither.cpp +++ b/samplecode/SampleDither.cpp @@ -1,3 +1,10 @@ + +/* + * 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" diff --git a/samplecode/SampleDitherBitmap.cpp b/samplecode/SampleDitherBitmap.cpp index 0d62446..c243782 100644 --- a/samplecode/SampleDitherBitmap.cpp +++ b/samplecode/SampleDitherBitmap.cpp @@ -1,3 +1,10 @@ + +/* + * 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 "SkColorPriv.h" #include "SkGradientShader.h" diff --git a/samplecode/SampleDraw.cpp b/samplecode/SampleDraw.cpp index deb1fb2..c418585 100644 --- a/samplecode/SampleDraw.cpp +++ b/samplecode/SampleDraw.cpp @@ -1,3 +1,10 @@ + +/* + * 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" diff --git a/samplecode/SampleDrawBitmap.cpp b/samplecode/SampleDrawBitmap.cpp new file mode 100644 index 0000000..aaf1123 --- /dev/null +++ b/samplecode/SampleDrawBitmap.cpp @@ -0,0 +1,84 @@ + +/* + * 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 "SkShader.h" +#include "SkUtils.h" +#include "SkDevice.h" + +static void create_bitmap(SkBitmap* bitmap) { + const int W = 100; + const int H = 100; + bitmap->setConfig(SkBitmap::kARGB_8888_Config, W, H); + bitmap->allocPixels(); + + SkCanvas canvas(*bitmap); + canvas.drawColor(SK_ColorRED); + SkPaint paint; + paint.setColor(SK_ColorBLUE); + canvas.drawCircle(SkIntToScalar(W)/2, SkIntToScalar(H)/2, SkIntToScalar(W)/2, paint); +} + +class DrawBitmapView : public SampleView { + SkPath fPath; +public: + DrawBitmapView() {} + +protected: + // overrides from SkEventSink + virtual bool onQuery(SkEvent* evt) { + if (SampleCode::TitleQ(*evt)) { + SampleCode::TitleR(evt, "DrawBitmap"); + return true; + } + return this->INHERITED::onQuery(evt); + } + + virtual void onDrawContent(SkCanvas* canvas) { + SkBitmap bitmap; + create_bitmap(&bitmap); + int x = bitmap.width() / 2; + int y = bitmap.height() / 2; + SkBitmap subset; + bitmap.extractSubset(&subset, SkIRect::MakeXYWH(x, y, x, y)); + + canvas->translate(SkIntToScalar(20), SkIntToScalar(20)); + + canvas->drawBitmap(bitmap, 0, 0); + canvas->drawBitmap(subset, 0, 0); + + // Now do the same but with a device bitmap as source image + SkRefPtr<SkDevice> primaryDevice(canvas->getDevice()); + SkRefPtr<SkDevice> secondDevice(canvas->createCompatibleDevice( + SkBitmap::kARGB_8888_Config, bitmap.width(), + bitmap.height(), true)); + secondDevice->unref(); + SkCanvas secondCanvas(secondDevice.get()); + secondCanvas.writePixels(bitmap, 0, 0); + + SkBitmap deviceBitmap = secondDevice->accessBitmap(false); + SkBitmap deviceSubset; + deviceBitmap.extractSubset(&deviceSubset, + SkIRect::MakeXYWH(x, y, x, y)); + + canvas->translate(SkIntToScalar(120), SkIntToScalar(0)); + + canvas->drawBitmap(deviceBitmap, 0, 0); + canvas->drawBitmap(deviceSubset, 0, 0); + + } + +private: + typedef SampleView INHERITED; +}; + +////////////////////////////////////////////////////////////////////////////// + +static SkView* MyFactory() { return new DrawBitmapView; } +static SkViewRegister reg(MyFactory); diff --git a/samplecode/SampleDrawLooper.cpp b/samplecode/SampleDrawLooper.cpp index 30879f7..7e317d7 100644 --- a/samplecode/SampleDrawLooper.cpp +++ b/samplecode/SampleDrawLooper.cpp @@ -1,3 +1,10 @@ + +/* + * 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" diff --git a/samplecode/SampleEffects.cpp b/samplecode/SampleEffects.cpp index a63c08d..bf83bae 100644 --- a/samplecode/SampleEffects.cpp +++ b/samplecode/SampleEffects.cpp @@ -1,3 +1,10 @@ + +/* + * 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 "SkCanvas.h" #include "SkPaint.h" @@ -127,4 +134,3 @@ private: static SkView* MyFactory() { return new EffectsView; } static SkViewRegister reg(MyFactory); - diff --git a/samplecode/SampleEmboss.cpp b/samplecode/SampleEmboss.cpp index 8b3f194..bf12636 100644 --- a/samplecode/SampleEmboss.cpp +++ b/samplecode/SampleEmboss.cpp @@ -1,3 +1,10 @@ + +/* + * 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" diff --git a/samplecode/SampleEmptyPath.cpp b/samplecode/SampleEmptyPath.cpp new file mode 100644 index 0000000..cffe6cf --- /dev/null +++ b/samplecode/SampleEmptyPath.cpp @@ -0,0 +1,130 @@ + +/* + * 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 "SkPaint.h" +#include "SkRandom.h" + +class EmptyPathView : public SampleView { +public: + EmptyPathView() {} + +protected: + // overrides from SkEventSink + virtual bool onQuery(SkEvent* evt) { + if (SampleCode::TitleQ(*evt)) { + SampleCode::TitleR(evt, "EmptyPath"); + return true; + } + return this->INHERITED::onQuery(evt); + } + + void drawEmpty(SkCanvas* canvas, + SkColor color, + const SkRect& clip, + SkPaint::Style style, + SkPath::FillType fill) { + SkPath path; + path.setFillType(fill); + SkPaint paint; + paint.setColor(color); + paint.setStyle(style); + canvas->save(); + canvas->clipRect(clip); + canvas->drawPath(path, paint); + canvas->restore(); + } + + virtual void onDrawContent(SkCanvas* canvas) { + struct FillAndName { + SkPath::FillType fFill; + const char* fName; + }; + static const FillAndName gFills[] = { + {SkPath::kWinding_FillType, "Winding"}, + {SkPath::kEvenOdd_FillType, "Even / Odd"}, + {SkPath::kInverseWinding_FillType, "Inverse Winding"}, + {SkPath::kInverseEvenOdd_FillType, "Inverse Even / Odd"}, + }; + struct StyleAndName { + SkPaint::Style fStyle; + const char* fName; + }; + static const StyleAndName gStyles[] = { + {SkPaint::kFill_Style, "Fill"}, + {SkPaint::kStroke_Style, "Stroke"}, + {SkPaint::kStrokeAndFill_Style, "Stroke And Fill"}, + }; + + SkPaint titlePaint; + titlePaint.setColor(SK_ColorBLACK); + titlePaint.setAntiAlias(true); + titlePaint.setLCDRenderText(true); + titlePaint.setTextSize(24 * SK_Scalar1); + const char title[] = "Empty Paths Drawn Into Rectangle Clips With Indicated Style and Fill"; + canvas->drawText(title, strlen(title), + 40 * SK_Scalar1, + 100*SK_Scalar1, + titlePaint); + + SkRandom rand; + SkRect rect = SkRect::MakeWH(125*SK_Scalar1, 100*SK_Scalar1); + int i = 0; + canvas->save(); + canvas->translate(80 * SK_Scalar1, 0); + canvas->save(); + for (size_t style = 0; style < SK_ARRAY_COUNT(gStyles); ++style) { + for (size_t fill = 0; fill < SK_ARRAY_COUNT(gFills); ++fill) { + if (0 == i % 4) { + canvas->restore(); + canvas->translate(0, rect.height() + 50 * SK_Scalar1); + canvas->save(); + } else { + canvas->translate(rect.width() + 100 * SK_Scalar1, 0); + } + ++i; + + + SkColor color = rand.nextU(); + color = 0xff000000| color; // force solid + this->drawEmpty(canvas, color, rect, + gStyles[style].fStyle, gFills[fill].fFill); + + SkPaint rectPaint; + rectPaint.setColor(SK_ColorBLACK); + rectPaint.setStyle(SkPaint::kStroke_Style); + rectPaint.setStrokeWidth(-1); + rectPaint.setAntiAlias(true); + canvas->drawRect(rect, rectPaint); + + char label[1024]; + sprintf(label, "%s, %s", gStyles[style].fName, + gFills[fill].fName); + SkPaint labelPaint; + labelPaint.setColor(color); + labelPaint.setAntiAlias(true); + labelPaint.setLCDRenderText(true); + canvas->drawText(label, strlen(label), + 0, rect.height() + 15 * SK_Scalar1, + labelPaint); + } + } + canvas->restore(); + canvas->restore(); + } + +private: + typedef SampleView INHERITED; +}; + +////////////////////////////////////////////////////////////////////////////// + +static SkView* MyFactory() { return new EmptyPathView; } +static SkViewRegister reg(MyFactory); + diff --git a/samplecode/SampleEncode.cpp b/samplecode/SampleEncode.cpp index f4ea195..6999a06 100644 --- a/samplecode/SampleEncode.cpp +++ b/samplecode/SampleEncode.cpp @@ -1,3 +1,10 @@ + +/* + * 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" diff --git a/samplecode/SampleExtractAlpha.cpp b/samplecode/SampleExtractAlpha.cpp deleted file mode 100644 index 860272d..0000000 --- a/samplecode/SampleExtractAlpha.cpp +++ /dev/null @@ -1,90 +0,0 @@ -#include "SampleCode.h" -#include "SkColorPriv.h" -#include "SkGradientShader.h" -#include "SkView.h" -#include "SkCanvas.h" -#include "SkUtils.h" - -static SkBitmap make_bitmap() { - SkBitmap bm; - SkColorTable* ctable = new SkColorTable(256); - - SkPMColor* c = ctable->lockColors(); - for (int i = 0; i < 256; i++) { - c[i] = SkPackARGB32(255 - i, 0, 0, 0); - } - ctable->unlockColors(true); - bm.setConfig(SkBitmap::kIndex8_Config, 256, 256); - bm.allocPixels(ctable); - ctable->unref(); - - bm.lockPixels(); - const float cx = bm.width() * 0.5f; - const float cy = bm.height() * 0.5f; - for (int y = 0; y < bm.height(); y++) { - float dy = y - cy; - dy *= dy; - uint8_t* p = bm.getAddr8(0, y); - for (int x = 0; x < 256; x++) { - float dx = x - cx; - dx *= dx; - float d = (dx + dy) / (cx/2); - int id = (int)d; - if (id > 255) { - id = 255; - } - p[x] = id; - } - } - bm.unlockPixels(); - return bm; -} - -class ExtractAlphaView : public SampleView { - SkBitmap fBM8; - SkBitmap fBM32; - SkBitmap fBM4; -public: - ExtractAlphaView() { - fBM8 = make_bitmap(); - fBM8.copyTo(&fBM32, SkBitmap::kARGB_8888_Config); - fBM8.copyTo(&fBM4, SkBitmap::kARGB_4444_Config); - - this->setBGColor(0xFFDDDDDD); - } - -protected: - // overrides from SkEventSink - virtual bool onQuery(SkEvent* evt) { - if (SampleCode::TitleQ(*evt)) { - SampleCode::TitleR(evt, "DitherBitmap"); - return true; - } - return this->INHERITED::onQuery(evt); - } - - virtual void onDrawContent(SkCanvas* canvas) { - SkPaint paint; - paint.setAntiAlias(true); - paint.setStyle(SkPaint::kStroke_Style); - - SkMatrix matrix; - matrix.setScale(3.55f, 80.f); - canvas->setMatrix(matrix); - - paint.setStrokeWidth(0.0588f); - canvas->drawLine(10, 5, 30, 4.8f, paint); - - paint.setStrokeWidth(0.06f); - canvas->drawLine(20, 5, 40, 4.8f, paint); - } - -private: - typedef SampleView INHERITED; -}; - -////////////////////////////////////////////////////////////////////////////// - -static SkView* MyFactory() { return new ExtractAlphaView; } -static SkViewRegister reg(MyFactory); - diff --git a/samplecode/SampleFillType.cpp b/samplecode/SampleFillType.cpp index 393c5f7..ae97720 100644 --- a/samplecode/SampleFillType.cpp +++ b/samplecode/SampleFillType.cpp @@ -1,3 +1,10 @@ + +/* + * 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" diff --git a/samplecode/SampleFilter.cpp b/samplecode/SampleFilter.cpp index a9089fa..350523d 100644 --- a/samplecode/SampleFilter.cpp +++ b/samplecode/SampleFilter.cpp @@ -1,3 +1,10 @@ + +/* + * 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" diff --git a/samplecode/SampleFilter2.cpp b/samplecode/SampleFilter2.cpp index c1a16a8..da4147e 100644 --- a/samplecode/SampleFilter2.cpp +++ b/samplecode/SampleFilter2.cpp @@ -1,3 +1,10 @@ + +/* + * 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" diff --git a/samplecode/SampleFontCache.cpp b/samplecode/SampleFontCache.cpp index 0b8187a..2546890 100644 --- a/samplecode/SampleFontCache.cpp +++ b/samplecode/SampleFontCache.cpp @@ -1,3 +1,10 @@ + +/* + * 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" diff --git a/samplecode/SampleFontScalerTest.cpp b/samplecode/SampleFontScalerTest.cpp index 0b0d349..062eca3 100644 --- a/samplecode/SampleFontScalerTest.cpp +++ b/samplecode/SampleFontScalerTest.cpp @@ -1,3 +1,10 @@ + +/* + * 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" @@ -38,7 +45,7 @@ public: fFaces[i] = SkTypeface::CreateFromName(gFaces[i].fName, gFaces[i].fStyle); } - this->setBGColor(0xFFDDDDDD); +// this->setBGColor(0xFFDDDDDD); } virtual ~FontScalerTestView() { @@ -57,6 +64,12 @@ protected: return this->INHERITED::onQuery(evt); } + static void rotate_about(SkCanvas* canvas, SkScalar degrees, SkScalar px, SkScalar py) { + canvas->translate(px, py); + canvas->rotate(degrees); + canvas->translate(-px, -py); + } + virtual void onDrawContent(SkCanvas* canvas) { SkPaint paint; @@ -74,35 +87,43 @@ protected: canvas->drawPath(path, paint); } - canvas->translate(200, 20); - canvas->rotate(30); - +// paint.setSubpixelText(true); paint.setAntiAlias(true); paint.setLCDRenderText(true); SkSafeUnref(paint.setTypeface(SkTypeface::CreateFromName("Times Roman", SkTypeface::kNormal))); // const char* text = "abcdefghijklmnopqrstuvwxyz"; - const char* text = "HnHnHnHnHnHnHnHnH"; - size_t textLen = strlen(text); - - SkScalar x = SkIntToScalar(10); - SkScalar y = SkIntToScalar(20); - - { - SkPaint p; - p.setColor(SK_ColorRED); - SkRect r; - r.set(0, 0, x, y*20); - canvas->drawRect(r, p); - } - - int index = 0; - for (int ps = 9; ps <= 24; ps++) { - textLen = strlen(text); - paint.setTextSize(SkIntToScalar(ps)); - canvas->drawText(text, textLen, x, y, paint); - y += paint.getFontMetrics(NULL); - index += 1; + const char* text = "Hamburgefons ooo mmm"; + const size_t textLen = strlen(text); + + for (int j = 0; j < 2; ++j) { + for (int i = 0; i < 6; ++i) { + SkScalar x = SkIntToScalar(10); + SkScalar y = SkIntToScalar(20); + + SkAutoCanvasRestore acr(canvas, true); + canvas->translate(SkIntToScalar(50 + i * 230), + SkIntToScalar(20)); + rotate_about(canvas, i * 5, x, y * 10); + + { + SkPaint p; + p.setAntiAlias(true); + SkRect r; + r.set(x-3, 15, x-1, 280); + canvas->drawRect(r, p); + } + + int index = 0; + for (int ps = 6; ps <= 22; ps++) { + paint.setTextSize(SkIntToScalar(ps)); + canvas->drawText(text, textLen, x, y, paint); + y += paint.getFontMetrics(NULL); + index += 1; + } + } + canvas->translate(0, 400); + paint.setSubpixelText(true); } } diff --git a/samplecode/SampleFuzz.cpp b/samplecode/SampleFuzz.cpp index 5c41886..36149c3 100644 --- a/samplecode/SampleFuzz.cpp +++ b/samplecode/SampleFuzz.cpp @@ -1,3 +1,10 @@ + +/* + * 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" @@ -38,7 +45,7 @@ static float huge() { } static float make_number() { - float v; + float v = 0; int sel; if (return_large == true && R(3) == 1) sel = R(6); else sel = R(4); @@ -124,9 +131,11 @@ static void do_fuzz(SkCanvas* canvas) { case 2: { SkXfermode::Mode mode; switch (R(3)) { - case 0: mode = SkXfermode::kSrc_Mode; break; + case 0: mode = SkXfermode::kSrc_Mode; break; case 1: mode = SkXfermode::kXor_Mode; break; - case 2: mode = SkXfermode::kSrcOver_Mode; break; + case 2: + default: // silence warning + mode = SkXfermode::kSrcOver_Mode; break; } paint.setXfermodeMode(mode); } @@ -347,7 +356,6 @@ protected: } virtual void onDrawContent(SkCanvas* canvas) { - SkIRect r = canvas->getTotalClip().getBounds(); do_fuzz(canvas); this->inval(NULL); } diff --git a/samplecode/SampleGM.cpp b/samplecode/SampleGM.cpp deleted file mode 100644 index ec5b22a..0000000 --- a/samplecode/SampleGM.cpp +++ /dev/null @@ -1,114 +0,0 @@ -#include "SampleCode.h" -#include "SkView.h" -#include "SkCanvas.h" - -#include "gm.h" - -using namespace skiagm; - -// need to explicitly declare this, or we get some weird infinite loop llist -template GMRegistry* GMRegistry::gHead; - -class Iter { -public: - Iter() { - fReg = GMRegistry::Head(); - } - - void reset() { - fReg = GMRegistry::Head(); - } - - GM* next() { - if (fReg) { - GMRegistry::Factory fact = fReg->factory(); - fReg = fReg->next(); - return fact(0); - } - return NULL; - } - - static int Count() { - const GMRegistry* reg = GMRegistry::Head(); - int count = 0; - while (reg) { - count += 1; - reg = reg->next(); - } - return count; - } - -private: - const GMRegistry* fReg; -}; - -/////////////////////////////////////////////////////////////////////////////// - -class GMView : public SampleView { - Iter fIter; - GM* fGM; -public: - GMView() { - fGM = fIter.next(); - this->postNextGM(); - - this->setBGColor(0xFFDDDDDD); - } - - virtual ~GMView() { - delete fGM; - } - -protected: - // overrides from SkEventSink - virtual bool onQuery(SkEvent* evt) { - if (SampleCode::TitleQ(*evt)) { - SampleCode::TitleR(evt, "GM"); - return true; - } - return this->INHERITED::onQuery(evt); - } - - virtual bool onEvent(const SkEvent& evt) { - if (evt.isType("next-gm")) { - delete fGM; - if (!(fGM = fIter.next())) { - fIter.reset(); - fGM = fIter.next(); - } - this->inval(NULL); - this->postNextGM(); - return true; - } - return this->INHERITED::onEvent(evt); - } - - virtual void onDrawContent(SkCanvas* canvas) { - fGM->draw(canvas); - } - -private: - void postNextGM() { - (new SkEvent("next-gm"))->post(this->getSinkID(), 1500); - } - - typedef SampleView INHERITED; -}; - -/////////////////////////////////////////////////////////////////////////////// - -static SkView* MyFactory() { return new GMView; } -static SkViewRegister reg(MyFactory); - -/////////////////////////////////////////////////////////////////////////////// - -using namespace skiagm; - -GM::GM() {} -GM::~GM() {} - -void GM::draw(SkCanvas* canvas) { - this->onDraw(canvas); -} - - diff --git a/samplecode/SampleGradients.cpp b/samplecode/SampleGradients.cpp index 902b0bd..18536cf 100644 --- a/samplecode/SampleGradients.cpp +++ b/samplecode/SampleGradients.cpp @@ -1,3 +1,10 @@ + +/* + * 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" diff --git a/samplecode/SampleHairCurves.cpp b/samplecode/SampleHairCurves.cpp new file mode 100644 index 0000000..152cbeb --- /dev/null +++ b/samplecode/SampleHairCurves.cpp @@ -0,0 +1,112 @@ + +/* + * 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 "SkPath.h" +#include "SkRandom.h" + +class HairCurvesView : public SampleView { +public: + HairCurvesView() { + } + +protected: + // overrides from SkEventSink + virtual bool onQuery(SkEvent* evt) { + if (SampleCode::TitleQ(*evt)) { + SampleCode::TitleR(evt, "HairCurves"); + return true; + } + return this->INHERITED::onQuery(evt); + } + + + virtual void onDrawContent(SkCanvas* canvas) { + SkPaint paint; + paint.setAntiAlias(true); + paint.setStyle(SkPaint::kStroke_Style); + paint.setStrokeWidth(-1); + canvas->save(); + canvas->scale(1000 * SK_Scalar1, 1000 * SK_Scalar1); + SkRandom rand; + SkPath curves; + SkPath hulls; + SkPath ctrlPts; + for (int i = 0; i < 100; ++i) { + SkScalar pts[] = { + rand.nextUScalar1(), rand.nextUScalar1(), + rand.nextUScalar1(), rand.nextUScalar1(), + rand.nextUScalar1(), rand.nextUScalar1(), + rand.nextUScalar1(), rand.nextUScalar1() + }; + curves.moveTo(pts[0], pts[1]); + curves.cubicTo(pts[2], pts[3], + pts[4], pts[5], + pts[6], pts[7]); + + hulls.moveTo(pts[0], pts[1]); + hulls.lineTo(pts[2], pts[3]); + hulls.lineTo(pts[4], pts[5]); + hulls.lineTo(pts[6], pts[7]); + + ctrlPts.addCircle(pts[0], pts[1], SK_Scalar1 / 200); + ctrlPts.addCircle(pts[2], pts[3], SK_Scalar1 / 200); + ctrlPts.addCircle(pts[4], pts[5], SK_Scalar1 / 200); + ctrlPts.addCircle(pts[6], pts[7], SK_Scalar1 / 200); + } + for (int i = 0; i < 100; ++i) { + SkScalar pts[] = { + rand.nextUScalar1(), rand.nextUScalar1(), + rand.nextUScalar1(), rand.nextUScalar1(), + rand.nextUScalar1(), rand.nextUScalar1(), + }; + curves.moveTo(pts[0], pts[1]); + curves.quadTo(pts[2], pts[3], + pts[4], pts[5]); + + hulls.moveTo(pts[0], pts[1]); + hulls.lineTo(pts[2], pts[3]); + hulls.lineTo(pts[4], pts[5]); + + ctrlPts.addCircle(pts[0], pts[1], SK_Scalar1 / 200); + ctrlPts.addCircle(pts[2], pts[3], SK_Scalar1 / 200); + ctrlPts.addCircle(pts[4], pts[5], SK_Scalar1 / 200); + } + for (int i = 0; i < 100; ++i) { + SkScalar pts[] = { + rand.nextUScalar1(), rand.nextUScalar1(), + rand.nextUScalar1(), rand.nextUScalar1(), + }; + curves.moveTo(pts[0], pts[1]); + curves.lineTo(pts[2], pts[3]); + + ctrlPts.addCircle(pts[0], pts[1], SK_Scalar1 / 200); + ctrlPts.addCircle(pts[2], pts[3], SK_Scalar1 / 200); + } + + paint.setColor(SK_ColorBLACK); + canvas->drawPath(curves, paint); + paint.setColor(SK_ColorRED); + //canvas->drawPath(hulls, paint); + paint.setStyle(SkPaint::kFill_Style); + paint.setColor(SK_ColorBLUE); + //canvas->drawPath(ctrlPts, paint); + + canvas->restore(); + } + +private: + typedef SampleView INHERITED; +}; + +////////////////////////////////////////////////////////////////////////////// + +static SkView* MyFactory() { return new HairCurvesView; } +static SkViewRegister reg(MyFactory); + diff --git a/samplecode/SampleHairModes.cpp b/samplecode/SampleHairModes.cpp new file mode 100644 index 0000000..cc22b17 --- /dev/null +++ b/samplecode/SampleHairModes.cpp @@ -0,0 +1,150 @@ +/* + * 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 "SkColorPriv.h" +#include "SkShader.h" + +static SkCanvas* create_canvas(int w, int h) { + SkBitmap bm; + bm.setConfig(SkBitmap::kARGB_8888_Config, w, h); + bm.allocPixels(); + bm.eraseColor(0); + return new SkCanvas(bm); +} + +static const SkBitmap& extract_bitmap(SkCanvas* canvas) { + return canvas->getDevice()->accessBitmap(false); +} + +static const struct { + SkXfermode::Mode fMode; + const char* fLabel; +} gModes[] = { + { SkXfermode::kClear_Mode, "Clear" }, + { SkXfermode::kSrc_Mode, "Src" }, + { SkXfermode::kDst_Mode, "Dst" }, + { SkXfermode::kSrcOver_Mode, "SrcOver" }, + { SkXfermode::kDstOver_Mode, "DstOver" }, + { SkXfermode::kSrcIn_Mode, "SrcIn" }, + { SkXfermode::kDstIn_Mode, "DstIn" }, + { SkXfermode::kSrcOut_Mode, "SrcOut" }, + { SkXfermode::kDstOut_Mode, "DstOut" }, + { SkXfermode::kSrcATop_Mode, "SrcATop" }, + { SkXfermode::kDstATop_Mode, "DstATop" }, + { SkXfermode::kXor_Mode, "Xor" }, +}; + +const int gWidth = 64; +const int gHeight = 64; +const SkScalar W = SkIntToScalar(gWidth); +const SkScalar H = SkIntToScalar(gHeight); + +static SkScalar drawCell(SkCanvas* canvas, SkXfermode* mode, SkAlpha a0, SkAlpha a1) { + + SkPaint paint; + paint.setAntiAlias(true); + + SkRect r = SkRect::MakeWH(W, H); + r.inset(W/10, H/10); + + paint.setColor(SK_ColorBLUE); + paint.setAlpha(a0); + canvas->drawOval(r, paint); + + paint.setColor(SK_ColorRED); + paint.setAlpha(a1); + paint.setXfermode(mode); + for (int angle = 0; angle < 24; ++angle) { + SkScalar x = SkScalarCos(SkIntToScalar(angle) * (SK_ScalarPI * 2) / 24) * gWidth; + SkScalar y = SkScalarSin(SkIntToScalar(angle) * (SK_ScalarPI * 2) / 24) * gHeight; + paint.setStrokeWidth(SK_Scalar1 * angle * 2 / 24); + canvas->drawLine(W/2, H/2, W/2 + x, H/2 + y, paint); + } + + return H; +} + +static SkShader* make_bg_shader() { + SkBitmap bm; + bm.setConfig(SkBitmap::kARGB_8888_Config, 2, 2); + bm.allocPixels(); + *bm.getAddr32(0, 0) = *bm.getAddr32(1, 1) = 0xFFFFFFFF; + *bm.getAddr32(1, 0) = *bm.getAddr32(0, 1) = SkPackARGB32(0xFF, 0xCC, 0xCC, 0xCC); + + SkShader* s = SkShader::CreateBitmapShader(bm, + SkShader::kRepeat_TileMode, + SkShader::kRepeat_TileMode); + + SkMatrix m; + m.setScale(SkIntToScalar(6), SkIntToScalar(6)); + s->setLocalMatrix(m); + return s; +} + +class HairModesView : public SampleView { + SkPaint fBGPaint; +public: + HairModesView() { + fBGPaint.setShader(make_bg_shader())->unref(); + } + +protected: + // overrides from SkEventSink + virtual bool onQuery(SkEvent* evt) { + if (SampleCode::TitleQ(*evt)) { + SampleCode::TitleR(evt, "HairlineModes"); + return true; + } + return this->INHERITED::onQuery(evt); + } + + virtual void onDrawContent(SkCanvas* canvas) { + const SkRect bounds = SkRect::MakeWH(W, H); + static const SkAlpha gAlphaValue[] = { 0xFF, 0x88, 0x88 }; + + canvas->translate(SkIntToScalar(4), SkIntToScalar(4)); + + for (int alpha = 0; alpha < 4; ++alpha) { + canvas->save(); + canvas->save(); + for (size_t i = 0; i < SK_ARRAY_COUNT(gModes); ++i) { + if (6 == i) { + canvas->restore(); + canvas->translate(W * 5, 0); + canvas->save(); + } + SkXfermode* mode = SkXfermode::Create(gModes[i].fMode); + + canvas->drawRect(bounds, fBGPaint); + canvas->saveLayer(&bounds, NULL); + SkScalar dy = drawCell(canvas, mode, + gAlphaValue[alpha & 1], + gAlphaValue[alpha & 2]); + canvas->restore(); + + canvas->translate(0, dy * 5 / 4); + SkSafeUnref(mode); + } + canvas->restore(); + canvas->restore(); + canvas->translate(W * 5 / 4, 0); + } + } + +private: + typedef SampleView INHERITED; +}; + +/////////////////////////////////////////////////////////////////////////////// + +static SkView* MyFactory() { return new HairModesView; } +static SkViewRegister reg(MyFactory); + diff --git a/samplecode/SampleHairline.cpp b/samplecode/SampleHairline.cpp index 8368f5b..065087e 100644 --- a/samplecode/SampleHairline.cpp +++ b/samplecode/SampleHairline.cpp @@ -1,3 +1,10 @@ + +/* + * 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" diff --git a/samplecode/SampleImage.cpp b/samplecode/SampleImage.cpp index 2944299..8867baf 100644 --- a/samplecode/SampleImage.cpp +++ b/samplecode/SampleImage.cpp @@ -1,3 +1,10 @@ + +/* + * 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" diff --git a/samplecode/SampleImageDir.cpp b/samplecode/SampleImageDir.cpp index 8ef59ad..8d6f5e0 100644 --- a/samplecode/SampleImageDir.cpp +++ b/samplecode/SampleImageDir.cpp @@ -1,3 +1,10 @@ + +/* + * 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" @@ -29,6 +36,10 @@ static void drawmarshmallow(SkCanvas* canvas) { SkMatrix m; SkImageDecoder::DecodeFile("/Users/reed/Downloads/3elfs.jpg", &bitmap); + if (!bitmap.pixelRef()) { + return; + } + SkShader* s = SkShader::CreateBitmapShader(bitmap, SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode); @@ -61,33 +72,33 @@ static void DrawRoundRect(SkCanvas& canvas) { // set up clipper SkRect skclip; - skclip.set(SkIntToFixed(284), SkIntToFixed(40), SkIntToFixed(1370), SkIntToFixed(708)); + skclip.set(SkIntToScalar(284), SkIntToScalar(40), SkIntToScalar(1370), SkIntToScalar(708)); // ret = canvas.clipRect(skclip); // SkASSERT(ret); - matrix.set(SkMatrix::kMTransX, SkFloatToFixed(-1153.28)); - matrix.set(SkMatrix::kMTransY, SkFloatToFixed(1180.50)); + matrix.set(SkMatrix::kMTransX, SkFloatToScalar(-1153.28f)); + matrix.set(SkMatrix::kMTransY, SkFloatToScalar(1180.50f)); - matrix.set(SkMatrix::kMScaleX, SkFloatToFixed(0.177171)); - matrix.set(SkMatrix::kMScaleY, SkFloatToFixed(0.177043)); + matrix.set(SkMatrix::kMScaleX, SkFloatToScalar(0.177171f)); + matrix.set(SkMatrix::kMScaleY, SkFloatToScalar(0.177043f)); - matrix.set(SkMatrix::kMSkewX, SkFloatToFixed(0.126968)); - matrix.set(SkMatrix::kMSkewY, SkFloatToFixed(-0.126876)); + matrix.set(SkMatrix::kMSkewX, SkFloatToScalar(0.126968f)); + matrix.set(SkMatrix::kMSkewY, SkFloatToScalar(-0.126876f)); - matrix.set(SkMatrix::kMPersp0, SkFloatToFixed(0.0)); - matrix.set(SkMatrix::kMPersp1, SkFloatToFixed(0.0)); + matrix.set(SkMatrix::kMPersp0, SkFloatToScalar(0.0f)); + matrix.set(SkMatrix::kMPersp1, SkFloatToScalar(0.0f)); ret = canvas.concat(matrix); paint.setAntiAlias(true); paint.setColor(0xb2202020); paint.setStyle(SkPaint::kStroke_Style); - paint.setStrokeWidth(SkFloatToFixed(68.13)); + paint.setStrokeWidth(SkFloatToScalar(68.13f)); SkRect r; - r.set(SkFloatToFixed(-313.714417), SkFloatToFixed(-4.826389), SkFloatToFixed(18014.447266), SkFloatToFixed(1858.154541)); - canvas.drawRoundRect(r, SkFloatToFixed(91.756363), SkFloatToFixed(91.756363), paint); + r.set(SkFloatToScalar(-313.714417f), SkFloatToScalar(-4.826389f), SkFloatToScalar(18014.447266f), SkFloatToScalar(1858.154541f)); + canvas.drawRoundRect(r, SkFloatToScalar(91.756363f), SkFloatToScalar(91.756363f), paint); } static bool SetImageRef(SkBitmap* bitmap, SkStream* stream, diff --git a/samplecode/SampleLCD.cpp b/samplecode/SampleLCD.cpp index 098958f..5f8cb0b 100644 --- a/samplecode/SampleLCD.cpp +++ b/samplecode/SampleLCD.cpp @@ -1,3 +1,10 @@ + +/* + * 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" diff --git a/samplecode/SampleLayerMask.cpp b/samplecode/SampleLayerMask.cpp index 9bd00ae..883642c 100644 --- a/samplecode/SampleLayerMask.cpp +++ b/samplecode/SampleLayerMask.cpp @@ -1,3 +1,10 @@ + +/* + * 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 "SkCanvas.h" #include "SkPaint.h" diff --git a/samplecode/SampleLayers.cpp b/samplecode/SampleLayers.cpp index 6fc9c83..06fdd3f 100644 --- a/samplecode/SampleLayers.cpp +++ b/samplecode/SampleLayers.cpp @@ -1,3 +1,10 @@ + +/* + * 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" diff --git a/samplecode/SampleLineClipper.cpp b/samplecode/SampleLineClipper.cpp index ac6b013..8565470 100644 --- a/samplecode/SampleLineClipper.cpp +++ b/samplecode/SampleLineClipper.cpp @@ -1,3 +1,10 @@ + +/* + * 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" @@ -146,7 +153,7 @@ enum { H = 480/3 }; -class LineClipperView : public SkView { +class LineClipperView : public SampleView { SkMSec fNow; int fCounter; int fProcIndex; @@ -185,10 +192,6 @@ protected: return this->INHERITED::onQuery(evt); } - void drawBG(SkCanvas* canvas) { - canvas->drawColor(SK_ColorWHITE); - } - static void drawVLine(SkCanvas* canvas, SkScalar x, const SkPaint& paint) { canvas->drawLine(x, -999, x, 999, paint); } @@ -197,9 +200,7 @@ protected: canvas->drawLine(-999, y, 999, y, paint); } - virtual void onDraw(SkCanvas* canvas) { - this->drawBG(canvas); - + virtual void onDrawContent(SkCanvas* canvas) { SkMSec now = SampleCode::GetAnimTime(); if (fNow != now) { fNow = now; @@ -229,6 +230,7 @@ protected: paint1.setColor(SK_ColorRED); paint1.setStyle(SkPaint::kStroke_Style); gProcs[fProcIndex](fPts, fClip, canvas, paint, paint1); + this->inval(NULL); } virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y) { @@ -245,7 +247,7 @@ protected: } private: - typedef SkView INHERITED; + typedef SampleView INHERITED; }; ////////////////////////////////////////////////////////////////////////////// diff --git a/samplecode/SampleLines.cpp b/samplecode/SampleLines.cpp index 03dd30f..0048d39 100644 --- a/samplecode/SampleLines.cpp +++ b/samplecode/SampleLines.cpp @@ -1,3 +1,10 @@ + +/* + * 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" diff --git a/samplecode/SampleMeasure.cpp b/samplecode/SampleMeasure.cpp index 8078e03..35ad5bd 100644 --- a/samplecode/SampleMeasure.cpp +++ b/samplecode/SampleMeasure.cpp @@ -1,3 +1,10 @@ + +/* + * 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" diff --git a/samplecode/SampleMipMap.cpp b/samplecode/SampleMipMap.cpp index 3d95156..de5aac5 100644 --- a/samplecode/SampleMipMap.cpp +++ b/samplecode/SampleMipMap.cpp @@ -1,3 +1,10 @@ + +/* + * 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" diff --git a/samplecode/SampleMovie.cpp b/samplecode/SampleMovie.cpp index af34198..17fbc79 100644 --- a/samplecode/SampleMovie.cpp +++ b/samplecode/SampleMovie.cpp @@ -1,3 +1,10 @@ + +/* + * 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" diff --git a/samplecode/SampleNinePatch.cpp b/samplecode/SampleNinePatch.cpp index e158287..bab7b23 100644 --- a/samplecode/SampleNinePatch.cpp +++ b/samplecode/SampleNinePatch.cpp @@ -1,28 +1,58 @@ + +/* + * 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 "SkImageDecoder.h" -#include "SkNinePatch.h" #include "SkPaint.h" -#include "SkUnPreMultiply.h" +#include "SkGpuDevice.h" + +static void make_bitmap(SkBitmap* bitmap, GrContext* ctx, SkIRect* center) { + SkDevice* dev; + SkCanvas canvas; + + const int kFixed = 28; + const int kStretchy = 8; + const int kSize = 2*kFixed + kStretchy; + + if (ctx) { + dev = new SkGpuDevice(ctx, SkBitmap::kARGB_8888_Config, kSize, kSize); + *bitmap = dev->accessBitmap(false); + } else { + bitmap->setConfig(SkBitmap::kARGB_8888_Config, kSize, kSize); + bitmap->allocPixels(); + dev = new SkDevice(*bitmap); + } + + canvas.setDevice(dev)->unref(); + canvas.clear(0); + + SkRect r = SkRect::MakeWH(SkIntToScalar(kSize), SkIntToScalar(kSize)); + const SkScalar strokeWidth = SkIntToScalar(6); + const SkScalar radius = SkIntToScalar(kFixed) - strokeWidth/2; + + center->setXYWH(kFixed, kFixed, kStretchy, kStretchy); + + SkPaint paint; + paint.setAntiAlias(true); + + paint.setColor(0xFFFF0000); + canvas.drawRoundRect(r, radius, radius, paint); + r.setXYWH(SkIntToScalar(kFixed), 0, SkIntToScalar(kStretchy), SkIntToScalar(kSize)); + paint.setColor(0x8800FF00); + canvas.drawRect(r, paint); + r.setXYWH(0, SkIntToScalar(kFixed), SkIntToScalar(kSize), SkIntToScalar(kStretchy)); + paint.setColor(0x880000FF); + canvas.drawRect(r, paint); +} + class NinePatchView : public SampleView { public: - SkBitmap fBM; - - NinePatchView() { - SkImageDecoder::DecodeFile("/skimages/btn_default_normal_disable.9.png", &fBM); - - // trim off the edge guide-lines - SkBitmap tmp; - SkIRect r; - r.set(1, 1, fBM.width() - 1, fBM.height() - 1); - fBM.extractSubset(&tmp, r); - fBM.swap(tmp); - - fX = SkIntToScalar(fBM.width()); - fY = 0; - } + NinePatchView() {} protected: // overrides from SkEventSink @@ -33,75 +63,40 @@ protected: } return this->INHERITED::onQuery(evt); } - - virtual void onDrawBackground(SkCanvas* canvas) { - SkPaint p; - p.setDither(true); - p.setColor(0xFF909090); - canvas->drawPaint(p); - } - static void test_rects(SkCanvas* canvas, const SkBitmap& bm, const SkPaint* paint) { - static const SkIRect src[] = { - { 0, 0, 18, 34 }, - { 18, 0, 19, 34 }, - { 19, 0, 36, 34 }, - { 0, 34, 18, 35 }, - { 18, 34, 19, 35 }, - { 19, 34, 36, 35 }, - { 0, 35, 18, 72 }, - { 18, 35, 19, 72 }, - { 19, 35, 36, 72 }, - }; - static const SkRect dst[] = { - { 0, 0, 18, 34 }, - { 18, 0, 283, 34 }, - { 283, 0, 300, 34 }, - { 0, 34, 18, 163 }, - { 18, 34, 283, 163 }, - { 283, 34, 300, 163 }, - { 0, 163, 18, 200 }, - { 18, 163, 283, 200 }, - { 283, 163, 300, 200 }, + virtual void onDrawContent(SkCanvas* canvas) { + SkBitmap bm; + SkIRect center; + make_bitmap(&bm, SampleCode::GetGr(), ¢er); + + // amount of bm that should not be stretched (unless we have to) + const SkScalar fixed = SkIntToScalar(bm.width() - center.width()); + + const SkTSize<SkScalar> size[] = { + { fixed * 4 / 5, fixed * 4 / 5 }, // shrink in both axes + { fixed * 4 / 5, fixed * 4 }, // shrink in X + { fixed * 4, fixed * 4 / 5 }, // shrink in Y + { fixed * 4, fixed * 4 } }; - for (size_t i = 0; i < SK_ARRAY_COUNT(src); i++) { - canvas->drawBitmapRect(bm, &src[i], dst[i], paint); - } - } - virtual void onDrawContent(SkCanvas* canvas) { - canvas->drawBitmap(fBM, 0, 0); - - SkIRect margins; - SkRect dst; - int d = 25; - - margins.set(d, d, d, d); - margins.fLeft = fBM.width()/2 - 1; - margins.fTop = fBM.height()/2 - 1; - margins.fRight = fBM.width() - margins.fLeft - 1; - margins.fBottom = fBM.height() - margins.fTop - 1; - - // canvas->translate(fX/5, fY/5); - canvas->translate(0, 76); - - dst.set(0, 0, SkIntToScalar(200), SkIntToScalar(200)); - + canvas->drawBitmap(bm, SkIntToScalar(10), SkIntToScalar(10), NULL); + + SkScalar x = SkIntToScalar(100); + SkScalar y = SkIntToScalar(100); + SkPaint paint; - paint.setAntiAlias(false); - paint.setDither(true); - paint.setFilterBitmap(false); - // SkNinePatch::DrawNine(canvas, dst, fBM, margins, &paint); - test_rects(canvas, fBM, &paint); + paint.setFilterBitmap(true); + + for (int iy = 0; iy < 2; ++iy) { + for (int ix = 0; ix < 2; ++ix) { + int i = ix * 2 + iy; + SkRect r = SkRect::MakeXYWH(x + ix * fixed, y + iy * fixed, + size[i].width(), size[i].height()); + canvas->drawBitmapNine(bm, center, r, &paint); + } + } } - virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y) { - fX = x / 1.5f; - fY = y / 1.5f; - fX = x; fY = y; - this->inval(NULL); - return this->INHERITED::onFindClickHandler(x, y); - } private: SkScalar fX, fY; typedef SampleView INHERITED; diff --git a/samplecode/SampleOvalTest.cpp b/samplecode/SampleOvalTest.cpp index f625529..dab4fbc 100644 --- a/samplecode/SampleOvalTest.cpp +++ b/samplecode/SampleOvalTest.cpp @@ -1,3 +1,10 @@ + +/* + * 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" diff --git a/samplecode/SampleOverflow.cpp b/samplecode/SampleOverflow.cpp index d3ecff7..05b28eb 100644 --- a/samplecode/SampleOverflow.cpp +++ b/samplecode/SampleOverflow.cpp @@ -1,3 +1,10 @@ + +/* + * 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" diff --git a/samplecode/SamplePageFlip.cpp b/samplecode/SamplePageFlip.cpp index 7c5bf48..b2d96f0 100644 --- a/samplecode/SamplePageFlip.cpp +++ b/samplecode/SamplePageFlip.cpp @@ -1,3 +1,10 @@ + +/* + * 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" @@ -8,7 +15,7 @@ #include <pthread.h> -#define WIDTH 200 +#define WIDTH 160 #define HEIGHT 200 static bool gDone; @@ -49,6 +56,9 @@ static void* draw_proc(void* context) { SkRect oval; oval.setEmpty(); + SkRect clipR = SkRect::MakeWH(SkIntToScalar(bm->width()), SkIntToScalar(bm->height())); + clipR.inset(SK_Scalar1/4, SK_Scalar1/4); + while (!gDone) { ref->inval(oval, true); oval.set(x, y, x + SkIntToScalar(OVALW), y + SkIntToScalar(OVALH)); @@ -60,34 +70,23 @@ static void* draw_proc(void* context) { // this must be local to the loop, since it needs to forget the pixels // its writing to after each iteration, since we do the swap SkCanvas canvas(update.bitmap()); - -// SkDebugf("----- dirty [%d %d %d %d]\n", dirty.getBounds().fLeft, dirty.getBounds().fTop, dirty.getBounds().width(), dirty.getBounds().height()); canvas.clipRegion(update.dirty()); - canvas.drawColor(0, SkXfermode::kClear_Mode); + canvas.clipRect(clipR, SkRegion::kIntersect_Op, true); + canvas.drawOval(oval, paint); } bounce(&x, &dx, WIDTH-OVALW); bounce(&y, &dy, HEIGHT-OVALH); - -#if 1 - for (int i = 0; i < 1000; i++) { - for (int j = 0; j < 10000; j++) { - SkFixedMul(j, 10); - } - } -#endif } return NULL; } static const SkBitmap::Config gConfigs[] = { SkBitmap::kARGB_8888_Config, -#if 1 SkBitmap::kRGB_565_Config, SkBitmap::kARGB_4444_Config, SkBitmap::kA8_Config -#endif }; class PageFlipView : public SampleView { diff --git a/samplecode/SamplePatch.cpp b/samplecode/SamplePatch.cpp index ea365c7..edc7804 100644 --- a/samplecode/SamplePatch.cpp +++ b/samplecode/SamplePatch.cpp @@ -1,3 +1,10 @@ + +/* + * 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" diff --git a/samplecode/SamplePath.cpp b/samplecode/SamplePath.cpp index cd45ed9..7e2750a 100644 --- a/samplecode/SamplePath.cpp +++ b/samplecode/SamplePath.cpp @@ -1,4 +1,11 @@ +/* + * 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" diff --git a/samplecode/SamplePathClip.cpp b/samplecode/SamplePathClip.cpp index 8139171..5ca39e8 100644 --- a/samplecode/SamplePathClip.cpp +++ b/samplecode/SamplePathClip.cpp @@ -1,3 +1,10 @@ + +/* + * 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" diff --git a/samplecode/SamplePathEffects.cpp b/samplecode/SamplePathEffects.cpp index 75566b0..1317b82 100644 --- a/samplecode/SamplePathEffects.cpp +++ b/samplecode/SamplePathEffects.cpp @@ -1,3 +1,10 @@ + +/* + * 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" diff --git a/samplecode/SamplePathFill.cpp b/samplecode/SamplePathFill.cpp index 845b7a8..bcc00d3 100644 --- a/samplecode/SamplePathFill.cpp +++ b/samplecode/SamplePathFill.cpp @@ -1,3 +1,10 @@ + +/* + * 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" diff --git a/samplecode/SamplePicture.cpp b/samplecode/SamplePicture.cpp index d7b6b22..d2c9d65 100644 --- a/samplecode/SamplePicture.cpp +++ b/samplecode/SamplePicture.cpp @@ -1,3 +1,10 @@ + +/* + * 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" @@ -14,7 +21,6 @@ #include "SkUtils.h" #include "SkColorPriv.h" #include "SkColorFilter.h" -#include "SkShape.h" #include "SkTime.h" #include "SkTypeface.h" #include "SkXfermode.h" @@ -22,67 +28,6 @@ #include "SkStream.h" #include "SkXMLParser.h" -class SignalShape : public SkShape { -public: - SignalShape() : fSignal(0) {} - - SkShape* setSignal(int n) { - fSignal = n; - return this; - } - -protected: - virtual void onDraw(SkCanvas* canvas) { - // SkDebugf("---- sc %d\n", canvas->getSaveCount() - 1); - } - -private: - int fSignal; -}; - -static SkPMColor SignalProc(SkPMColor src, SkPMColor dst) { - return dst; -} - -/* Picture playback will skip blocks of draw calls that follow a clip() call - that returns empty, and jump down to the corresponding restore() call. - - This is a great preformance win for drawing very large/tall pictures with - a small visible window (think scrolling a long document). These tests make - sure that (a) we are performing the culling, and (b) we don't get confused - by nested save() calls, nor by calls to restoreToCount(). - */ -static void test_saveRestoreCulling() { - SkPaint signalPaint; - SignalShape signalShape; - - SkPicture pic; - SkRect r = SkRect::MakeWH(0, 0); - int n; - SkCanvas* canvas = pic.beginRecording(100, 100); - int startN = canvas->getSaveCount(); - SkDebugf("---- start sc %d\n", startN); - canvas->drawShape(signalShape.setSignal(1)); - canvas->save(); - canvas->drawShape(signalShape.setSignal(2)); - n = canvas->save(); - canvas->drawShape(signalShape.setSignal(3)); - canvas->save(); - canvas->clipRect(r); - canvas->drawShape(signalShape.setSignal(4)); - canvas->restoreToCount(n); - canvas->drawShape(signalShape.setSignal(5)); - canvas->restore(); - canvas->drawShape(signalShape.setSignal(6)); - SkASSERT(canvas->getSaveCount() == startN); - - SkBitmap bm; - bm.setConfig(SkBitmap::kARGB_8888_Config, 100, 100); - bm.allocPixels(); - SkCanvas c(bm); - c.drawPicture(pic); -} - /////////////////////////////////////////////////////////////////////////////// #include "SkImageRef_GlobalPool.h" @@ -137,8 +82,6 @@ public: // unref fPicture in our destructor, and it will in turn take care of // the other references to fSubPicture fSubPicture->unref(); - - test_saveRestoreCulling(); } virtual ~PictureView() { @@ -230,7 +173,7 @@ private: #define INVAL_ALL_TYPE "inval-all" void delayInval(SkMSec delay) { - (new SkEvent(INVAL_ALL_TYPE))->post(this->getSinkID(), delay); + (new SkEvent(INVAL_ALL_TYPE, this->getSinkID()))->postDelay(delay); } virtual bool onEvent(const SkEvent& evt) { diff --git a/samplecode/SamplePoints.cpp b/samplecode/SamplePoints.cpp index a2804b4..717cd8c 100644 --- a/samplecode/SamplePoints.cpp +++ b/samplecode/SamplePoints.cpp @@ -1,3 +1,10 @@ + +/* + * 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" diff --git a/samplecode/SamplePolyToPoly.cpp b/samplecode/SamplePolyToPoly.cpp index aea0cb4..dbda4da 100644 --- a/samplecode/SamplePolyToPoly.cpp +++ b/samplecode/SamplePolyToPoly.cpp @@ -1,3 +1,10 @@ + +/* + * 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" @@ -56,8 +63,9 @@ public: { SkIntToScalar(32), SkIntToScalar(17) } }; - SkMatrix m0, m1; + SkMatrix m0; m0.setPolyToPoly(src, dst, 3); + // SkMatrix m1; // SkSetPoly3To3(&m1, src, dst); // m0.dump(); // m1.dump(); diff --git a/samplecode/SampleRegion.cpp b/samplecode/SampleRegion.cpp index 822bd6f..48153ef 100644 --- a/samplecode/SampleRegion.cpp +++ b/samplecode/SampleRegion.cpp @@ -1,3 +1,10 @@ + +/* + * 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" diff --git a/samplecode/SampleRepeatTile.cpp b/samplecode/SampleRepeatTile.cpp index 9867074..16a23ad 100644 --- a/samplecode/SampleRepeatTile.cpp +++ b/samplecode/SampleRepeatTile.cpp @@ -1,3 +1,10 @@ + +/* + * 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" diff --git a/samplecode/SampleShaderText.cpp b/samplecode/SampleShaderText.cpp index 2748b55..bed4835 100644 --- a/samplecode/SampleShaderText.cpp +++ b/samplecode/SampleShaderText.cpp @@ -1,3 +1,10 @@ + +/* + * 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" @@ -118,7 +125,7 @@ protected: virtual void onDrawContent(SkCanvas* canvas) { const char text[] = "Shaded Text"; const int textLen = SK_ARRAY_COUNT(text) - 1; - static int pointSize = 48; + static int pointSize = 36; int w = pointSize * textLen; int h = pointSize; @@ -166,17 +173,31 @@ protected: canvas->save(); canvas->translate(SkIntToScalar(20), SkIntToScalar(10)); + SkPath path; + path.arcTo(SkRect::MakeXYWH(SkIntToScalar(-40), SkIntToScalar(15), + SkIntToScalar(300), SkIntToScalar(90)), + SkIntToScalar(225), SkIntToScalar(90), + false); + path.close(); + static const int testsPerCol = 8; static const int rowHeight = 60; static const int colWidth = 300; canvas->save(); for (size_t s = 0; s < SK_ARRAY_COUNT(shaders); s++) { canvas->save(); - canvas->translate(SkIntToScalar((s / testsPerCol) * colWidth), - SkIntToScalar((s % testsPerCol) * rowHeight)); + int i = 2*s; + canvas->translate(SkIntToScalar((i / testsPerCol) * colWidth), + SkIntToScalar((i % testsPerCol) * rowHeight)); paint.setShader(shaders[s])->unref(); canvas->drawText(text, textLen, 0, textBase, paint); canvas->restore(); + canvas->save(); + ++i; + canvas->translate(SkIntToScalar((i / testsPerCol) * colWidth), + SkIntToScalar((i % testsPerCol) * rowHeight)); + canvas->drawTextOnPath(text, textLen, path, NULL, paint); + canvas->restore(); } canvas->restore(); diff --git a/samplecode/SampleShaders.cpp b/samplecode/SampleShaders.cpp index c1bb0fd..99cd680 100644 --- a/samplecode/SampleShaders.cpp +++ b/samplecode/SampleShaders.cpp @@ -1,3 +1,10 @@ + +/* + * 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" diff --git a/samplecode/SampleShapes.cpp b/samplecode/SampleShapes.cpp index dc10f1a..5a5bb4c 100644 --- a/samplecode/SampleShapes.cpp +++ b/samplecode/SampleShapes.cpp @@ -1,3 +1,10 @@ + +/* + * 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 "SkCanvas.h" #include "SkPaint.h" @@ -127,16 +134,14 @@ protected: matrix.preScale(SK_Scalar1*2, SK_Scalar1*2); gs->appendShape(&fGroup, matrix); -#if 0 - canvas->drawShape(gs); -#else +#if 1 SkPicture* pict = new SkPicture; SkCanvas* cv = pict->beginRecording(1000, 1000); cv->scale(SK_ScalarHalf, SK_ScalarHalf); - cv->drawShape(gs); + gs->draw(cv); cv->translate(SkIntToScalar(680), SkIntToScalar(480)); cv->scale(-SK_Scalar1, SK_Scalar1); - cv->drawShape(gs); + gs->draw(cv); pict->endRecording(); drawpicture(canvas, *pict); diff --git a/samplecode/SampleSkLayer.cpp b/samplecode/SampleSkLayer.cpp index 11976e9..bff6034 100644 --- a/samplecode/SampleSkLayer.cpp +++ b/samplecode/SampleSkLayer.cpp @@ -1,3 +1,10 @@ + +/* + * 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 "SkCanvas.h" #include "SkPaint.h" diff --git a/samplecode/SampleSlides.cpp b/samplecode/SampleSlides.cpp index 3b7d05b..d39cee0 100644 --- a/samplecode/SampleSlides.cpp +++ b/samplecode/SampleSlides.cpp @@ -1,3 +1,10 @@ + +/* + * 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" @@ -87,23 +94,18 @@ static void discrete_pe(SkPaint* paint) { paint->setPathEffect(new SkDiscretePathEffect(10, 4))->unref(); } -class TilePathEffect : public Sk2DPathEffect { - static SkMatrix make_mat() { - SkMatrix m; - m.setScale(12, 12); - return m; - } -public: - TilePathEffect() : Sk2DPathEffect(make_mat()) {} +static SkPathEffect* MakeTileEffect() { + SkMatrix m; + m.setScale(SkIntToScalar(12), SkIntToScalar(12)); -protected: - virtual void next(const SkPoint& loc, int u, int v, SkPath* dst) { - dst->addCircle(loc.fX, loc.fY, 5); - } -}; + SkPath path; + path.addCircle(0, 0, SkIntToScalar(5)); + + return new SkPath2DPathEffect(m, path); +} static void tile_pe(SkPaint* paint) { - paint->setPathEffect(new TilePathEffect)->unref(); + paint->setPathEffect(MakeTileEffect())->unref(); } static const PE_Proc gPE2[] = { fill_pe, discrete_pe, tile_pe }; @@ -312,7 +314,6 @@ static void textonpath_slide(SkCanvas* canvas) { #include "SkOSFile.h" #include "SkRandom.h" #include "SkStream.h" -#include "SkNinePatch.h" static SkShader* make_shader0(SkIPoint* size) { SkBitmap bm; @@ -563,46 +564,18 @@ static void r6(SkLayerRasterizer* rast, SkPaint& p) #include "Sk2DPathEffect.h" -class Dot2DPathEffect : public Sk2DPathEffect { -public: - Dot2DPathEffect(SkScalar radius, const SkMatrix& matrix) - : Sk2DPathEffect(matrix), fRadius(radius) {} - - virtual void flatten(SkFlattenableWriteBuffer& buffer) - { - this->INHERITED::flatten(buffer); - - buffer.writeScalar(fRadius); - } - virtual Factory getFactory() { return CreateProc; } - -protected: - virtual void next(const SkPoint& loc, int u, int v, SkPath* dst) - { - dst->addCircle(loc.fX, loc.fY, fRadius); - } - - Dot2DPathEffect(SkFlattenableReadBuffer& buffer) : Sk2DPathEffect(buffer) - { - fRadius = buffer.readScalar(); - } -private: - SkScalar fRadius; - - static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) - { - return new Dot2DPathEffect(buffer); - } - - typedef Sk2DPathEffect INHERITED; -}; +static SkPathEffect* MakeDotEffect(SkScalar radius, const SkMatrix& matrix) { + SkPath path; + path.addCircle(0, 0, radius); + return new SkPath2DPathEffect(matrix, path); +} static void r7(SkLayerRasterizer* rast, SkPaint& p) { SkMatrix lattice; lattice.setScale(SK_Scalar1*6, SK_Scalar1*6, 0, 0); lattice.postSkew(SK_Scalar1/3, 0, 0, 0); - p.setPathEffect(new Dot2DPathEffect(SK_Scalar1*4, lattice))->unref(); + p.setPathEffect(MakeDotEffect(SK_Scalar1*4, lattice))->unref(); rast->addLayer(p); } @@ -613,7 +586,7 @@ static void r8(SkLayerRasterizer* rast, SkPaint& p) SkMatrix lattice; lattice.setScale(SK_Scalar1*6, SK_Scalar1*6, 0, 0); lattice.postSkew(SK_Scalar1/3, 0, 0, 0); - p.setPathEffect(new Dot2DPathEffect(SK_Scalar1*2, lattice))->unref(); + p.setPathEffect(MakeDotEffect(SK_Scalar1*2, lattice))->unref(); p.setXfermodeMode(SkXfermode::kClear_Mode); rast->addLayer(p); diff --git a/samplecode/SampleSpiral.cpp b/samplecode/SampleSpiral.cpp index 1a41440..89810fa 100644 --- a/samplecode/SampleSpiral.cpp +++ b/samplecode/SampleSpiral.cpp @@ -1,3 +1,10 @@ + +/* + * 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" diff --git a/samplecode/SampleStrokePath.cpp b/samplecode/SampleStrokePath.cpp index ae630ef..1fb5fea 100644 --- a/samplecode/SampleStrokePath.cpp +++ b/samplecode/SampleStrokePath.cpp @@ -1,3 +1,10 @@ + +/* + * 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 "SkCanvas.h" #include "SkParsePath.h" diff --git a/samplecode/SampleStrokeRect.cpp b/samplecode/SampleStrokeRect.cpp index 20c9e2c..e9d3c2e 100644 --- a/samplecode/SampleStrokeRect.cpp +++ b/samplecode/SampleStrokeRect.cpp @@ -1,3 +1,10 @@ + +/* + * 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" diff --git a/samplecode/SampleStrokeText.cpp b/samplecode/SampleStrokeText.cpp index bcb9e4f..f90dc55 100644 --- a/samplecode/SampleStrokeText.cpp +++ b/samplecode/SampleStrokeText.cpp @@ -1,3 +1,10 @@ + +/* + * 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" diff --git a/samplecode/SampleTests.cpp b/samplecode/SampleTests.cpp index 4ce8640..5542bf6 100644 --- a/samplecode/SampleTests.cpp +++ b/samplecode/SampleTests.cpp @@ -1,3 +1,10 @@ + +/* + * Copyright 2011 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ utils#include "SampleCode.h" #include "SkView.h" #include "SkCanvas.h" diff --git a/samplecode/SampleText.cpp b/samplecode/SampleText.cpp index 2676530..6a0eba8 100644 --- a/samplecode/SampleText.cpp +++ b/samplecode/SampleText.cpp @@ -1,3 +1,10 @@ + +/* + * 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" diff --git a/samplecode/SampleTextAlpha.cpp b/samplecode/SampleTextAlpha.cpp index ccfed68..09134c4 100644 --- a/samplecode/SampleTextAlpha.cpp +++ b/samplecode/SampleTextAlpha.cpp @@ -1,3 +1,10 @@ + +/* + * 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 "SkBlurMaskFilter.h" diff --git a/samplecode/SampleTextBox.cpp b/samplecode/SampleTextBox.cpp index 37a6be0..5f37380 100644 --- a/samplecode/SampleTextBox.cpp +++ b/samplecode/SampleTextBox.cpp @@ -1,7 +1,15 @@ + +/* + * 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 "SkBlurMaskFilter.h" #include "SkCanvas.h" +#include "SkColorShader.h" #include "SkGradientShader.h" #include "SkGraphics.h" #include "SkImageDecoder.h" @@ -20,6 +28,8 @@ #include "SkStream.h" #include "SkKey.h" +extern void skia_set_text_gamma(float blackGamma, float whiteGamma); + #ifdef SK_BUILD_FOR_WIN extern SkTypeface* SkCreateTypefaceFromLOGFONT(const LOGFONT&); #endif @@ -47,7 +57,7 @@ public: tf0->unref(); tf1->unref(); #endif - } + } protected: // overrides from SkEventSink @@ -60,17 +70,22 @@ protected: return this->INHERITED::onQuery(evt); } - virtual void onDrawContent(SkCanvas* canvas) { + void drawTest(SkCanvas* canvas, SkScalar w, SkScalar h, SkColor fg, SkColor bg) { + SkAutoCanvasRestore acr(canvas, true); + + canvas->clipRect(SkRect::MakeWH(w, h)); + canvas->drawColor(bg); SkScalar margin = 20; SkTextBox tbox; tbox.setMode(SkTextBox::kLineBreak_Mode); tbox.setBox(margin, margin, - this->width() - margin, this->height() - margin); + w - margin, h - margin); tbox.setSpacing(SkIntToScalar(3)/3, 0); SkPaint paint; paint.setAntiAlias(true); paint.setLCDRenderText(true); + paint.setColor(fg); tbox.setText(gText, strlen(gText), paint); for (int i = 9; i < 24; i += 2) { @@ -80,8 +95,19 @@ protected: } } + virtual void onDrawContent(SkCanvas* canvas) { + SkScalar width = this->width() / 3; + drawTest(canvas, width, this->height(), SK_ColorBLACK, SK_ColorWHITE); + canvas->translate(width, 0); + drawTest(canvas, width, this->height(), SK_ColorWHITE, SK_ColorBLACK); + canvas->translate(width, 0); + drawTest(canvas, width, this->height()/2, SK_ColorGRAY, SK_ColorWHITE); + canvas->translate(0, this->height()/2); + drawTest(canvas, width, this->height()/2, SK_ColorGRAY, SK_ColorBLACK); + } + private: - typedef SkView INHERITED; + typedef SampleView INHERITED; }; ////////////////////////////////////////////////////////////////////////////// diff --git a/samplecode/SampleTextEffects.cpp b/samplecode/SampleTextEffects.cpp index f256b2e..6eadffd 100644 --- a/samplecode/SampleTextEffects.cpp +++ b/samplecode/SampleTextEffects.cpp @@ -1,3 +1,10 @@ + +/* + * 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" @@ -138,41 +145,17 @@ static void r6(SkLayerRasterizer* rast, SkPaint& p) { #include "Sk2DPathEffect.h" -class Dot2DPathEffect : public Sk2DPathEffect { -public: - Dot2DPathEffect(SkScalar radius, const SkMatrix& matrix) - : Sk2DPathEffect(matrix), fRadius(radius) {} - - virtual void flatten(SkFlattenableWriteBuffer& buffer) { - this->INHERITED::flatten(buffer); - - buffer.writeScalar(fRadius); - } - virtual Factory getFactory() { return CreateProc; } - -protected: - virtual void next(const SkPoint& loc, int u, int v, SkPath* dst) { - dst->addCircle(loc.fX, loc.fY, fRadius); - } - - Dot2DPathEffect(SkFlattenableReadBuffer& buffer) : Sk2DPathEffect(buffer) { - fRadius = buffer.readScalar(); - } -private: - SkScalar fRadius; - - static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) { - return new Dot2DPathEffect(buffer); - } - - typedef Sk2DPathEffect INHERITED; -}; +static SkPathEffect* MakeDotEffect(SkScalar radius, const SkMatrix& matrix) { + SkPath path; + path.addCircle(0, 0, radius); + return new SkPath2DPathEffect(matrix, path); +} static void r7(SkLayerRasterizer* rast, SkPaint& p) { SkMatrix lattice; lattice.setScale(SK_Scalar1*6, SK_Scalar1*6, 0, 0); lattice.postSkew(SK_Scalar1/3, 0, 0, 0); - p.setPathEffect(new Dot2DPathEffect(SK_Scalar1*4, lattice))->unref(); + p.setPathEffect(MakeDotEffect(SK_Scalar1*4, lattice))->unref(); rast->addLayer(p); } @@ -182,7 +165,7 @@ static void r8(SkLayerRasterizer* rast, SkPaint& p) { SkMatrix lattice; lattice.setScale(SK_Scalar1*6, SK_Scalar1*6, 0, 0); lattice.postSkew(SK_Scalar1/3, 0, 0, 0); - p.setPathEffect(new Dot2DPathEffect(SK_Scalar1*2, lattice))->unref(); + p.setPathEffect(MakeDotEffect(SK_Scalar1*2, lattice))->unref(); p.setXfermodeMode(SkXfermode::kClear_Mode); rast->addLayer(p); diff --git a/samplecode/SampleTextOnPath.cpp b/samplecode/SampleTextOnPath.cpp index 96e8c9a..f3c98f8 100644 --- a/samplecode/SampleTextOnPath.cpp +++ b/samplecode/SampleTextOnPath.cpp @@ -1,3 +1,10 @@ + +/* + * 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" diff --git a/samplecode/SampleTextureDomain.cpp b/samplecode/SampleTextureDomain.cpp index be000f9..4291468 100755 --- a/samplecode/SampleTextureDomain.cpp +++ b/samplecode/SampleTextureDomain.cpp @@ -1,6 +1,14 @@ + +/* + * 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 "SkCanvas.h" #include "SkDevice.h" +#include "SkBlurMaskFilter.h" namespace { SkBitmap make_bitmap() { @@ -31,7 +39,7 @@ protected: // overrides from SkEventSink virtual bool onQuery(SkEvent* evt) { if (SampleCode::TitleQ(*evt)) { - SampleCode::TitleR(evt, "Texture Domian"); + SampleCode::TitleR(evt, "Texture Domain"); return true; } return this->INHERITED::onQuery(evt); @@ -54,8 +62,8 @@ protected: // Note: GPU-backed bitmaps follow a different rendering path // when copying from one GPU device to another. SkRefPtr<SkDevice> primaryDevice(canvas->getDevice()); - SkRefPtr<SkDevice> secondDevice(canvas->createDevice( - SkBitmap::kARGB_8888_Config, 5, 5, true, true)); + SkRefPtr<SkDevice> secondDevice(canvas->createCompatibleDevice( + SkBitmap::kARGB_8888_Config, 5, 5, true)); secondDevice->unref(); SkCanvas secondCanvas(secondDevice.get()); @@ -68,6 +76,34 @@ protected: srcRect.setXYWH(1, 1, 3, 3); dstRect.setXYWH(405.0f, 5.0f, 305.0f, 305.0f); canvas->drawBitmapRect(deviceBitmap, &srcRect, dstRect, &paint); + + // Test that bitmap blurring using a subrect + // renders correctly + srcRect.setXYWH(1, 1, 3, 3); + dstRect.setXYWH(5.0f, 405.0f, 305.0f, 305.0f); + SkMaskFilter* mf = SkBlurMaskFilter::Create( + 5, + SkBlurMaskFilter::kNormal_BlurStyle, + SkBlurMaskFilter::kHighQuality_BlurFlag | + SkBlurMaskFilter::kIgnoreTransform_BlurFlag); + paint.setMaskFilter(mf)->unref(); + canvas->drawBitmapRect(deviceBitmap, &srcRect, dstRect, &paint); + + // Blur and a rotation + NULL src rect + // This should not trigger the texture domain code + // but it will test a code path in SkGpuDevice::drawBitmap + // that handles blurs with rects transformed to non- + // orthogonal rects. It also tests the NULL src rect handling + mf = SkBlurMaskFilter::Create( + 5, + SkBlurMaskFilter::kNormal_BlurStyle, + SkBlurMaskFilter::kHighQuality_BlurFlag); + paint.setMaskFilter(mf)->unref(); + + dstRect.setXYWH(-150.0f, -150.0f, 300.0f, 300.0f); + canvas->translate(550, 550); + canvas->rotate(45); + canvas->drawBitmapRect(fBM, NULL, dstRect, &paint); } private: typedef SkView INHERITED; diff --git a/samplecode/SampleTiling.cpp b/samplecode/SampleTiling.cpp index 4752ed1..d72544b 100644 --- a/samplecode/SampleTiling.cpp +++ b/samplecode/SampleTiling.cpp @@ -1,3 +1,10 @@ + +/* + * 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" @@ -56,17 +63,22 @@ static const int gWidth = 32; static const int gHeight = 32; class TilingView : public SampleView { - SkPicture fTextPicture; + SkPicture* fTextPicture; SkBlurDrawLooper fLooper; public: TilingView() : fLooper(SkIntToScalar(1), SkIntToScalar(2), SkIntToScalar(2), 0x88000000) { + fTextPicture = new SkPicture(); for (size_t i = 0; i < SK_ARRAY_COUNT(gConfigs); i++) { makebm(&fTexture[i], gConfigs[i], gWidth, gHeight); } } + ~TilingView() { + fTextPicture->unref(); + } + SkBitmap fTexture[SK_ARRAY_COUNT(gConfigs)]; protected: @@ -94,8 +106,8 @@ protected: SkScalar x = SkIntToScalar(10); SkCanvas* textCanvas = NULL; - if (fTextPicture.width() == 0) { - textCanvas = fTextPicture.beginRecording(1000, 1000); + if (fTextPicture->width() == 0) { + textCanvas = fTextPicture->beginRecording(1000, 1000); } if (textCanvas) { @@ -148,7 +160,7 @@ protected: } } - canvas->drawPicture(fTextPicture); + canvas->drawPicture(*fTextPicture); } private: diff --git a/samplecode/SampleTinyBitmap.cpp b/samplecode/SampleTinyBitmap.cpp index 0841474..605d829 100644 --- a/samplecode/SampleTinyBitmap.cpp +++ b/samplecode/SampleTinyBitmap.cpp @@ -1,3 +1,10 @@ + +/* + * 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 "SkColorPriv.h" #include "SkShader.h" diff --git a/samplecode/SampleTriangles.cpp b/samplecode/SampleTriangles.cpp index be9da8f..e2ba652 100644 --- a/samplecode/SampleTriangles.cpp +++ b/samplecode/SampleTriangles.cpp @@ -1,3 +1,10 @@ + +/* + * 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" diff --git a/samplecode/SampleTypeface.cpp b/samplecode/SampleTypeface.cpp index 63f1d5a..ccdb086 100644 --- a/samplecode/SampleTypeface.cpp +++ b/samplecode/SampleTypeface.cpp @@ -1,3 +1,10 @@ + +/* + * 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" diff --git a/samplecode/SampleUnitMapper.cpp b/samplecode/SampleUnitMapper.cpp index b20aece..d323ecb 100644 --- a/samplecode/SampleUnitMapper.cpp +++ b/samplecode/SampleUnitMapper.cpp @@ -1,3 +1,10 @@ + +/* + * 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" diff --git a/samplecode/SampleVertices.cpp b/samplecode/SampleVertices.cpp index 74e757f..b59442d 100644 --- a/samplecode/SampleVertices.cpp +++ b/samplecode/SampleVertices.cpp @@ -1,3 +1,10 @@ + +/* + * 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" @@ -17,7 +24,6 @@ #include "SkOSFile.h" #include "SkStream.h" -#include "SkNinePatch.h" static SkShader* make_shader0(SkIPoint* size) { SkBitmap bm; diff --git a/samplecode/SampleWarp.cpp b/samplecode/SampleWarp.cpp index bf4ef0d..b421c60 100644 --- a/samplecode/SampleWarp.cpp +++ b/samplecode/SampleWarp.cpp @@ -1,3 +1,10 @@ + +/* + * 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" diff --git a/samplecode/SampleWritePixels.cpp b/samplecode/SampleWritePixels.cpp new file mode 100644 index 0000000..45e9f41 --- /dev/null +++ b/samplecode/SampleWritePixels.cpp @@ -0,0 +1,70 @@ + +/* + * 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 "SkCornerPathEffect.h" +#include "SkCullPoints.h" +#include "SkGradientShader.h" +#include "SkPath.h" +#include "SkRegion.h" +#include "SkShader.h" +#include "SkUtils.h" + +static void create_bitmap(SkBitmap* bitmap) { + const int W = 100; + const int H = 100; + bitmap->setConfig(SkBitmap::kARGB_8888_Config, W, H); + bitmap->allocPixels(); + + SkCanvas canvas(*bitmap); + canvas.drawColor(SK_ColorRED); + SkPaint paint; + paint.setColor(SK_ColorBLUE); + canvas.drawCircle(SkIntToScalar(W)/2, SkIntToScalar(H)/2, SkIntToScalar(W)/2, paint); +} + +class WritePixelsView : public SampleView { + SkPath fPath; +public: + WritePixelsView() {} + +protected: + // overrides from SkEventSink + virtual bool onQuery(SkEvent* evt) { + if (SampleCode::TitleQ(*evt)) { + SampleCode::TitleR(evt, "WritePixels"); + return true; + } + return this->INHERITED::onQuery(evt); + } + + virtual void onDrawContent(SkCanvas* canvas) { + SkBitmap bitmap; + create_bitmap(&bitmap); + int x = bitmap.width() / 2; + int y = bitmap.height() / 2; + + SkBitmap subset; + bitmap.extractSubset(&subset, SkIRect::MakeXYWH(x, y, x, y)); + + canvas->translate(SkIntToScalar(20), SkIntToScalar(20)); + + canvas->writePixels(bitmap, 0, 0); + canvas->writePixels(subset, 0, 0); + } + +private: + typedef SampleView INHERITED; +}; + +////////////////////////////////////////////////////////////////////////////// + +static SkView* MyFactory() { return new WritePixelsView; } +static SkViewRegister reg(MyFactory); + diff --git a/samplecode/SampleXfermodes.cpp b/samplecode/SampleXfermodes.cpp index 0a3c4c7..ffea954 100644 --- a/samplecode/SampleXfermodes.cpp +++ b/samplecode/SampleXfermodes.cpp @@ -1,3 +1,10 @@ + +/* + * 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" diff --git a/samplecode/SampleXfermodesBlur.cpp b/samplecode/SampleXfermodesBlur.cpp index 166e4e5..11b1268 100644 --- a/samplecode/SampleXfermodesBlur.cpp +++ b/samplecode/SampleXfermodesBlur.cpp @@ -1,3 +1,10 @@ + +/* + * 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" @@ -24,6 +31,11 @@ #include "SkImageDecoder.h" #include "SkBlurMaskFilter.h" +#ifdef SK_BUILD_FOR_MAC +#import <ApplicationServices/ApplicationServices.h> +SkTypeface* SkCreateTypefaceFromCTFont(CTFontRef fontRef); +#endif + static void setNamedTypeface(SkPaint* paint, const char name[]) { SkTypeface* face = SkTypeface::CreateFromName(name, SkTypeface::kNormal); paint->setTypeface(face); @@ -61,12 +73,32 @@ class XfermodesBlurView : public SampleView { r.set(ww/3, hh/3, ww*19/20, hh*19/20); r.offset(x, y); canvas->drawRect(r, p); + +#ifdef SK_BUILD_FOR_MAC + static const char* gNames[] = { "Arial", "Times", "Courier", "Lucida" }; + for (int j = 0; j < SK_ARRAY_COUNT(gNames); ++j) { + CFStringRef name = CFStringCreateWithCString(NULL, gNames[j], kCFStringEncodingUTF8); + CTFontRef font = CTFontCreateWithName(name, 0, NULL); + SkTypeface* face = SkCreateTypefaceFromCTFont(font); + SkDebugf("%s ct:%p face:%p ats:%p\n", gNames[j], font, face, CTFontGetPlatformFont(font, NULL)); + for (int i = 9; i <= 24; ++i) { + CTFontRef newFont = CTFontCreateCopyWithAttributes(font, i, NULL, NULL); + SkTypeface* newFace = SkCreateTypefaceFromCTFont(newFont); + SkDebugf("size:%d ct:%p face:%p ats:%p\n", i, newFont, newFace, CTFontGetPlatformFont(newFont, NULL)); + newFace->unref(); + CFRelease(newFont); + } + face->unref(); + CFRelease(font); + CFRelease(name); + } +#endif } public: const static int W = 64; const static int H = 64; - XfermodesBlurView() { + XfermodesBlurView() { const int W = 64; const int H = 64; @@ -88,6 +120,30 @@ protected: virtual void onDrawContent(SkCanvas* canvas) { canvas->translate(SkIntToScalar(10), SkIntToScalar(20)); + if (false) { + SkPaint paint; + paint.setAntiAlias(true); + paint.setTextSize(50); + paint.setTypeface(SkTypeface::CreateFromName("Arial Unicode MS", SkTypeface::kNormal)); + SkSafeUnref(paint.getTypeface()); + char buffer[10]; + size_t len = SkUTF8_FromUnichar(0x8500, buffer); + canvas->drawText(buffer, len, 40, 40, paint); + return; + } + if (false) { + SkPaint paint; + paint.setAntiAlias(true); + + SkRect r0 = { 0, 0, 10.5f, 20 }; + SkRect r1 = { 10.5f, 10, 20, 30 }; + paint.setColor(SK_ColorRED); + canvas->drawRect(r0, paint); + paint.setColor(SK_ColorBLUE); + canvas->drawRect(r1, paint); + return; + } + const struct { SkXfermode::Mode fMode; const char* fLabel; diff --git a/samplecode/TransitionView.cpp b/samplecode/TransitionView.cpp new file mode 100644 index 0000000..99d1275 --- /dev/null +++ b/samplecode/TransitionView.cpp @@ -0,0 +1,186 @@ +/* + * 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 "SkTime.h" +#include "SkInterpolator.h" + +extern bool is_overview(SkView* view); + +static const char gIsTransitionQuery[] = "is-transition"; +static const char gReplaceTransitionEvt[] = "replace-transition-view"; + +bool is_transition(SkView* view) { + SkEvent isTransition(gIsTransitionQuery); + return view->doQuery(&isTransition); +} + +class TransitionView : public SampleView { +public: + TransitionView(SkView* prev, SkView* next, int direction) : fInterp(4, 2){ + fAnimationDirection = (Direction)(1 << (direction % 8)); + + fPrev = prev; + fPrev->setClipToBounds(false); + fPrev->setVisibleP(true); + (void)SampleView::SetUsePipe(fPrev, false); + //Not calling unref because fPrev is assumed to have been created, so + //this will result in a transfer of ownership + this->attachChildToBack(fPrev); + + fNext = next; + fNext->setClipToBounds(true); + fNext->setVisibleP(true); + (void)SampleView::SetUsePipe(fNext, false); + //Calling unref because next is a newly created view and TransitionView + //is now the sole owner of fNext + this->attachChildToFront(fNext)->unref(); + + fDone = false; + //SkDebugf("--created transition\n"); + } + + ~TransitionView(){ + //SkDebugf("--deleted transition\n"); + } + + virtual void requestMenu(SkOSMenu* menu) { + if (SampleView::IsSampleView(fNext)) + ((SampleView*)fNext)->requestMenu(menu); + } + +protected: + virtual bool onQuery(SkEvent* evt) { + if (SampleCode::TitleQ(*evt)) { + SkString title; + if (SampleCode::RequestTitle(fNext, &title)) { + SampleCode::TitleR(evt, title.c_str()); + return true; + } + return false; + } + if (evt->isType(gIsTransitionQuery)) { + return true; + } + return this->INHERITED::onQuery(evt); + } + virtual bool onEvent(const SkEvent& evt) { + if (evt.isType(gReplaceTransitionEvt)) { + fPrev->detachFromParent(); + fPrev = (SkView*)SkEventSink::FindSink(evt.getFast32()); + (void)SampleView::SetUsePipe(fPrev, false); + //attach the new fPrev and call unref to balance the ref in onDraw + this->attachChildToBack(fPrev)->unref(); + this->inval(NULL); + return true; + } + if (evt.isType("transition-done")) { + fNext->setLoc(0, 0); + fNext->setClipToBounds(false); + SkEvent* evt = new SkEvent(gReplaceTransitionEvt, + this->getParent()->getSinkID()); + evt->setFast32(fNext->getSinkID()); + //increate ref count of fNext so it survives detachAllChildren + fNext->ref(); + this->detachAllChildren(); + evt->post(); + return true; + } + return this->INHERITED::onEvent(evt); + } + virtual void onDrawBackground(SkCanvas* canvas) {} + virtual void onDrawContent(SkCanvas* canvas) { + if (fDone) + return; + + if (is_overview(fNext) || is_overview(fPrev)) { + fUsePipe = false; + } + + SkScalar values[4]; + SkInterpolator::Result result = fInterp.timeToValues(SkTime::GetMSecs(), values); + //SkDebugf("transition %x %d pipe:%d\n", this, result, fUsePipe); + //SkDebugf("%f %f %f %f %d\n", values[0], values[1], values[2], values[3], result); + if (SkInterpolator::kNormal_Result == result) { + fPrev->setLocX(values[kPrevX]); + fPrev->setLocY(values[kPrevY]); + fNext->setLocX(values[kNextX]); + fNext->setLocY(values[kNextY]); + this->inval(NULL); + } + else { + (new SkEvent("transition-done", this->getSinkID()))->post(); + fDone = true; + } + } + + virtual void onSizeChange() { + this->INHERITED::onSizeChange(); + + fNext->setSize(this->width(), this->height()); + fPrev->setSize(this->width(), this->height()); + + SkScalar lr = 0, ud = 0; + if (fAnimationDirection & (kLeftDirection|kULDirection|kDLDirection)) + lr = this->width(); + if (fAnimationDirection & (kRightDirection|kURDirection|kDRDirection)) + lr = -this->width(); + if (fAnimationDirection & (kUpDirection|kULDirection|kURDirection)) + ud = this->height(); + if (fAnimationDirection & (kDownDirection|kDLDirection|kDRDirection)) + ud = -this->height(); + + fBegin[kPrevX] = fBegin[kPrevY] = 0; + fBegin[kNextX] = lr; + fBegin[kNextY] = ud; + fNext->setLocX(lr); + fNext->setLocY(ud); + + if (is_transition(fPrev)) + lr = ud = 0; + fEnd[kPrevX] = -lr; + fEnd[kPrevY] = -ud; + fEnd[kNextX] = fEnd[kNextY] = 0; + SkScalar blend[] = {0.8, 0.0, 0.0, 1.0}; + fInterp.setKeyFrame(0, SkTime::GetMSecs(), fBegin, blend); + fInterp.setKeyFrame(1, SkTime::GetMSecs()+500, fEnd, blend); + } + +private: + enum { + kPrevX = 0, + kPrevY = 1, + kNextX = 2, + kNextY = 3 + }; + SkView* fPrev; + SkView* fNext; + bool fDone; + SkInterpolator fInterp; + + enum Direction{ + kUpDirection = 1, + kURDirection = 1 << 1, + kRightDirection = 1 << 2, + kDRDirection = 1 << 3, + kDownDirection = 1 << 4, + kDLDirection = 1 << 5, + kLeftDirection = 1 << 6, + kULDirection = 1 << 7 + }; + + Direction fAnimationDirection; + SkScalar fBegin[4]; + SkScalar fEnd[4]; + + typedef SampleView INHERITED; +}; + +SkView* create_transition(SkView* prev, SkView* next, int direction) { + return SkNEW_ARGS(TransitionView, (prev, next, direction)); +};
\ No newline at end of file diff --git a/samplecode/samplecode_files.mk b/samplecode/samplecode_files.mk index 4c660e5..cb757de 100644 --- a/samplecode/samplecode_files.mk +++ b/samplecode/samplecode_files.mk @@ -56,8 +56,6 @@ SOURCE := \ OverView.cpp \ SampleFuzz.cpp \ SampleShaders.cpp \ - SampleText.cpp \ - SampleTextBox.cpp \ SampleImage.cpp \ SampleMovie.cpp \ SampleImageDir.cpp \ diff --git a/samplecode/vertexdump.cpp b/samplecode/vertexdump.cpp index c124ad8..ae310a5 100644 --- a/samplecode/vertexdump.cpp +++ b/samplecode/vertexdump.cpp @@ -1,3 +1,10 @@ + +/* + * 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 "SkPoint.h" void setup_vertexbug(SkPoint verts[], SkPoint texs[], uint16_t index[]); |