1/* 2 * Copyright 2015 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8#include "gm.h" 9#include "SkCanvas.h" 10#include "SkRSXform.h" 11#include "SkSurface.h" 12 13// Create a square atlas of: 14// opaque white | opaque red 15// ------------------------------------ 16// opaque green | transparent black 17// 18static SkImage* make_atlas(SkCanvas* caller, int atlasSize) { 19 const int kBlockSize = atlasSize/2; 20 21 SkImageInfo info = SkImageInfo::MakeN32Premul(atlasSize, atlasSize); 22 SkAutoTUnref<SkSurface> surface(caller->newSurface(info)); 23 if (nullptr == surface) { 24 surface.reset(SkSurface::NewRaster(info)); 25 } 26 SkCanvas* canvas = surface->getCanvas(); 27 28 SkPaint paint; 29 paint.setXfermode(SkXfermode::Create(SkXfermode::kSrc_Mode)); 30 31 paint.setColor(SK_ColorWHITE); 32 SkRect r = SkRect::MakeXYWH(0, 0, 33 SkIntToScalar(kBlockSize), SkIntToScalar(kBlockSize)); 34 canvas->drawRect(r, paint); 35 36 paint.setColor(SK_ColorRED); 37 r = SkRect::MakeXYWH(SkIntToScalar(kBlockSize), 0, 38 SkIntToScalar(kBlockSize), SkIntToScalar(kBlockSize)); 39 canvas->drawRect(r, paint); 40 41 paint.setColor(SK_ColorGREEN); 42 r = SkRect::MakeXYWH(0, SkIntToScalar(kBlockSize), 43 SkIntToScalar(kBlockSize), SkIntToScalar(kBlockSize)); 44 canvas->drawRect(r, paint); 45 46 paint.setColor(SK_ColorTRANSPARENT); 47 r = SkRect::MakeXYWH(SkIntToScalar(kBlockSize), SkIntToScalar(kBlockSize), 48 SkIntToScalar(kBlockSize), SkIntToScalar(kBlockSize)); 49 canvas->drawRect(r, paint); 50 51 return surface->newImageSnapshot(); 52} 53 54// This GM tests the drawAtlas API with colors, different xfer modes 55// and transparency in the atlas image 56class DrawAtlasColorsGM : public skiagm::GM { 57public: 58 DrawAtlasColorsGM() { 59 this->setBGColor(sk_tool_utils::color_to_565(0xFFCCCCCC)); 60 } 61 62protected: 63 SkString onShortName() override { 64 return SkString("draw-atlas-colors"); 65 } 66 67 SkISize onISize() override { 68 return SkISize::Make(kNumXferModes * (kAtlasSize + kPad) + kPad, 69 2 * kNumColors * (kAtlasSize + kPad) + kTextPad + kPad); 70 } 71 72 void onDraw(SkCanvas* canvas) override { 73 const SkRect target = SkRect::MakeWH(SkIntToScalar(kAtlasSize), SkIntToScalar(kAtlasSize)); 74 75 if (nullptr == fAtlas) { 76 fAtlas.reset(make_atlas(canvas, kAtlasSize)); 77 } 78 79 const struct { 80 SkXfermode::Mode fMode; 81 const char* fLabel; 82 } gModes[] = { 83 { SkXfermode::kClear_Mode, "Clear" }, 84 { SkXfermode::kSrc_Mode, "Src" }, 85 { SkXfermode::kDst_Mode, "Dst" }, 86 { SkXfermode::kSrcOver_Mode, "SrcOver" }, 87 { SkXfermode::kDstOver_Mode, "DstOver" }, 88 { SkXfermode::kSrcIn_Mode, "SrcIn" }, 89 { SkXfermode::kDstIn_Mode, "DstIn" }, 90 { SkXfermode::kSrcOut_Mode, "SrcOut" }, 91 { SkXfermode::kDstOut_Mode, "DstOut" }, 92 { SkXfermode::kSrcATop_Mode, "SrcATop" }, 93 { SkXfermode::kDstATop_Mode, "DstATop" }, 94 { SkXfermode::kXor_Mode, "Xor" }, 95 { SkXfermode::kPlus_Mode, "Plus" }, 96 { SkXfermode::kModulate_Mode, "Mod" }, 97 { SkXfermode::kScreen_Mode, "Screen" }, 98 { SkXfermode::kOverlay_Mode, "Overlay" }, 99 { SkXfermode::kDarken_Mode, "Darken" }, 100 { SkXfermode::kLighten_Mode, "Lighten" }, 101 { SkXfermode::kColorDodge_Mode, "Dodge" }, 102 { SkXfermode::kColorBurn_Mode, "Burn" }, 103 { SkXfermode::kHardLight_Mode, "Hard" }, 104 { SkXfermode::kSoftLight_Mode, "Soft" }, 105 { SkXfermode::kDifference_Mode, "Diff" }, 106 { SkXfermode::kExclusion_Mode, "Exclusion" }, 107 { SkXfermode::kMultiply_Mode, "Multiply" }, 108 { SkXfermode::kHue_Mode, "Hue" }, 109 { SkXfermode::kSaturation_Mode, "Sat" }, 110 { SkXfermode::kColor_Mode, "Color" }, 111 { SkXfermode::kLuminosity_Mode, "Luminosity"}, 112 }; 113 114 SkColor gColors[] = { 115 SK_ColorWHITE, 116 SK_ColorRED, 117 0x88888888, // transparent grey 118 0x88000088 // transparent blue 119 }; 120 121 const int numModes = SK_ARRAY_COUNT(gModes); 122 SkASSERT(numModes == kNumXferModes); 123 const int numColors = SK_ARRAY_COUNT(gColors); 124 SkASSERT(numColors == kNumColors); 125 SkRSXform xforms[numColors]; 126 SkRect rects[numColors]; 127 SkColor quadColors[numColors]; 128 129 SkPaint paint; 130 paint.setAntiAlias(true); 131 132 for (int i = 0; i < numColors; ++i) { 133 xforms[i].set(1.0f, 0.0f, SkIntToScalar(kPad), i*(target.width()+kPad)); 134 rects[i] = target; 135 quadColors[i] = gColors[i]; 136 } 137 138 SkPaint textP; 139 textP.setTextSize(SkIntToScalar(kTextPad)); 140 textP.setAntiAlias(true); 141 sk_tool_utils::set_portable_typeface(&textP, nullptr); 142 143 for (int i = 0; i < numModes; ++i) { 144 canvas->drawText(gModes[i].fLabel, strlen(gModes[i].fLabel), 145 i*(target.width()+kPad)+kPad, SkIntToScalar(kTextPad), 146 textP); 147 } 148 149 for (int i = 0; i < numModes; ++i) { 150 canvas->save(); 151 canvas->translate(SkIntToScalar(i*(target.height()+kPad)), 152 SkIntToScalar(kTextPad+kPad)); 153 // w/o a paint 154 canvas->drawAtlas(fAtlas, xforms, rects, quadColors, numColors, 155 gModes[i].fMode, nullptr, nullptr); 156 canvas->translate(0.0f, numColors*(target.height()+kPad)); 157 // w a paint 158 canvas->drawAtlas(fAtlas, xforms, rects, quadColors, numColors, 159 gModes[i].fMode, nullptr, &paint); 160 canvas->restore(); 161 } 162 } 163 164private: 165 static const int kNumXferModes = 29; 166 static const int kNumColors = 4; 167 static const int kAtlasSize = 30; 168 static const int kPad = 2; 169 static const int kTextPad = 8; 170 171 172 SkAutoTUnref<SkImage> fAtlas; 173 174 typedef GM INHERITED; 175}; 176DEF_GM( return new DrawAtlasColorsGM; ) 177 178