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