FastLED 3.10.8
Loading...
Searching...
No Matches

◆ drawLineCore()

template<typename PixelT, typename Coord, bool Overwrite>
void fl::gfx::detail::drawLineCore ( Canvas< PixelT > & canvas,
const PixelT & color,
Coord x0,
Coord y0,
Coord x1,
Coord y1 )
inline

Definition at line 532 of file primitives.h.

533 {
534 PixelT* pixels = canvas.pixels;
535 int width = canvas.width;
536 int height = canvas.height;
537
538 // Convert to 8.8 fixed-point
539 fl::i32 fx0 = detail::toFixed8(x0);
540 fl::i32 fy0 = detail::toFixed8(y0);
541 fl::i32 fx1 = detail::toFixed8(x1);
542 fl::i32 fy1 = detail::toFixed8(y1);
543
544 bool steep = fl::abs(fy1 - fy0) > fl::abs(fx1 - fx0);
545 if (steep) { fl::swap(fx0, fy0); fl::swap(fx1, fy1); }
546 if (fx0 > fx1) { fl::swap(fx0, fx1); fl::swap(fy0, fy1); }
547
548 fl::i32 dx8 = fx1 - fx0;
549 fl::i32 dy8 = fy1 - fy0;
550
551 // Gradient per pixel step in 8.8: (dy * 256) / dx
552 fl::i32 gradient = (dx8 == 0) ? 0 : ((dy8 << 8) / dx8);
553
554 // First endpoint: round x to nearest pixel boundary
555 fl::i32 xend = (fx0 + 128) & ~0xFF;
556 fl::i32 yend = fy0 + ((gradient * (xend - fx0)) >> 8);
557 fl::i32 xgap = 256 - ((fx0 + 128) & 0xFF); // rfpart(x0 + 0.5)
558 int xpxl1 = xend >> 8;
559 int ypxl1 = yend >> 8;
560 fl::u8 yfrac1 = static_cast<fl::u8>(yend & 0xFF);
561
562 // Second endpoint
563 fl::i32 xend2 = (fx1 + 128) & ~0xFF;
564 fl::i32 yend2 = fy1 + ((gradient * (xend2 - fx1)) >> 8);
565 fl::i32 xgap2 = (fx1 + 128) & 0xFF; // fpart(x1 + 0.5)
566 int xpxl2 = xend2 >> 8;
567 int ypxl2 = yend2 >> 8;
568 fl::u8 yfrac2 = static_cast<fl::u8>(yend2 & 0xFF);
569
570 // Draw first endpoint
571 {
572 fl::u8 b1 = static_cast<fl::u8>(((255 - yfrac1) * xgap) >> 8);
573 fl::u8 b2 = static_cast<fl::u8>((yfrac1 * xgap) >> 8);
574 if (steep) {
575 PixelT c = color; c.nscale8(b1);
576 addPixelToBuffer<PixelT, Overwrite>(pixels, width, height, ypxl1, xpxl1, c);
577 c = color; c.nscale8(b2);
578 addPixelToBuffer<PixelT, Overwrite>(pixels, width, height, ypxl1 + 1, xpxl1, c);
579 } else {
580 PixelT c = color; c.nscale8(b1);
581 addPixelToBuffer<PixelT, Overwrite>(pixels, width, height, xpxl1, ypxl1, c);
582 c = color; c.nscale8(b2);
583 addPixelToBuffer<PixelT, Overwrite>(pixels, width, height, xpxl1, ypxl1 + 1, c);
584 }
585 }
586
587 // Draw second endpoint
588 {
589 fl::u8 b1 = static_cast<fl::u8>(((255 - yfrac2) * xgap2) >> 8);
590 fl::u8 b2 = static_cast<fl::u8>((yfrac2 * xgap2) >> 8);
591 if (steep) {
592 PixelT c = color; c.nscale8(b1);
593 addPixelToBuffer<PixelT, Overwrite>(pixels, width, height, ypxl2, xpxl2, c);
594 c = color; c.nscale8(b2);
595 addPixelToBuffer<PixelT, Overwrite>(pixels, width, height, ypxl2 + 1, xpxl2, c);
596 } else {
597 PixelT c = color; c.nscale8(b1);
598 addPixelToBuffer<PixelT, Overwrite>(pixels, width, height, xpxl2, ypxl2, c);
599 c = color; c.nscale8(b2);
600 addPixelToBuffer<PixelT, Overwrite>(pixels, width, height, xpxl2, ypxl2 + 1, c);
601 }
602 }
603
604 // Main loop: integer counter, 8.8 intery accumulation
605 fl::i32 intery = yend + gradient;
606 if (steep) {
607 for (int x = xpxl1 + 1; x < xpxl2; ++x) {
608 int y = intery >> 8;
609 fl::u8 frac = static_cast<fl::u8>(intery & 0xFF);
610 PixelT c = color; c.nscale8(255 - frac);
612 c = color; c.nscale8(frac);
614 intery += gradient;
615 }
616 } else {
617 for (int x = xpxl1 + 1; x < xpxl2; ++x) {
618 int y = intery >> 8;
619 fl::u8 frac = static_cast<fl::u8>(intery & 0xFF);
620 PixelT c = color; c.nscale8(255 - frac);
622 c = color; c.nscale8(frac);
624 intery += gradient;
625 }
626 }
627}
fl::i32 toFixed8(Coord val) FL_NO_EXCEPT
Convert any Coord type to 8.8 fixed-point (fl::i32).
Definition primitives.h:182
void addPixelToBuffer(PixelT *pixels, int width, int height, int x, int y, const PixelT &color) FL_NO_EXCEPT
Internal helper: add or set pixel to rectangular buffer with bounds checking Direct row-major indexin...
Definition primitives.h:124
unsigned char u8
Definition stdint.h:131
void swap(array< T, N > &lhs, array< T, N > &rhs) FL_NO_EXCEPT
Definition array.h:209
u8 u8 height
Definition blur.h:186
u8 width
Definition blur.h:186
constexpr enable_if< is_fixed_point< T >::value, T >::type abs(T x) FL_NO_EXCEPT
RGB_T * pixels
Definition canvas.h:72

References fl::abs(), fl::gfx::addPixelToBuffer(), fl::FL_NO_EXCEPT, fl::height, fl::swap(), toFixed8(), fl::width, fl::x, and fl::y.

Referenced by fl::gfx::drawLine().

+ Here is the call graph for this function:
+ Here is the caller graph for this function: