SkScanPriv.h 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. /*
  2. * Copyright 2006 The Android Open Source Project
  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. #ifndef SkScanPriv_DEFINED
  8. #define SkScanPriv_DEFINED
  9. #include "include/core/SkPath.h"
  10. #include "src/core/SkBlitter.h"
  11. #include "src/core/SkScan.h"
  12. // controls how much we super-sample (when we use that scan convertion)
  13. #define SK_SUPERSAMPLE_SHIFT 2
  14. class SkScanClipper {
  15. public:
  16. SkScanClipper(SkBlitter* blitter, const SkRegion* clip, const SkIRect& bounds,
  17. bool skipRejectTest = false, bool boundsPreClipped = false);
  18. SkBlitter* getBlitter() const { return fBlitter; }
  19. const SkIRect* getClipRect() const { return fClipRect; }
  20. private:
  21. SkRectClipBlitter fRectBlitter;
  22. SkRgnClipBlitter fRgnBlitter;
  23. #ifdef SK_DEBUG
  24. SkRectClipCheckBlitter fRectClipCheckBlitter;
  25. #endif
  26. SkBlitter* fBlitter;
  27. const SkIRect* fClipRect;
  28. };
  29. void sk_fill_path(const SkPath& path, const SkIRect& clipRect,
  30. SkBlitter* blitter, int start_y, int stop_y, int shiftEdgesUp,
  31. bool pathContainedInClip);
  32. // blit the rects above and below avoid, clipped to clip
  33. void sk_blit_above(SkBlitter*, const SkIRect& avoid, const SkRegion& clip);
  34. void sk_blit_below(SkBlitter*, const SkIRect& avoid, const SkRegion& clip);
  35. template<class EdgeType>
  36. static inline void remove_edge(EdgeType* edge) {
  37. edge->fPrev->fNext = edge->fNext;
  38. edge->fNext->fPrev = edge->fPrev;
  39. }
  40. template<class EdgeType>
  41. static inline void insert_edge_after(EdgeType* edge, EdgeType* afterMe) {
  42. edge->fPrev = afterMe;
  43. edge->fNext = afterMe->fNext;
  44. afterMe->fNext->fPrev = edge;
  45. afterMe->fNext = edge;
  46. }
  47. template<class EdgeType>
  48. static void backward_insert_edge_based_on_x(EdgeType* edge) {
  49. SkFixed x = edge->fX;
  50. EdgeType* prev = edge->fPrev;
  51. while (prev->fPrev && prev->fX > x) {
  52. prev = prev->fPrev;
  53. }
  54. if (prev->fNext != edge) {
  55. remove_edge(edge);
  56. insert_edge_after(edge, prev);
  57. }
  58. }
  59. // Start from the right side, searching backwards for the point to begin the new edge list
  60. // insertion, marching forwards from here. The implementation could have started from the left
  61. // of the prior insertion, and search to the right, or with some additional caching, binary
  62. // search the starting point. More work could be done to determine optimal new edge insertion.
  63. template<class EdgeType>
  64. static EdgeType* backward_insert_start(EdgeType* prev, SkFixed x) {
  65. while (prev->fPrev && prev->fX > x) {
  66. prev = prev->fPrev;
  67. }
  68. return prev;
  69. }
  70. // Check if the path is a rect and fat enough after clipping; if so, blit it.
  71. static inline bool TryBlitFatAntiRect(SkBlitter* blitter, const SkPath& path, const SkIRect& clip) {
  72. SkRect rect;
  73. if (!path.isRect(&rect)) {
  74. return false; // not rect
  75. }
  76. if (!rect.intersect(SkRect::Make(clip))) {
  77. return true; // The intersection is empty. Hence consider it done.
  78. }
  79. SkIRect bounds = rect.roundOut();
  80. if (bounds.width() < 3) {
  81. return false; // not fat
  82. }
  83. blitter->blitFatAntiRect(rect);
  84. return true;
  85. }
  86. #endif