Line data Source code
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 226 : class SkScanClipper {
16 : public:
17 : SkScanClipper(SkBlitter* blitter, const SkRegion* clip, const SkIRect& bounds,
18 : bool skipRejectTest = false);
19 :
20 450 : SkBlitter* getBlitter() const { return fBlitter; }
21 275 : 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>
42 959 : static inline void remove_edge(EdgeType* edge) {
43 959 : edge->fPrev->fNext = edge->fNext;
44 959 : edge->fNext->fPrev = edge->fPrev;
45 959 : }
46 :
47 : template<class EdgeType>
48 226 : static inline void insert_edge_after(EdgeType* edge, EdgeType* afterMe) {
49 226 : edge->fPrev = afterMe;
50 226 : edge->fNext = afterMe->fNext;
51 226 : afterMe->fNext->fPrev = edge;
52 226 : afterMe->fNext = edge;
53 226 : }
54 :
55 : template<class EdgeType>
56 0 : static void backward_insert_edge_based_on_x(EdgeType* edge) {
57 0 : SkFixed x = edge->fX;
58 0 : EdgeType* prev = edge->fPrev;
59 0 : while (prev->fPrev && prev->fX > x) {
60 0 : prev = prev->fPrev;
61 : }
62 0 : if (prev->fNext != edge) {
63 0 : remove_edge(edge);
64 0 : insert_edge_after(edge, prev);
65 : }
66 0 : }
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>
73 377 : static EdgeType* backward_insert_start(EdgeType* prev, SkFixed x) {
74 619 : while (prev->fPrev && prev->fX > x) {
75 242 : prev = prev->fPrev;
76 : }
77 135 : return prev;
78 : }
79 :
80 : #endif
|