blob: eca3c9c67e2d06852b10d9392dc7b111074028e7 [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
9#ifndef SkScanPriv_DEFINED
10#define SkScanPriv_DEFINED
11
12#include "SkScan.h"
13#include "SkBlitter.h"
14
15class SkScanClipper {
16public:
reed@google.com5ee64912012-06-11 17:30:33 +000017 SkScanClipper(SkBlitter* blitter, const SkRegion* clip, const SkIRect& bounds,
18 bool skipRejectTest = false);
reed@android.com8a1c16f2008-12-17 15:59:43 +000019
20 SkBlitter* getBlitter() const { return fBlitter; }
21 const SkIRect* getClipRect() const { return fClipRect; }
22
23private:
24 SkRectClipBlitter fRectBlitter;
25 SkRgnClipBlitter fRgnBlitter;
Mike Reed28930b42016-11-09 15:23:26 -050026#ifdef SK_DEBUG
Yuqian Li99bba9e2016-11-21 09:44:59 -050027 SkRectClipCheckBlitter fRectClipCheckBlitter;
Mike Reed28930b42016-11-09 15:23:26 -050028#endif
reed@android.com8a1c16f2008-12-17 15:59:43 +000029 SkBlitter* fBlitter;
30 const SkIRect* fClipRect;
31};
32
Yuqian Lie4b8b522016-11-16 10:12:58 -050033void sk_fill_path(const SkPath& path, const SkIRect& clipRect,
reed@android.comdca6a562010-02-22 16:05:48 +000034 SkBlitter* blitter, int start_y, int stop_y, int shiftEdgesUp,
Yuqian Lie4b8b522016-11-16 10:12:58 -050035 bool pathContainedInClip);
36
reed@google.com55b6b582011-03-02 15:58:18 +000037// blit the rects above and below avoid, clipped to clip
38void sk_blit_above(SkBlitter*, const SkIRect& avoid, const SkRegion& clip);
39void sk_blit_below(SkBlitter*, const SkIRect& avoid, const SkRegion& clip);
reed@android.com8a1c16f2008-12-17 15:59:43 +000040
Yuqian Lia33b43d2017-03-17 11:26:29 -040041template<class EdgeType>
42static inline void remove_edge(EdgeType* edge) {
43 edge->fPrev->fNext = edge->fNext;
44 edge->fNext->fPrev = edge->fPrev;
45}
46
47template<class EdgeType>
48static 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
55template<class EdgeType>
56static 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.
72template<class EdgeType>
73static 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
reed@android.com8a1c16f2008-12-17 15:59:43 +000080#endif