agg/
line_interp.rs

1
2use crate::render::LineInterpolator;
3use crate::render::LineInterpolatorImage;
4//use crate::render::RendererPrimatives;
5
6use 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    //pub dist: [i64; MAX_HALF_WIDTH + 1],
28    dist: Vec<i64>,
29    //pub covers: [u64; MAX_HALF_WIDTH * 2 + 4],
30    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 count(&self) -> i64 {        self.li.count    }
296    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 count(&self) -> i64 {        self.li.count    }
403    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; // Really dist_end
460
461        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 count(&self) -> i64 {        self.li.count    }
612    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}