11ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com/*
21ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com * Copyright 2011 Google Inc.
31ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com *
41ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com * Use of this source code is governed by a BSD-style license that can be
51ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com * found in the LICENSE file.
61ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com */
71ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com
81ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com#include "SampleCode.h"
91ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com#include "SkView.h"
101ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com#include "SkCanvas.h"
111ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com#include "SkDevice.h"
121ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com#include "SkColorPriv.h"
131ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com#include "SkShader.h"
141ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com
151ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.comstatic const struct {
161ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com    SkXfermode::Mode  fMode;
171ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com    const char*         fLabel;
181ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com} gModes[] = {
191ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com    { SkXfermode::kClear_Mode,    "Clear"     },
201ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com    { SkXfermode::kSrc_Mode,      "Src"       },
211ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com    { SkXfermode::kDst_Mode,      "Dst"       },
221ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com    { SkXfermode::kSrcOver_Mode,  "SrcOver"   },
231ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com    { SkXfermode::kDstOver_Mode,  "DstOver"   },
241ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com    { SkXfermode::kSrcIn_Mode,    "SrcIn"     },
251ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com    { SkXfermode::kDstIn_Mode,    "DstIn"     },
261ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com    { SkXfermode::kSrcOut_Mode,   "SrcOut"    },
271ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com    { SkXfermode::kDstOut_Mode,   "DstOut"    },
281ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com    { SkXfermode::kSrcATop_Mode,  "SrcATop"   },
291ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com    { SkXfermode::kDstATop_Mode,  "DstATop"   },
301ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com    { SkXfermode::kXor_Mode,      "Xor"       },
311ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com};
321ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com
331ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.comconst int gWidth = 64;
341ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.comconst int gHeight = 64;
351ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.comconst SkScalar W = SkIntToScalar(gWidth);
361ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.comconst SkScalar H = SkIntToScalar(gHeight);
371ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com
381ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.comstatic SkScalar drawCell(SkCanvas* canvas, SkXfermode* mode, SkAlpha a0, SkAlpha a1) {
391ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com
401ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com    SkPaint paint;
411ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com    paint.setAntiAlias(true);
421ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com
431ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com    SkRect r = SkRect::MakeWH(W, H);
441ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com    r.inset(W/10, H/10);
451ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com
461ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com    paint.setColor(SK_ColorBLUE);
471ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com    paint.setAlpha(a0);
481ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com    canvas->drawOval(r, paint);
491ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com
501ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com    paint.setColor(SK_ColorRED);
511ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com    paint.setAlpha(a1);
521ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com    paint.setXfermode(mode);
531ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com    for (int angle = 0; angle < 24; ++angle) {
541ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com        SkScalar x = SkScalarCos(SkIntToScalar(angle) * (SK_ScalarPI * 2) / 24) * gWidth;
551ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com        SkScalar y = SkScalarSin(SkIntToScalar(angle) * (SK_ScalarPI * 2) / 24) * gHeight;
561ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com        paint.setStrokeWidth(SK_Scalar1 * angle * 2 / 24);
571ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com        canvas->drawLine(W/2, H/2, W/2 + x, H/2 + y, paint);
581ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com    }
59ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
601ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com    return H;
611ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com}
621ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com
631ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.comstatic SkShader* make_bg_shader() {
641ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com    SkBitmap bm;
65a8c183125f2861067daf432cada06d431a795cd0commit-bot@chromium.org    bm.allocN32Pixels(2, 2);
661ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com    *bm.getAddr32(0, 0) = *bm.getAddr32(1, 1) = 0xFFFFFFFF;
671ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com    *bm.getAddr32(1, 0) = *bm.getAddr32(0, 1) = SkPackARGB32(0xFF, 0xCC, 0xCC, 0xCC);
681ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com
691ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com    SkMatrix m;
701ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com    m.setScale(SkIntToScalar(6), SkIntToScalar(6));
719c9005a347e9996f357bd79591bd34f74f8bbc66commit-bot@chromium.org
729c9005a347e9996f357bd79591bd34f74f8bbc66commit-bot@chromium.org    return SkShader::CreateBitmapShader(bm,
739c9005a347e9996f357bd79591bd34f74f8bbc66commit-bot@chromium.org                                        SkShader::kRepeat_TileMode,
749c9005a347e9996f357bd79591bd34f74f8bbc66commit-bot@chromium.org                                        SkShader::kRepeat_TileMode,
759c9005a347e9996f357bd79591bd34f74f8bbc66commit-bot@chromium.org                                        &m);
761ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com}
771ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com
781ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.comclass HairModesView : public SampleView {
791ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com    SkPaint fBGPaint;
801ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.compublic:
81ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com    HairModesView() {
821ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com        fBGPaint.setShader(make_bg_shader())->unref();
831ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com    }
841ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com
851ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.comprotected:
861ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com    // overrides from SkEventSink
871ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com    virtual bool onQuery(SkEvent* evt) {
881ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com        if (SampleCode::TitleQ(*evt)) {
891ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com            SampleCode::TitleR(evt, "HairlineModes");
901ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com            return true;
911ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com        }
921ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com        return this->INHERITED::onQuery(evt);
931ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com    }
941ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com
951ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com    virtual void onDrawContent(SkCanvas* canvas) {
961ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com        const SkRect bounds = SkRect::MakeWH(W, H);
971ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com        static const SkAlpha gAlphaValue[] = { 0xFF, 0x88, 0x88 };
981ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com
991ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com        canvas->translate(SkIntToScalar(4), SkIntToScalar(4));
1001ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com
1011ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com        for (int alpha = 0; alpha < 4; ++alpha) {
1021ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com            canvas->save();
1031ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com            canvas->save();
1041ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com            for (size_t i = 0; i < SK_ARRAY_COUNT(gModes); ++i) {
1051ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com                if (6 == i) {
1061ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com                    canvas->restore();
1071ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com                    canvas->translate(W * 5, 0);
1081ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com                    canvas->save();
1091ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com                }
1101ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com                SkXfermode* mode = SkXfermode::Create(gModes[i].fMode);
111ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
1121ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com                canvas->drawRect(bounds, fBGPaint);
1131ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com                canvas->saveLayer(&bounds, NULL);
1141ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com                SkScalar dy = drawCell(canvas, mode,
1151ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com                                       gAlphaValue[alpha & 1],
1161ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com                                       gAlphaValue[alpha & 2]);
1171ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com                canvas->restore();
1181ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com
1191ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com                canvas->translate(0, dy * 5 / 4);
1201ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com                SkSafeUnref(mode);
1211ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com            }
1221ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com            canvas->restore();
1231ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com            canvas->restore();
1241ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com            canvas->translate(W * 5 / 4, 0);
1251ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com        }
1261ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com    }
127ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
1281ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.comprivate:
1291ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com    typedef SampleView INHERITED;
1301ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com};
1311ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com
1321ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com///////////////////////////////////////////////////////////////////////////////
1331ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.com
1341ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.comstatic SkView* MyFactory() { return new HairModesView; }
1351ec27a0211a90f8fa919579be77f2cb29ed7ccc5reed@google.comstatic SkViewRegister reg(MyFactory);
136