blob: a1fddb24d73932a2d738ac1286b4b7a263ed20b0 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001/*
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
reed@android.com8a1c16f2008-12-17 15:59:43 +00008#ifndef SkScanPriv_DEFINED
9#define SkScanPriv_DEFINED
10
Yuqian Lica50b872017-06-12 10:40:50 -040011#include "SkPath.h"
reed@android.com8a1c16f2008-12-17 15:59:43 +000012#include "SkScan.h"
13#include "SkBlitter.h"
14
Mike Reed23e0cf22018-01-16 13:58:01 -050015// controls how much we super-sample (when we use that scan convertion)
16#define SK_SUPERSAMPLE_SHIFT 2
17
reed@android.com8a1c16f2008-12-17 15:59:43 +000018class SkScanClipper {
19public:
reed@google.com5ee64912012-06-11 17:30:33 +000020 SkScanClipper(SkBlitter* blitter, const SkRegion* clip, const SkIRect& bounds,
Ben Wagner1c35e572017-10-09 22:58:53 +000021 bool skipRejectTest = false, bool boundsPreClipped = false);
reed@android.com8a1c16f2008-12-17 15:59:43 +000022
23 SkBlitter* getBlitter() const { return fBlitter; }
24 const SkIRect* getClipRect() const { return fClipRect; }
25
26private:
27 SkRectClipBlitter fRectBlitter;
28 SkRgnClipBlitter fRgnBlitter;
Mike Reed28930b42016-11-09 15:23:26 -050029#ifdef SK_DEBUG
Yuqian Li99bba9e2016-11-21 09:44:59 -050030 SkRectClipCheckBlitter fRectClipCheckBlitter;
Mike Reed28930b42016-11-09 15:23:26 -050031#endif
reed@android.com8a1c16f2008-12-17 15:59:43 +000032 SkBlitter* fBlitter;
33 const SkIRect* fClipRect;
34};
35
Yuqian Lie4b8b522016-11-16 10:12:58 -050036void sk_fill_path(const SkPath& path, const SkIRect& clipRect,
reed@android.comdca6a562010-02-22 16:05:48 +000037 SkBlitter* blitter, int start_y, int stop_y, int shiftEdgesUp,
Yuqian Lie4b8b522016-11-16 10:12:58 -050038 bool pathContainedInClip);
39
reed@google.com55b6b582011-03-02 15:58:18 +000040// blit the rects above and below avoid, clipped to clip
41void sk_blit_above(SkBlitter*, const SkIRect& avoid, const SkRegion& clip);
42void sk_blit_below(SkBlitter*, const SkIRect& avoid, const SkRegion& clip);
reed@android.com8a1c16f2008-12-17 15:59:43 +000043
Yuqian Lia33b43d2017-03-17 11:26:29 -040044template<class EdgeType>
45static inline void remove_edge(EdgeType* edge) {
46 edge->fPrev->fNext = edge->fNext;
47 edge->fNext->fPrev = edge->fPrev;
48}
49
50template<class EdgeType>
51static inline void insert_edge_after(EdgeType* edge, EdgeType* afterMe) {
52 edge->fPrev = afterMe;
53 edge->fNext = afterMe->fNext;
54 afterMe->fNext->fPrev = edge;
55 afterMe->fNext = edge;
56}
57
58template<class EdgeType>
59static void backward_insert_edge_based_on_x(EdgeType* edge) {
60 SkFixed x = edge->fX;
61 EdgeType* prev = edge->fPrev;
62 while (prev->fPrev && prev->fX > x) {
63 prev = prev->fPrev;
64 }
65 if (prev->fNext != edge) {
66 remove_edge(edge);
67 insert_edge_after(edge, prev);
68 }
69}
70
71// Start from the right side, searching backwards for the point to begin the new edge list
72// insertion, marching forwards from here. The implementation could have started from the left
73// of the prior insertion, and search to the right, or with some additional caching, binary
74// search the starting point. More work could be done to determine optimal new edge insertion.
75template<class EdgeType>
76static EdgeType* backward_insert_start(EdgeType* prev, SkFixed x) {
77 while (prev->fPrev && prev->fX > x) {
78 prev = prev->fPrev;
79 }
80 return prev;
81}
82
Yuqian Lif60c1a32017-09-25 11:18:08 -040083// Check if the path is a rect and fat enough after clipping; if so, blit it.
84static inline bool TryBlitFatAntiRect(SkBlitter* blitter, const SkPath& path, const SkIRect& clip) {
85 SkRect rect;
86 if (!path.isRect(&rect)) {
87 return false; // not rect
88 }
89 if (!rect.intersect(SkRect::Make(clip))) {
90 return true; // The intersection is empty. Hence consider it done.
91 }
92 SkIRect bounds = rect.roundOut();
Yuqian Li63f69cd2018-04-18 15:09:44 -040093 if (bounds.width() < 3) {
Yuqian Lif60c1a32017-09-25 11:18:08 -040094 return false; // not fat
95 }
96 blitter->blitFatAntiRect(rect);
97 return true;
98}
99
reed@android.com8a1c16f2008-12-17 15:59:43 +0000100#endif