imagescalealigned.cpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  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. #include "gm/gm.h"
  8. #include "include/core/SkCanvas.h"
  9. #include "include/core/SkColor.h"
  10. #include "include/core/SkFilterQuality.h"
  11. #include "include/core/SkImage.h"
  12. #include "include/core/SkPaint.h"
  13. #include "include/core/SkPoint.h"
  14. #include "include/core/SkRect.h"
  15. #include "include/core/SkRefCnt.h"
  16. #include "include/core/SkScalar.h"
  17. #include "include/core/SkSize.h"
  18. #include "include/core/SkString.h"
  19. #include "include/core/SkSurface.h"
  20. #include "include/core/SkTypes.h"
  21. #include "include/private/SkTArray.h"
  22. class ImageScaleAlignedGM : public skiagm::GM {
  23. protected:
  24. void onOnceBeforeDraw() override {
  25. const SkVector vectors[] = { { 1, 0 }, { 0, 1 } };
  26. for (size_t i = 0; i < SK_ARRAY_COUNT(vectors); ++i) {
  27. auto& set = fSets.push_back();
  28. set.fVector = vectors[i];
  29. set.fImages.push_back() = MakeImage(vectors[i], SK_ColorGREEN);
  30. set.fScales.push_back() = 1;
  31. set.fImages.push_back() = MakeImage(vectors[i], SK_ColorRED);
  32. set.fScales.push_back() = kStretchFactor;
  33. set.fImages.push_back() = MakeImage(vectors[i], SK_ColorGREEN);
  34. set.fScales.push_back() = 1;
  35. }
  36. }
  37. SkString onShortName() override {
  38. return SkString("image_scale_aligned");
  39. }
  40. SkISize onISize() override {
  41. return SkISize::Make(580, 780);
  42. }
  43. void onDraw(SkCanvas* canvas) override {
  44. struct {
  45. SkPoint offset;
  46. SkVector scale;
  47. } cfgs[] = {
  48. {{ 10, 10 }, { 1, 1 }},
  49. {{ 300.5f, 10 }, { 1, 1 }},
  50. {{ 10, 200.5f }, { 1, 1 }},
  51. {{ 300.5f, 200.5f }, { 1, 1 }},
  52. {{ 10.5f, 400.5f }, { 1, 1 }},
  53. {{ 550.5f, 400.5f }, { -1, 1 }},
  54. {{ 10.5f, 750.5f }, { 1, -1 }},
  55. {{ 550.5f, 750.5f }, { -1, -1 }},
  56. };
  57. for (size_t i = 0; i < SK_ARRAY_COUNT(cfgs); ++i) {
  58. SkAutoCanvasRestore acr(canvas, true);
  59. canvas->translate(cfgs[i].offset.x(), cfgs[i].offset.y());
  60. canvas->scale(cfgs[i].scale.x(), cfgs[i].scale.y());
  61. drawSets(canvas);
  62. }
  63. }
  64. private:
  65. struct ImageSet {
  66. SkSTArray<3, sk_sp<SkImage>, true> fImages;
  67. SkSTArray<3, SkScalar> fScales;
  68. SkVector fVector;
  69. };
  70. static sk_sp<SkImage> MakeImage(const SkVector& vec, SkColor color) {
  71. const SkPoint start = SkPoint::Make(vec.y() * kSegLen / 2, vec.x() * kSegLen / 2);
  72. const SkPoint end = SkPoint::Make(start.x() + vec.x() * (kSegLen - 1),
  73. start.y() + vec.y() * (kSegLen - 1));
  74. auto surface(SkSurface::MakeRasterN32Premul(kSegLen, kSegLen));
  75. surface->getCanvas()->clear(SK_ColorTRANSPARENT);
  76. SkPaint paint;
  77. paint.setAntiAlias(true);
  78. const SkRect border = SkRect::MakeIWH(kSegLen, kSegLen).makeInset(.5f, .5f);
  79. paint.setColor(SK_ColorBLUE);
  80. paint.setStyle(SkPaint::kStroke_Style);
  81. surface->getCanvas()->drawRect(border, paint);
  82. paint.setColor(SK_ColorBLACK);
  83. surface->getCanvas()->drawLine(start, end, paint);
  84. paint.reset();
  85. paint.setColor(color);
  86. const SkPoint pts[] = { start, end };
  87. surface->getCanvas()->drawPoints(SkCanvas::kPoints_PointMode, 2, pts, paint);
  88. return surface->makeImageSnapshot();
  89. }
  90. void drawSets(SkCanvas* canvas) const {
  91. SkAutoCanvasRestore acr(canvas, true);
  92. const SkFilterQuality filters[] = {
  93. kNone_SkFilterQuality,
  94. kLow_SkFilterQuality,
  95. kMedium_SkFilterQuality,
  96. kHigh_SkFilterQuality
  97. };
  98. const bool AAs[] = { false, true };
  99. SkPaint paint;
  100. for (int i = 0; i < fSets.count(); ++i) {
  101. auto& set = fSets[i];
  102. SkPoint lastPt;
  103. for (size_t j = 0; j < SK_ARRAY_COUNT(AAs); ++j) {
  104. paint.setAntiAlias(AAs[j]);
  105. for (size_t k = 0; k < SK_ARRAY_COUNT(filters); ++k) {
  106. paint.setFilterQuality(filters[k]);
  107. lastPt = drawSet(canvas, set, paint);
  108. canvas->translate((kSegLen + 4) * set.fVector.y(),
  109. (kSegLen + 4) * set.fVector.x());
  110. }
  111. }
  112. canvas->translate(lastPt.x() + kSegLen,
  113. - SkIntToScalar(kSegLen + 4) * SK_ARRAY_COUNT(filters) * SK_ARRAY_COUNT(AAs));
  114. }
  115. }
  116. SkPoint drawSet(SkCanvas* canvas, const ImageSet& set, const SkPaint& paint) const {
  117. SkASSERT(set.fImages.count() == set.fScales.count());
  118. SkPoint pt = SkPoint::Make(0, 0);
  119. for (int i = 0; i < set.fImages.count(); ++i) {
  120. auto& img = set.fImages[i];
  121. const SkRect dst =
  122. SkRect::MakeXYWH(pt.x(), pt.y(),
  123. img->width() * (1 + (set.fScales[i] - 1) * set.fVector.x()),
  124. img->height() * (1 + (set.fScales[i] - 1) * set.fVector.y()));
  125. canvas->drawImageRect(img.get(), dst, &paint);
  126. pt.offset(dst.width() * set.fVector.x(), dst.height() * set.fVector.y());
  127. }
  128. return pt;
  129. }
  130. static constexpr unsigned kSegLen = 15;
  131. static constexpr unsigned kStretchFactor = 4;
  132. SkSTArray<2, ImageSet> fSets;
  133. typedef GM INHERITED;
  134. };
  135. DEF_GM(return new ImageScaleAlignedGM();)