...
1
2
3
4
5 package vector
6
7
8
9
10 import (
11 "math"
12 )
13
14 func floatingMax(x, y float32) float32 {
15 if x > y {
16 return x
17 }
18 return y
19 }
20
21 func floatingMin(x, y float32) float32 {
22 if x < y {
23 return x
24 }
25 return y
26 }
27
28 func floatingFloor(x float32) int32 { return int32(math.Floor(float64(x))) }
29 func floatingCeil(x float32) int32 { return int32(math.Ceil(float64(x))) }
30
31 func (z *Rasterizer) floatingLineTo(bx, by float32) {
32 ax, ay := z.penX, z.penY
33 z.penX, z.penY = bx, by
34 dir := float32(1)
35 if ay > by {
36 dir, ax, ay, bx, by = -1, bx, by, ax, ay
37 }
38
39
40
41
42 if by-ay <= 0.000001 {
43 return
44 }
45 dxdy := (bx - ax) / (by - ay)
46
47 x := ax
48 y := floatingFloor(ay)
49 yMax := floatingCeil(by)
50 if yMax > int32(z.size.Y) {
51 yMax = int32(z.size.Y)
52 }
53 width := int32(z.size.X)
54
55 for ; y < yMax; y++ {
56 dy := floatingMin(float32(y+1), by) - floatingMax(float32(y), ay)
57
58
59
60
61
62
63
64
65
66
67
68
69 xNext := x + float32(dy*dxdy)
70 if y < 0 {
71 x = xNext
72 continue
73 }
74 buf := z.bufF32[y*width:]
75 d := float32(dy * dir)
76 x0, x1 := x, xNext
77 if x > xNext {
78 x0, x1 = x1, x0
79 }
80 x0i := floatingFloor(x0)
81 x0Floor := float32(x0i)
82 x1i := floatingCeil(x1)
83 x1Ceil := float32(x1i)
84
85 if x1i <= x0i+1 {
86 xmf := float32(0.5*(x+xNext)) - x0Floor
87 if i := clamp(x0i+0, width); i < uint(len(buf)) {
88 buf[i] += d - float32(d*xmf)
89 }
90 if i := clamp(x0i+1, width); i < uint(len(buf)) {
91 buf[i] += float32(d * xmf)
92 }
93 } else {
94 s := 1 / (x1 - x0)
95 x0f := x0 - x0Floor
96 oneMinusX0f := 1 - x0f
97 a0 := float32(0.5 * s * oneMinusX0f * oneMinusX0f)
98 x1f := x1 - x1Ceil + 1
99 am := float32(0.5 * s * x1f * x1f)
100
101 if i := clamp(x0i, width); i < uint(len(buf)) {
102 buf[i] += float32(d * a0)
103 }
104
105 if x1i == x0i+2 {
106 if i := clamp(x0i+1, width); i < uint(len(buf)) {
107 buf[i] += float32(d * (1 - a0 - am))
108 }
109 } else {
110 a1 := float32(s * (1.5 - x0f))
111 if i := clamp(x0i+1, width); i < uint(len(buf)) {
112 buf[i] += float32(d * (a1 - a0))
113 }
114 dTimesS := float32(d * s)
115 for xi := x0i + 2; xi < x1i-1; xi++ {
116 if i := clamp(xi, width); i < uint(len(buf)) {
117 buf[i] += dTimesS
118 }
119 }
120 a2 := a1 + float32(s*float32(x1i-x0i-3))
121 if i := clamp(x1i-1, width); i < uint(len(buf)) {
122 buf[i] += float32(d * (1 - a2 - am))
123 }
124 }
125
126 if i := clamp(x1i, width); i < uint(len(buf)) {
127 buf[i] += float32(d * am)
128 }
129 }
130
131 x = xNext
132 }
133 }
134
135 const (
136
137
138
139
140
141
142
143
144
145
146
147
148
149 almost256 = 255.99998
150
151
152
153
154
155 almost65536 = almost256 * 256
156 )
157
158 func floatingAccumulateOpOver(dst []uint8, src []float32) {
159
160 if len(dst) < len(src) {
161 return
162 }
163
164 acc := float32(0)
165 for i, v := range src {
166 acc += v
167 a := acc
168 if a < 0 {
169 a = -a
170 }
171 if a > 1 {
172 a = 1
173 }
174
175 dstA := uint32(dst[i]) * 0x101
176 maskA := uint32(almost65536 * a)
177 outA := dstA*(0xffff-maskA)/0xffff + maskA
178 dst[i] = uint8(outA >> 8)
179 }
180 }
181
182 func floatingAccumulateOpSrc(dst []uint8, src []float32) {
183
184 if len(dst) < len(src) {
185 return
186 }
187
188 acc := float32(0)
189 for i, v := range src {
190 acc += v
191 a := acc
192 if a < 0 {
193 a = -a
194 }
195 if a > 1 {
196 a = 1
197 }
198 dst[i] = uint8(almost256 * a)
199 }
200 }
201
202 func floatingAccumulateMask(dst []uint32, src []float32) {
203
204 if len(dst) < len(src) {
205 return
206 }
207
208 acc := float32(0)
209 for i, v := range src {
210 acc += v
211 a := acc
212 if a < 0 {
213 a = -a
214 }
215 if a > 1 {
216 a = 1
217 }
218 dst[i] = uint32(almost65536 * a)
219 }
220 }
221
View as plain text