aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/SkScan.h
blob: 75fd2ac3c68cbcb893c63139311ad8ad24aa1501 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
/*
 * Copyright 2011 The Android Open Source Project
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */


#ifndef SkScan_DEFINED
#define SkScan_DEFINED

#include "SkCoverageDelta.h"
#include "SkFixed.h"
#include "SkRect.h"
#include <atomic>

class SkRasterClip;
class SkRegion;
class SkBlitter;
class SkPath;

/** Defines a fixed-point rectangle, identical to the integer SkIRect, but its
    coordinates are treated as SkFixed rather than int32_t.
*/
typedef SkIRect SkXRect;

extern std::atomic<bool> gSkUseDeltaAA;
extern std::atomic<bool> gSkForceDeltaAA;
extern std::atomic<bool> gSkUseAnalyticAA;
extern std::atomic<bool> gSkForceAnalyticAA;

class AdditiveBlitter;

class SkScan {
public:
    /*
     *  Draws count-1 line segments, one at a time:
     *      line(pts[0], pts[1])
     *      line(pts[1], pts[2])
     *      line(......, pts[count - 1])
     */
    typedef void (*HairRgnProc)(const SkPoint[], int count, const SkRegion*, SkBlitter*);
    typedef void (*HairRCProc)(const SkPoint[], int count, const SkRasterClip&, SkBlitter*);

    static void FillPath(const SkPath&, const SkIRect&, SkBlitter*);

    ///////////////////////////////////////////////////////////////////////////
    // rasterclip

    static void FillIRect(const SkIRect&, const SkRasterClip&, SkBlitter*);
    static void FillXRect(const SkXRect&, const SkRasterClip&, SkBlitter*);
    static void FillRect(const SkRect&, const SkRasterClip&, SkBlitter*);
    static void AntiFillRect(const SkRect&, const SkRasterClip&, SkBlitter*);
    static void AntiFillXRect(const SkXRect&, const SkRasterClip&, SkBlitter*);
    static void FillPath(const SkPath&, const SkRasterClip&, SkBlitter*);
    static void AntiFillPath(const SkPath&, const SkRasterClip&, SkBlitter*, SkDAARecord*);
    static void FrameRect(const SkRect&, const SkPoint& strokeSize,
                          const SkRasterClip&, SkBlitter*);
    static void AntiFrameRect(const SkRect&, const SkPoint& strokeSize,
                              const SkRasterClip&, SkBlitter*);
    static void FillTriangle(const SkPoint pts[], const SkRasterClip&, SkBlitter*);
    static void HairLine(const SkPoint[], int count, const SkRasterClip&, SkBlitter*);
    static void AntiHairLine(const SkPoint[], int count, const SkRasterClip&, SkBlitter*);
    static void HairRect(const SkRect&, const SkRasterClip&, SkBlitter*);
    static void AntiHairRect(const SkRect&, const SkRasterClip&, SkBlitter*);
    static void HairPath(const SkPath&, const SkRasterClip&, SkBlitter*);
    static void AntiHairPath(const SkPath&, const SkRasterClip&, SkBlitter*);
    static void HairSquarePath(const SkPath&, const SkRasterClip&, SkBlitter*);
    static void AntiHairSquarePath(const SkPath&, const SkRasterClip&, SkBlitter*);
    static void HairRoundPath(const SkPath&, const SkRasterClip&, SkBlitter*);
    static void AntiHairRoundPath(const SkPath&, const SkRasterClip&, SkBlitter*);

    // Needed by do_fill_path in SkScanPriv.h
    static void FillPath(const SkPath&, const SkRegion& clip, SkBlitter*);

    // We have this instead of a default nullptr parameter because of function pointer match.
    static void AntiFillPath(const SkPath& path, const SkRasterClip& rc, SkBlitter* blitter) {
        AntiFillPath(path, rc, blitter, nullptr);
    }
private:
    friend class SkAAClip;
    friend class SkRegion;

    static void FillIRect(const SkIRect&, const SkRegion* clip, SkBlitter*);
    static void FillXRect(const SkXRect&, const SkRegion* clip, SkBlitter*);
    static void FillRect(const SkRect&, const SkRegion* clip, SkBlitter*);
    static void AntiFillRect(const SkRect&, const SkRegion* clip, SkBlitter*);
    static void AntiFillXRect(const SkXRect&, const SkRegion*, SkBlitter*);
    static void AntiFillPath(const SkPath&, const SkRegion& clip, SkBlitter*,
                             bool forceRLE = false, SkDAARecord* daaRecord = nullptr);
    static void FillTriangle(const SkPoint pts[], const SkRegion*, SkBlitter*);

    static void AntiFrameRect(const SkRect&, const SkPoint& strokeSize,
                              const SkRegion*, SkBlitter*);
    static void HairLineRgn(const SkPoint[], int count, const SkRegion*, SkBlitter*);
    static void AntiHairLineRgn(const SkPoint[], int count, const SkRegion*, SkBlitter*);
    static void AAAFillPath(const SkPath& path, SkBlitter* blitter, const SkIRect& pathIR,
                            const SkIRect& clipBounds, bool forceRLE);
    static void DAAFillPath(const SkPath& path, SkBlitter* blitter, const SkIRect& pathIR,
                            const SkIRect& clipBounds, bool forceRLE, SkDAARecord* daaRecord);
    static void SAAFillPath(const SkPath& path, SkBlitter* blitter, const SkIRect& pathIR,
                            const SkIRect& clipBounds, bool forceRLE);
};

/** Assign an SkXRect from a SkIRect, by promoting the src rect's coordinates
    from int to SkFixed. Does not check for overflow if the src coordinates
    exceed 32K
*/
static inline void XRect_set(SkXRect* xr, const SkIRect& src) {
    xr->fLeft = SkIntToFixed(src.fLeft);
    xr->fTop = SkIntToFixed(src.fTop);
    xr->fRight = SkIntToFixed(src.fRight);
    xr->fBottom = SkIntToFixed(src.fBottom);
}

/** Assign an SkXRect from a SkRect, by promoting the src rect's coordinates
    from SkScalar to SkFixed. Does not check for overflow if the src coordinates
    exceed 32K
*/
static inline void XRect_set(SkXRect* xr, const SkRect& src) {
    xr->fLeft = SkScalarToFixed(src.fLeft);
    xr->fTop = SkScalarToFixed(src.fTop);
    xr->fRight = SkScalarToFixed(src.fRight);
    xr->fBottom = SkScalarToFixed(src.fBottom);
}

/** Round the SkXRect coordinates, and store the result in the SkIRect.
*/
static inline void XRect_round(const SkXRect& xr, SkIRect* dst) {
    dst->fLeft = SkFixedRoundToInt(xr.fLeft);
    dst->fTop = SkFixedRoundToInt(xr.fTop);
    dst->fRight = SkFixedRoundToInt(xr.fRight);
    dst->fBottom = SkFixedRoundToInt(xr.fBottom);
}

/** Round the SkXRect coordinates out (i.e. use floor for left/top, and ceiling
    for right/bottom), and store the result in the SkIRect.
*/
static inline void XRect_roundOut(const SkXRect& xr, SkIRect* dst) {
    dst->fLeft = SkFixedFloorToInt(xr.fLeft);
    dst->fTop = SkFixedFloorToInt(xr.fTop);
    dst->fRight = SkFixedCeilToInt(xr.fRight);
    dst->fBottom = SkFixedCeilToInt(xr.fBottom);
}

#endif