12880df2609eba09b555ca37be04b6ad89290c765Tom Hudson/*
22880df2609eba09b555ca37be04b6ad89290c765Tom Hudson * Copyright 2015 Google Inc.
32880df2609eba09b555ca37be04b6ad89290c765Tom Hudson *
42880df2609eba09b555ca37be04b6ad89290c765Tom Hudson * Use of this source code is governed by a BSD-style license that can be
52880df2609eba09b555ca37be04b6ad89290c765Tom Hudson * found in the LICENSE file.
62880df2609eba09b555ca37be04b6ad89290c765Tom Hudson */
72880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
82880df2609eba09b555ca37be04b6ad89290c765Tom Hudson#include "gm.h"
92880df2609eba09b555ca37be04b6ad89290c765Tom Hudson#include "SkCanvas.h"
102880df2609eba09b555ca37be04b6ad89290c765Tom Hudson#include "SkRSXform.h"
112880df2609eba09b555ca37be04b6ad89290c765Tom Hudson#include "SkSurface.h"
122880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
132880df2609eba09b555ca37be04b6ad89290c765Tom Hudson// Create a square atlas of:
142880df2609eba09b555ca37be04b6ad89290c765Tom Hudson//   opaque white  |     opaque red
152880df2609eba09b555ca37be04b6ad89290c765Tom Hudson//  ------------------------------------
162880df2609eba09b555ca37be04b6ad89290c765Tom Hudson//   opaque green  |  transparent black
172880df2609eba09b555ca37be04b6ad89290c765Tom Hudson//
182880df2609eba09b555ca37be04b6ad89290c765Tom Hudsonstatic SkImage* make_atlas(SkCanvas* caller, int atlasSize) {
192880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    const int kBlockSize = atlasSize/2;
202880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
212880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    SkImageInfo info = SkImageInfo::MakeN32Premul(atlasSize, atlasSize);
222880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    SkAutoTUnref<SkSurface> surface(caller->newSurface(info));
232880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    if (nullptr == surface) {
242880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        surface.reset(SkSurface::NewRaster(info));
252880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    }
262880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    SkCanvas* canvas = surface->getCanvas();
272880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
282880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    SkPaint paint;
292880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    paint.setXfermode(SkXfermode::Create(SkXfermode::kSrc_Mode));
302880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
312880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    paint.setColor(SK_ColorWHITE);
322880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    SkRect r = SkRect::MakeXYWH(0, 0,
332880df2609eba09b555ca37be04b6ad89290c765Tom Hudson                                SkIntToScalar(kBlockSize), SkIntToScalar(kBlockSize));
342880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    canvas->drawRect(r, paint);
352880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
362880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    paint.setColor(SK_ColorRED);
372880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    r = SkRect::MakeXYWH(SkIntToScalar(kBlockSize), 0,
382880df2609eba09b555ca37be04b6ad89290c765Tom Hudson                         SkIntToScalar(kBlockSize), SkIntToScalar(kBlockSize));
392880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    canvas->drawRect(r, paint);
402880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
412880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    paint.setColor(SK_ColorGREEN);
422880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    r = SkRect::MakeXYWH(0, SkIntToScalar(kBlockSize),
432880df2609eba09b555ca37be04b6ad89290c765Tom Hudson                         SkIntToScalar(kBlockSize), SkIntToScalar(kBlockSize));
442880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    canvas->drawRect(r, paint);
452880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
462880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    paint.setColor(SK_ColorTRANSPARENT);
472880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    r = SkRect::MakeXYWH(SkIntToScalar(kBlockSize), SkIntToScalar(kBlockSize),
482880df2609eba09b555ca37be04b6ad89290c765Tom Hudson                         SkIntToScalar(kBlockSize), SkIntToScalar(kBlockSize));
492880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    canvas->drawRect(r, paint);
502880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
512880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    return surface->newImageSnapshot();
522880df2609eba09b555ca37be04b6ad89290c765Tom Hudson}
532880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
542880df2609eba09b555ca37be04b6ad89290c765Tom Hudson// This GM tests the drawAtlas API with colors, different xfer modes
552880df2609eba09b555ca37be04b6ad89290c765Tom Hudson// and transparency in the atlas image
562880df2609eba09b555ca37be04b6ad89290c765Tom Hudsonclass DrawAtlasColorsGM : public skiagm::GM {
572880df2609eba09b555ca37be04b6ad89290c765Tom Hudsonpublic:
582880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    DrawAtlasColorsGM() {
592880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        this->setBGColor(sk_tool_utils::color_to_565(0xFFCCCCCC));
602880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    }
612880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
622880df2609eba09b555ca37be04b6ad89290c765Tom Hudsonprotected:
632880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    SkString onShortName() override {
642880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        return SkString("draw-atlas-colors");
652880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    }
662880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
672880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    SkISize onISize() override {
682880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        return SkISize::Make(kNumXferModes * (kAtlasSize + kPad) + kPad,
692880df2609eba09b555ca37be04b6ad89290c765Tom Hudson                             2 * kNumColors * (kAtlasSize + kPad) + kTextPad + kPad);
702880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    }
712880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
722880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    void onDraw(SkCanvas* canvas) override {
732880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        const SkRect target = SkRect::MakeWH(SkIntToScalar(kAtlasSize), SkIntToScalar(kAtlasSize));
742880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
752880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        if (nullptr == fAtlas) {
762880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            fAtlas.reset(make_atlas(canvas, kAtlasSize));
772880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        }
782880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
792880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        const struct {
802880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            SkXfermode::Mode fMode;
812880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            const char*      fLabel;
822880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        } gModes[] = {
832880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            { SkXfermode::kClear_Mode,      "Clear"     },
842880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            { SkXfermode::kSrc_Mode,        "Src"       },
852880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            { SkXfermode::kDst_Mode,        "Dst"       },
862880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            { SkXfermode::kSrcOver_Mode,    "SrcOver"   },
872880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            { SkXfermode::kDstOver_Mode,    "DstOver"   },
882880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            { SkXfermode::kSrcIn_Mode,      "SrcIn"     },
892880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            { SkXfermode::kDstIn_Mode,      "DstIn"     },
902880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            { SkXfermode::kSrcOut_Mode,     "SrcOut"    },
912880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            { SkXfermode::kDstOut_Mode,     "DstOut"    },
922880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            { SkXfermode::kSrcATop_Mode,    "SrcATop"   },
932880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            { SkXfermode::kDstATop_Mode,    "DstATop"   },
942880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            { SkXfermode::kXor_Mode,        "Xor"       },
952880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            { SkXfermode::kPlus_Mode,       "Plus"      },
962880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            { SkXfermode::kModulate_Mode,   "Mod"       },
972880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            { SkXfermode::kScreen_Mode,     "Screen"    },
982880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            { SkXfermode::kOverlay_Mode,    "Overlay"   },
992880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            { SkXfermode::kDarken_Mode,     "Darken"    },
1002880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            { SkXfermode::kLighten_Mode,    "Lighten"   },
1012880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            { SkXfermode::kColorDodge_Mode, "Dodge"     },
1022880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            { SkXfermode::kColorBurn_Mode,  "Burn"      },
1032880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            { SkXfermode::kHardLight_Mode,  "Hard"      },
1042880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            { SkXfermode::kSoftLight_Mode,  "Soft"      },
1052880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            { SkXfermode::kDifference_Mode, "Diff"      },
1062880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            { SkXfermode::kExclusion_Mode,  "Exclusion" },
1072880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            { SkXfermode::kMultiply_Mode,   "Multiply"  },
1082880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            { SkXfermode::kHue_Mode,        "Hue"       },
1092880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            { SkXfermode::kSaturation_Mode, "Sat"       },
1102880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            { SkXfermode::kColor_Mode,      "Color"     },
1112880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            { SkXfermode::kLuminosity_Mode, "Luminosity"},
1122880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        };
1132880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
1142880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        SkColor gColors[] = {
1152880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            SK_ColorWHITE,
1162880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            SK_ColorRED,
1172880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            0x88888888,         // transparent grey
1182880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            0x88000088          // transparent blue
1192880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        };
1202880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
1212880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        const int numModes = SK_ARRAY_COUNT(gModes);
1222880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        SkASSERT(numModes == kNumXferModes);
1232880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        const int numColors = SK_ARRAY_COUNT(gColors);
1242880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        SkASSERT(numColors == kNumColors);
1252880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        SkRSXform xforms[numColors];
1262880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        SkRect rects[numColors];
1272880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        SkColor quadColors[numColors];
1282880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
1292880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        SkPaint paint;
1302880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        paint.setAntiAlias(true);
1312880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
1322880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        for (int i = 0; i < numColors; ++i) {
1332880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            xforms[i].set(1.0f, 0.0f, SkIntToScalar(kPad), i*(target.width()+kPad));
1342880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            rects[i] = target;
1352880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            quadColors[i] = gColors[i];
1362880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        }
1372880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
1382880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        SkPaint textP;
1392880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        textP.setTextSize(SkIntToScalar(kTextPad));
1402880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        textP.setAntiAlias(true);
1412880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        sk_tool_utils::set_portable_typeface(&textP, nullptr);
1422880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
1432880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        for (int i = 0; i < numModes; ++i) {
1442880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            canvas->drawText(gModes[i].fLabel, strlen(gModes[i].fLabel),
1452880df2609eba09b555ca37be04b6ad89290c765Tom Hudson                             i*(target.width()+kPad)+kPad, SkIntToScalar(kTextPad),
1462880df2609eba09b555ca37be04b6ad89290c765Tom Hudson                             textP);
1472880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        }
1482880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
1492880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        for (int i = 0; i < numModes; ++i) {
1502880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            canvas->save();
1512880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            canvas->translate(SkIntToScalar(i*(target.height()+kPad)),
1522880df2609eba09b555ca37be04b6ad89290c765Tom Hudson                              SkIntToScalar(kTextPad+kPad));
1532880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            // w/o a paint
1542880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            canvas->drawAtlas(fAtlas, xforms, rects, quadColors, numColors,
1552880df2609eba09b555ca37be04b6ad89290c765Tom Hudson                              gModes[i].fMode, nullptr, nullptr);
1562880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            canvas->translate(0.0f, numColors*(target.height()+kPad));
1572880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            // w a paint
1582880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            canvas->drawAtlas(fAtlas, xforms, rects, quadColors, numColors,
1592880df2609eba09b555ca37be04b6ad89290c765Tom Hudson                              gModes[i].fMode, nullptr, &paint);
1602880df2609eba09b555ca37be04b6ad89290c765Tom Hudson            canvas->restore();
1612880df2609eba09b555ca37be04b6ad89290c765Tom Hudson        }
1622880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    }
1632880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
1642880df2609eba09b555ca37be04b6ad89290c765Tom Hudsonprivate:
1652880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    static const int kNumXferModes = 29;
1662880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    static const int kNumColors = 4;
1672880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    static const int kAtlasSize = 30;
1682880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    static const int kPad = 2;
1692880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    static const int kTextPad = 8;
1702880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
1712880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
1722880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    SkAutoTUnref<SkImage> fAtlas;
1732880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
1742880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    typedef GM INHERITED;
1752880df2609eba09b555ca37be04b6ad89290c765Tom Hudson};
1762880df2609eba09b555ca37be04b6ad89290c765Tom HudsonDEF_GM( return new DrawAtlasColorsGM; )
1772880df2609eba09b555ca37be04b6ad89290c765Tom Hudson
178