| /* | 
 |  * Copyright 2015 Google Inc. | 
 |  * | 
 |  * Use of this source code is governed by a BSD-style license that can be | 
 |  * found in the LICENSE file. | 
 |  */ | 
 |  | 
 | #include "gm.h" | 
 | #include "SkCanvas.h" | 
 | #include "SkRSXform.h" | 
 | #include "SkSurface.h" | 
 |  | 
 | // Create a square atlas of: | 
 | //   opaque white  |     opaque red | 
 | //  ------------------------------------ | 
 | //   opaque green  |  transparent black | 
 | // | 
 | static SkImage* make_atlas(SkCanvas* caller, int atlasSize) { | 
 |     const int kBlockSize = atlasSize/2; | 
 |  | 
 |     SkImageInfo info = SkImageInfo::MakeN32Premul(atlasSize, atlasSize); | 
 |     SkAutoTUnref<SkSurface> surface(caller->newSurface(info)); | 
 |     if (nullptr == surface) { | 
 |         surface.reset(SkSurface::NewRaster(info)); | 
 |     } | 
 |     SkCanvas* canvas = surface->getCanvas(); | 
 |  | 
 |     SkPaint paint; | 
 |     paint.setXfermode(SkXfermode::Create(SkXfermode::kSrc_Mode)); | 
 |  | 
 |     paint.setColor(SK_ColorWHITE); | 
 |     SkRect r = SkRect::MakeXYWH(0, 0,  | 
 |                                 SkIntToScalar(kBlockSize), SkIntToScalar(kBlockSize)); | 
 |     canvas->drawRect(r, paint); | 
 |  | 
 |     paint.setColor(SK_ColorRED); | 
 |     r = SkRect::MakeXYWH(SkIntToScalar(kBlockSize), 0,  | 
 |                          SkIntToScalar(kBlockSize), SkIntToScalar(kBlockSize)); | 
 |     canvas->drawRect(r, paint); | 
 |  | 
 |     paint.setColor(SK_ColorGREEN); | 
 |     r = SkRect::MakeXYWH(0, SkIntToScalar(kBlockSize),  | 
 |                          SkIntToScalar(kBlockSize), SkIntToScalar(kBlockSize)); | 
 |     canvas->drawRect(r, paint); | 
 |  | 
 |     paint.setColor(SK_ColorTRANSPARENT); | 
 |     r = SkRect::MakeXYWH(SkIntToScalar(kBlockSize), SkIntToScalar(kBlockSize),  | 
 |                          SkIntToScalar(kBlockSize), SkIntToScalar(kBlockSize)); | 
 |     canvas->drawRect(r, paint); | 
 |  | 
 |     return surface->newImageSnapshot(); | 
 | } | 
 |  | 
 | // This GM tests the drawAtlas API with colors, different xfer modes | 
 | // and transparency in the atlas image | 
 | class DrawAtlasColorsGM : public skiagm::GM { | 
 | public: | 
 |     DrawAtlasColorsGM() { | 
 |         this->setBGColor(sk_tool_utils::color_to_565(0xFFCCCCCC)); | 
 |     } | 
 |      | 
 | protected: | 
 |     SkString onShortName() override { | 
 |         return SkString("draw-atlas-colors"); | 
 |     } | 
 |      | 
 |     SkISize onISize() override { | 
 |         return SkISize::Make(kNumXferModes * (kAtlasSize + kPad) + kPad, | 
 |                              2 * kNumColors * (kAtlasSize + kPad) + kTextPad + kPad); | 
 |     } | 
 |      | 
 |     void onDraw(SkCanvas* canvas) override { | 
 |         const SkRect target = SkRect::MakeWH(SkIntToScalar(kAtlasSize), SkIntToScalar(kAtlasSize)); | 
 |  | 
 |         if (nullptr == fAtlas) { | 
 |             fAtlas.reset(make_atlas(canvas, kAtlasSize)); | 
 |         } | 
 |  | 
 |         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"       }, | 
 |             { SkXfermode::kPlus_Mode,       "Plus"      }, | 
 |             { SkXfermode::kModulate_Mode,   "Mod"       }, | 
 |             { SkXfermode::kScreen_Mode,     "Screen"    }, | 
 |             { SkXfermode::kOverlay_Mode,    "Overlay"   }, | 
 |             { SkXfermode::kDarken_Mode,     "Darken"    }, | 
 |             { SkXfermode::kLighten_Mode,    "Lighten"   }, | 
 |             { SkXfermode::kColorDodge_Mode, "Dodge"     }, | 
 |             { SkXfermode::kColorBurn_Mode,  "Burn"      }, | 
 |             { SkXfermode::kHardLight_Mode,  "Hard"      }, | 
 |             { SkXfermode::kSoftLight_Mode,  "Soft"      }, | 
 |             { SkXfermode::kDifference_Mode, "Diff"      }, | 
 |             { SkXfermode::kExclusion_Mode,  "Exclusion" }, | 
 |             { SkXfermode::kMultiply_Mode,   "Multiply"  }, | 
 |             { SkXfermode::kHue_Mode,        "Hue"       }, | 
 |             { SkXfermode::kSaturation_Mode, "Sat"       }, | 
 |             { SkXfermode::kColor_Mode,      "Color"     }, | 
 |             { SkXfermode::kLuminosity_Mode, "Luminosity"}, | 
 |         }; | 
 |  | 
 |         SkColor gColors[] = { | 
 |             SK_ColorWHITE, | 
 |             SK_ColorRED, | 
 |             0x88888888,         // transparent grey | 
 |             0x88000088          // transparent blue | 
 |         }; | 
 |  | 
 |         const int numModes = SK_ARRAY_COUNT(gModes); | 
 |         SkASSERT(numModes == kNumXferModes); | 
 |         const int numColors = SK_ARRAY_COUNT(gColors); | 
 |         SkASSERT(numColors == kNumColors); | 
 |         SkRSXform xforms[numColors]; | 
 |         SkRect rects[numColors]; | 
 |         SkColor quadColors[numColors]; | 
 |  | 
 |         SkPaint paint; | 
 |         paint.setAntiAlias(true); | 
 |  | 
 |         for (int i = 0; i < numColors; ++i) { | 
 |             xforms[i].set(1.0f, 0.0f, SkIntToScalar(kPad), i*(target.width()+kPad)); | 
 |             rects[i] = target; | 
 |             quadColors[i] = gColors[i]; | 
 |         } | 
 |  | 
 |         SkPaint textP; | 
 |         textP.setTextSize(SkIntToScalar(kTextPad)); | 
 |         textP.setAntiAlias(true); | 
 |         sk_tool_utils::set_portable_typeface(&textP, nullptr); | 
 |  | 
 |         for (int i = 0; i < numModes; ++i) { | 
 |             canvas->drawText(gModes[i].fLabel, strlen(gModes[i].fLabel), | 
 |                              i*(target.width()+kPad)+kPad, SkIntToScalar(kTextPad), | 
 |                              textP); | 
 |         } | 
 |  | 
 |         for (int i = 0; i < numModes; ++i) { | 
 |             canvas->save();             | 
 |             canvas->translate(SkIntToScalar(i*(target.height()+kPad)), | 
 |                               SkIntToScalar(kTextPad+kPad)); | 
 |             // w/o a paint | 
 |             canvas->drawAtlas(fAtlas, xforms, rects, quadColors, numColors,  | 
 |                               gModes[i].fMode, nullptr, nullptr); | 
 |             canvas->translate(0.0f, numColors*(target.height()+kPad)); | 
 |             // w a paint | 
 |             canvas->drawAtlas(fAtlas, xforms, rects, quadColors, numColors,  | 
 |                               gModes[i].fMode, nullptr, &paint); | 
 |             canvas->restore();         | 
 |         } | 
 |     } | 
 |      | 
 | private: | 
 |     static const int kNumXferModes = 29; | 
 |     static const int kNumColors = 4; | 
 |     static const int kAtlasSize = 30; | 
 |     static const int kPad = 2; | 
 |     static const int kTextPad = 8; | 
 |  | 
 |  | 
 |     SkAutoTUnref<SkImage> fAtlas; | 
 |  | 
 |     typedef GM INHERITED; | 
 | }; | 
 | DEF_GM( return new DrawAtlasColorsGM; ) | 
 |  |