1
2use crate::render::LineInterpolator;
3use crate::render::LineInterpolatorImage;
4use crate::MAX_HALF_WIDTH;
7use crate::POLY_MR_SUBPIXEL_SHIFT;
8use crate::POLY_SUBPIXEL_SHIFT;
9use crate::POLY_SUBPIXEL_MASK;
10use crate::POLY_SUBPIXEL_SCALE;
11use crate::DistanceInterpolator;
12use crate::RenderOutline;
13
14#[derive(Debug)]
15pub struct LineInterpolatorAA {
16 lp: LineParameters,
17 li: LineInterpolator,
18 len: i64,
19 x: i64,
20 y: i64,
21 old_x: i64,
22 old_y: i64,
23 count: i64,
24 width: i64,
25 max_extent: i64,
26 step: i64,
27 dist: Vec<i64>,
29 covers: Vec<u64>,
31}
32
33impl LineInterpolatorAA {
34 fn new(lp: LineParameters, subpixel_width: i64) -> Self {
35 let len = if lp.vertical == (lp.inc > 0) { -lp.len } else { lp.len };
36 let x = lp.x1 >> POLY_SUBPIXEL_SHIFT;
37 let y = lp.y1 >> POLY_SUBPIXEL_SHIFT;
38 let old_x = x;
39 let old_y = y;
40 let count = if lp.vertical {
41 ((lp.y2 >> POLY_SUBPIXEL_SHIFT) - y).abs()
42 } else {
43 ((lp.x2 >> POLY_SUBPIXEL_SHIFT) - x).abs()
44 };
45 let width = subpixel_width;
46 let max_extent = (width + POLY_SUBPIXEL_MASK) >> POLY_SUBPIXEL_SHIFT;
47 let step = 0;
48 let y1 = if lp.vertical {
49 (lp.x2-lp.x1) << POLY_SUBPIXEL_SHIFT
50 } else {
51 (lp.y2-lp.y1) << POLY_SUBPIXEL_SHIFT
52 };
53 let n = if lp.vertical {
54 (lp.y2-lp.y1).abs()
55 } else {
56 (lp.x2-lp.x1).abs() + 1
57 };
58
59 let m_li = LineInterpolator::new_back_adjusted_2(y1, n);
60
61 let mut dd = if lp.vertical { lp.dy } else { lp.dx };
62 dd <<= POLY_SUBPIXEL_SHIFT;
63 let mut li = LineInterpolator::new_foward_adjusted(0, dd, lp.len);
64
65 let mut dist = vec![0i64; MAX_HALF_WIDTH + 1];
66 let stop = width + POLY_SUBPIXEL_SCALE * 2;
67 for i in 0 .. MAX_HALF_WIDTH {
68 dist[i] = li.y;
69 if li.y >= stop {
70 break;
71 }
72 li.inc();
73 }
74 dist[MAX_HALF_WIDTH] = 0x7FFF_0000 ;
75 let covers = vec![0u64; MAX_HALF_WIDTH * 2 + 4];
76 Self { lp, li: m_li, len, x, y, old_x, old_y, count,
77 width, max_extent, step,
78 dist, covers }
79 }
80 pub fn step_hor_base<DI>(&mut self, di: &mut DI) -> i64
81 where DI: DistanceInterpolator
82 {
83 self.li.inc();
84 self.x += self.lp.inc;
85 self.y = (self.lp.y1 + self.li.y) >> POLY_SUBPIXEL_SHIFT;
86 if self.lp.inc > 0 {
87 di.inc_x(self.y - self.old_y);
88 } else {
89 di.dec_x(self.y - self.old_y);
90 }
91 self.old_y = self.y;
92 di.dist() / self.len
93 }
94 pub fn step_ver_base<DI>(&mut self, di: &mut DI) -> i64
95 where DI: DistanceInterpolator
96 {
97 self.li.inc();
98 self.y += self.lp.inc;
99 self.x = (self.lp.x1 + self.li.y) >> POLY_SUBPIXEL_SHIFT;
100
101 if self.lp.inc > 0 {
102 di.inc_y(self.x - self.old_x);
103 } else {
104 di.dec_y(self.x - self.old_x);
105 }
106
107 self.old_x = self.x;
108 di.dist() / self.len
109 }
110}
111
112#[derive(Debug)]
113pub(crate) struct AA0 {
114 di: DistanceInterpolator1,
115 li: LineInterpolatorAA,
116}
117impl AA0 {
118 pub fn new(lp: LineParameters, subpixel_width: i64) -> Self {
119 let mut li = LineInterpolatorAA::new(lp, subpixel_width);
120 li.li.adjust_forward();
121 Self { li, di: DistanceInterpolator1::new(lp.x1,lp.y1,lp.x2,lp.y2,
122 lp.x1 & ! POLY_SUBPIXEL_MASK,
123 lp.y1 & ! POLY_SUBPIXEL_MASK)
124 }
125 }
126 pub fn count(&self) -> i64 { self.li.count }
127 pub fn vertical(&self) -> bool { self.li.lp.vertical }
128 pub fn step_hor<R>(&mut self, ren: &mut R) -> bool
129 where R: RenderOutline
130 {
131 let s1 = self.li.step_hor_base(&mut self.di);
132 let mut p0 = MAX_HALF_WIDTH + 2;
133 let mut p1 = p0;
134
135 self.li.covers[p1] = ren.cover(s1);
136
137 p1 += 1;
138 let mut dy = 1;
139 let mut dist = self.li.dist[dy] - s1;
140 while dist <= self.li.width {
141 self.li.covers[p1] = ren.cover(dist);
142 p1 += 1;
143 dy += 1;
144 dist = self.li.dist[dy] - s1;
145 }
146
147 let mut dy = 1;
148 dist = self.li.dist[dy] + s1;
149 while dist <= self.li.width {
150 p0 -= 1;
151 self.li.covers[p0] = ren.cover(dist);
152 dy += 1;
153 dist = self.li.dist[dy] + s1;
154 }
155 ren.blend_solid_vspan(self.li.x,
156 self.li.y - dy as i64 + 1,
157 (p1 - p0) as i64,
158 &self.li.covers[p0..]);
159 self.li.step += 1;
160 self.li.step < self.li.count
161 }
162 pub fn step_ver<R: RenderOutline>(&mut self, ren: &mut R) -> bool {
163 let s1 = self.li.step_ver_base(&mut self.di);
164 let mut p0 = MAX_HALF_WIDTH + 2;
165 let mut p1 = p0;
166 self.li.covers[p1] = ren.cover(s1);
167 p1 += 1;
168 let mut dx = 1;
169 let mut dist = self.li.dist[dx] - s1;
170 while dist <= self.li.width {
171 self.li.covers[p1] = ren.cover(dist);
172 p1 += 1;
173 dx += 1;
174 dist = self.li.dist[dx] - s1;
175 }
176
177 dx = 1;
178 dist = self.li.dist[dx] + s1;
179 while dist <= self.li.width {
180 p0 -= 1;
181 self.li.covers[p0] = ren.cover(dist);
182 dx += 1;
183 dist = self.li.dist[dx] + s1;
184 }
185 ren.blend_solid_hspan(self.li.x - dx as i64 + 1,
186 self.li.y,
187 (p1 - p0) as i64,
188 &self.li.covers[p0..]);
189 self.li.step += 1;
190 self.li.step < self.li.count
191 }
192}
193#[derive(Debug)]
194pub(crate) struct AA1 {
195 di: DistanceInterpolator2,
196 li: LineInterpolatorAA,
197}
198impl AA1 {
199 pub fn new(lp: LineParameters, sx: i64, sy: i64, subpixel_width: i64) -> Self {
200 let mut li = LineInterpolatorAA::new(lp, subpixel_width);
201 let mut di = DistanceInterpolator2::new(lp.x1,lp.y1,lp.x2,lp.y2, sx, sy,
202 lp.x1 & ! POLY_SUBPIXEL_MASK,
203 lp.y1 & ! POLY_SUBPIXEL_MASK,
204 true);
205 let mut npix = 1;
206 if lp.vertical {
207 loop {
208 li.li.dec();
209 li.y -= lp.inc;
210 li.x = (li.lp.x1 + li.li.y) >> POLY_SUBPIXEL_SHIFT;
211
212 if lp.inc > 0 {
213 di.dec_y(li.x - li.old_x);
214 } else {
215 di.inc_y(li.x - li.old_x);
216 }
217 li.old_x = li.x;
218
219 let mut dist1_start = di.dist_start;
220 let mut dist2_start = di.dist_start;
221
222 let mut dx = 0;
223 if dist1_start < 0 {
224 npix += 1;
225 }
226 loop {
227 dist1_start += di.dy_start;
228 dist2_start -= di.dy_start;
229 if dist1_start < 0 {
230 npix += 1;
231 }
232 if dist2_start < 0 {
233 npix += 1
234 }
235 dx += 1;
236 if li.dist[dx] > li.width {
237 break;
238 }
239 }
240 li.step -= 1;
241 if npix == 0 {
242 break;
243 }
244 npix = 0;
245 if li.step < -li.max_extent {
246 break;
247 }
248 }
249 } else {
250 loop {
251 li.li.dec();
252 li.x -= lp.inc;
253 li.y = (li.lp.y1 + li.li.y) >> POLY_SUBPIXEL_SHIFT;
254 if lp.inc > 0 {
255 di.dec_x(li.y - li.old_y);
256 } else {
257 di.inc_x(li.y - li.old_y);
258 }
259 li.old_y = li.y;
260
261 let mut dist1_start = di.dist_start;
262 let mut dist2_start = di.dist_start;
263
264 let mut dy = 0;
265 if dist1_start < 0 {
266 npix += 1;
267 }
268 loop {
269 dist1_start -= di.dx_start;
270 dist2_start += di.dx_start;
271 if dist1_start < 0 {
272 npix += 1;
273 }
274 if dist2_start < 0 {
275 npix += 1;
276 }
277 dy += 1;
278 if li.dist[dy] > li.width {
279 break;
280 }
281 }
282 li.step -= 1;
283 if npix == 0 {
284 break;
285 }
286 npix = 0;
287 if li.step < -li.max_extent {
288 break;
289 }
290 }
291 }
292 li.li.adjust_forward();
293 Self { li, di }
294 }
295 pub fn vertical(&self) -> bool { self.li.lp.vertical }
297 pub fn step_hor<R: RenderOutline>(&mut self, ren: &mut R) -> bool {
298 let s1 = self.li.step_hor_base(&mut self.di);
299
300 let mut dist_start = self.di.dist_start;
301 let mut p0 = MAX_HALF_WIDTH + 2;
302 let mut p1 = p0;
303 self.li.covers[p1] = 0;
304 if dist_start <= 0 {
305 self.li.covers[p1] = ren.cover(s1);
306 }
307 p1 += 1;
308 let mut dy = 1;
309 let mut dist = self.li.dist[dy] - s1;
310 while dist <= self.li.width {
311 dist_start -= self.di.dx_start;
312 self.li.covers[p1] = 0;
313 if dist_start <= 0 {
314 self.li.covers[p1] = ren.cover(dist);
315 }
316 p1 += 1;
317 dy += 1;
318 dist = self.li.dist[dy] - s1;
319 }
320
321 dy = 1;
322 dist_start = self.di.dist_start;
323 dist = self.li.dist[dy] + s1;
324 while dist <= self.li.width {
325 dist_start += self.di.dx_start;
326 p0 -= 1;
327 self.li.covers[p0] = 0;
328 if dist_start <= 0 {
329 self.li.covers[p0] = ren.cover(dist);
330 }
331 dy += 1;
332 dist = self.li.dist[dy] + s1;
333 }
334 ren.blend_solid_vspan(self.li.x,
335 self.li.y - dy as i64 + 1,
336 (p1 - p0) as i64,
337 &self.li.covers[p0..]);
338 self.li.step += 1;
339 self.li.step < self.li.count
340
341 }
342 pub fn step_ver<R: RenderOutline>(&mut self, ren: &mut R) -> bool {
343 let s1 = self.li.step_ver_base(&mut self.di);
344 let mut p0 = MAX_HALF_WIDTH + 2;
345 let mut p1 = p0;
346
347 let mut dist_start = self.di.dist_start;
348 self.li.covers[p1] = 0;
349 if dist_start <= 0 {
350 self.li.covers[p1] = ren.cover(s1);
351 }
352 p1 += 1;
353 let mut dx = 1;
354 let mut dist = self.li.dist[dx] - s1;
355 while dist <= self.li.width {
356 dist_start += self.di.dy_start;
357 self.li.covers[p1] = 0;
358 if dist_start <= 0 {
359 self.li.covers[p1] = ren.cover(dist);
360 }
361 p1 += 1;
362 dx += 1;
363 dist = self.li.dist[dx] - s1;
364 }
365 dx = 1;
366 dist_start = self.di.dist_start;
367 dist = self.li.dist[dx] + s1;
368 while dist <= self.li.width {
369 dist_start -= self.di.dy_start;
370 p0 -= 1;
371 self.li.covers[p0] = 0;
372 if dist_start <= 0 {
373 self.li.covers[p0] = ren.cover(dist);
374 }
375 dx += 1;
376 dist = self.li.dist[dx] + s1;
377 }
378 ren.blend_solid_hspan(self.li.x - dx as i64 + 1,
379 self.li.y,
380 (p1 - p0) as i64,
381 &self.li.covers[p0..]);
382 self.li.step += 1;
383 self.li.step < self.li.count
384 }
385}
386#[derive(Debug)]
387pub(crate) struct AA2 {
388 di: DistanceInterpolator2,
389 li: LineInterpolatorAA,
390}
391impl AA2 {
392 pub fn new(lp: LineParameters, ex: i64, ey: i64, subpixel_width: i64) -> Self {
393 let mut li = LineInterpolatorAA::new(lp, subpixel_width);
394 let di = DistanceInterpolator2::new(lp.x1,lp.y1,lp.x2,lp.y2, ex, ey,
395 lp.x1 & ! POLY_SUBPIXEL_MASK,
396 lp.y1 & ! POLY_SUBPIXEL_MASK,
397 false);
398 li.li.adjust_forward();
399 li.step -= li.max_extent;
400 Self { li, di }
401 }
402 pub fn vertical(&self) -> bool { self.li.lp.vertical }
404 pub fn step_hor<R: RenderOutline>(&mut self, ren: &mut R) -> bool {
405 let s1 = self.li.step_hor_base(&mut self.di);
406 let mut p0 = MAX_HALF_WIDTH + 2;
407 let mut p1 = p0;
408
409 let mut dist_end = self.di.dist_start;
410
411 let mut npix = 0;
412 self.li.covers[p1] = 0;
413 if dist_end > 0 {
414 self.li.covers[p1] = ren.cover(s1);
415 npix += 1;
416 }
417 p1 += 1;
418
419 let mut dy = 1;
420 let mut dist = self.li.dist[dy] - s1;
421 while dist <= self.li.width {
422 dist_end -= self.di.dx_start;
423 self.li.covers[p1] = 0;
424 if dist_end > 0 {
425 self.li.covers[p1] = ren.cover(dist);
426 npix += 1;
427 }
428 p1 += 1;
429 dy += 1;
430 dist = self.li.dist[dy] - s1;
431 }
432
433 dy = 1;
434 dist_end = self.di.dist_start;
435 dist = self.li.dist[dy] + s1;
436 while dist <= self.li.width {
437 dist_end += self.di.dx_start;
438 p0 -= 1;
439 self.li.covers[p0] = 0;
440 if dist_end > 0 {
441 self.li.covers[p0] = ren.cover(dist);
442 npix += 1;
443 }
444 dy += 1;
445 dist = self.li.dist[dy] + s1;
446 }
447 ren.blend_solid_vspan(self.li.x,
448 self.li.y - dy as i64 + 1,
449 (p1 - p0) as i64,
450 &self.li.covers[p0..]);
451 self.li.step += 1;
452 npix != 0 && self.li.step < self.li.count
453 }
454 pub fn step_ver<R: RenderOutline>(&mut self, ren: &mut R) -> bool {
455 let s1 = self.li.step_ver_base(&mut self.di);
456 let mut p0 = MAX_HALF_WIDTH + 2;
457 let mut p1 = p0;
458
459 let mut dist_end = self.di.dist_start; let mut npix = 0;
462 self.li.covers[p1] = 0;
463 if dist_end > 0 {
464 self.li.covers[p1] = ren.cover(s1);
465 npix += 1;
466 }
467 p1 += 1;
468
469 let mut dx = 1;
470 let mut dist = self.li.dist[dx] - s1;
471 while dist <= self.li.width {
472 dist_end += self.di.dy_start;
473 self.li.covers[p1] = 0;
474 if dist_end > 0 {
475 self.li.covers[p1] = ren.cover(dist);
476 npix += 1;
477 }
478 p1 += 1;
479 dx += 1;
480 dist = self.li.dist[dx] - s1;
481 }
482
483 dx = 1;
484 dist_end = self.di.dist_start;
485 dist = self.li.dist[dx] + s1;
486 while dist <= self.li.width {
487 dist_end -= self.di.dy_start;
488 p0 -= 1;
489 self.li.covers[p0] = 0;
490 if dist_end > 0 {
491 self.li.covers[p0] = ren.cover(dist);
492 npix += 1;
493 }
494 dx += 1;
495 dist = self.li.dist[dx] + s1;
496 }
497 ren.blend_solid_hspan(self.li.x - dx as i64 + 1,
498 self.li.y,
499 (p1 - p0) as i64,
500 &self.li.covers[p0..]);
501 self.li.step += 1;
502 npix != 0 && self.li.step < self.li.count
503 }
504}
505#[derive(Debug)]
506pub(crate) struct AA3 {
507 di: DistanceInterpolator3,
508 li: LineInterpolatorAA,
509}
510impl AA3 {
511 pub fn new(lp: LineParameters, sx: i64, sy: i64, ex: i64, ey: i64, subpixel_width: i64) -> Self {
512 let mut li = LineInterpolatorAA::new(lp, subpixel_width);
513 let mut di = DistanceInterpolator3::new(lp.x1, lp.y1, lp.x2, lp.y2,
514 sx, sy, ex, ey,
515 lp.x1 & ! POLY_SUBPIXEL_MASK,
516 lp.y1 & ! POLY_SUBPIXEL_MASK);
517 let mut npix = 1;
518 if lp.vertical {
519 loop {
520 li.li.dec();
521 li.y -= lp.inc;
522 li.x = (li.lp.x1 + li.li.y) >> POLY_SUBPIXEL_SHIFT;
523
524 if lp.inc > 0 {
525 di.dec_y(li.x - li.old_x);
526 } else {
527 di.inc_y(li.x - li.old_x);
528 }
529
530 li.old_x = li.x;
531
532 let mut dist1_start = di.dist_start;
533 let mut dist2_start = di.dist_start;
534
535 let mut dx = 0;
536 if dist1_start < 0 {
537 npix += 1;
538 }
539 loop {
540 dist1_start += di.dy_start;
541 dist2_start -= di.dy_start;
542 if dist1_start < 0 {
543 npix += 1;
544 }
545 if dist2_start < 0 {
546 npix += 1;
547 }
548 dx += 1;
549 if li.dist[dx] > li.width {
550 break;
551 }
552 }
553 if npix == 0 {
554 break;
555 }
556 npix = 0;
557 li.step -= 1;
558 if li.step < -li.max_extent {
559 break;
560 }
561 }
562 } else {
563 loop {
564 li.li.dec();
565 li.x -= lp.inc;
566 li.y = (li.lp.y1 + li.li.y) >> POLY_SUBPIXEL_SHIFT;
567
568 if lp.inc > 0 {
569 di.dec_x(li.y - li.old_y);
570 } else {
571 di.inc_x(li.y - li.old_y);
572 }
573
574 li.old_y = li.y;
575
576 let mut dist1_start = di.dist_start;
577 let mut dist2_start = di.dist_start;
578
579 let mut dy = 0;
580 if dist1_start < 0 {
581 npix += 1;
582 }
583 loop {
584 dist1_start -= di.dx_start;
585 dist2_start += di.dx_start;
586 if dist1_start < 0 {
587 npix += 1;
588 }
589 if dist2_start < 0 {
590 npix += 1;
591 }
592 dy += 1;
593 if li.dist[dy] > li.width {
594 break;
595 }
596 }
597 if npix == 0 {
598 break;
599 }
600 npix = 0;
601 li.step -= 1;
602 if li.step < -li.max_extent {
603 break;
604 }
605 }
606 }
607 li.li.adjust_forward();
608 li.step -= li.max_extent;
609 Self { li, di }
610 }
611 pub fn vertical(&self) -> bool { self.li.lp.vertical }
613 pub fn step_hor<R: RenderOutline>(&mut self, ren: &mut R) -> bool {
614 let s1 = self.li.step_hor_base(&mut self.di);
615 let mut p0 = MAX_HALF_WIDTH + 2;
616 let mut p1 = p0;
617
618 let mut dist_start = self.di.dist_start;
619 let mut dist_end = self.di.dist_end;
620
621 let mut npix = 0;
622 self.li.covers[p1] = 0;
623 if dist_end > 0 {
624 if dist_start <= 0 {
625 self.li.covers[p1] = ren.cover(s1);
626 }
627 npix += 1;
628 }
629 p1 += 1;
630
631 let mut dy = 1;
632 let mut dist = self.li.dist[dy] - s1;
633 while dist <= self.li.width {
634 dist_start -= self.di.dx_start;
635 dist_end -= self.di.dx_end;
636 self.li.covers[p1] = 0;
637 if dist_end > 0 && dist_start <= 0 {
638 self.li.covers[p1] = ren.cover(dist);
639 npix += 1;
640 }
641 p1 += 1;
642 dy += 1;
643 dist = self.li.dist[dy] - s1;
644 }
645
646 dy = 1;
647 dist_start = self.di.dist_start;
648 dist_end = self.di.dist_end;
649 dist = self.li.dist[dy] + s1;
650 while dist <= self.li.width {
651 dist_start += self.di.dx_start;
652 dist_end += self.di.dx_end;
653 p0 -= 1;
654 self.li.covers[p0] = 0;
655 if dist_end > 0 && dist_start <= 0 {
656 self.li.covers[p0] = ren.cover(dist);
657 npix += 1;
658 }
659 dy += 1;
660 }
661 ren.blend_solid_vspan(self.li.x,
662 self.li.y - dy as i64 + 1,
663 (p1 - p0) as i64,
664 &self.li.covers[p0..]);
665 self.li.step -= 1;
666 npix != 0 && self.li.step < self.li.count
667
668 }
669 pub fn step_ver<R: RenderOutline>(&mut self, ren: &mut R) -> bool {
670 let s1 = self.li.step_ver_base(&mut self.di);
671 let mut p0 = MAX_HALF_WIDTH + 2;
672 let mut p1 = p0;
673
674 let mut dist_start = self.di.dist_start;
675 let mut dist_end = self.di.dist_end;
676
677 let mut npix = 0;
678 self.li.covers[p1] = 0;
679 if dist_end > 0 {
680 if dist_start <= 0 {
681 self.li.covers[p1] = ren.cover(s1);
682 }
683 npix += 1;
684 }
685 p1 += 1;
686
687 let mut dx = 1;
688 let mut dist = self.li.dist[dx] - s1;
689 while dist <= self.li.width {
690 dist_start += self.di.dy_start;
691 dist_end += self.di.dy_end;
692 self.li.covers[p1] = 0;
693 if dist_end > 0 && dist_start <= 0 {
694 self.li.covers[p1] = ren.cover(dist);
695 npix += 1;
696 }
697 p1 += 1;
698 dx += 1;
699 dist = self.li.dist[dx] - s1;
700 }
701
702 dx = 1;
703 dist_start = self.di.dist_start;
704 dist_end = self.di.dist_end;
705 dist = self.li.dist[dx] + s1;
706 while dist <= self.li.width {
707 dist_start -= self.di.dy_start;
708 dist_end -= self.di.dy_end;
709 p0 -= 1;
710 self.li.covers[p0] = 0;
711 if dist_end > 0 && dist_start <= 0 {
712 self.li.covers[p0] = ren.cover(dist);
713 npix += 1;
714 }
715 dx += 1;
716 dist = self.li.dist[dx] + s1;
717 }
718 ren.blend_solid_hspan(self.li.x - dx as i64 + 1,
719 self.li.y,
720 (p1 - p0) as i64,
721 &self.li.covers[p0..p1]);
722 self.li.step -= 1;
723 npix != 0&& self.li.step < self.li.count
724
725 }
726}
727
728#[derive(Debug)]
729pub(crate) struct DistanceInterpolator00 {
730 dx1: i64,
731 dy1: i64,
732 dx2: i64,
733 dy2: i64,
734 pub dist1: i64,
735 pub dist2: i64,
736}
737
738impl DistanceInterpolator00 {
739 pub fn new(xc: i64, yc: i64, x1: i64, y1: i64, x2: i64, y2: i64, x: i64, y: i64) -> Self {
740 let dx1 = line_mr(x1) - line_mr(xc);
741 let dy1 = line_mr(y1) - line_mr(yc);
742 let dx2 = line_mr(x2) - line_mr(xc);
743 let dy2 = line_mr(y2) - line_mr(yc);
744 let dist1 = (line_mr(x + POLY_SUBPIXEL_SCALE/2) - line_mr(x1)) * dy1 -
745 (line_mr(y + POLY_SUBPIXEL_SCALE/2) - line_mr(y1)) * dx1;
746 let dist2 = (line_mr(x + POLY_SUBPIXEL_SCALE/2) - line_mr(x2)) * dy2 -
747 (line_mr(y + POLY_SUBPIXEL_SCALE/2) - line_mr(y2)) * dx2;
748 let dx1 = dx1 << POLY_MR_SUBPIXEL_SHIFT;
749 let dy1 = dy1 << POLY_MR_SUBPIXEL_SHIFT;
750 let dx2 = dx2 << POLY_MR_SUBPIXEL_SHIFT;
751 let dy2 = dy2 << POLY_MR_SUBPIXEL_SHIFT;
752
753 Self { dx1, dy1, dx2, dy2, dist1, dist2 }
754 }
755 pub fn inc_x(&mut self) {
756 self.dist1 += self.dy1;
757 self.dist2 += self.dy2;
758 }
759}
760#[derive(Debug)]
761pub(crate) struct DistanceInterpolator0 {
762 dx: i64,
763 dy: i64,
764 pub dist: i64,
765}
766
767impl DistanceInterpolator0 {
768 pub fn new(x1: i64, y1: i64, x2: i64, y2: i64, x: i64, y: i64) -> Self {
769 let dx = line_mr(x2) - line_mr(x1);
770 let dy = line_mr(y2) - line_mr(y1);
771 let dist = (line_mr(x + POLY_SUBPIXEL_SCALE/2) - line_mr(x2)) * dy -
772 (line_mr(y + POLY_SUBPIXEL_SCALE/2) - line_mr(y2)) * dx;
773 let dx = dx << POLY_MR_SUBPIXEL_SHIFT;
774 let dy = dy << POLY_MR_SUBPIXEL_SHIFT;
775 Self { dx, dy, dist }
776 }
777 pub fn inc_x(&mut self) {
778 self.dist += self.dy;
779 }
780}
781#[derive(Debug)]
782struct DistanceInterpolator1 {
783 dx: i64,
784 dy: i64,
785 pub dist: i64
786}
787#[derive(Debug)]
788struct DistanceInterpolator2 {
789 dx: i64,
790 dy: i64,
791 dx_start: i64,
792 dy_start: i64,
793 dist: i64,
794 dist_start: i64,
795}
796#[derive(Debug)]
797struct DistanceInterpolator3 {
798 dx: i64,
799 dy: i64,
800 dx_start: i64,
801 dy_start: i64,
802 dx_end: i64,
803 dy_end: i64,
804 dist: i64,
805 dist_start: i64,
806 dist_end: i64,
807}
808impl DistanceInterpolator1 {
809 pub fn new(x1: i64, y1: i64, x2: i64, y2: i64, x: i64, y: i64) -> Self {
810 let dx = x2-x1;
811 let dy = y2-y1;
812 let dist_fp = (x + POLY_SUBPIXEL_SCALE/2 - x2) as f64 * dy as f64 -
813 (y + POLY_SUBPIXEL_SCALE/2 - y2) as f64 * dx as f64;
814 let dist = dist_fp.round() as i64;
815 let dx = dx << POLY_SUBPIXEL_SHIFT;
816 let dy = dy << POLY_SUBPIXEL_SHIFT;
817 Self { dist, dx, dy }
818 }
819}
820impl DistanceInterpolator for DistanceInterpolator1 {
821 fn dist(&self) -> i64 {
822 self.dist
823 }
824 fn inc_x(&mut self, dy: i64) {
825 self.dist += self.dy;
826 if dy > 0 {
827 self.dist -= self.dx;
828 }
829 if dy < 0 {
830 self.dist += self.dx;
831 }
832 }
833 fn dec_x(&mut self, dy: i64) {
834 self.dist -= self.dy;
835 if dy > 0 {
836 self.dist -= self.dx;
837 }
838 if dy < 0 {
839 self.dist += self.dx;
840 }
841 }
842 fn inc_y(&mut self, dx: i64) {
843 self.dist -= self.dx;
844 if dx > 0 {
845 self.dist += self.dy;
846 }
847 if dx < 0 {
848 self.dist -= self.dy;
849 }
850 }
851 fn dec_y(&mut self, dx: i64) {
852 self.dist += self.dx;
853 if dx > 0 {
854 self.dist += self.dy;
855 }
856 if dx < 0 {
857 self.dist -= self.dy;
858 }
859 }
860}
861
862
863pub(crate) fn line_mr(x: i64) -> i64 {
864 x >> (POLY_SUBPIXEL_SHIFT - POLY_MR_SUBPIXEL_SHIFT)
865}
866
867impl DistanceInterpolator2 {
868 pub fn new(x1: i64, y1: i64, x2: i64, y2: i64,
869 sx: i64, sy: i64, x: i64, y: i64, start: bool) -> Self {
870 let dx = x2-x1;
871 let dy = y2-y1;
872 let (dx_start, dy_start) = if start {
873 (line_mr(sx) - line_mr(x1), line_mr(sy) - line_mr(y1))
874 } else {
875 (line_mr(sx) - line_mr(x2), line_mr(sy) - line_mr(y2))
876 };
877 let dist = (x + POLY_SUBPIXEL_SCALE/2 - x2) as f64 * dy as f64 -
878 (y + POLY_SUBPIXEL_SCALE/2 - y2) as f64 * dx as f64;
879 let dist = dist.round() as i64;
880 let dist_start = (line_mr(x + POLY_SUBPIXEL_SCALE/2) - line_mr(sx)) * dy_start -
881 (line_mr(y + POLY_SUBPIXEL_SCALE/2) - line_mr(sy)) * dx_start;
882 let dx = dx << POLY_SUBPIXEL_SHIFT;
883 let dy = dy << POLY_SUBPIXEL_SHIFT;
884 let dx_start = dx_start << POLY_MR_SUBPIXEL_SHIFT;
885 let dy_start = dy_start << POLY_MR_SUBPIXEL_SHIFT;
886
887 Self { dx, dy, dx_start, dy_start, dist, dist_start }
888 }
889}
890
891impl DistanceInterpolator for DistanceInterpolator2 {
892 fn dist(&self) -> i64 {
893 self.dist
894 }
895 fn inc_x(&mut self, dy: i64) {
896 self.dist += self.dy;
897 self.dist_start += self.dy_start;
898 if dy > 0 {
899 self.dist -= self.dx;
900 self.dist_start -= self.dx_start;
901 }
902 if dy < 0 {
903 self.dist += self.dx;
904 self.dist_start += self.dx_start;
905 }
906 }
907 fn inc_y(&mut self, dx: i64) {
908 self.dist -= self.dx;
909 self.dist_start -= self.dx_start;
910 if dx > 0 {
911 self.dist += self.dy;
912 self.dist_start += self.dy_start;
913 }
914 if dx < 0 {
915 self.dist -= self.dy;
916 self.dist_start -= self.dy_start;
917 }
918 }
919 fn dec_x(&mut self, dy: i64) {
920 self.dist -= self.dy;
921 self.dist_start -= self.dy_start;
922 if dy > 0 {
923 self.dist -= self.dx;
924 self.dist_start -= self.dx_start;
925 }
926 if dy < 0 {
927 self.dist += self.dx;
928 self.dist_start += self.dx_start;
929 }
930 }
931 fn dec_y(&mut self, dx: i64) {
932 self.dist += self.dx;
933 self.dist_start += self.dx_start;
934 if dx > 0 {
935 self.dist += self.dy;
936 self.dist_start += self.dy_start;
937 }
938 if dx < 0 {
939 self.dist -= self.dy;
940 self.dist_start -= self.dy_start;
941 }
942 }
943}
944
945impl DistanceInterpolator3 {
946 pub fn new(x1: i64, y1: i64, x2: i64, y2: i64,
947 sx: i64, sy: i64, ex: i64, ey: i64,
948 x: i64, y: i64) -> Self {
949 let dx = x2-x1;
950 let dy = y2-y1;
951 let dx_start = line_mr(sx) - line_mr(x1);
952 let dy_start = line_mr(sy) - line_mr(y1);
953 let dx_end = line_mr(ex) - line_mr(x2);
954 let dy_end = line_mr(ey) - line_mr(y2);
955
956 let dist = (x + POLY_SUBPIXEL_SCALE/2 - x2) as f64 * dy as f64 -
957 (y + POLY_SUBPIXEL_SCALE/2 - y2) as f64 * dx as f64;
958 let dist = dist.round() as i64;
959 let dist_start = (line_mr(x + POLY_SUBPIXEL_SCALE/2) - line_mr(sx)) * dy_start -
960 (line_mr(y + POLY_SUBPIXEL_SCALE/2) - line_mr(sy)) * dx_start;
961 let dist_end = (line_mr(x + POLY_SUBPIXEL_SCALE/2) - line_mr(ex)) * dy_end -
962 (line_mr(y + POLY_SUBPIXEL_SCALE/2) - line_mr(ey)) * dx_end;
963
964
965 let dx = dx << POLY_SUBPIXEL_SHIFT;
966 let dy = dy << POLY_SUBPIXEL_SHIFT;
967 let dx_start = dx_start << POLY_MR_SUBPIXEL_SHIFT;
968 let dy_start = dy_start << POLY_MR_SUBPIXEL_SHIFT;
969 let dx_end = dx_end << POLY_MR_SUBPIXEL_SHIFT;
970 let dy_end = dy_end << POLY_MR_SUBPIXEL_SHIFT;
971 Self {
972 dx, dy, dx_start, dy_start, dx_end, dy_end, dist_start, dist_end, dist
973 }
974 }
975}
976
977impl DistanceInterpolator for DistanceInterpolator3 {
978 fn dist(&self) -> i64 {
979 self.dist
980 }
981 fn inc_x(&mut self, dy: i64) {
982 self.dist += self.dy;
983 self.dist_start += self.dy_start;
984 self.dist_end += self.dy_end;
985 if dy > 0 {
986 self.dist -= self.dx;
987 self.dist_start -= self.dx_start;
988 self.dist_end -= self.dx_end;
989 }
990 if dy < 0 {
991 self.dist += self.dx;
992 self.dist_start += self.dx_start;
993 self.dist_end += self.dx_end;
994 }
995 }
996 fn inc_y(&mut self, dx: i64) {
997 self.dist -= self.dx;
998 self.dist_start -= self.dx_start;
999 self.dist_end -= self.dx_end;
1000 if dx > 0 {
1001 self.dist += self.dy;
1002 self.dist_start += self.dy_start;
1003 self.dist_end += self.dy_end;
1004 }
1005 if dx < 0 {
1006 self.dist -= self.dy;
1007 self.dist_start -= self.dy_start;
1008 self.dist_end -= self.dy_end;
1009 }
1010 }
1011 fn dec_x(&mut self, dy: i64) {
1012 self.dist -= self.dy;
1013 self.dist_start -= self.dy_start;
1014 self.dist_end -= self.dy_end;
1015 if dy > 0 {
1016 self.dist -= self.dx;
1017 self.dist_start -= self.dx_start;
1018 self.dist_end -= self.dx_end;
1019 }
1020 if dy < 0 {
1021 self.dist += self.dx;
1022 self.dist_start += self.dx_start;
1023 self.dist_end += self.dx_end;
1024 }
1025 }
1026 fn dec_y(&mut self, dx: i64) {
1027 self.dist += self.dx;
1028 self.dist_start += self.dx_start;
1029 self.dist_end += self.dx_end;
1030 if dx > 0 {
1031 self.dist += self.dy;
1032 self.dist_start += self.dy_start;
1033 self.dist_end += self.dy_end;
1034 }
1035 if dx < 0 {
1036 self.dist -= self.dy;
1037 self.dist_start -= self.dy_start;
1038 self.dist_end -= self.dy_end;
1039 }
1040 }
1041}
1042
1043
1044#[derive(Debug,Default)]
1045pub struct DrawVars {
1046 pub idx: usize,
1047 pub x1: i64,
1048 pub y1: i64,
1049 pub x2: i64,
1050 pub y2: i64,
1051 pub curr: LineParameters,
1052 pub next: LineParameters,
1053 pub lcurr: i64,
1054 pub lnext: i64,
1055 pub xb1: i64,
1056 pub yb1: i64,
1057 pub xb2: i64,
1058 pub yb2: i64,
1059 pub flags: u8,
1060}
1061
1062impl DrawVars {
1063 pub fn new() -> Self {
1064 Self { .. Default::default() }
1065 }
1066}
1067#[derive(Debug,Default,Copy,Clone)]
1068pub struct LineParameters {
1069 pub x1: i64,
1070 pub y1: i64,
1071 pub x2: i64,
1072 pub y2: i64,
1073 pub dx: i64,
1074 pub dy: i64,
1075 pub sx: i64,
1076 pub sy: i64,
1077 pub vertical: bool,
1078 pub inc: i64,
1079 pub len: i64,
1080 pub octant: usize,
1081}
1082
1083impl LineParameters {
1084 pub fn new(x1: i64, y1: i64, x2: i64, y2: i64, len: i64) -> Self {
1085 let dx = (x2-x1).abs();
1086 let dy = (y2-y1).abs();
1087 let vertical = dy >= dx;
1088 let sx = if x2 > x1 { 1 } else { -1 };
1089 let sy = if y2 > y1 { 1 } else { -1 };
1090 let inc = if vertical { sy } else { sx };
1091 let octant = (sy & 4) as usize | (sx & 2) as usize | vertical as usize;
1092 Self {x1,y1,x2,y2,len,dx,dy,vertical,sx,sy,inc,octant}
1093 }
1094 pub fn diagonal_quadrant(&self) -> u8 {
1095 let quads = [0,1,2,1,0,3,2,3];
1096 quads[ self.octant ]
1097 }
1098 pub fn divide(&self) -> (LineParameters, LineParameters) {
1099 let xmid = (self.x1+self.x2) / 2;
1100 let ymid = (self.y1+self.y2) / 2;
1101 let len2 = self.len / 2;
1102
1103 let lp1 = LineParameters::new(self.x1, self.y1, xmid, ymid, len2);
1104 let lp2 = LineParameters::new(xmid, ymid, self.x2, self.y2, len2);
1105
1106 (lp1, lp2)
1107 }
1108 fn fix_degenerate_bisectrix_setup(&self, x: i64, y: i64) -> i64 {
1109 let dx = (self.x2 - self.x1) as f64;
1110 let dy = (self.y2 - self.y1) as f64;
1111 let dx0 = (x - self.x2) as f64;
1112 let dy0 = (y - self.y2) as f64;
1113 let len = self.len as f64;
1114 ((dx0 * dy - dy0 * dx) / len).round() as i64
1115 }
1116 pub fn fix_degenerate_bisectrix_end(&self, x: i64, y: i64) -> (i64, i64) {
1117 let d = self.fix_degenerate_bisectrix_setup(x,y);
1118 if d < POLY_SUBPIXEL_SCALE / 2 {
1119 (self.x2 + (self.y2 - self.y1), self.y2 - (self.x2 - self.x1))
1120 } else {
1121 (x,y)
1122 }
1123 }
1124 pub fn fix_degenerate_bisectrix_start(&self, x: i64, y: i64) -> (i64, i64) {
1125 let d = self.fix_degenerate_bisectrix_setup(x,y);
1126 if d < POLY_SUBPIXEL_SCALE / 2 {
1127 (self.x1 + (self.y2 - self.y1), self.y1 - (self.x2 - self.x1))
1128 } else {
1129 (x,y)
1130 }
1131 }
1132 pub(crate) fn interp0(&self, subpixel_width: i64) -> AA0 {
1133 AA0::new(*self, subpixel_width)
1134 }
1135 pub(crate) fn interp1(&self, sx: i64, sy: i64, subpixel_width: i64) -> AA1 {
1136 AA1::new(*self, sx, sy, subpixel_width)
1137 }
1138 pub(crate) fn interp2(&self, ex: i64, ey: i64, subpixel_width: i64) -> AA2 {
1139 AA2::new(*self, ex, ey, subpixel_width)
1140 }
1141 pub(crate) fn interp3(&self, sx: i64, sy: i64, ex: i64, ey: i64, subpixel_width: i64) -> AA3 {
1142 AA3::new(*self, sx, sy, ex, ey, subpixel_width)
1143 }
1144 pub fn interp_image(&self, sx: i64, sy: i64, ex: i64, ey: i64, subpixel_width: i64, pattern_start: i64, pattern_width: i64, scale_x: f64) -> LineInterpolatorImage {
1145 LineInterpolatorImage::new(*self, sx, sy, ex, ey,
1146 subpixel_width, pattern_start,
1147 pattern_width, scale_x)
1148 }
1149}