SkDrawLooper.cpp 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. /*
  2. * Copyright 2013 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/SkDrawLooper.h"
  9. #include "include/core/SkMatrix.h"
  10. #include "include/core/SkPaint.h"
  11. #include "include/core/SkRect.h"
  12. #include "src/core/SkArenaAlloc.h"
  13. bool SkDrawLooper::canComputeFastBounds(const SkPaint& paint) const {
  14. SkCanvas canvas;
  15. SkSTArenaAlloc<48> alloc;
  16. SkDrawLooper::Context* context = this->makeContext(&canvas, &alloc);
  17. for (;;) {
  18. SkPaint p(paint);
  19. if (context->next(&canvas, &p)) {
  20. #ifdef SK_SUPPORT_LEGACY_DRAWLOOPER
  21. p.setLooper(nullptr);
  22. #endif
  23. if (!p.canComputeFastBounds()) {
  24. return false;
  25. }
  26. } else {
  27. break;
  28. }
  29. }
  30. return true;
  31. }
  32. void SkDrawLooper::computeFastBounds(const SkPaint& paint, const SkRect& s,
  33. SkRect* dst) const {
  34. // src and dst rects may alias and we need to keep the original src, so copy it.
  35. const SkRect src = s;
  36. SkCanvas canvas;
  37. SkSTArenaAlloc<48> alloc;
  38. *dst = src; // catch case where there are no loops
  39. SkDrawLooper::Context* context = this->makeContext(&canvas, &alloc);
  40. for (bool firstTime = true;; firstTime = false) {
  41. SkPaint p(paint);
  42. if (context->next(&canvas, &p)) {
  43. SkRect r(src);
  44. #ifdef SK_SUPPORT_LEGACY_DRAWLOOPER
  45. p.setLooper(nullptr);
  46. #endif
  47. p.computeFastBounds(r, &r);
  48. canvas.getTotalMatrix().mapRect(&r);
  49. if (firstTime) {
  50. *dst = r;
  51. } else {
  52. dst->join(r);
  53. }
  54. } else {
  55. break;
  56. }
  57. }
  58. }
  59. bool SkDrawLooper::asABlurShadow(BlurShadowRec*) const {
  60. return false;
  61. }
  62. void SkDrawLooper::apply(SkCanvas* canvas, const SkPaint& paint,
  63. std::function<void(SkCanvas*, const SkPaint&)> proc) {
  64. SkSTArenaAlloc<256> alloc;
  65. Context* ctx = this->makeContext(canvas, &alloc);
  66. if (ctx) {
  67. for (;;) {
  68. SkPaint p = paint;
  69. if (!ctx->next(canvas, &p)) {
  70. break;
  71. }
  72. proc(canvas, p);
  73. }
  74. }
  75. }