SampleMixer.cpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. /*
  2. * Copyright 2017 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. #include "include/core/SkCanvas.h"
  8. #include "include/core/SkColorFilter.h"
  9. #include "include/core/SkImage.h"
  10. #include "include/core/SkPath.h"
  11. #include "include/core/SkRegion.h"
  12. #include "include/core/SkShader.h"
  13. #include "include/effects/SkGradientShader.h"
  14. #include "samplecode/Sample.h"
  15. #include "src/core/SkUtils.h"
  16. #include "tools/Resources.h"
  17. const float gMat[] = {
  18. .3f, .6f, .1f, 0, 0,
  19. .3f, .6f, .1f, 0, 0,
  20. .3f, .6f, .1f, 0, 0,
  21. 0, 0, 0, 1, 0,
  22. };
  23. class MixerView : public Sample {
  24. sk_sp<SkImage> fImg;
  25. sk_sp<SkColorFilter> fCF0;
  26. sk_sp<SkColorFilter> fCF1;
  27. float fWeight = 0;
  28. float fDW = 0.02f;
  29. public:
  30. MixerView() {}
  31. protected:
  32. SkString name() override { return SkString("Mixer"); }
  33. void dodraw(SkCanvas* canvas, sk_sp<SkColorFilter> cf0, sk_sp<SkColorFilter> cf1, float gap) {
  34. SkPaint paint;
  35. paint.setColorFilter(cf0);
  36. canvas->drawImage(fImg, 0, 0, &paint);
  37. paint.setColorFilter(SkColorFilters::Lerp(fWeight, cf0, cf1));
  38. canvas->drawImage(fImg, fImg->width() + gap * fWeight, 0, &paint);
  39. paint.setColorFilter(cf1);
  40. canvas->drawImage(fImg, 2*fImg->width() + gap, 0, &paint);
  41. }
  42. void onDrawContent(SkCanvas* canvas) override {
  43. if (!fImg) {
  44. fImg = GetResourceAsImage("images/mandrill_256.png");
  45. fCF0 = SkColorFilters::Matrix(gMat);
  46. fCF1 = SkColorFilters::Blend(0xFF44CC88, SkBlendMode::kScreen);
  47. }
  48. float gap = fImg->width() * 3;
  49. canvas->translate(10, 10);
  50. dodraw(canvas, nullptr, fCF1, gap);
  51. canvas->translate(0, fImg->height() + 10);
  52. dodraw(canvas, fCF0, nullptr, gap);
  53. canvas->translate(0, fImg->height() + 10);
  54. dodraw(canvas, fCF0, fCF1, gap);
  55. fWeight += fDW;
  56. if (fWeight > 1 || fWeight < 0) {
  57. fDW = -fDW;
  58. }
  59. }
  60. virtual Click* onFindClickHandler(SkScalar x, SkScalar y, ModifierKey) override {
  61. return fRect.contains(SkScalarRoundToInt(x),
  62. SkScalarRoundToInt(y)) ? new Click() : nullptr;
  63. }
  64. bool onClick(Click* click) override {
  65. fRect.offset(click->fCurr.fX - click->fPrev.fX,
  66. click->fCurr.fY - click->fPrev.fY);
  67. return true;
  68. }
  69. private:
  70. SkIRect fRect;
  71. typedef Sample INHERITED;
  72. };
  73. DEF_SAMPLE( return new MixerView; )
  74. //////////////////////////////////////////////////////////////////////////////
  75. #include "include/core/SkMaskFilter.h"
  76. #include "include/core/SkSurface.h"
  77. static sk_sp<SkShader> make_resource_shader(const char path[], int size) {
  78. auto img = GetResourceAsImage(path);
  79. if (!img) {
  80. return nullptr;
  81. }
  82. SkRect src = SkRect::MakeIWH(img->width(), img->height());
  83. SkRect dst = SkRect::MakeIWH(size, size);
  84. SkMatrix m;
  85. m.setRectToRect(src, dst, SkMatrix::kFill_ScaleToFit);
  86. return img->makeShader(&m);
  87. }
  88. class ShaderMixerView : public Sample {
  89. sk_sp<SkShader> fSH0;
  90. sk_sp<SkShader> fSH1;
  91. sk_sp<SkSurface> fSurface;
  92. SkBlendMode fMode = SkBlendMode::kClear;
  93. enum { SIZE = 256 };
  94. const SkRect fRect = SkRect::MakeXYWH(10, 10 + SIZE + 10, SIZE, SIZE);
  95. public:
  96. ShaderMixerView() {}
  97. void onOnceBeforeDraw() override {
  98. fSH0 = make_resource_shader("images/mandrill_256.png", SIZE);
  99. fSH1 = make_resource_shader("images/baby_tux.png", SIZE);
  100. }
  101. protected:
  102. SkString name() override { return SkString("ShaderMixer"); }
  103. void onDrawContent(SkCanvas* canvas) override {
  104. if (!fSurface) {
  105. fSurface = canvas->makeSurface(SkImageInfo::MakeN32Premul(SIZE, SIZE));
  106. }
  107. SkPaint paint;
  108. const SkRect r = SkRect::MakeIWH(SIZE, SIZE);
  109. canvas->translate(10, 10);
  110. canvas->save();
  111. paint.setShader(fSH0); canvas->drawRect(r, paint);
  112. canvas->translate(SIZE + 10.f, 0);
  113. paint.setShader(fSH1); canvas->drawRect(r, paint);
  114. canvas->restore();
  115. canvas->translate(0, SIZE + 10.f);
  116. auto sh = fSurface->makeImageSnapshot()->makeShader();
  117. canvas->save();
  118. paint.setShader(sh); canvas->drawRect(r, paint);
  119. canvas->translate(SIZE + 10.f, 0);
  120. paint.setShader(SkShaders::Lerp(sh, fSH0, fSH1)); canvas->drawRect(r, paint);
  121. canvas->restore();
  122. }
  123. virtual Click* onFindClickHandler(SkScalar x, SkScalar y, ModifierKey) override {
  124. fMode = (fMode == SkBlendMode::kSrcOver) ? SkBlendMode::kClear : SkBlendMode::kSrcOver;
  125. return fRect.contains(SkScalarRoundToInt(x),
  126. SkScalarRoundToInt(y)) ? new Click() : nullptr;
  127. }
  128. bool onClick(Click* click) override {
  129. SkPaint p;
  130. p.setAntiAlias(true);
  131. p.setColor(SK_ColorRED);
  132. p.setBlendMode(fMode);
  133. p.setMaskFilter(SkMaskFilter::MakeBlur(kNormal_SkBlurStyle, 12));
  134. SkScalar x = click->fCurr.fX - fRect.fLeft;
  135. SkScalar y = click->fCurr.fY - fRect.fTop;
  136. fSurface->getCanvas()->drawCircle(x, y, 10, p);
  137. return true;
  138. }
  139. private:
  140. typedef Sample INHERITED;
  141. };
  142. DEF_SAMPLE( return new ShaderMixerView; )