summaryrefslogtreecommitdiffstats
path: root/chromium/third_party/skia/samplecode/SampleDraw.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/skia/samplecode/SampleDraw.cpp')
-rw-r--r--chromium/third_party/skia/samplecode/SampleDraw.cpp379
1 files changed, 379 insertions, 0 deletions
diff --git a/chromium/third_party/skia/samplecode/SampleDraw.cpp b/chromium/third_party/skia/samplecode/SampleDraw.cpp
new file mode 100644
index 00000000000..616650f9ef9
--- /dev/null
+++ b/chromium/third_party/skia/samplecode/SampleDraw.cpp
@@ -0,0 +1,379 @@
+
+/*
+ * 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 "SkGraphics.h"
+#include "SkRandom.h"
+
+static void test_clearonlayers(SkCanvas* canvas) {
+ SkCanvas& c = *canvas;
+
+ SkPaint paint;
+ paint.setColor(SK_ColorBLUE);
+ paint.setStyle(SkPaint::kStrokeAndFill_Style);
+ SkRect rect = SkRect::MakeXYWH(25, 25, 50, 50);
+ c.drawRect(rect, paint);
+
+ c.clipRect(rect);
+
+ c.saveLayer(NULL, NULL);
+ rect = SkRect::MakeXYWH(50, 10, 40, 80);
+ c.clipRect(rect, SkRegion::kUnion_Op);
+
+ rect = SkRect::MakeXYWH(50, 0, 50, 100);
+ // You might draw something here, but it's not necessary.
+ // paint.setColor(SK_ColorRED);
+ // c.drawRect(rect, paint);
+ paint.setXfermodeMode(SkXfermode::kClear_Mode);
+ c.drawRect(rect, paint);
+ c.restore();
+}
+
+static void test_strokerect(SkCanvas* canvas, const SkRect& r) {
+ SkPaint p;
+
+ p.setAntiAlias(true);
+ p.setStyle(SkPaint::kStroke_Style);
+ p.setStrokeWidth(4);
+
+ canvas->drawRect(r, p);
+
+ SkPath path;
+ SkRect r2(r);
+ r2.offset(18, 0);
+ path.addRect(r2);
+
+ canvas->drawPath(path, p);
+}
+
+static void test_strokerect(SkCanvas* canvas) {
+ canvas->drawColor(SK_ColorWHITE);
+
+ SkRect r;
+
+ r.set(10, 10, 14, 14);
+ r.offset(0.25f, 0.3333f);
+ test_strokerect(canvas, r);
+ canvas->translate(0, 20);
+
+ r.set(10, 10, 14.5f, 14.5f);
+ r.offset(0.25f, 0.3333f);
+ test_strokerect(canvas, r);
+ canvas->translate(0, 20);
+
+ r.set(10, 10, 14.5f, 20);
+ r.offset(0.25f, 0.3333f);
+ test_strokerect(canvas, r);
+ canvas->translate(0, 20);
+
+ r.set(10, 10, 20, 14.5f);
+ r.offset(0.25f, 0.3333f);
+ test_strokerect(canvas, r);
+ canvas->translate(0, 20);
+
+ r.set(10, 10, 20, 20);
+ r.offset(0.25f, 0.3333f);
+ test_strokerect(canvas, r);
+ canvas->translate(0, 20);
+
+}
+
+class Draw : public SkRefCnt {
+public:
+ Draw() : fFlags(0) {}
+
+ enum Flags {
+ kSelected_Flag = 1 << 0
+ };
+ int getFlags() const { return fFlags; }
+ void setFlags(int flags);
+
+ bool isSelected() const { return SkToBool(fFlags & kSelected_Flag); }
+ void setSelected(bool pred) {
+ if (pred) {
+ fFlags |= kSelected_Flag;
+ } else {
+ fFlags &= ~kSelected_Flag;
+ }
+ }
+
+ void draw(SkCanvas* canvas) {
+ int sc = canvas->save();
+ this->onDraw(canvas);
+ canvas->restoreToCount(sc);
+
+ if (this->isSelected()) {
+ this->drawSelection(canvas);
+ }
+ }
+
+ void drawSelection(SkCanvas* canvas) {
+ int sc = canvas->save();
+ this->onDrawSelection(canvas);
+ canvas->restoreToCount(sc);
+ }
+
+ void getBounds(SkRect* bounds) {
+ this->onGetBounds(bounds);
+ }
+
+ bool hitTest(SkScalar x, SkScalar y) {
+ return this->onHitTest(x, y);
+ }
+
+ void offset(SkScalar dx, SkScalar dy) {
+ if (dx || dy) {
+ this->onOffset(dx, dy);
+ }
+ }
+
+protected:
+ virtual void onDraw(SkCanvas*) = 0;
+ virtual void onGetBounds(SkRect*) = 0;
+ virtual void onOffset(SkScalar dx, SkScalar dy) = 0;
+ virtual void onDrawSelection(SkCanvas* canvas) {
+ SkRect r;
+ this->getBounds(&r);
+ SkPaint paint;
+ SkPoint pts[4];
+ r.toQuad(pts);
+ paint.setStrokeWidth(SkIntToScalar(10));
+ paint.setColor(0x80FF8844);
+ paint.setStrokeCap(SkPaint::kRound_Cap);
+ canvas->drawPoints(SkCanvas::kPoints_PointMode, 4, pts, paint);
+ }
+ virtual bool onHitTest(SkScalar x, SkScalar y) {
+ SkRect bounds;
+ this->getBounds(&bounds);
+ return bounds.contains(x, y);
+ }
+
+private:
+ int fFlags;
+};
+
+class RDraw : public Draw {
+public:
+ enum Style {
+ kRect_Style,
+ kOval_Style,
+ kRRect_Style,
+ kFrame_Style
+ };
+
+ RDraw(const SkRect& r, Style s) : fRect(r), fStyle(s) {}
+
+ void setRect(const SkRect& r) {
+ fRect = r;
+ }
+
+ void setPaint(const SkPaint& p) {
+ fPaint = p;
+ }
+
+protected:
+ virtual void onDraw(SkCanvas* canvas) {
+ switch (fStyle) {
+ case kRect_Style:
+ canvas->drawRect(fRect, fPaint);
+ break;
+ case kOval_Style:
+ canvas->drawOval(fRect, fPaint);
+ break;
+ case kRRect_Style: {
+ SkScalar rx = fRect.width() / 5;
+ SkScalar ry = fRect.height() / 5;
+ if (rx < ry) {
+ ry = rx;
+ } else {
+ rx = ry;
+ }
+ canvas->drawRoundRect(fRect, rx, ry, fPaint);
+ break;
+ }
+ case kFrame_Style: {
+ SkPath path;
+ path.addOval(fRect, SkPath::kCW_Direction);
+ SkRect r = fRect;
+ r.inset(fRect.width()/6, 0);
+ path.addOval(r, SkPath::kCCW_Direction);
+ canvas->drawPath(path, fPaint);
+ break;
+ }
+ }
+ }
+
+ virtual void onGetBounds(SkRect* bounds) {
+ *bounds = fRect;
+ }
+
+ virtual void onOffset(SkScalar dx, SkScalar dy) {
+ fRect.offset(dx, dy);
+ }
+
+private:
+ SkRect fRect;
+ SkPaint fPaint;
+ Style fStyle;
+};
+
+class DrawFactory {
+public:
+ DrawFactory() {
+ fPaint.setAntiAlias(true);
+ }
+
+ const SkPaint& getPaint() const { return fPaint; }
+
+ void setPaint(const SkPaint& p) {
+ fPaint = p;
+ }
+
+ virtual Draw* create(const SkPoint&, const SkPoint&) = 0;
+
+private:
+ SkPaint fPaint;
+};
+
+class RectFactory : public DrawFactory {
+public:
+ virtual Draw* create(const SkPoint& p0, const SkPoint& p1) {
+ SkRect r;
+ r.set(p0.x(), p0.y(), p1.x(), p1.y());
+ r.sort();
+
+// RDraw* d = new RDraw(r, RDraw::kRRect_Style);
+ RDraw* d = new RDraw(r, RDraw::kFrame_Style);
+ d->setPaint(this->getPaint());
+ return d;
+ }
+};
+
+class DrawView : public SkView {
+ Draw* fDraw;
+ DrawFactory* fFactory;
+ SkRandom fRand;
+ SkTDArray<Draw*> fList;
+
+public:
+ DrawView() : fDraw(NULL) {
+ fFactory = new RectFactory;
+ }
+
+ virtual ~DrawView() {
+ fList.unrefAll();
+ SkSafeUnref(fDraw);
+ delete fFactory;
+ }
+
+ Draw* setDraw(Draw* d) {
+ SkRefCnt_SafeAssign(fDraw, d);
+ return d;
+ }
+
+ SkColor randColor() {
+ return (SkColor)fRand.nextU() | 0xFF000000;
+ }
+
+ Draw* hitTestList(SkScalar x, SkScalar y) const {
+ Draw** first = fList.begin();
+ for (Draw** iter = fList.end(); iter > first;) {
+ --iter;
+ if ((*iter)->hitTest(x, y)) {
+ return *iter;
+ }
+ }
+ return NULL;
+ }
+
+protected:
+ // overrides from SkEventSink
+ virtual bool onQuery(SkEvent* evt) {
+ if (SampleCode::TitleQ(*evt)) {
+ SampleCode::TitleR(evt, "Draw");
+ return true;
+ }
+ return this->INHERITED::onQuery(evt);
+ }
+
+ void drawBG(SkCanvas* canvas) {
+ canvas->drawColor(0xFFDDDDDD);
+// canvas->drawColor(SK_ColorWHITE);
+ }
+
+ virtual void onDraw(SkCanvas* canvas) {
+ this->drawBG(canvas);
+ test_clearonlayers(canvas); return;
+ // test_strokerect(canvas); return;
+
+ for (Draw** iter = fList.begin(); iter < fList.end(); iter++) {
+ (*iter)->draw(canvas);
+ }
+ if (fDraw) {
+ fDraw->draw(canvas);
+ }
+ }
+
+ virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y) {
+ for (Draw** iter = fList.begin(); iter < fList.end(); iter++) {
+ (*iter)->setSelected(false);
+ }
+
+ Click* c = new Click(this);
+ Draw* d = this->hitTestList(x, y);
+ if (d) {
+ d->setSelected(true);
+ c->setType("dragger");
+ } else {
+ c->setType("maker");
+ }
+ return c;
+ }
+
+ virtual bool onClick(Click* click) {
+ if (Click::kUp_State == click->fState) {
+ if (click->isType("maker")) {
+ if (SkPoint::Distance(click->fOrig, click->fCurr) > SkIntToScalar(3)) {
+ *fList.append() = fDraw;
+ } else {
+ fDraw->unref();
+ }
+ fDraw = NULL;
+ }
+ return true;
+ }
+
+ if (Click::kDown_State == click->fState) {
+ SkPaint p = fFactory->getPaint();
+ p.setColor(this->randColor());
+ fFactory->setPaint(p);
+ }
+
+ if (click->isType("maker")) {
+ this->setDraw(fFactory->create(click->fOrig, click->fCurr))->unref();
+ } else if (click->isType("dragger")) {
+ for (Draw** iter = fList.begin(); iter < fList.end(); iter++) {
+ if ((*iter)->isSelected()) {
+ (*iter)->offset(click->fCurr.x() - click->fPrev.x(),
+ click->fCurr.y() - click->fPrev.y());
+ }
+ }
+ }
+ this->inval(NULL);
+ return true;
+ }
+
+private:
+ typedef SkView INHERITED;
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
+static SkView* MyFactory() { return new DrawView; }
+static SkViewRegister reg(MyFactory);