11cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/*
21cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Copyright 2011 Google Inc.
31cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *
41cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be
51cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * found in the LICENSE file.
61cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */
71cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
81cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "gm.h"
91cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "SkCanvas.h"
101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "SkColorPriv.h"
111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "SkShader.h"
121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void test4(SkCanvas* canvas) {
141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPaint paint;
151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    paint.setAntiAlias(true);
161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPoint pts[] = {
171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        {10, 160}, {610, 160},
181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        {610, 160}, {10, 160},
191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        {610, 160}, {610, 160},
211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        {610, 199}, {610, 199},
221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        {10, 198}, {610, 198},
241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        {610, 199}, {10, 199},
251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        {10, 160}, {10, 160},
271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        {10, 199}, {10, 199}
281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    };
291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    char verbs[] = {
301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        0, 1, 1, 1, 4,
311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        0, 1, 1, 1, 4,
321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        0, 1, 1, 1, 4,
331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        0, 1, 1, 1, 4
341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    };
351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPath path;
361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPoint* ptPtr = pts;
371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    for (size_t i = 0; i < sizeof(verbs); ++i) {
381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        switch ((SkPath::Verb) verbs[i]) {
391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            case SkPath::kMove_Verb:
401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                path.moveTo(ptPtr->fX, ptPtr->fY);
411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                ++ptPtr;
421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                break;
431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            case SkPath::kLine_Verb:
441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                path.lineTo(ptPtr->fX, ptPtr->fY);
451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                ++ptPtr;
461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                break;
471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            case SkPath::kClose_Verb:
481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                path.close();
491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                break;
501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            default:
511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                SkASSERT(false);
521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                break;
531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkRect clip = {0, 130, 772, 531};
561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    canvas->clipRect(clip);
571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    canvas->drawPath(path, paint);
581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic SkCanvas* create_canvas(int w, int h) {
611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkBitmap bm;
621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    bm.setConfig(SkBitmap::kARGB_8888_Config, w, h);
631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    bm.allocPixels();
641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    bm.eraseColor(0);
651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return new SkCanvas(bm);
661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic const SkBitmap& extract_bitmap(SkCanvas* canvas) {
691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return canvas->getDevice()->accessBitmap(false);
701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic const struct {
731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkXfermode::Mode  fMode;
741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    const char*         fLabel;
751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} gModes[] = {
761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    { SkXfermode::kClear_Mode,    "Clear"     },
771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    { SkXfermode::kSrc_Mode,      "Src"       },
781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    { SkXfermode::kDst_Mode,      "Dst"       },
791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    { SkXfermode::kSrcOver_Mode,  "SrcOver"   },
801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    { SkXfermode::kDstOver_Mode,  "DstOver"   },
811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    { SkXfermode::kSrcIn_Mode,    "SrcIn"     },
821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    { SkXfermode::kDstIn_Mode,    "DstIn"     },
831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    { SkXfermode::kSrcOut_Mode,   "SrcOut"    },
841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    { SkXfermode::kDstOut_Mode,   "DstOut"    },
851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    { SkXfermode::kSrcATop_Mode,  "SrcATop"   },
861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    { SkXfermode::kDstATop_Mode,  "DstATop"   },
871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    { SkXfermode::kXor_Mode,      "Xor"       },
881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger};
891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerconst int gWidth = 64;
911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerconst int gHeight = 64;
921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerconst SkScalar W = SkIntToScalar(gWidth);
931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerconst SkScalar H = SkIntToScalar(gHeight);
941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic SkScalar drawCell(SkCanvas* canvas, SkXfermode* mode,
961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                         SkAlpha a0, SkAlpha a1) {
971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkPaint paint;
991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    paint.setAntiAlias(true);
1001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkRect r = SkRect::MakeWH(W, H);
1021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    r.inset(W/10, H/10);
1031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    paint.setColor(SK_ColorBLUE);
1051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    paint.setAlpha(a0);
1061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    canvas->drawOval(r, paint);
1071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    paint.setColor(SK_ColorRED);
1091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    paint.setAlpha(a1);
1101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    paint.setXfermode(mode);
1111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkScalar offset = SK_Scalar1 / 3;
1131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkRect rect = SkRect::MakeXYWH(W / 4 + offset,
1141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                   H / 4 + offset,
1151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                   W / 2, H / 2);
1161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    canvas->drawRect(rect, paint);
1171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return H;
1191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
1201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic SkShader* make_bg_shader() {
1221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkBitmap bm;
1231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    bm.setConfig(SkBitmap::kARGB_8888_Config, 2, 2);
1241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    bm.allocPixels();
1251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    *bm.getAddr32(0, 0) = *bm.getAddr32(1, 1) = 0xFFFFFFFF;
1261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    *bm.getAddr32(1, 0) = *bm.getAddr32(0, 1) = SkPackARGB32(0xFF, 0xCC,
1271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                                             0xCC, 0xCC);
1281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkShader* s = SkShader::CreateBitmapShader(bm,
1301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                               SkShader::kRepeat_TileMode,
1311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                               SkShader::kRepeat_TileMode);
1321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkMatrix m;
1341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    m.setScale(SkIntToScalar(6), SkIntToScalar(6));
1351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    s->setLocalMatrix(m);
1361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return s;
1371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
1381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergernamespace skiagm {
1401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    class AARectModesGM : public GM {
1421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkPaint fBGPaint;
1431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    public:
1441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        AARectModesGM () {
1451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            fBGPaint.setShader(make_bg_shader())->unref();
1461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
1471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    protected:
1491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        virtual SkString onShortName() {
1511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            return SkString("aarectmodes");
1521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
1531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        virtual SkISize onISize() { return make_isize(640, 480); }
1551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        virtual void onDraw(SkCanvas* canvas) {
1571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger//            test4(canvas);
1581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            const SkRect bounds = SkRect::MakeWH(W, H);
1591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            static const SkAlpha gAlphaValue[] = { 0xFF, 0x88, 0x88 };
1601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            canvas->translate(SkIntToScalar(4), SkIntToScalar(4));
1621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            for (int alpha = 0; alpha < 4; ++alpha) {
1641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                canvas->save();
1651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                canvas->save();
1661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                for (size_t i = 0; i < SK_ARRAY_COUNT(gModes); ++i) {
1671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    if (6 == i) {
1681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                        canvas->restore();
1691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                        canvas->translate(W * 5, 0);
1701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                        canvas->save();
1711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    }
1721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    SkXfermode* mode = SkXfermode::Create(gModes[i].fMode);
1731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    canvas->drawRect(bounds, fBGPaint);
1751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    canvas->saveLayer(&bounds, NULL);
1761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    SkScalar dy = drawCell(canvas, mode,
1771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                           gAlphaValue[alpha & 1],
1781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                           gAlphaValue[alpha & 2]);
1791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    canvas->restore();
1801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    canvas->translate(0, dy * 5 / 4);
1821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    SkSafeUnref(mode);
1831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                }
1841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                canvas->restore();
1851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                canvas->restore();
1861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                canvas->translate(W * 5 / 4, 0);
1871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            }
1881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
1891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // disable pdf for now, since it crashes on mac
1911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        virtual uint32_t onGetFlags() const { return kSkipPDF_Flag; }
1921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    private:
1941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        typedef GM INHERITED;
1951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    };
1961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger//////////////////////////////////////////////////////////////////////////////
1981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    static GM* MyFactory(void*) { return new AARectModesGM; }
2001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    static GMRegistry reg(MyFactory);
2011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
2021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
2031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
204