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 #include "SkScan.h"
10 #include "SkBlitter.h"
11 #include "SkRasterClip.h"
12 
13 std::atomic<bool> gSkUseAnalyticAA{true};
14 std::atomic<bool> gSkForceAnalyticAA{false};
15 
16 std::atomic<bool> gSkUseDeltaAA{true};
17 std::atomic<bool> gSkForceDeltaAA{false};
18 
blitrect(SkBlitter * blitter,const SkIRect & r)19 static inline void blitrect(SkBlitter* blitter, const SkIRect& r) {
20     blitter->blitRect(r.fLeft, r.fTop, r.width(), r.height());
21 }
22 
FillIRect(const SkIRect & r,const SkRegion * clip,SkBlitter * blitter)23 void SkScan::FillIRect(const SkIRect& r, const SkRegion* clip,
24                        SkBlitter* blitter) {
25     if (!r.isEmpty()) {
26         if (clip) {
27             if (clip->isRect()) {
28                 const SkIRect& clipBounds = clip->getBounds();
29 
30                 if (clipBounds.contains(r)) {
31                     blitrect(blitter, r);
32                 } else {
33                     SkIRect rr = r;
34                     if (rr.intersect(clipBounds)) {
35                         blitrect(blitter, rr);
36                     }
37                 }
38             } else {
39                 SkRegion::Cliperator    cliper(*clip, r);
40                 const SkIRect&          rr = cliper.rect();
41 
42                 while (!cliper.done()) {
43                     blitrect(blitter, rr);
44                     cliper.next();
45                 }
46             }
47         } else {
48             blitrect(blitter, r);
49         }
50     }
51 }
52 
FillXRect(const SkXRect & xr,const SkRegion * clip,SkBlitter * blitter)53 void SkScan::FillXRect(const SkXRect& xr, const SkRegion* clip,
54                        SkBlitter* blitter) {
55     SkIRect r;
56 
57     XRect_round(xr, &r);
58     SkScan::FillIRect(r, clip, blitter);
59 }
60 
FillRect(const SkRect & r,const SkRegion * clip,SkBlitter * blitter)61 void SkScan::FillRect(const SkRect& r, const SkRegion* clip,
62                        SkBlitter* blitter) {
63     SkIRect ir;
64 
65     r.round(&ir);
66     SkScan::FillIRect(ir, clip, blitter);
67 }
68 
69 ///////////////////////////////////////////////////////////////////////////////
70 
FillIRect(const SkIRect & r,const SkRasterClip & clip,SkBlitter * blitter)71 void SkScan::FillIRect(const SkIRect& r, const SkRasterClip& clip,
72                        SkBlitter* blitter) {
73     if (clip.isEmpty() || r.isEmpty()) {
74         return;
75     }
76 
77     if (clip.isBW()) {
78         FillIRect(r, &clip.bwRgn(), blitter);
79         return;
80     }
81 
82     SkAAClipBlitterWrapper wrapper(clip, blitter);
83     FillIRect(r, &wrapper.getRgn(), wrapper.getBlitter());
84 }
85 
FillXRect(const SkXRect & xr,const SkRasterClip & clip,SkBlitter * blitter)86 void SkScan::FillXRect(const SkXRect& xr, const SkRasterClip& clip,
87                        SkBlitter* blitter) {
88     if (clip.isEmpty() || xr.isEmpty()) {
89         return;
90     }
91 
92     if (clip.isBW()) {
93         FillXRect(xr, &clip.bwRgn(), blitter);
94         return;
95     }
96 
97     SkAAClipBlitterWrapper wrapper(clip, blitter);
98     FillXRect(xr, &wrapper.getRgn(), wrapper.getBlitter());
99 }
100 
FillRect(const SkRect & r,const SkRasterClip & clip,SkBlitter * blitter)101 void SkScan::FillRect(const SkRect& r, const SkRasterClip& clip,
102                       SkBlitter* blitter) {
103     if (clip.isEmpty() || r.isEmpty()) {
104         return;
105     }
106 
107     if (clip.isBW()) {
108         FillRect(r, &clip.bwRgn(), blitter);
109         return;
110     }
111 
112     SkAAClipBlitterWrapper wrapper(clip, blitter);
113     FillRect(r, &wrapper.getRgn(), wrapper.getBlitter());
114 }
115