123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228 |
- /*
- * Copyright 2013 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
- #include "gm/gm.h"
- #include "include/core/SkBitmap.h"
- #include "include/core/SkBlendMode.h"
- #include "include/core/SkCanvas.h"
- #include "include/core/SkColor.h"
- #include "include/core/SkColorPriv.h"
- #include "include/core/SkColorSpace.h"
- #include "include/core/SkFont.h"
- #include "include/core/SkImageInfo.h"
- #include "include/core/SkMatrix.h"
- #include "include/core/SkPaint.h"
- #include "include/core/SkPoint.h"
- #include "include/core/SkRect.h"
- #include "include/core/SkRefCnt.h"
- #include "include/core/SkScalar.h"
- #include "include/core/SkShader.h"
- #include "include/core/SkSize.h"
- #include "include/core/SkString.h"
- #include "include/core/SkSurface.h"
- #include "include/core/SkTileMode.h"
- #include "include/core/SkTypeface.h"
- #include "include/core/SkTypes.h"
- #include "include/effects/SkGradientShader.h"
- #include "tools/ToolUtils.h"
- #include <string.h>
- namespace skiagm {
- /**
- * This tests drawing device-covering rects with solid colors and bitmap shaders over a
- * checkerboard background using different xfermodes.
- */
- class Xfermodes3GM : public GM {
- public:
- Xfermodes3GM() { this->setBGColor(ToolUtils::color_to_565(0xFF70D0E0)); }
- protected:
- SkString onShortName() override {
- return SkString("xfermodes3");
- }
- SkISize onISize() override {
- return SkISize::Make(630, 1215);
- }
- void onDraw(SkCanvas* canvas) override {
- canvas->translate(SkIntToScalar(10), SkIntToScalar(20));
- SkFont font(ToolUtils::create_portable_typeface());
- SkPaint labelP;
- constexpr SkColor kSolidColors[] = {
- SK_ColorTRANSPARENT,
- SK_ColorBLUE,
- 0x80808000
- };
- constexpr SkColor kBmpAlphas[] = {
- 0xff,
- 0x80,
- };
- auto tempSurface(this->makeTempSurface(canvas, kSize, kSize));
- int test = 0;
- int x = 0, y = 0;
- constexpr struct { SkPaint::Style fStyle; SkScalar fWidth; } kStrokes[] = {
- {SkPaint::kFill_Style, 0},
- {SkPaint::kStroke_Style, SkIntToScalar(kSize) / 2},
- };
- for (size_t s = 0; s < SK_ARRAY_COUNT(kStrokes); ++s) {
- for (size_t m = 0; m <= (size_t)SkBlendMode::kLastMode; ++m) {
- SkBlendMode mode = static_cast<SkBlendMode>(m);
- canvas->drawString(SkBlendMode_Name(mode),
- SkIntToScalar(x),
- SkIntToScalar(y + kSize + 3) + font.getSize(),
- font, labelP);
- for (size_t c = 0; c < SK_ARRAY_COUNT(kSolidColors); ++c) {
- SkPaint modePaint;
- modePaint.setBlendMode(mode);
- modePaint.setColor(kSolidColors[c]);
- modePaint.setStyle(kStrokes[s].fStyle);
- modePaint.setStrokeWidth(kStrokes[s].fWidth);
- this->drawMode(canvas, x, y, kSize, kSize, modePaint, tempSurface.get());
- ++test;
- x += kSize + 10;
- if (!(test % kTestsPerRow)) {
- x = 0;
- y += kSize + 30;
- }
- }
- for (size_t a = 0; a < SK_ARRAY_COUNT(kBmpAlphas); ++a) {
- SkPaint modePaint;
- modePaint.setBlendMode(mode);
- modePaint.setAlpha(kBmpAlphas[a]);
- modePaint.setShader(fBmpShader);
- modePaint.setStyle(kStrokes[s].fStyle);
- modePaint.setStrokeWidth(kStrokes[s].fWidth);
- this->drawMode(canvas, x, y, kSize, kSize, modePaint, tempSurface.get());
- ++test;
- x += kSize + 10;
- if (!(test % kTestsPerRow)) {
- x = 0;
- y += kSize + 30;
- }
- }
- }
- }
- }
- private:
- /**
- * GrContext has optimizations around full rendertarget draws that can be replaced with clears.
- * We are trying to test those. We could use saveLayer() to create small SkGpuDevices but
- * saveLayer() uses the texture cache. This means that the actual render target may be larger
- * than the layer. Because the clip will contain the layer's bounds, no draws will be full-RT.
- * So explicitly create a temporary canvas with dimensions exactly the layer size.
- */
- sk_sp<SkSurface> makeTempSurface(SkCanvas* baseCanvas, int w, int h) {
- SkImageInfo baseInfo = baseCanvas->imageInfo();
- SkImageInfo info = SkImageInfo::Make(w, h, baseInfo.colorType(), baseInfo.alphaType(),
- baseInfo.refColorSpace());
- return baseCanvas->makeSurface(info);
- }
- void drawMode(SkCanvas* canvas,
- int x, int y, int w, int h,
- const SkPaint& modePaint, SkSurface* surface) {
- canvas->save();
- canvas->translate(SkIntToScalar(x), SkIntToScalar(y));
- SkRect r = SkRect::MakeWH(SkIntToScalar(w), SkIntToScalar(h));
- SkCanvas* modeCanvas;
- if (nullptr == surface) {
- canvas->saveLayer(&r, nullptr);
- canvas->clipRect(r);
- modeCanvas = canvas;
- } else {
- modeCanvas = surface->getCanvas();
- }
- SkPaint bgPaint;
- bgPaint.setAntiAlias(false);
- bgPaint.setShader(fBGShader);
- modeCanvas->drawRect(r, bgPaint);
- modeCanvas->drawRect(r, modePaint);
- modeCanvas = nullptr;
- if (nullptr == surface) {
- canvas->restore();
- } else {
- surface->draw(canvas, 0, 0, nullptr);
- }
- r.inset(-SK_ScalarHalf, -SK_ScalarHalf);
- SkPaint borderPaint;
- borderPaint.setStyle(SkPaint::kStroke_Style);
- canvas->drawRect(r, borderPaint);
- canvas->restore();
- }
- void onOnceBeforeDraw() override {
- const uint32_t kCheckData[] = {
- SkPackARGB32(0xFF, 0x42, 0x41, 0x42),
- SkPackARGB32(0xFF, 0xD6, 0xD3, 0xD6),
- SkPackARGB32(0xFF, 0xD6, 0xD3, 0xD6),
- SkPackARGB32(0xFF, 0x42, 0x41, 0x42)
- };
- SkBitmap bg;
- bg.allocN32Pixels(2, 2, true);
- memcpy(bg.getPixels(), kCheckData, sizeof(kCheckData));
- SkMatrix lm;
- lm.setScale(SkIntToScalar(kCheckSize), SkIntToScalar(kCheckSize));
- fBGShader = bg.makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat, &lm);
- SkPaint bmpPaint;
- const SkPoint kCenter = { SkIntToScalar(kSize) / 2, SkIntToScalar(kSize) / 2 };
- const SkColor kColors[] = {
- SK_ColorTRANSPARENT, 0x80800000, 0xF020F060, SK_ColorWHITE
- };
- bmpPaint.setShader(SkGradientShader::MakeRadial(kCenter, 3 * SkIntToScalar(kSize) / 4,
- kColors, nullptr, SK_ARRAY_COUNT(kColors),
- SkTileMode::kRepeat));
- SkBitmap bmp;
- bmp.allocN32Pixels(kSize, kSize);
- SkCanvas bmpCanvas(bmp);
- bmpCanvas.clear(SK_ColorTRANSPARENT);
- SkRect rect = { SkIntToScalar(kSize) / 8, SkIntToScalar(kSize) / 8,
- 7 * SkIntToScalar(kSize) / 8, 7 * SkIntToScalar(kSize) / 8};
- bmpCanvas.drawRect(rect, bmpPaint);
- fBmpShader = bmp.makeShader();
- }
- enum {
- kCheckSize = 8,
- kSize = 30,
- kTestsPerRow = 15,
- };
- sk_sp<SkShader> fBGShader;
- sk_sp<SkShader> fBmpShader;
- typedef GM INHERITED;
- };
- //////////////////////////////////////////////////////////////////////////////
- DEF_GM(return new Xfermodes3GM;)
- }
|