| 818 | // --------------------------------------------------------------------------- |
| 819 | template<typename PixelT, typename Coord, bool Overwrite> |
| 820 | inline void detail::drawStrokeLineCore(Canvas<PixelT>& canvas, const PixelT& color, |
| 821 | Coord x0, Coord y0, Coord x1, Coord y1, |
| 822 | Coord thickness, LineCap cap) { |
| 823 | PixelT* pixels = canvas.pixels; |
| 824 | int width = canvas.width; |
| 825 | int height = canvas.height; |
| 826 | |
| 827 | fl::i32 x0_8 = detail::toFixed8(x0), y0_8 = detail::toFixed8(y0); |
| 828 | fl::i32 x1_8 = detail::toFixed8(x1), y1_8 = detail::toFixed8(y1); |
| 829 | fl::i32 dx_8 = x1_8 - x0_8; |
| 830 | fl::i32 dy_8 = y1_8 - y0_8; |
| 831 | if (dx_8 == 0 && dy_8 == 0) return; |
| 832 | |
| 833 | fl::i32 len2_16 = dx_8 * dx_8 + dy_8 * dy_8; |
| 834 | fl::i32 len_8 = static_cast<fl::i32>( |
| 835 | fl::isqrt32(static_cast<fl::u32>(len2_16))); |
| 836 | fl::i32 thickness_8 = detail::toFixed8(thickness); |
| 837 | fl::i32 r_max_8 = thickness_8 >> 1; |
| 838 | fl::i32 threshold_q = r_max_8 * len_8; |
| 839 | |
| 840 | if (threshold_q <= 0) return; |
| 841 | |
| 842 | int x0i = x0_8 >> 8, y0i = y0_8 >> 8; |
| 843 | int x1i = x1_8 >> 8, y1i = y1_8 >> 8; |
| 844 | int margin = ((r_max_8 + 255) >> 8) + 2; |
| 845 | int xmin = (x0i < x1i ? x0i : x1i) - margin; |
| 846 | int xmax = (x0i > x1i ? x0i : x1i) + margin; |
| 847 | int ymin = (y0i < y1i ? y0i : y1i) - margin; |
| 848 | int ymax = (y0i > y1i ? y0i : y1i) + margin; |
| 849 | |
| 850 | if (xmin < 0) xmin = 0; |
| 851 | if (xmax >= width) xmax = width - 1; |
| 852 | if (ymin < 0) ymin = 0; |
| 853 | if (ymax >= height) ymax = height - 1; |
| 854 | if (xmin > xmax || ymin > ymax) return; |
| 855 | |
| 856 | fl::i32 dx_q = dx_8 << 8; |
| 857 | fl::i32 dy_q = dy_8 << 8; |
| 858 | |
| 859 | fl::i32 rx_base_8 = (static_cast<fl::i32>(xmin) << 8) - x0_8; |
| 860 | fl::i32 ry_row_8 = (static_cast<fl::i32>(ymin) << 8) - y0_8; |
| 861 | fl::i32 cross_row_q = rx_base_8 * dy_8 - ry_row_8 * dx_8; |
| 862 | fl::i32 dot_row_q = rx_base_8 * dx_8 + ry_row_8 * dy_8; |
| 863 | |
| 864 | fl::i32 len2_q = len_8 * len_8; |
| 865 | fl::i32 dot_ext_q = (cap == LineCap::SQUARE) ? threshold_q : 0; |
| 866 | |
| 867 | detail::StrokeCtx<PixelT> sc; |
| 868 | sc.threshold_q = threshold_q; |
| 869 | sc.len2_q = len2_q; |
| 870 | sc.dx_q = dx_q; |
| 871 | sc.dy_q = dy_q; |
| 872 | sc.dot_ext_q = dot_ext_q; |
| 873 | detail::computeBandShift(threshold_q, sc.aa_shift, sc.aa_inv); |
| 874 | sc.x0_8 = x0_8; sc.y0_8 = y0_8; |
| 875 | sc.x1_8 = x1_8; sc.y1_8 = y1_8; |
| 876 | sc.r_max2_8 = r_max_8 * r_max_8; |
| 877 | sc.cap_shift = 0; sc.cap_inv = 0; |
nothing calls this directly
no test coverage detected