FastLED 3.9.15
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 530 of file primitives.h.

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

References fl::abs(), fl::gfx::addPixelToBuffer(), fl::gfx::Canvas< RGB_T >::height, fl::height, fl::gfx::Canvas< RGB_T >::pixels, fl::fl::swap(), toFixed8(), fl::gfx::Canvas< RGB_T >::width, 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: