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
8
9 #ifndef SkScanPriv_DEFINED
10 #define SkScanPriv_DEFINED
11
12 #include "SkScan.h"
13 #include "SkBlitter.h"
14
15 class SkScanClipper {
16 public:
17 SkScanClipper(SkBlitter* blitter, const SkRegion* clip, const SkIRect& bounds,
18 bool skipRejectTest = false);
19
getBlitter()20 SkBlitter* getBlitter() const { return fBlitter; }
getClipRect()21 const SkIRect* getClipRect() const { return fClipRect; }
22
23 private:
24 SkRectClipBlitter fRectBlitter;
25 SkRgnClipBlitter fRgnBlitter;
26 #ifdef SK_DEBUG
27 SkRectClipCheckBlitter fRectClipCheckBlitter;
28 #endif
29 SkBlitter* fBlitter;
30 const SkIRect* fClipRect;
31 };
32
33 void sk_fill_path(const SkPath& path, const SkIRect& clipRect,
34 SkBlitter* blitter, int start_y, int stop_y, int shiftEdgesUp,
35 bool pathContainedInClip);
36
37 // blit the rects above and below avoid, clipped to clip
38 void sk_blit_above(SkBlitter*, const SkIRect& avoid, const SkRegion& clip);
39 void sk_blit_below(SkBlitter*, const SkIRect& avoid, const SkRegion& clip);
40
41 template<class EdgeType>
remove_edge(EdgeType * edge)42 static inline void remove_edge(EdgeType* edge) {
43 edge->fPrev->fNext = edge->fNext;
44 edge->fNext->fPrev = edge->fPrev;
45 }
46
47 template<class EdgeType>
insert_edge_after(EdgeType * edge,EdgeType * afterMe)48 static inline void insert_edge_after(EdgeType* edge, EdgeType* afterMe) {
49 edge->fPrev = afterMe;
50 edge->fNext = afterMe->fNext;
51 afterMe->fNext->fPrev = edge;
52 afterMe->fNext = edge;
53 }
54
55 template<class EdgeType>
backward_insert_edge_based_on_x(EdgeType * edge)56 static void backward_insert_edge_based_on_x(EdgeType* edge) {
57 SkFixed x = edge->fX;
58 EdgeType* prev = edge->fPrev;
59 while (prev->fPrev && prev->fX > x) {
60 prev = prev->fPrev;
61 }
62 if (prev->fNext != edge) {
63 remove_edge(edge);
64 insert_edge_after(edge, prev);
65 }
66 }
67
68 // Start from the right side, searching backwards for the point to begin the new edge list
69 // insertion, marching forwards from here. The implementation could have started from the left
70 // of the prior insertion, and search to the right, or with some additional caching, binary
71 // search the starting point. More work could be done to determine optimal new edge insertion.
72 template<class EdgeType>
backward_insert_start(EdgeType * prev,SkFixed x)73 static EdgeType* backward_insert_start(EdgeType* prev, SkFixed x) {
74 while (prev->fPrev && prev->fX > x) {
75 prev = prev->fPrev;
76 }
77 return prev;
78 }
79
80 #endif
81